Index: trunk/extensions/MetavidWiki/includes/MV_ImageGallery.php |
— | — | @@ -67,11 +67,10 @@ |
68 | 68 | # handlers since they may emit block-level elements as opposed to simple <img> tags. |
69 | 69 | # ref http://css-discuss.incutio.com/?page=CenteringBlockElement |
70 | 70 | . '<div style="margin-left: auto; margin-right: auto; width: ' . htmlspecialchars( $this->mWidths ) . 'px;">' |
71 | | - . $mvTitle->getEmbedVideoHtml( array('size'=>$vidRes ) ) |
72 | | - // . '<img width="'.$this->mWidths.'" src="'.$mvTitle->getStreamImageURL() . '">' |
| 71 | + . $sk->makeKnownLinkObj( $nt, '<img title="'. htmlspecialchars($mvTitle->getStreamNameText()) .'"' |
| 72 | + . ' width="160" height="120" src="'.$mvTitle->getStreamImageURL('160x120') . '">') |
73 | 73 | . '</div>' . |
74 | 74 | '</div>' . |
75 | | - '<div style="clear:both;"></div>' . |
76 | 75 | // @@todo clean up link |
77 | 76 | '<span class="gallerytext" style="float:left">' . |
78 | 77 | $sk->makeKnownLinkObj( $nt, $mvTitle->getStreamNameText() . ' ' . $mvTitle->getTimeDesc() ) . |
Index: trunk/extensions/MetavidWiki/includes/MV_Title.php |
— | — | @@ -358,7 +358,7 @@ |
359 | 359 | }*/ |
360 | 360 | $o .= '<' . htmlspecialchars( $tag ) . ' '; |
361 | 361 | $o .= ( $vid_id == '' ) ? '':' id="' . htmlspecialchars( $vid_id ) . '" '; |
362 | | - $o .= 'thumbnail="' . $this->getStreamImageURL( $size, null, $force_server ) . '" ' . |
| 362 | + $o .= 'poster="' . $this->getStreamImageURL( $size, null, $force_server ) . '" ' . |
363 | 363 | 'roe="' . $roe_url . '" '; |
364 | 364 | $o .= ($showmeta)?'show_meta_link="true" ':'show_meta_link="false" ' ; |
365 | 365 | |
Index: trunk/extensions/MetavidWiki/skins/mv_stream.js |
— | — | @@ -239,37 +239,32 @@ |
240 | 240 | mvdOver:function(mvd_id){ |
241 | 241 | js_log('f:mvdOver' + mvd_id ); |
242 | 242 | var vid_elm = $j('#embed_vid').get(0); |
243 | | - if( mv_lock_vid_updates ){ |
244 | | - js_log('f:mvdOver' + mvd_id + ' updates locked'); |
245 | | - if(!vid_elm.onClipDone_disp){ |
246 | | - this.delay_cur_mvd_id= mvd_id; |
247 | | - setTimeout("mv_stream_interface.delayDoVidMvdUpdate()", 250); |
248 | | - } |
249 | | - }else{ |
250 | | - this.cur_mvd_id=this.delay_cur_mvd_id=mvd_id; |
251 | | - do_video_mvd_update(mvd_id); |
252 | | - } |
| 243 | + //never do mvdOver while video is playing: |
| 244 | + if( vid_elm.isPlaying() ){ |
| 245 | + return false; |
| 246 | + } |
| 247 | + //stop the video if not already stopped |
| 248 | + vid_elm.stop(); |
| 249 | + mv_lock_vid_updates=false; |
| 250 | + //set the onClipDone_disp to false: |
| 251 | + this.cur_mvd_id=this.delay_cur_mvd_id=mvd_id; |
| 252 | + do_video_mvd_update(mvd_id); |
253 | 253 | highlight_tl_ts(mvd_id); |
254 | | - highlight_fd(mvd_id); |
| 254 | + highlight_fd(mvd_id); |
255 | 255 | }, |
256 | | - mvdOut:function(mvd_id){ |
257 | | - js_log('do out ' + mvd_id ); |
258 | | - this.cur_mvd_id='base'; |
259 | | - de_highlight_tl_ts(mvd_id); |
260 | | - de_highlight_fd(mvd_id); |
261 | | - js_log('calling interface restore: '); |
262 | | - setTimeout('mv_stream_interface.doRestore()',500); |
263 | | - //activiate over on time restore |
264 | | - /*$j('#mv_stream_time').hoverIntent({ |
265 | | - interval:200, //polling interval |
266 | | - timeout:200, //delay before onMouseOut |
267 | | - over:function(){ |
268 | | - mv_stream_interface.doRestore(); |
269 | | - }, |
270 | | - out:function(){ |
271 | | - |
272 | | - } |
273 | | - });*/ |
| 256 | + mvdOut:function(mvd_id){ |
| 257 | + var vid_elm = $j('#embed_vid').get(0); |
| 258 | + //only proccess out if in "stoped" state |
| 259 | + if( vid_elm.isStoped() ){ |
| 260 | + js_log('do out ' + mvd_id ); |
| 261 | + this.cur_mvd_id='base'; |
| 262 | + de_highlight_tl_ts(mvd_id); |
| 263 | + de_highlight_fd(mvd_id); |
| 264 | + js_log('calling interface restore: '); |
| 265 | + setTimeout('mv_stream_interface.doRestore()',500); |
| 266 | + }else{ |
| 267 | + setTimeout('mv_stream_interface.mvdOut(\''+mvd_id+'\')',100); |
| 268 | + } |
274 | 269 | }, |
275 | 270 | //delay video updates until we are not playing the clip and clipEnd is not displayed |
276 | 271 | delayDoVidMvdUpdate:function(){ |
— | — | @@ -1017,7 +1012,7 @@ |
1018 | 1013 | //get the current thumbnail |
1019 | 1014 | var vid_elm = document.getElementById('embed_vid'); |
1020 | 1015 | if(!vid_elm)return ''; |
1021 | | - //make the play button visable again (if its hidden) : |
| 1016 | + //make the play button vissable again (if its hidden) : |
1022 | 1017 | $j('#big_play_link_embed_vid').show(); |
1023 | 1018 | do_video_time_update(time_ary[1], time_ary[2],mvd_id); |
1024 | 1019 | } |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer-3.0.0-rc2.swf |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer.controls-3.0.0-beta5.swf |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/FlowPlayerDark.swf |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_sequencer.js |
— | — | @@ -100,8 +100,6 @@ |
101 | 101 | for(var i in sequencerDefaultValues){ |
102 | 102 | this[ i ] = sequencerDefaultValues[i]; |
103 | 103 | } |
104 | | - //@@todo deal with multi-dimensional object updates |
105 | | - // (ie one word in wfMsg does not replace the whole wfMsg default set) |
106 | 104 | for(var i in initObj){ |
107 | 105 | //js_log('on '+ i + ' :' + initObj[i]); |
108 | 106 | if(sequencerDefaultValues[i]){ //make sure its a valid property |
— | — | @@ -152,7 +150,8 @@ |
153 | 151 | |
154 | 152 | js_log('set: '+this.sequence_container_id + ' html to:'+ "\n"+ |
155 | 153 | $j('#'+this.sequence_container_id).html() |
156 | | - ); |
| 154 | + ); |
| 155 | + |
157 | 156 | //add src based pl: |
158 | 157 | if( this.mv_pl_src != 'null' ) { |
159 | 158 | js_log( ' pl src:: '+ this.mv_pl_src ); |
— | — | @@ -339,7 +338,7 @@ |
340 | 339 | var track_height=this.track_clipThumb_height; |
341 | 340 | //add in play box and container tracks |
342 | 341 | $j('#'+this.timeline_id).append(''+ |
343 | | - '<div id="container_track_'+i+'" style="position:absolute;top:'+top_pos+'px;height:'+(track_height+20)+'px;left:10px;right:0px;" class="container_track">' + |
| 342 | + '<div id="container_track_'+i+'" style="position:absolute;top:20px;height:'+(track_height+20)+'px;left:10px;right:0px;" class="container_track">' + |
344 | 343 | '</div>' |
345 | 344 | ); |
346 | 345 | top_pos+=track_height+20; |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_playlist.js |
— | — | @@ -64,7 +64,7 @@ |
65 | 65 | seq_thumb:.25, //size for thumbnails (same as seq by default) |
66 | 66 | seq_nav:0, //for a nav bar at the base (currently disabled) |
67 | 67 | //some pl_layout info: |
68 | | - title_bar_height:20, |
| 68 | + title_bar_height:17, |
69 | 69 | control_height:29 |
70 | 70 | }, |
71 | 71 | init : function(element){ |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_playlists.php |
— | — | @@ -60,7 +60,7 @@ |
61 | 61 | <table border="1" cellpadding="6" width="600"> |
62 | 62 | <? foreach ( $sample_embed as $key => $aval ) { |
63 | 63 | // $key!=8 |
64 | | - if ( $key != 9 )continue; |
| 64 | + if ( $key != 9 && $key != 8)continue; |
65 | 65 | ?> |
66 | 66 | <tr> |
67 | 67 | <td valign="top"><?=$aval['tag']?></td> |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_page.php |
— | — | @@ -43,7 +43,7 @@ |
44 | 44 | $sample_embed[1]['tag'] = '<video roe="http://metavid.org/wiki/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_06-06-06_1&t=0:07:50/0:09:06">'; |
45 | 45 | $sample_embed[1]['desc'] = 'Demo of json ROE attribute'; |
46 | 46 | |
47 | | -$sample_embed[3]['tag'] = '<video roe="http://metavid.org/mvw-exp/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_08-01-07&t=0:11:40/0:12:20" ></video>'; |
| 47 | +$sample_embed[3]['tag'] = '<video roe="http://metavid.org/w/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_08-01-07&t=0:11:40/0:12:20" ></video>'; |
48 | 48 | $sample_embed[3]['desc'] = 'Demo of ROE only attribute'; |
49 | 49 | |
50 | 50 | |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/README.txt |
— | — | @@ -0,0 +1,52 @@ |
| 2 | +Version history: |
| 3 | + |
| 4 | +RC2 |
| 5 | +--- |
| 6 | +- fixed: setting the screen height in configuration did not have any effect |
| 7 | + |
| 8 | +RC1 |
| 9 | +----- |
| 10 | +- better error message if plugin loading fails, shows the URL used |
| 11 | +- validates our redesigned multidomain license key correctly |
| 12 | +- fix to prevent the play button going visible when the onBufferEmpty event occurs |
| 13 | +- the commercial swf now correctly loads the controls using version information |
| 14 | +- fixed: the play button overlay became invisible with long fadeOutSpeeds |
| 15 | + |
| 16 | +beta6 |
| 17 | +----- |
| 18 | +- removed the onFirstFramePause event |
| 19 | +- playing a clip for the second time caused a doubled sound |
| 20 | +- pausing on first frame did not work on some FLV files |
| 21 | + |
| 22 | +beta5 |
| 23 | +----- |
| 24 | +- logo only uses percentage scaling if it's a SWF file (there is ".swf" in it's url) |
| 25 | +- context menu now correctly builds up from string entries in configuration |
| 26 | +-always closes the previous connection before starting a new clip |
| 27 | + |
| 28 | +beta4 |
| 29 | +----- |
| 30 | +- now it's possible to load a plugin into the panel without specifying any position/dimensions |
| 31 | + information, the plugin is placed to left: "50%", top: "50%" and using the plugin DisplayObject's width & height |
| 32 | +- The Flowplayer API was not fully initialized when onLoad was invoked on Flash plugins |
| 33 | + |
| 34 | +beta3 |
| 35 | +----- |
| 36 | +- tweaking logo placement |
| 37 | +- "play" did not show up after repeated pause/resume |
| 38 | +- player now loads the latest controls SWF version, right now the latest SWF is called 'flowplayer.controls-3.0.0-beta2.swf' |
| 39 | + |
| 40 | +beta2 |
| 41 | +----- |
| 42 | +- fixed support for RTMP stream groups |
| 43 | +- changed to loop through available fonts in order to find a suitable font also in IE |
| 44 | +- Preloader was broken on IE: When the player SWf was in browser's cache it did not initialize properly |
| 45 | +- Context menu now correctly handles menu items that are configured by their string labels only (not using json objects) |
| 46 | +- fixed custom logo positioning (was moved to the left edge of screen in fullscreen) |
| 47 | +- "play" now always follows the position and size of the screen |
| 48 | +- video was stretched below the controls in fullscreen when autoHide: 'never' |
| 49 | +- logo now takes 6.5% of the screen height, width is scaled so that the aspect ratio is preserved |
| 50 | + |
| 51 | +beta1 |
| 52 | +----- |
| 53 | +- First public beta release |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer.controls-3.0.0-beta5.swf |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer.controls-3.0.0-beta5.swf |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 54 | + application/octet-stream |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.js |
— | — | @@ -0,0 +1,1520 @@ |
| 2 | +/** |
| 3 | + * flowplayer.js 3.0.0-rc2. The Flowplayer API. |
| 4 | + * |
| 5 | + * This file is part of Flowplayer, http://flowplayer.org |
| 6 | + * |
| 7 | + * Author: Tero Piirainen, <support@flowplayer.org> |
| 8 | + * Copyright (c) 2008 Flowplayer Ltd |
| 9 | + * |
| 10 | + * Released under the MIT License: |
| 11 | + * http://www.opensource.org/licenses/mit-license.php |
| 12 | + * |
| 13 | + * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:59 GMT-0000 (GMT+00:00) |
| 14 | + */ |
| 15 | +(function() { |
| 16 | + |
| 17 | +/* |
| 18 | + FEATURES |
| 19 | + -------- |
| 20 | + - handling multiple instances |
| 21 | + - Flowplayer programming API |
| 22 | + - Flowplayer event model |
| 23 | + - player loading / unloading |
| 24 | + - $f() function |
| 25 | + - jQuery support |
| 26 | +*/ |
| 27 | + |
| 28 | + |
| 29 | +/*jslint glovar: true, browser: true */ |
| 30 | +/*global flowplayer, $f */ |
| 31 | + |
| 32 | +// {{{ private utility methods |
| 33 | + |
| 34 | + function log(args) { |
| 35 | + |
| 36 | + // write into opera console |
| 37 | + if (typeof opera == 'object') { |
| 38 | + opera.postError("$f.fireEvent: " + args.join(" | ")); |
| 39 | + |
| 40 | + |
| 41 | + } else if (typeof console == 'object') { |
| 42 | + console.log("$f.fireEvent", [].slice.call(args)); |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + |
| 47 | + // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone |
| 48 | + function clone(obj) { |
| 49 | + if (!obj || typeof obj != 'object') { return obj; } |
| 50 | + var temp = new obj.constructor(); |
| 51 | + for (var key in obj) { |
| 52 | + if (obj.hasOwnProperty(key)) { |
| 53 | + temp[key] = clone(obj[key]); |
| 54 | + } |
| 55 | + } |
| 56 | + return temp; |
| 57 | + } |
| 58 | + |
| 59 | + // stripped from jQuery, thanks John Resig |
| 60 | + function each(obj, fn) { |
| 61 | + if (!obj) { return; } |
| 62 | + |
| 63 | + var name, i = 0, length = obj.length; |
| 64 | + |
| 65 | + // object |
| 66 | + if (length === undefined) { |
| 67 | + for (name in obj) { |
| 68 | + if (fn.call(obj[name], name, obj[name]) === false) { break; } |
| 69 | + } |
| 70 | + |
| 71 | + // array |
| 72 | + } else { |
| 73 | + for (var value = obj[0]; |
| 74 | + i < length && fn.call( value, i, value ) !== false; value = obj[++i]) { |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + return obj; |
| 79 | + } |
| 80 | + |
| 81 | + |
| 82 | + // convenience |
| 83 | + function el(id) { |
| 84 | + return document.getElementById(id); |
| 85 | + } |
| 86 | + |
| 87 | + |
| 88 | + // used extensively. a very simple implementation. |
| 89 | + function extend(to, from, skipFuncs) { |
| 90 | + if (to && from) { |
| 91 | + each(from, function(name, value) { |
| 92 | + if (!skipFuncs || typeof value != 'function') { |
| 93 | + to[name] = value; |
| 94 | + } |
| 95 | + }); |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + // var arr = select("elem.className"); |
| 100 | + function select(query) { |
| 101 | + var index = query.indexOf("."); |
| 102 | + if (index != -1) { |
| 103 | + var tag = query.substring(0, index) || "*"; |
| 104 | + var klass = query.substring(index + 1, query.length); |
| 105 | + var els = []; |
| 106 | + each(document.getElementsByTagName(tag), function() { |
| 107 | + if (this.className && this.className.indexOf(klass) != -1) { |
| 108 | + els.push(this); |
| 109 | + } |
| 110 | + }); |
| 111 | + return els; |
| 112 | + } |
| 113 | + } |
| 114 | + |
| 115 | + // fix event inconsistencies across browsers |
| 116 | + function stopEvent(e) { |
| 117 | + e = e || window.event; |
| 118 | + |
| 119 | + if (e.preventDefault) { |
| 120 | + e.stopPropagation(); |
| 121 | + e.preventDefault(); |
| 122 | + |
| 123 | + } else { |
| 124 | + e.returnValue = false; |
| 125 | + e.cancelBubble = true; |
| 126 | + } |
| 127 | + return false; |
| 128 | + } |
| 129 | + |
| 130 | + // push an event listener into existing array of listeners |
| 131 | + function bind(to, evt, fn) { |
| 132 | + to[evt] = to[evt] || []; |
| 133 | + to[evt].push(fn); |
| 134 | + } |
| 135 | + |
| 136 | + |
| 137 | + // generates an unique id |
| 138 | + function makeId() { |
| 139 | + return "_" + ("" + Math.random()).substring(2, 10); |
| 140 | + } |
| 141 | + |
| 142 | +//}}} |
| 143 | + |
| 144 | + |
| 145 | +// {{{ Clip |
| 146 | + |
| 147 | + var Clip = function(json, index, player) { |
| 148 | + |
| 149 | + // private variables |
| 150 | + var self = this; |
| 151 | + var cuepoints = {}; |
| 152 | + var listeners = {}; |
| 153 | + this.index = index; |
| 154 | + |
| 155 | + // instance variables |
| 156 | + if (typeof json == 'string') { |
| 157 | + json = {url:json}; |
| 158 | + } |
| 159 | + |
| 160 | + extend(this, json, true); |
| 161 | + |
| 162 | + // event handling |
| 163 | + each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","), |
| 164 | + function() { |
| 165 | + |
| 166 | + var evt = "on" + this; |
| 167 | + |
| 168 | + // before event |
| 169 | + if (evt.indexOf("*") != -1) { |
| 170 | + evt = evt.substring(0, evt.length -1); |
| 171 | + var before = "onBefore" + evt.substring(2); |
| 172 | + |
| 173 | + self[before] = function(fn) { |
| 174 | + bind(listeners, before, fn); |
| 175 | + return self; |
| 176 | + }; |
| 177 | + } |
| 178 | + |
| 179 | + self[evt] = function(fn) { |
| 180 | + bind(listeners, evt, fn); |
| 181 | + return self; |
| 182 | + }; |
| 183 | + |
| 184 | + |
| 185 | + // set common clip event listeners to player level |
| 186 | + if (index == -1) { |
| 187 | + if (self[before]) { |
| 188 | + player[before] = self[before]; |
| 189 | + } |
| 190 | + if (self[evt]) { |
| 191 | + player[evt] = self[evt]; |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + }); |
| 196 | + |
| 197 | + extend(this, { |
| 198 | + |
| 199 | + |
| 200 | + onCuepoint: function(points, fn) { |
| 201 | + |
| 202 | + // embedded cuepoints |
| 203 | + if (arguments.length == 1) { |
| 204 | + cuepoints.embedded = [null, points]; |
| 205 | + return self; |
| 206 | + } |
| 207 | + |
| 208 | + if (typeof points == 'number') { |
| 209 | + points = [points]; |
| 210 | + } |
| 211 | + |
| 212 | + var fnId = makeId(); |
| 213 | + cuepoints[fnId] = [points, fn]; |
| 214 | + |
| 215 | + if (player.isLoaded()) { |
| 216 | + player._api().fp_addCuepoints(points, index, fnId); |
| 217 | + } |
| 218 | + |
| 219 | + return self; |
| 220 | + }, |
| 221 | + |
| 222 | + update: function(json) { |
| 223 | + extend(self, json); |
| 224 | + |
| 225 | + if (player.isLoaded()) { |
| 226 | + player._api().fp_updateClip(json, index); |
| 227 | + } |
| 228 | + var conf = player._config(); |
| 229 | + var clip = (index == -1) ? conf.clip : conf.playlist[index]; |
| 230 | + extend(clip, json, true); |
| 231 | + }, |
| 232 | + |
| 233 | + |
| 234 | + // internal event for performing clip tasks. should be made private someday |
| 235 | + _fireEvent: function(evt, arg1, arg2, target) { |
| 236 | + |
| 237 | + if (evt == 'onLoad') { |
| 238 | + each(cuepoints, function(key, val) { |
| 239 | + player._api().fp_addCuepoints(val[0], index, key); |
| 240 | + }); |
| 241 | + return false; |
| 242 | + } |
| 243 | + |
| 244 | + // target clip we are working against |
| 245 | + if (index != -1) { |
| 246 | + target = self; |
| 247 | + } |
| 248 | + |
| 249 | + if (evt == 'onCuepoint') { |
| 250 | + var fn = cuepoints[arg1]; |
| 251 | + if (fn) { |
| 252 | + return fn[1].call(player, target, arg2); |
| 253 | + } |
| 254 | + } |
| 255 | + |
| 256 | + if (evt == 'onMetaData' || evt == 'onUpdate') { |
| 257 | + |
| 258 | + extend(target, arg1); |
| 259 | + |
| 260 | + if (!target.duration) { |
| 261 | + target.duration = arg1.metaData.duration; |
| 262 | + } else { |
| 263 | + target.fullDuration = arg1.metaData.duration; |
| 264 | + } |
| 265 | + } |
| 266 | + |
| 267 | + var ret = true; |
| 268 | + each(listeners[evt], function() { |
| 269 | + ret = this.call(player, target, arg1); |
| 270 | + }); |
| 271 | + return ret; |
| 272 | + } |
| 273 | + |
| 274 | + }); |
| 275 | + |
| 276 | + |
| 277 | + // get cuepoints from config |
| 278 | + if (json.onCuepoint) { |
| 279 | + self.onCuepoint.apply(self, json.onCuepoint); |
| 280 | + delete json.onCuepoint; |
| 281 | + } |
| 282 | + |
| 283 | + // get other events |
| 284 | + each(json, function(key, val) { |
| 285 | + if (typeof val == 'function') { |
| 286 | + bind(listeners, key, val); |
| 287 | + delete json[key]; |
| 288 | + } |
| 289 | + }); |
| 290 | + |
| 291 | + |
| 292 | + // setup common clip event callbacks for Player object too (shortcuts) |
| 293 | + if (index == -1) { |
| 294 | + player.onCuepoint = this.onCuepoint; |
| 295 | + } |
| 296 | + |
| 297 | + }; |
| 298 | + |
| 299 | +//}}} |
| 300 | + |
| 301 | + |
| 302 | +// {{{ Plugin |
| 303 | + |
| 304 | + var Plugin = function(name, json, player, fn) { |
| 305 | + |
| 306 | + var listeners = {}; |
| 307 | + var self = this; |
| 308 | + var hasMethods = false; |
| 309 | + |
| 310 | + if (fn) { |
| 311 | + extend(listeners, fn); |
| 312 | + } |
| 313 | + |
| 314 | + // custom callback functions in configuration |
| 315 | + each(json, function(key, val) { |
| 316 | + if (typeof val == 'function') { |
| 317 | + listeners[key] = val; |
| 318 | + delete json[key]; |
| 319 | + } |
| 320 | + }); |
| 321 | + |
| 322 | + // core plugin methods |
| 323 | + extend(this, { |
| 324 | + |
| 325 | + animate: function(props, speed, fn) { |
| 326 | + if (!props) { |
| 327 | + return self; |
| 328 | + } |
| 329 | + |
| 330 | + if (typeof speed == 'function') { |
| 331 | + fn = speed; |
| 332 | + speed = 500; |
| 333 | + } |
| 334 | + |
| 335 | + if (typeof props == 'string') { |
| 336 | + var key = props; |
| 337 | + props = {}; |
| 338 | + props[key] = speed; |
| 339 | + speed = 500; |
| 340 | + } |
| 341 | + |
| 342 | + if (fn) { |
| 343 | + var fnId = makeId(); |
| 344 | + listeners[fnId] = fn; |
| 345 | + } |
| 346 | + |
| 347 | + if (speed === undefined) { speed = 500; } |
| 348 | + json = player._api().fp_animate(name, props, speed, fnId); |
| 349 | + return self; |
| 350 | + }, |
| 351 | + |
| 352 | + css: function(props, val) { |
| 353 | + if (val !== undefined) { |
| 354 | + var css = {}; |
| 355 | + css[props] = val; |
| 356 | + props = css; |
| 357 | + } |
| 358 | + json = player._api().fp_css(name, props); |
| 359 | + extend(self, json); |
| 360 | + return self; |
| 361 | + }, |
| 362 | + |
| 363 | + show: function() { |
| 364 | + this.display = 'block'; |
| 365 | + player._api().fp_showPlugin(name); |
| 366 | + return self; |
| 367 | + }, |
| 368 | + |
| 369 | + hide: function() { |
| 370 | + this.display = 'none'; |
| 371 | + player._api().fp_hidePlugin(name); |
| 372 | + return self; |
| 373 | + }, |
| 374 | + |
| 375 | + toggle: function() { |
| 376 | + this.display = player._api().fp_togglePlugin(name); |
| 377 | + return self; |
| 378 | + }, |
| 379 | + |
| 380 | + fadeTo: function(o, speed, fn) { |
| 381 | + |
| 382 | + if (typeof speed == 'function') { |
| 383 | + fn = speed; |
| 384 | + speed = 500; |
| 385 | + } |
| 386 | + |
| 387 | + if (fn) { |
| 388 | + var fnId = makeId(); |
| 389 | + listeners[fnId] = fn; |
| 390 | + } |
| 391 | + this.display = player._api().fp_fadeTo(name, o, speed, fnId); |
| 392 | + this.opacity = o; |
| 393 | + return self; |
| 394 | + }, |
| 395 | + |
| 396 | + fadeIn: function(speed, fn) { |
| 397 | + return self.fadeTo(1, speed, fn); |
| 398 | + }, |
| 399 | + |
| 400 | + fadeOut: function(speed, fn) { |
| 401 | + return self.fadeTo(0, speed, fn); |
| 402 | + }, |
| 403 | + |
| 404 | + getName: function() { |
| 405 | + return name; |
| 406 | + }, |
| 407 | + |
| 408 | + |
| 409 | + // internal method not meant to be used by clients |
| 410 | + _fireEvent: function(evt, arg) { |
| 411 | + |
| 412 | + |
| 413 | + // update plugins properties & methods |
| 414 | + if (evt == 'onUpdate') { |
| 415 | + var json = arg || player._api().fp_getPlugin(name); |
| 416 | + if (!json) { return; } |
| 417 | + |
| 418 | + extend(self, json); |
| 419 | + delete self.methods; |
| 420 | + |
| 421 | + if (!hasMethods) { |
| 422 | + each(json.methods, function() { |
| 423 | + var method = "" + this; |
| 424 | + |
| 425 | + self[method] = function() { |
| 426 | + var a = [].slice.call(arguments); |
| 427 | + var ret = player._api().fp_invoke(name, method, a); |
| 428 | + return ret == 'undefined' ? self : ret; |
| 429 | + }; |
| 430 | + }); |
| 431 | + hasMethods = true; |
| 432 | + } |
| 433 | + } |
| 434 | + |
| 435 | + // plugin callbacks |
| 436 | + var fn = listeners[evt]; |
| 437 | + |
| 438 | + if (fn) { |
| 439 | + |
| 440 | + fn.call(self, arg); |
| 441 | + |
| 442 | + // "one-shot" callback |
| 443 | + if (evt.substring(0, 1) == "_") { |
| 444 | + delete listeners[evt]; |
| 445 | + } |
| 446 | + } |
| 447 | + } |
| 448 | + |
| 449 | + }); |
| 450 | + |
| 451 | + }; |
| 452 | + |
| 453 | + |
| 454 | +//}}} |
| 455 | + |
| 456 | + |
| 457 | +function Player(wrapper, params, conf) { |
| 458 | + |
| 459 | + // private variables (+ arguments) |
| 460 | + var |
| 461 | + self = this, |
| 462 | + api = null, |
| 463 | + html, |
| 464 | + commonClip, |
| 465 | + playlist = [], |
| 466 | + plugins = {}, |
| 467 | + listeners = {}, |
| 468 | + playerId, |
| 469 | + apiId, |
| 470 | + activeIndex, |
| 471 | + swfHeight; |
| 472 | + |
| 473 | + |
| 474 | +// {{{ public methods |
| 475 | + |
| 476 | + extend(self, { |
| 477 | + |
| 478 | + id: function() { |
| 479 | + return playerId; |
| 480 | + }, |
| 481 | + |
| 482 | + isLoaded: function() { |
| 483 | + return (api !== null); |
| 484 | + }, |
| 485 | + |
| 486 | + getParent: function() { |
| 487 | + return wrapper; |
| 488 | + }, |
| 489 | + |
| 490 | + hide: function() { |
| 491 | + if (api) { api.style.height = "0px"; } |
| 492 | + return self; |
| 493 | + }, |
| 494 | + |
| 495 | + show: function() { |
| 496 | + if (api) { api.style.height = swfHeight + "px"; } |
| 497 | + return self; |
| 498 | + }, |
| 499 | + |
| 500 | + isHidden: function() { |
| 501 | + return api && parseInt(api.style.height, 10) === 0; |
| 502 | + }, |
| 503 | + |
| 504 | + |
| 505 | + load: function(fn) { |
| 506 | + |
| 507 | + if (!api && self._fireEvent("onBeforeLoad") !== false) { |
| 508 | + |
| 509 | + // unload all instances |
| 510 | + each(players, function() { |
| 511 | + this.unload(); |
| 512 | + }); |
| 513 | + |
| 514 | + html = wrapper.innerHTML; |
| 515 | + flashembed(wrapper, params, {config: conf}); |
| 516 | + |
| 517 | + // function argument |
| 518 | + if (fn) { |
| 519 | + fn.cached = true; |
| 520 | + bind(listeners, "onLoad", fn); |
| 521 | + } |
| 522 | + } |
| 523 | + |
| 524 | + return self; |
| 525 | + }, |
| 526 | + |
| 527 | + unload: function() { |
| 528 | + |
| 529 | + if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() && |
| 530 | + self._fireEvent("onBeforeUnload") !== false) { |
| 531 | + api.fp_close(); |
| 532 | + wrapper.innerHTML = html; |
| 533 | + self._fireEvent("onUnload"); |
| 534 | + api = null; |
| 535 | + } |
| 536 | + |
| 537 | + return self; |
| 538 | + }, |
| 539 | + |
| 540 | + getClip: function(index) { |
| 541 | + if (index === undefined) { |
| 542 | + index = activeIndex; |
| 543 | + } |
| 544 | + return playlist[index]; |
| 545 | + }, |
| 546 | + |
| 547 | + |
| 548 | + getCommonClip: function() { |
| 549 | + return commonClip; |
| 550 | + }, |
| 551 | + |
| 552 | + getPlaylist: function() { |
| 553 | + return playlist; |
| 554 | + }, |
| 555 | + |
| 556 | + getPlugin: function(name) { |
| 557 | + var plugin = plugins[name]; |
| 558 | + |
| 559 | + // create plugin if nessessary |
| 560 | + if (!plugin && self.isLoaded()) { |
| 561 | + var json = self._api().fp_getPlugin(name); |
| 562 | + if (json) { |
| 563 | + plugin = new Plugin(name, json, self); |
| 564 | + plugins[name] = plugin; |
| 565 | + } |
| 566 | + } |
| 567 | + return plugin; |
| 568 | + }, |
| 569 | + |
| 570 | + getScreen: function() { |
| 571 | + return self.getPlugin("screen"); |
| 572 | + }, |
| 573 | + |
| 574 | + getControls: function() { |
| 575 | + return self.getPlugin("controls"); |
| 576 | + }, |
| 577 | + |
| 578 | + getConfig: function() { |
| 579 | + return clone(conf); |
| 580 | + }, |
| 581 | + |
| 582 | + getFlashParams: function() { |
| 583 | + return params; |
| 584 | + }, |
| 585 | + |
| 586 | + loadPlugin: function(name, url, props, fn) { |
| 587 | + |
| 588 | + // properties not supplied |
| 589 | + if (typeof props == 'function') { |
| 590 | + fn = props; |
| 591 | + props = {}; |
| 592 | + } |
| 593 | + |
| 594 | + // if fn not given, make a fake id so that plugin's onUpdate get's fired |
| 595 | + var fnId = fn ? makeId() : "_"; |
| 596 | + self._api().fp_loadPlugin(name, url, props, fnId); |
| 597 | + |
| 598 | + // create new plugin |
| 599 | + var arg = {}; |
| 600 | + arg[fnId] = fn; |
| 601 | + var p = new Plugin(name, null, self, arg); |
| 602 | + plugins[name] = p; |
| 603 | + return p; |
| 604 | + }, |
| 605 | + |
| 606 | + |
| 607 | + getState: function() { |
| 608 | + return api ? api.fp_getState() : -1; |
| 609 | + }, |
| 610 | + |
| 611 | + // "lazy" play |
| 612 | + play: function(clip) { |
| 613 | + |
| 614 | + function play() { |
| 615 | + if (clip !== undefined) { |
| 616 | + self._api().fp_play(clip); |
| 617 | + } else { |
| 618 | + self._api().fp_play(); |
| 619 | + } |
| 620 | + } |
| 621 | + |
| 622 | + if (api) { |
| 623 | + play(); |
| 624 | + |
| 625 | + } else { |
| 626 | + self.load(function() { |
| 627 | + play(); |
| 628 | + }); |
| 629 | + } |
| 630 | + |
| 631 | + return self; |
| 632 | + }, |
| 633 | + |
| 634 | + getVersion: function() { |
| 635 | + var js = "flowplayer.js 3.0.0-rc2"; |
| 636 | + if (api) { |
| 637 | + var ver = api.fp_getVersion(); |
| 638 | + ver.push(js); |
| 639 | + return ver; |
| 640 | + } |
| 641 | + return js; |
| 642 | + }, |
| 643 | + |
| 644 | + _api: function() { |
| 645 | + if (!api) { |
| 646 | + throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event"; |
| 647 | + } |
| 648 | + return api; |
| 649 | + }, |
| 650 | + |
| 651 | + _config: function() { |
| 652 | + return conf; |
| 653 | + } |
| 654 | + |
| 655 | + }); |
| 656 | + |
| 657 | + |
| 658 | + // event handlers |
| 659 | + each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","), |
| 660 | + function() { |
| 661 | + var name = "on" + this; |
| 662 | + |
| 663 | + // before event |
| 664 | + if (name.indexOf("*") != -1) { |
| 665 | + name = name.substring(0, name.length -1); |
| 666 | + var name2 = "onBefore" + name.substring(2); |
| 667 | + self[name2] = function(fn) { |
| 668 | + bind(listeners, name2, fn); |
| 669 | + return self; |
| 670 | + }; |
| 671 | + } |
| 672 | + |
| 673 | + // normal event |
| 674 | + self[name] = function(fn) { |
| 675 | + bind(listeners, name, fn); |
| 676 | + return self; |
| 677 | + }; |
| 678 | + } |
| 679 | + ); |
| 680 | + |
| 681 | + |
| 682 | + // core API methods |
| 683 | + each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","), |
| 684 | + function() { |
| 685 | + var name = this; |
| 686 | + |
| 687 | + self[name] = function(arg) { |
| 688 | + if (!api) { return self; } |
| 689 | + var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg); |
| 690 | + return ret == 'undefined' ? self : ret; |
| 691 | + }; |
| 692 | + } |
| 693 | + ); |
| 694 | + |
| 695 | +//}}} |
| 696 | + |
| 697 | + |
| 698 | +// {{{ public method: _fireEvent |
| 699 | + |
| 700 | + self._fireEvent = function(evt, arg0, arg1, arg2) { |
| 701 | + |
| 702 | + if (conf.debug) { |
| 703 | + log(arguments); |
| 704 | + } |
| 705 | + |
| 706 | + // internal onLoad |
| 707 | + if (evt == 'onLoad' && !api) { |
| 708 | + |
| 709 | + api = api || el(apiId); |
| 710 | + swfHeight = api.clientHeight; |
| 711 | + |
| 712 | + each(playlist, function() { |
| 713 | + this._fireEvent("onLoad"); |
| 714 | + }); |
| 715 | + |
| 716 | + each(plugins, function(name, p) { |
| 717 | + p._fireEvent("onUpdate"); |
| 718 | + }); |
| 719 | + |
| 720 | + |
| 721 | + commonClip._fireEvent("onLoad"); |
| 722 | + } |
| 723 | + |
| 724 | + if (evt == 'onContextMenu') { |
| 725 | + each(conf.contextMenu[arg0], function(key, fn) { |
| 726 | + fn.call(self); |
| 727 | + }); |
| 728 | + return; |
| 729 | + } |
| 730 | + |
| 731 | + if (evt == 'onPluginEvent') { |
| 732 | + var name = arg0.name || arg0; |
| 733 | + var p = plugins[name]; |
| 734 | + if (p) { |
| 735 | + if (arg0.name) { |
| 736 | + p._fireEvent("onUpdate", arg0); |
| 737 | + } |
| 738 | + p._fireEvent(arg1); |
| 739 | + } |
| 740 | + return; |
| 741 | + } |
| 742 | + |
| 743 | + // onPlaylistReplace |
| 744 | + if (evt == 'onPlaylistReplace') { |
| 745 | + playlist = []; |
| 746 | + var index = 0; |
| 747 | + each(arg0, function() { |
| 748 | + playlist.push(new Clip(this, index++)); |
| 749 | + }); |
| 750 | + } |
| 751 | + |
| 752 | + var ret = true; |
| 753 | + |
| 754 | + // clip event |
| 755 | + if (arg0 === 0 || (arg0 && arg0 >= 0)) { |
| 756 | + |
| 757 | + activeIndex = arg0; |
| 758 | + var clip = playlist[arg0]; |
| 759 | + |
| 760 | + if (!clip || clip._fireEvent(evt, arg1, arg2) !== false) { |
| 761 | + |
| 762 | + // clip argument is given for common clip, because it behaves as the target |
| 763 | + ret = commonClip._fireEvent(evt, arg1, arg2, clip); |
| 764 | + } |
| 765 | + } |
| 766 | + |
| 767 | + // player event |
| 768 | + var i = 0; |
| 769 | + each(listeners[evt], function() { |
| 770 | + ret = this.call(self, arg0); |
| 771 | + |
| 772 | + // remove cached entry |
| 773 | + if (this.cached) { |
| 774 | + listeners[evt].splice(i, 1); |
| 775 | + } |
| 776 | + |
| 777 | + // break loop |
| 778 | + if (ret === false) { return false; } |
| 779 | + i++; |
| 780 | + |
| 781 | + }); |
| 782 | + |
| 783 | + return ret; |
| 784 | + }; |
| 785 | + |
| 786 | +//}}} |
| 787 | + |
| 788 | + |
| 789 | +// {{{ init |
| 790 | + |
| 791 | + function init() { |
| 792 | + |
| 793 | + if ($f(wrapper)) { |
| 794 | + return null; |
| 795 | + } |
| 796 | + |
| 797 | + // register this player into global array of instances |
| 798 | + players.push(self); |
| 799 | + |
| 800 | + |
| 801 | + // flashembed parameters |
| 802 | + if (typeof params == 'string') { |
| 803 | + params = {src: params}; |
| 804 | + } |
| 805 | + |
| 806 | + // playerId |
| 807 | + playerId = wrapper.id || "fp" + makeId(); |
| 808 | + apiId = params.id || playerId + "_api"; |
| 809 | + params.id = apiId; |
| 810 | + conf.playerId = playerId; |
| 811 | + |
| 812 | + |
| 813 | + // plain url is given as config |
| 814 | + if (typeof conf == 'string') { |
| 815 | + conf = {clip:{url:conf}}; |
| 816 | + } |
| 817 | + |
| 818 | + // common clip is always there |
| 819 | + conf.clip = conf.clip || {}; |
| 820 | + commonClip = new Clip(conf.clip, -1, self); |
| 821 | + |
| 822 | + |
| 823 | + // wrapper href as playlist |
| 824 | + if (wrapper.getAttribute("href")) { |
| 825 | + conf.playlist = [{url:wrapper.getAttribute("href", 2)}]; |
| 826 | + } |
| 827 | + |
| 828 | + // playlist |
| 829 | + conf.playlist = conf.playlist || [conf.clip]; |
| 830 | + |
| 831 | + var index = 0; |
| 832 | + each(conf.playlist, function() { |
| 833 | + |
| 834 | + var clip = this; |
| 835 | + |
| 836 | + // clip is an array, we don't allow that |
| 837 | + if (typeof clip == 'object' && clip.length) { |
| 838 | + clip = "" + clip; |
| 839 | + } |
| 840 | + |
| 841 | + if (!clip.url && typeof clip == 'string') { |
| 842 | + clip = {url: clip}; |
| 843 | + } |
| 844 | + |
| 845 | + // populate common clip properties to each clip |
| 846 | + extend(clip, conf.clip, true); |
| 847 | + |
| 848 | + // modify configuration playlist |
| 849 | + conf.playlist[index] = clip; |
| 850 | + |
| 851 | + // populate playlist array |
| 852 | + clip = new Clip(clip, index, self); |
| 853 | + playlist.push(clip); |
| 854 | + index++; |
| 855 | + }); |
| 856 | + |
| 857 | + |
| 858 | + // event listeners |
| 859 | + each(conf, function(key, val) { |
| 860 | + if (typeof val == 'function') { |
| 861 | + bind(listeners, key, val); |
| 862 | + delete conf[key]; |
| 863 | + } |
| 864 | + }); |
| 865 | + |
| 866 | + |
| 867 | + // plugins |
| 868 | + each(conf.plugins, function(name, val) { |
| 869 | + if (val) { |
| 870 | + plugins[name] = new Plugin(name, val, self); |
| 871 | + } |
| 872 | + }); |
| 873 | + |
| 874 | + |
| 875 | + // setup controlbar plugin if not explicitly defined |
| 876 | + if (!conf.plugins || conf.plugins.controls === undefined) { |
| 877 | + plugins.controls = new Plugin("controls", null, self); |
| 878 | + } |
| 879 | + |
| 880 | + // Flowplayer uses black background by default |
| 881 | + params.bgcolor = params.bgcolor || "#000000"; |
| 882 | + |
| 883 | + |
| 884 | + // setup default settings for express install |
| 885 | + params.version = params.version || [9,0]; |
| 886 | + params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf'; |
| 887 | + |
| 888 | + |
| 889 | + // click function |
| 890 | + function doClick(e) { |
| 891 | + if (self._fireEvent("onBeforeClick") !== false) { |
| 892 | + self.load(); |
| 893 | + } |
| 894 | + return stopEvent(e); |
| 895 | + } |
| 896 | + |
| 897 | + // defer loading upon click |
| 898 | + html = wrapper.innerHTML; |
| 899 | + if (html.replace(/\s/g, '') !== '') { |
| 900 | + |
| 901 | + if (wrapper.addEventListener) { |
| 902 | + wrapper.addEventListener("click", doClick, false); |
| 903 | + |
| 904 | + } else if (wrapper.attachEvent) { |
| 905 | + wrapper.attachEvent("onclick", doClick); |
| 906 | + } |
| 907 | + |
| 908 | + // player is loaded upon page load |
| 909 | + } else { |
| 910 | + |
| 911 | + // prevent default action from wrapper (safari problem) loaded |
| 912 | + if (wrapper.addEventListener) { |
| 913 | + wrapper.addEventListener("click", stopEvent, false); |
| 914 | + } |
| 915 | + |
| 916 | + // load player |
| 917 | + self.load(); |
| 918 | + } |
| 919 | + |
| 920 | + } |
| 921 | + |
| 922 | + // possibly defer initialization until DOM get's loaded |
| 923 | + if (typeof wrapper == 'string') { |
| 924 | + flashembed.domReady(function() { |
| 925 | + var node = el(wrapper); |
| 926 | + |
| 927 | + if (!node) { |
| 928 | + throw "Flowplayer cannot access element: " + wrapper; |
| 929 | + } else { |
| 930 | + wrapper = node; |
| 931 | + init(); |
| 932 | + } |
| 933 | + }); |
| 934 | + |
| 935 | + // we have a DOM element so page is already loaded |
| 936 | + } else { |
| 937 | + init(); |
| 938 | + } |
| 939 | + |
| 940 | + |
| 941 | +//}}} |
| 942 | + |
| 943 | + |
| 944 | +} |
| 945 | + |
| 946 | + |
| 947 | +// {{{ flowplayer() & statics |
| 948 | + |
| 949 | +// container for player instances |
| 950 | +var players = []; |
| 951 | + |
| 952 | + |
| 953 | +// this object is returned when multiple player's are requested |
| 954 | +function Iterator(arr) { |
| 955 | + |
| 956 | + this.length = arr.length; |
| 957 | + |
| 958 | + this.each = function(fn) { |
| 959 | + each(arr, fn); |
| 960 | + }; |
| 961 | + |
| 962 | + this.size = function() { |
| 963 | + return arr.length; |
| 964 | + }; |
| 965 | +} |
| 966 | + |
| 967 | +// these two variables are the only global variables |
| 968 | +window.flowplayer = window.$f = function() { |
| 969 | + |
| 970 | + var instance = null; |
| 971 | + var arg = arguments[0]; |
| 972 | + |
| 973 | + |
| 974 | + // $f() |
| 975 | + if (!arguments.length) { |
| 976 | + each(players, function() { |
| 977 | + if (this.isLoaded()) { |
| 978 | + instance = this; |
| 979 | + return false; |
| 980 | + } |
| 981 | + }); |
| 982 | + |
| 983 | + return instance || players[0]; |
| 984 | + } |
| 985 | + |
| 986 | + if (arguments.length == 1) { |
| 987 | + |
| 988 | + // $f(index); |
| 989 | + if (typeof arg == 'number') { |
| 990 | + return players[arg]; |
| 991 | + |
| 992 | + |
| 993 | + // $f(wrapper || 'containerId' || '*'); |
| 994 | + } else { |
| 995 | + |
| 996 | + // $f("*"); |
| 997 | + if (arg == '*') { |
| 998 | + return new Iterator(players); |
| 999 | + } |
| 1000 | + |
| 1001 | + // $f(wrapper || 'containerId'); |
| 1002 | + each(players, function() { |
| 1003 | + if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) { |
| 1004 | + instance = this; |
| 1005 | + return false; |
| 1006 | + } |
| 1007 | + }); |
| 1008 | + |
| 1009 | + return instance; |
| 1010 | + } |
| 1011 | + } |
| 1012 | + |
| 1013 | + // instance builder |
| 1014 | + if (arguments.length > 1) { |
| 1015 | + |
| 1016 | + var swf = arguments[1]; |
| 1017 | + var conf = (arguments.length == 3) ? arguments[2] : {}; |
| 1018 | + |
| 1019 | + if (typeof arg == 'string') { |
| 1020 | + |
| 1021 | + // select arg by classname |
| 1022 | + if (arg.indexOf(".") != -1) { |
| 1023 | + var instances = []; |
| 1024 | + |
| 1025 | + each(select(arg), function() { |
| 1026 | + instances.push(new Player(this, clone(swf), clone(conf))); |
| 1027 | + }); |
| 1028 | + |
| 1029 | + return new Iterator(instances); |
| 1030 | + |
| 1031 | + // select node by id |
| 1032 | + } else { |
| 1033 | + var node = el(arg); |
| 1034 | + return new Player(node !== null ? node : arg, swf, conf); |
| 1035 | + } |
| 1036 | + |
| 1037 | + |
| 1038 | + // arg is a DOM element |
| 1039 | + } else if (arg) { |
| 1040 | + return new Player(arg, swf, conf); |
| 1041 | + } |
| 1042 | + |
| 1043 | + } |
| 1044 | + |
| 1045 | + return null; |
| 1046 | +}; |
| 1047 | + |
| 1048 | +extend(window.$f, { |
| 1049 | + |
| 1050 | + // called by Flash External Interface |
| 1051 | + fireEvent: function(id, evt, a0, a1, a2) { |
| 1052 | + var p = $f(id); |
| 1053 | + return p ? p._fireEvent(evt, a0, a1, a2) : null; |
| 1054 | + }, |
| 1055 | + |
| 1056 | + |
| 1057 | + // create plugins by modifying Player's prototype |
| 1058 | + addPlugin: function(name, fn) { |
| 1059 | + Player.prototype[name] = fn; |
| 1060 | + return $f; |
| 1061 | + }, |
| 1062 | + |
| 1063 | + // utility methods for plugin developers |
| 1064 | + each: each, |
| 1065 | + |
| 1066 | + extend: extend |
| 1067 | + |
| 1068 | +}); |
| 1069 | + |
| 1070 | +//}}} |
| 1071 | + |
| 1072 | + |
| 1073 | +//{{{ jQuery support |
| 1074 | + |
| 1075 | +if (typeof jQuery == 'function') { |
| 1076 | + |
| 1077 | + jQuery.prototype.flowplayer = function(params, conf) { |
| 1078 | + |
| 1079 | + // select instances |
| 1080 | + if (!arguments.length || typeof arguments[0] == 'number') { |
| 1081 | + var arr = []; |
| 1082 | + this.each(function() { |
| 1083 | + var p = $f(this); |
| 1084 | + if (p) { |
| 1085 | + arr.push(p); |
| 1086 | + } |
| 1087 | + }); |
| 1088 | + return arguments.length ? arr[arguments[0]] : new Iterator(arr); |
| 1089 | + } |
| 1090 | + |
| 1091 | + // create flowplayer instances |
| 1092 | + return this.each(function() { |
| 1093 | + $f(this, clone(params), conf ? clone(conf) : {}); |
| 1094 | + }); |
| 1095 | + |
| 1096 | + }; |
| 1097 | + |
| 1098 | +} |
| 1099 | + |
| 1100 | +//}}} |
| 1101 | + |
| 1102 | + |
| 1103 | +})(); |
| 1104 | +/** |
| 1105 | + * flashembed 0.33. Adobe Flash embedding script |
| 1106 | + * |
| 1107 | + * http://flowplayer.org/tools/flash-embed.html |
| 1108 | + * |
| 1109 | + * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org) |
| 1110 | + * |
| 1111 | + * Released under the MIT License: |
| 1112 | + * http://www.opensource.org/licenses/mit-license.php |
| 1113 | + * |
| 1114 | + * >> Basically you can do anything you want but leave this header as is << |
| 1115 | + * |
| 1116 | + * first version 0.01 - 03/11/2008 |
| 1117 | + * version 0.33 - Mon Nov 03 2008 15:37:15 GMT-0000 (GMT+00:00) |
| 1118 | + */ |
| 1119 | +(function() { |
| 1120 | + |
| 1121 | +//{{{ utility functions |
| 1122 | + |
| 1123 | +var jQ = typeof jQuery == 'function'; |
| 1124 | + |
| 1125 | + |
| 1126 | +// from "Pro JavaScript techniques" by John Resig |
| 1127 | +function isDomReady() { |
| 1128 | + if (domReady.done) { return false; } |
| 1129 | + |
| 1130 | + var d = document; |
| 1131 | + if (d && d.getElementsByTagName && d.getElementById && d.body) { |
| 1132 | + clearInterval(domReady.timer); |
| 1133 | + domReady.timer = null; |
| 1134 | + |
| 1135 | + for (var i = 0; i < domReady.ready.length; i++) { |
| 1136 | + domReady.ready[i].call(); |
| 1137 | + } |
| 1138 | + |
| 1139 | + domReady.ready = null; |
| 1140 | + domReady.done = true; |
| 1141 | + } |
| 1142 | +} |
| 1143 | + |
| 1144 | +// if jQuery is present, use it's more effective domReady method |
| 1145 | +var domReady = jQ ? jQuery : function(f) { |
| 1146 | + |
| 1147 | + if (domReady.done) { |
| 1148 | + return f(); |
| 1149 | + } |
| 1150 | + |
| 1151 | + if (domReady.timer) { |
| 1152 | + domReady.ready.push(f); |
| 1153 | + |
| 1154 | + } else { |
| 1155 | + domReady.ready = [f]; |
| 1156 | + domReady.timer = setInterval(isDomReady, 13); |
| 1157 | + } |
| 1158 | +}; |
| 1159 | + |
| 1160 | + |
| 1161 | +// override extend params function |
| 1162 | +function extend(to, from) { |
| 1163 | + if (from) { |
| 1164 | + for (key in from) { |
| 1165 | + if (from.hasOwnProperty(key)) { |
| 1166 | + to[key] = from[key]; |
| 1167 | + } |
| 1168 | + } |
| 1169 | + } |
| 1170 | +} |
| 1171 | + |
| 1172 | + |
| 1173 | +function concatVars(vars) { |
| 1174 | + var out = ""; |
| 1175 | + |
| 1176 | + for (var key in vars) { |
| 1177 | + if (vars[key]) { |
| 1178 | + out += [key] + '=' + toString(vars[key]) + '&'; |
| 1179 | + } |
| 1180 | + } |
| 1181 | + return out.substring(0, out.length -1); |
| 1182 | +} |
| 1183 | + |
| 1184 | + |
| 1185 | + |
| 1186 | +// JSON.toString() function |
| 1187 | +function toString(obj) { |
| 1188 | + |
| 1189 | + switch (typeOf(obj)){ |
| 1190 | + case 'string': |
| 1191 | + obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1'); |
| 1192 | + |
| 1193 | + // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit) |
| 1194 | + obj = obj.replace(/^\s?(\d+)%/, "$1pct"); |
| 1195 | + return '"' +obj+ '"'; |
| 1196 | + |
| 1197 | + case 'array': |
| 1198 | + return '['+ map(obj, function(el) { |
| 1199 | + return toString(el); |
| 1200 | + }).join(',') +']'; |
| 1201 | + |
| 1202 | + case 'function': |
| 1203 | + return '"function()"'; |
| 1204 | + |
| 1205 | + case 'object': |
| 1206 | + var str = []; |
| 1207 | + for (var prop in obj) { |
| 1208 | + if (obj.hasOwnProperty(prop)) { |
| 1209 | + str.push('"'+prop+'":'+ toString(obj[prop])); |
| 1210 | + } |
| 1211 | + } |
| 1212 | + return '{'+str.join(',')+'}'; |
| 1213 | + } |
| 1214 | + |
| 1215 | + // replace ' --> " and remove spaces |
| 1216 | + return String(obj).replace(/\s/g, " ").replace(/\'/g, "\""); |
| 1217 | +} |
| 1218 | + |
| 1219 | + |
| 1220 | +// private functions |
| 1221 | +function typeOf(obj) { |
| 1222 | + if (obj === null || obj === undefined) { return false; } |
| 1223 | + var type = typeof obj; |
| 1224 | + return (type == 'object' && obj.push) ? 'array' : type; |
| 1225 | +} |
| 1226 | + |
| 1227 | + |
| 1228 | +// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/) |
| 1229 | +if (window.attachEvent) { |
| 1230 | + window.attachEvent("onbeforeunload", function() { |
| 1231 | + __flash_unloadHandler = function() {}; |
| 1232 | + __flash_savedUnloadHandler = function() {}; |
| 1233 | + }); |
| 1234 | +} |
| 1235 | + |
| 1236 | +function map(arr, func) { |
| 1237 | + var newArr = []; |
| 1238 | + for (var i in arr) { |
| 1239 | + if (arr.hasOwnProperty(i)) { |
| 1240 | + newArr[i] = func(arr[i]); |
| 1241 | + } |
| 1242 | + } |
| 1243 | + return newArr; |
| 1244 | +} |
| 1245 | + |
| 1246 | +//}}} |
| 1247 | + |
| 1248 | + |
| 1249 | +window.flashembed = function(root, userParams, flashvars) { |
| 1250 | + |
| 1251 | + |
| 1252 | +//{{{ getHTML |
| 1253 | + |
| 1254 | + function getHTML() { |
| 1255 | + |
| 1256 | + var html = ""; |
| 1257 | + if (typeof flashvars == 'function') { flashvars = flashvars(); } |
| 1258 | + |
| 1259 | + |
| 1260 | + // sometimes ie fails to load flash if it's on cache |
| 1261 | + params.src += ((params.src.indexOf("?") != -1 ? "&" : "?") + Math.random()); |
| 1262 | + |
| 1263 | + |
| 1264 | + // mozilla |
| 1265 | + if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { |
| 1266 | + |
| 1267 | + html = '<embed type="application/x-shockwave-flash" '; |
| 1268 | + |
| 1269 | + if (params.id) { |
| 1270 | + extend(params, {name:params.id}); |
| 1271 | + } |
| 1272 | + |
| 1273 | + for (var key in params) { |
| 1274 | + if (params[key] !== null) { |
| 1275 | + html += [key] + '="' +params[key]+ '"\n\t'; |
| 1276 | + } |
| 1277 | + } |
| 1278 | + |
| 1279 | + if (flashvars) { |
| 1280 | + html += 'flashvars=\'' + concatVars(flashvars) + '\''; |
| 1281 | + } |
| 1282 | + |
| 1283 | + // thanks Tom Price (07/17/2008) |
| 1284 | + html += '/>'; |
| 1285 | + |
| 1286 | + // ie |
| 1287 | + } else { |
| 1288 | + |
| 1289 | + html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '; |
| 1290 | + html += 'width="' + params.width + '" height="' + params.height + '"'; |
| 1291 | + |
| 1292 | + // force id for IE. otherwise embedded Flash object cannot be returned |
| 1293 | + if (!params.id && document.all) { |
| 1294 | + params.id = "_" + ("" + Math.random()).substring(5); |
| 1295 | + } |
| 1296 | + |
| 1297 | + if (params.id) { |
| 1298 | + html += ' id="' + params.id + '"'; |
| 1299 | + } |
| 1300 | + |
| 1301 | + html += '>'; |
| 1302 | + html += '\n\t<param name="movie" value="'+ params.src +'" />'; |
| 1303 | + |
| 1304 | + params.id = params.src = params.width = params.height = null; |
| 1305 | + |
| 1306 | + for (var k in params) { |
| 1307 | + if (params[k] !== null) { |
| 1308 | + html += '\n\t<param name="'+ k +'" value="'+ params[k] +'" />'; |
| 1309 | + } |
| 1310 | + } |
| 1311 | + |
| 1312 | + if (flashvars) { |
| 1313 | + html += '\n\t<param name="flashvars" value=\'' + concatVars(flashvars) + '\' />'; |
| 1314 | + } |
| 1315 | + |
| 1316 | + html += "</object>"; |
| 1317 | + if (debug) { |
| 1318 | + alert(html); |
| 1319 | + } |
| 1320 | + |
| 1321 | + } |
| 1322 | + |
| 1323 | + return html; |
| 1324 | + } |
| 1325 | + |
| 1326 | + //}}} |
| 1327 | + |
| 1328 | + |
| 1329 | +//{{{ construction |
| 1330 | + |
| 1331 | + // setup params |
| 1332 | + var params = { |
| 1333 | + |
| 1334 | + // very common params |
| 1335 | + src: '#', |
| 1336 | + width: '100%', |
| 1337 | + height: '100%', |
| 1338 | + |
| 1339 | + // flashembed specific options |
| 1340 | + version:null, |
| 1341 | + onFail:null, |
| 1342 | + expressInstall:null, |
| 1343 | + debug: false, |
| 1344 | + |
| 1345 | + // flashembed defaults |
| 1346 | + // bgcolor: 'transparent', |
| 1347 | + allowfullscreen: true, |
| 1348 | + allowscriptaccess: 'always', |
| 1349 | + quality: 'high', |
| 1350 | + type: 'application/x-shockwave-flash', |
| 1351 | + pluginspage: 'http://www.adobe.com/go/getflashplayer' |
| 1352 | + }; |
| 1353 | + |
| 1354 | + |
| 1355 | + if (typeof userParams == 'string') { |
| 1356 | + userParams = {src: userParams}; |
| 1357 | + } |
| 1358 | + |
| 1359 | + extend(params, userParams); |
| 1360 | + |
| 1361 | + var version = flashembed.getVersion(); |
| 1362 | + var required = params.version; |
| 1363 | + var express = params.expressInstall; |
| 1364 | + var debug = params.debug; |
| 1365 | + |
| 1366 | + |
| 1367 | + if (typeof root == 'string') { |
| 1368 | + var el = document.getElementById(root); |
| 1369 | + if (el) { |
| 1370 | + root = el; |
| 1371 | + } else { |
| 1372 | + domReady(function() { |
| 1373 | + flashembed(root, userParams, flashvars); |
| 1374 | + }); |
| 1375 | + return; |
| 1376 | + } |
| 1377 | + } |
| 1378 | + |
| 1379 | + if (!root) { return; } |
| 1380 | + |
| 1381 | + |
| 1382 | + // is supported |
| 1383 | + if (!required || flashembed.isSupported(required)) { |
| 1384 | + params.onFail = params.version = params.expressInstall = params.debug = null; |
| 1385 | + |
| 1386 | + // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99 |
| 1387 | + // thanks to: Ryan Rud |
| 1388 | + // var tmp = document.createElement("extradiv"); |
| 1389 | + // tmp.innerHTML = getHTML(); |
| 1390 | + // root.appendChild(tmp); |
| 1391 | + |
| 1392 | + root.innerHTML = getHTML(); |
| 1393 | + |
| 1394 | + // return our API |
| 1395 | + return root.firstChild; |
| 1396 | + |
| 1397 | + // custom fail event |
| 1398 | + } else if (params.onFail) { |
| 1399 | + var ret = params.onFail.call(params, flashembed.getVersion(), flashvars); |
| 1400 | + if (ret === true) { root.innerHTML = ret; } |
| 1401 | + |
| 1402 | + |
| 1403 | + // express install |
| 1404 | + } else if (required && express && flashembed.isSupported([6,65])) { |
| 1405 | + |
| 1406 | + extend(params, {src: express}); |
| 1407 | + |
| 1408 | + flashvars = { |
| 1409 | + MMredirectURL: location.href, |
| 1410 | + MMplayerType: 'PlugIn', |
| 1411 | + MMdoctitle: document.title |
| 1412 | + }; |
| 1413 | + |
| 1414 | + root.innerHTML = getHTML(); |
| 1415 | + |
| 1416 | + // not supported |
| 1417 | + } else { |
| 1418 | + |
| 1419 | + // minor bug fixed here 08.04.2008 (thanks JRodman) |
| 1420 | + |
| 1421 | + if (root.innerHTML.replace(/\s/g, '') !== '') { |
| 1422 | + // custom content was supplied |
| 1423 | + |
| 1424 | + } else { |
| 1425 | + root.innerHTML = |
| 1426 | + "<h2>Flash version " + required + " or greater is required</h2>" + |
| 1427 | + "<h3>" + |
| 1428 | + (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") + |
| 1429 | + "</h3>" + |
| 1430 | + "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>"; |
| 1431 | + } |
| 1432 | + } |
| 1433 | + |
| 1434 | + return root; |
| 1435 | + |
| 1436 | +//}}} |
| 1437 | + |
| 1438 | + |
| 1439 | +}; |
| 1440 | + |
| 1441 | + |
| 1442 | +//{{{ static methods |
| 1443 | + |
| 1444 | +extend(window.flashembed, { |
| 1445 | + |
| 1446 | + // arr[major, minor, fix] |
| 1447 | + getVersion: function() { |
| 1448 | + |
| 1449 | + var version = [0, 0]; |
| 1450 | + |
| 1451 | + if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") { |
| 1452 | + var _d = navigator.plugins["Shockwave Flash"].description; |
| 1453 | + if (typeof _d != "undefined") { |
| 1454 | + _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); |
| 1455 | + var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10); |
| 1456 | + var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0; |
| 1457 | + version = [_m, _r]; |
| 1458 | + } |
| 1459 | + |
| 1460 | + } else if (window.ActiveXObject) { |
| 1461 | + |
| 1462 | + try { // avoid fp 6 crashes |
| 1463 | + var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); |
| 1464 | + |
| 1465 | + } catch(e) { |
| 1466 | + try { |
| 1467 | + _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); |
| 1468 | + version = [6, 0]; |
| 1469 | + _a.AllowScriptAccess = "always"; // throws if fp < 6.47 |
| 1470 | + |
| 1471 | + } catch(ee) { |
| 1472 | + if (version[0] == 6) { return; } |
| 1473 | + } |
| 1474 | + try { |
| 1475 | + _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); |
| 1476 | + } catch(eee) { |
| 1477 | + |
| 1478 | + } |
| 1479 | + |
| 1480 | + } |
| 1481 | + |
| 1482 | + if (typeof _a == "object") { |
| 1483 | + _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23 |
| 1484 | + if (typeof _d != "undefined") { |
| 1485 | + _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(","); |
| 1486 | + version = [parseInt(_d[0], 10), parseInt(_d[2], 10)]; |
| 1487 | + } |
| 1488 | + } |
| 1489 | + } |
| 1490 | + |
| 1491 | + return version; |
| 1492 | + }, |
| 1493 | + |
| 1494 | + isSupported: function(version) { |
| 1495 | + var now = flashembed.getVersion(); |
| 1496 | + var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]); |
| 1497 | + return ret; |
| 1498 | + }, |
| 1499 | + |
| 1500 | + domReady: domReady, |
| 1501 | + |
| 1502 | + // returns a String representation from JSON object |
| 1503 | + toString: toString |
| 1504 | + |
| 1505 | +}); |
| 1506 | + |
| 1507 | +//}}} |
| 1508 | + |
| 1509 | + |
| 1510 | +// setup jquery support |
| 1511 | +if (jQ) { |
| 1512 | + |
| 1513 | + jQuery.prototype.flashembed = function(params, flashvars) { |
| 1514 | + return this.each(function() { |
| 1515 | + flashembed(this, params, flashvars); |
| 1516 | + }); |
| 1517 | + }; |
| 1518 | + |
| 1519 | +} |
| 1520 | + |
| 1521 | +})(); |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/LICENSE.txt |
— | — | @@ -0,0 +1,674 @@ |
| 2 | + GNU GENERAL PUBLIC LICENSE |
| 3 | + Version 3, 29 June 2007 |
| 4 | + |
| 5 | + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |
| 6 | + Everyone is permitted to copy and distribute verbatim copies |
| 7 | + of this license document, but changing it is not allowed. |
| 8 | + |
| 9 | + Preamble |
| 10 | + |
| 11 | + The GNU General Public License is a free, copyleft license for |
| 12 | +software and other kinds of works. |
| 13 | + |
| 14 | + The licenses for most software and other practical works are designed |
| 15 | +to take away your freedom to share and change the works. By contrast, |
| 16 | +the GNU General Public License is intended to guarantee your freedom to |
| 17 | +share and change all versions of a program--to make sure it remains free |
| 18 | +software for all its users. We, the Free Software Foundation, use the |
| 19 | +GNU General Public License for most of our software; it applies also to |
| 20 | +any other work released this way by its authors. You can apply it to |
| 21 | +your programs, too. |
| 22 | + |
| 23 | + When we speak of free software, we are referring to freedom, not |
| 24 | +price. Our General Public Licenses are designed to make sure that you |
| 25 | +have the freedom to distribute copies of free software (and charge for |
| 26 | +them if you wish), that you receive source code or can get it if you |
| 27 | +want it, that you can change the software or use pieces of it in new |
| 28 | +free programs, and that you know you can do these things. |
| 29 | + |
| 30 | + To protect your rights, we need to prevent others from denying you |
| 31 | +these rights or asking you to surrender the rights. Therefore, you have |
| 32 | +certain responsibilities if you distribute copies of the software, or if |
| 33 | +you modify it: responsibilities to respect the freedom of others. |
| 34 | + |
| 35 | + For example, if you distribute copies of such a program, whether |
| 36 | +gratis or for a fee, you must pass on to the recipients the same |
| 37 | +freedoms that you received. You must make sure that they, too, receive |
| 38 | +or can get the source code. And you must show them these terms so they |
| 39 | +know their rights. |
| 40 | + |
| 41 | + Developers that use the GNU GPL protect your rights with two steps: |
| 42 | +(1) assert copyright on the software, and (2) offer you this License |
| 43 | +giving you legal permission to copy, distribute and/or modify it. |
| 44 | + |
| 45 | + For the developers' and authors' protection, the GPL clearly explains |
| 46 | +that there is no warranty for this free software. For both users' and |
| 47 | +authors' sake, the GPL requires that modified versions be marked as |
| 48 | +changed, so that their problems will not be attributed erroneously to |
| 49 | +authors of previous versions. |
| 50 | + |
| 51 | + Some devices are designed to deny users access to install or run |
| 52 | +modified versions of the software inside them, although the manufacturer |
| 53 | +can do so. This is fundamentally incompatible with the aim of |
| 54 | +protecting users' freedom to change the software. The systematic |
| 55 | +pattern of such abuse occurs in the area of products for individuals to |
| 56 | +use, which is precisely where it is most unacceptable. Therefore, we |
| 57 | +have designed this version of the GPL to prohibit the practice for those |
| 58 | +products. If such problems arise substantially in other domains, we |
| 59 | +stand ready to extend this provision to those domains in future versions |
| 60 | +of the GPL, as needed to protect the freedom of users. |
| 61 | + |
| 62 | + Finally, every program is threatened constantly by software patents. |
| 63 | +States should not allow patents to restrict development and use of |
| 64 | +software on general-purpose computers, but in those that do, we wish to |
| 65 | +avoid the special danger that patents applied to a free program could |
| 66 | +make it effectively proprietary. To prevent this, the GPL assures that |
| 67 | +patents cannot be used to render the program non-free. |
| 68 | + |
| 69 | + The precise terms and conditions for copying, distribution and |
| 70 | +modification follow. |
| 71 | + |
| 72 | + TERMS AND CONDITIONS |
| 73 | + |
| 74 | + 0. Definitions. |
| 75 | + |
| 76 | + "This License" refers to version 3 of the GNU General Public License. |
| 77 | + |
| 78 | + "Copyright" also means copyright-like laws that apply to other kinds of |
| 79 | +works, such as semiconductor masks. |
| 80 | + |
| 81 | + "The Program" refers to any copyrightable work licensed under this |
| 82 | +License. Each licensee is addressed as "you". "Licensees" and |
| 83 | +"recipients" may be individuals or organizations. |
| 84 | + |
| 85 | + To "modify" a work means to copy from or adapt all or part of the work |
| 86 | +in a fashion requiring copyright permission, other than the making of an |
| 87 | +exact copy. The resulting work is called a "modified version" of the |
| 88 | +earlier work or a work "based on" the earlier work. |
| 89 | + |
| 90 | + A "covered work" means either the unmodified Program or a work based |
| 91 | +on the Program. |
| 92 | + |
| 93 | + To "propagate" a work means to do anything with it that, without |
| 94 | +permission, would make you directly or secondarily liable for |
| 95 | +infringement under applicable copyright law, except executing it on a |
| 96 | +computer or modifying a private copy. Propagation includes copying, |
| 97 | +distribution (with or without modification), making available to the |
| 98 | +public, and in some countries other activities as well. |
| 99 | + |
| 100 | + To "convey" a work means any kind of propagation that enables other |
| 101 | +parties to make or receive copies. Mere interaction with a user through |
| 102 | +a computer network, with no transfer of a copy, is not conveying. |
| 103 | + |
| 104 | + An interactive user interface displays "Appropriate Legal Notices" |
| 105 | +to the extent that it includes a convenient and prominently visible |
| 106 | +feature that (1) displays an appropriate copyright notice, and (2) |
| 107 | +tells the user that there is no warranty for the work (except to the |
| 108 | +extent that warranties are provided), that licensees may convey the |
| 109 | +work under this License, and how to view a copy of this License. If |
| 110 | +the interface presents a list of user commands or options, such as a |
| 111 | +menu, a prominent item in the list meets this criterion. |
| 112 | + |
| 113 | + 1. Source Code. |
| 114 | + |
| 115 | + The "source code" for a work means the preferred form of the work |
| 116 | +for making modifications to it. "Object code" means any non-source |
| 117 | +form of a work. |
| 118 | + |
| 119 | + A "Standard Interface" means an interface that either is an official |
| 120 | +standard defined by a recognized standards body, or, in the case of |
| 121 | +interfaces specified for a particular programming language, one that |
| 122 | +is widely used among developers working in that language. |
| 123 | + |
| 124 | + The "System Libraries" of an executable work include anything, other |
| 125 | +than the work as a whole, that (a) is included in the normal form of |
| 126 | +packaging a Major Component, but which is not part of that Major |
| 127 | +Component, and (b) serves only to enable use of the work with that |
| 128 | +Major Component, or to implement a Standard Interface for which an |
| 129 | +implementation is available to the public in source code form. A |
| 130 | +"Major Component", in this context, means a major essential component |
| 131 | +(kernel, window system, and so on) of the specific operating system |
| 132 | +(if any) on which the executable work runs, or a compiler used to |
| 133 | +produce the work, or an object code interpreter used to run it. |
| 134 | + |
| 135 | + The "Corresponding Source" for a work in object code form means all |
| 136 | +the source code needed to generate, install, and (for an executable |
| 137 | +work) run the object code and to modify the work, including scripts to |
| 138 | +control those activities. However, it does not include the work's |
| 139 | +System Libraries, or general-purpose tools or generally available free |
| 140 | +programs which are used unmodified in performing those activities but |
| 141 | +which are not part of the work. For example, Corresponding Source |
| 142 | +includes interface definition files associated with source files for |
| 143 | +the work, and the source code for shared libraries and dynamically |
| 144 | +linked subprograms that the work is specifically designed to require, |
| 145 | +such as by intimate data communication or control flow between those |
| 146 | +subprograms and other parts of the work. |
| 147 | + |
| 148 | + The Corresponding Source need not include anything that users |
| 149 | +can regenerate automatically from other parts of the Corresponding |
| 150 | +Source. |
| 151 | + |
| 152 | + The Corresponding Source for a work in source code form is that |
| 153 | +same work. |
| 154 | + |
| 155 | + 2. Basic Permissions. |
| 156 | + |
| 157 | + All rights granted under this License are granted for the term of |
| 158 | +copyright on the Program, and are irrevocable provided the stated |
| 159 | +conditions are met. This License explicitly affirms your unlimited |
| 160 | +permission to run the unmodified Program. The output from running a |
| 161 | +covered work is covered by this License only if the output, given its |
| 162 | +content, constitutes a covered work. This License acknowledges your |
| 163 | +rights of fair use or other equivalent, as provided by copyright law. |
| 164 | + |
| 165 | + You may make, run and propagate covered works that you do not |
| 166 | +convey, without conditions so long as your license otherwise remains |
| 167 | +in force. You may convey covered works to others for the sole purpose |
| 168 | +of having them make modifications exclusively for you, or provide you |
| 169 | +with facilities for running those works, provided that you comply with |
| 170 | +the terms of this License in conveying all material for which you do |
| 171 | +not control copyright. Those thus making or running the covered works |
| 172 | +for you must do so exclusively on your behalf, under your direction |
| 173 | +and control, on terms that prohibit them from making any copies of |
| 174 | +your copyrighted material outside their relationship with you. |
| 175 | + |
| 176 | + Conveying under any other circumstances is permitted solely under |
| 177 | +the conditions stated below. Sublicensing is not allowed; section 10 |
| 178 | +makes it unnecessary. |
| 179 | + |
| 180 | + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. |
| 181 | + |
| 182 | + No covered work shall be deemed part of an effective technological |
| 183 | +measure under any applicable law fulfilling obligations under article |
| 184 | +11 of the WIPO copyright treaty adopted on 20 December 1996, or |
| 185 | +similar laws prohibiting or restricting circumvention of such |
| 186 | +measures. |
| 187 | + |
| 188 | + When you convey a covered work, you waive any legal power to forbid |
| 189 | +circumvention of technological measures to the extent such circumvention |
| 190 | +is effected by exercising rights under this License with respect to |
| 191 | +the covered work, and you disclaim any intention to limit operation or |
| 192 | +modification of the work as a means of enforcing, against the work's |
| 193 | +users, your or third parties' legal rights to forbid circumvention of |
| 194 | +technological measures. |
| 195 | + |
| 196 | + 4. Conveying Verbatim Copies. |
| 197 | + |
| 198 | + You may convey verbatim copies of the Program's source code as you |
| 199 | +receive it, in any medium, provided that you conspicuously and |
| 200 | +appropriately publish on each copy an appropriate copyright notice; |
| 201 | +keep intact all notices stating that this License and any |
| 202 | +non-permissive terms added in accord with section 7 apply to the code; |
| 203 | +keep intact all notices of the absence of any warranty; and give all |
| 204 | +recipients a copy of this License along with the Program. |
| 205 | + |
| 206 | + You may charge any price or no price for each copy that you convey, |
| 207 | +and you may offer support or warranty protection for a fee. |
| 208 | + |
| 209 | + 5. Conveying Modified Source Versions. |
| 210 | + |
| 211 | + You may convey a work based on the Program, or the modifications to |
| 212 | +produce it from the Program, in the form of source code under the |
| 213 | +terms of section 4, provided that you also meet all of these conditions: |
| 214 | + |
| 215 | + a) The work must carry prominent notices stating that you modified |
| 216 | + it, and giving a relevant date. |
| 217 | + |
| 218 | + b) The work must carry prominent notices stating that it is |
| 219 | + released under this License and any conditions added under section |
| 220 | + 7. This requirement modifies the requirement in section 4 to |
| 221 | + "keep intact all notices". |
| 222 | + |
| 223 | + c) You must license the entire work, as a whole, under this |
| 224 | + License to anyone who comes into possession of a copy. This |
| 225 | + License will therefore apply, along with any applicable section 7 |
| 226 | + additional terms, to the whole of the work, and all its parts, |
| 227 | + regardless of how they are packaged. This License gives no |
| 228 | + permission to license the work in any other way, but it does not |
| 229 | + invalidate such permission if you have separately received it. |
| 230 | + |
| 231 | + d) If the work has interactive user interfaces, each must display |
| 232 | + Appropriate Legal Notices; however, if the Program has interactive |
| 233 | + interfaces that do not display Appropriate Legal Notices, your |
| 234 | + work need not make them do so. |
| 235 | + |
| 236 | + A compilation of a covered work with other separate and independent |
| 237 | +works, which are not by their nature extensions of the covered work, |
| 238 | +and which are not combined with it such as to form a larger program, |
| 239 | +in or on a volume of a storage or distribution medium, is called an |
| 240 | +"aggregate" if the compilation and its resulting copyright are not |
| 241 | +used to limit the access or legal rights of the compilation's users |
| 242 | +beyond what the individual works permit. Inclusion of a covered work |
| 243 | +in an aggregate does not cause this License to apply to the other |
| 244 | +parts of the aggregate. |
| 245 | + |
| 246 | + 6. Conveying Non-Source Forms. |
| 247 | + |
| 248 | + You may convey a covered work in object code form under the terms |
| 249 | +of sections 4 and 5, provided that you also convey the |
| 250 | +machine-readable Corresponding Source under the terms of this License, |
| 251 | +in one of these ways: |
| 252 | + |
| 253 | + a) Convey the object code in, or embodied in, a physical product |
| 254 | + (including a physical distribution medium), accompanied by the |
| 255 | + Corresponding Source fixed on a durable physical medium |
| 256 | + customarily used for software interchange. |
| 257 | + |
| 258 | + b) Convey the object code in, or embodied in, a physical product |
| 259 | + (including a physical distribution medium), accompanied by a |
| 260 | + written offer, valid for at least three years and valid for as |
| 261 | + long as you offer spare parts or customer support for that product |
| 262 | + model, to give anyone who possesses the object code either (1) a |
| 263 | + copy of the Corresponding Source for all the software in the |
| 264 | + product that is covered by this License, on a durable physical |
| 265 | + medium customarily used for software interchange, for a price no |
| 266 | + more than your reasonable cost of physically performing this |
| 267 | + conveying of source, or (2) access to copy the |
| 268 | + Corresponding Source from a network server at no charge. |
| 269 | + |
| 270 | + c) Convey individual copies of the object code with a copy of the |
| 271 | + written offer to provide the Corresponding Source. This |
| 272 | + alternative is allowed only occasionally and noncommercially, and |
| 273 | + only if you received the object code with such an offer, in accord |
| 274 | + with subsection 6b. |
| 275 | + |
| 276 | + d) Convey the object code by offering access from a designated |
| 277 | + place (gratis or for a charge), and offer equivalent access to the |
| 278 | + Corresponding Source in the same way through the same place at no |
| 279 | + further charge. You need not require recipients to copy the |
| 280 | + Corresponding Source along with the object code. If the place to |
| 281 | + copy the object code is a network server, the Corresponding Source |
| 282 | + may be on a different server (operated by you or a third party) |
| 283 | + that supports equivalent copying facilities, provided you maintain |
| 284 | + clear directions next to the object code saying where to find the |
| 285 | + Corresponding Source. Regardless of what server hosts the |
| 286 | + Corresponding Source, you remain obligated to ensure that it is |
| 287 | + available for as long as needed to satisfy these requirements. |
| 288 | + |
| 289 | + e) Convey the object code using peer-to-peer transmission, provided |
| 290 | + you inform other peers where the object code and Corresponding |
| 291 | + Source of the work are being offered to the general public at no |
| 292 | + charge under subsection 6d. |
| 293 | + |
| 294 | + A separable portion of the object code, whose source code is excluded |
| 295 | +from the Corresponding Source as a System Library, need not be |
| 296 | +included in conveying the object code work. |
| 297 | + |
| 298 | + A "User Product" is either (1) a "consumer product", which means any |
| 299 | +tangible personal property which is normally used for personal, family, |
| 300 | +or household purposes, or (2) anything designed or sold for incorporation |
| 301 | +into a dwelling. In determining whether a product is a consumer product, |
| 302 | +doubtful cases shall be resolved in favor of coverage. For a particular |
| 303 | +product received by a particular user, "normally used" refers to a |
| 304 | +typical or common use of that class of product, regardless of the status |
| 305 | +of the particular user or of the way in which the particular user |
| 306 | +actually uses, or expects or is expected to use, the product. A product |
| 307 | +is a consumer product regardless of whether the product has substantial |
| 308 | +commercial, industrial or non-consumer uses, unless such uses represent |
| 309 | +the only significant mode of use of the product. |
| 310 | + |
| 311 | + "Installation Information" for a User Product means any methods, |
| 312 | +procedures, authorization keys, or other information required to install |
| 313 | +and execute modified versions of a covered work in that User Product from |
| 314 | +a modified version of its Corresponding Source. The information must |
| 315 | +suffice to ensure that the continued functioning of the modified object |
| 316 | +code is in no case prevented or interfered with solely because |
| 317 | +modification has been made. |
| 318 | + |
| 319 | + If you convey an object code work under this section in, or with, or |
| 320 | +specifically for use in, a User Product, and the conveying occurs as |
| 321 | +part of a transaction in which the right of possession and use of the |
| 322 | +User Product is transferred to the recipient in perpetuity or for a |
| 323 | +fixed term (regardless of how the transaction is characterized), the |
| 324 | +Corresponding Source conveyed under this section must be accompanied |
| 325 | +by the Installation Information. But this requirement does not apply |
| 326 | +if neither you nor any third party retains the ability to install |
| 327 | +modified object code on the User Product (for example, the work has |
| 328 | +been installed in ROM). |
| 329 | + |
| 330 | + The requirement to provide Installation Information does not include a |
| 331 | +requirement to continue to provide support service, warranty, or updates |
| 332 | +for a work that has been modified or installed by the recipient, or for |
| 333 | +the User Product in which it has been modified or installed. Access to a |
| 334 | +network may be denied when the modification itself materially and |
| 335 | +adversely affects the operation of the network or violates the rules and |
| 336 | +protocols for communication across the network. |
| 337 | + |
| 338 | + Corresponding Source conveyed, and Installation Information provided, |
| 339 | +in accord with this section must be in a format that is publicly |
| 340 | +documented (and with an implementation available to the public in |
| 341 | +source code form), and must require no special password or key for |
| 342 | +unpacking, reading or copying. |
| 343 | + |
| 344 | + 7. Additional Terms. |
| 345 | + |
| 346 | + "Additional permissions" are terms that supplement the terms of this |
| 347 | +License by making exceptions from one or more of its conditions. |
| 348 | +Additional permissions that are applicable to the entire Program shall |
| 349 | +be treated as though they were included in this License, to the extent |
| 350 | +that they are valid under applicable law. If additional permissions |
| 351 | +apply only to part of the Program, that part may be used separately |
| 352 | +under those permissions, but the entire Program remains governed by |
| 353 | +this License without regard to the additional permissions. |
| 354 | + |
| 355 | + When you convey a copy of a covered work, you may at your option |
| 356 | +remove any additional permissions from that copy, or from any part of |
| 357 | +it. (Additional permissions may be written to require their own |
| 358 | +removal in certain cases when you modify the work.) You may place |
| 359 | +additional permissions on material, added by you to a covered work, |
| 360 | +for which you have or can give appropriate copyright permission. |
| 361 | + |
| 362 | + Notwithstanding any other provision of this License, for material you |
| 363 | +add to a covered work, you may (if authorized by the copyright holders of |
| 364 | +that material) supplement the terms of this License with terms: |
| 365 | + |
| 366 | + a) Disclaiming warranty or limiting liability differently from the |
| 367 | + terms of sections 15 and 16 of this License; or |
| 368 | + |
| 369 | + b) Requiring preservation of specified reasonable legal notices or |
| 370 | + author attributions in that material or in the Appropriate Legal |
| 371 | + Notices displayed by works containing it; or |
| 372 | + |
| 373 | + c) Prohibiting misrepresentation of the origin of that material, or |
| 374 | + requiring that modified versions of such material be marked in |
| 375 | + reasonable ways as different from the original version; or |
| 376 | + |
| 377 | + d) Limiting the use for publicity purposes of names of licensors or |
| 378 | + authors of the material; or |
| 379 | + |
| 380 | + e) Declining to grant rights under trademark law for use of some |
| 381 | + trade names, trademarks, or service marks; or |
| 382 | + |
| 383 | + f) Requiring indemnification of licensors and authors of that |
| 384 | + material by anyone who conveys the material (or modified versions of |
| 385 | + it) with contractual assumptions of liability to the recipient, for |
| 386 | + any liability that these contractual assumptions directly impose on |
| 387 | + those licensors and authors. |
| 388 | + |
| 389 | + All other non-permissive additional terms are considered "further |
| 390 | +restrictions" within the meaning of section 10. If the Program as you |
| 391 | +received it, or any part of it, contains a notice stating that it is |
| 392 | +governed by this License along with a term that is a further |
| 393 | +restriction, you may remove that term. If a license document contains |
| 394 | +a further restriction but permits relicensing or conveying under this |
| 395 | +License, you may add to a covered work material governed by the terms |
| 396 | +of that license document, provided that the further restriction does |
| 397 | +not survive such relicensing or conveying. |
| 398 | + |
| 399 | + If you add terms to a covered work in accord with this section, you |
| 400 | +must place, in the relevant source files, a statement of the |
| 401 | +additional terms that apply to those files, or a notice indicating |
| 402 | +where to find the applicable terms. |
| 403 | + |
| 404 | + Additional terms, permissive or non-permissive, may be stated in the |
| 405 | +form of a separately written license, or stated as exceptions; |
| 406 | +the above requirements apply either way. |
| 407 | + |
| 408 | + 8. Termination. |
| 409 | + |
| 410 | + You may not propagate or modify a covered work except as expressly |
| 411 | +provided under this License. Any attempt otherwise to propagate or |
| 412 | +modify it is void, and will automatically terminate your rights under |
| 413 | +this License (including any patent licenses granted under the third |
| 414 | +paragraph of section 11). |
| 415 | + |
| 416 | + However, if you cease all violation of this License, then your |
| 417 | +license from a particular copyright holder is reinstated (a) |
| 418 | +provisionally, unless and until the copyright holder explicitly and |
| 419 | +finally terminates your license, and (b) permanently, if the copyright |
| 420 | +holder fails to notify you of the violation by some reasonable means |
| 421 | +prior to 60 days after the cessation. |
| 422 | + |
| 423 | + Moreover, your license from a particular copyright holder is |
| 424 | +reinstated permanently if the copyright holder notifies you of the |
| 425 | +violation by some reasonable means, this is the first time you have |
| 426 | +received notice of violation of this License (for any work) from that |
| 427 | +copyright holder, and you cure the violation prior to 30 days after |
| 428 | +your receipt of the notice. |
| 429 | + |
| 430 | + Termination of your rights under this section does not terminate the |
| 431 | +licenses of parties who have received copies or rights from you under |
| 432 | +this License. If your rights have been terminated and not permanently |
| 433 | +reinstated, you do not qualify to receive new licenses for the same |
| 434 | +material under section 10. |
| 435 | + |
| 436 | + 9. Acceptance Not Required for Having Copies. |
| 437 | + |
| 438 | + You are not required to accept this License in order to receive or |
| 439 | +run a copy of the Program. Ancillary propagation of a covered work |
| 440 | +occurring solely as a consequence of using peer-to-peer transmission |
| 441 | +to receive a copy likewise does not require acceptance. However, |
| 442 | +nothing other than this License grants you permission to propagate or |
| 443 | +modify any covered work. These actions infringe copyright if you do |
| 444 | +not accept this License. Therefore, by modifying or propagating a |
| 445 | +covered work, you indicate your acceptance of this License to do so. |
| 446 | + |
| 447 | + 10. Automatic Licensing of Downstream Recipients. |
| 448 | + |
| 449 | + Each time you convey a covered work, the recipient automatically |
| 450 | +receives a license from the original licensors, to run, modify and |
| 451 | +propagate that work, subject to this License. You are not responsible |
| 452 | +for enforcing compliance by third parties with this License. |
| 453 | + |
| 454 | + An "entity transaction" is a transaction transferring control of an |
| 455 | +organization, or substantially all assets of one, or subdividing an |
| 456 | +organization, or merging organizations. If propagation of a covered |
| 457 | +work results from an entity transaction, each party to that |
| 458 | +transaction who receives a copy of the work also receives whatever |
| 459 | +licenses to the work the party's predecessor in interest had or could |
| 460 | +give under the previous paragraph, plus a right to possession of the |
| 461 | +Corresponding Source of the work from the predecessor in interest, if |
| 462 | +the predecessor has it or can get it with reasonable efforts. |
| 463 | + |
| 464 | + You may not impose any further restrictions on the exercise of the |
| 465 | +rights granted or affirmed under this License. For example, you may |
| 466 | +not impose a license fee, royalty, or other charge for exercise of |
| 467 | +rights granted under this License, and you may not initiate litigation |
| 468 | +(including a cross-claim or counterclaim in a lawsuit) alleging that |
| 469 | +any patent claim is infringed by making, using, selling, offering for |
| 470 | +sale, or importing the Program or any portion of it. |
| 471 | + |
| 472 | + 11. Patents. |
| 473 | + |
| 474 | + A "contributor" is a copyright holder who authorizes use under this |
| 475 | +License of the Program or a work on which the Program is based. The |
| 476 | +work thus licensed is called the contributor's "contributor version". |
| 477 | + |
| 478 | + A contributor's "essential patent claims" are all patent claims |
| 479 | +owned or controlled by the contributor, whether already acquired or |
| 480 | +hereafter acquired, that would be infringed by some manner, permitted |
| 481 | +by this License, of making, using, or selling its contributor version, |
| 482 | +but do not include claims that would be infringed only as a |
| 483 | +consequence of further modification of the contributor version. For |
| 484 | +purposes of this definition, "control" includes the right to grant |
| 485 | +patent sublicenses in a manner consistent with the requirements of |
| 486 | +this License. |
| 487 | + |
| 488 | + Each contributor grants you a non-exclusive, worldwide, royalty-free |
| 489 | +patent license under the contributor's essential patent claims, to |
| 490 | +make, use, sell, offer for sale, import and otherwise run, modify and |
| 491 | +propagate the contents of its contributor version. |
| 492 | + |
| 493 | + In the following three paragraphs, a "patent license" is any express |
| 494 | +agreement or commitment, however denominated, not to enforce a patent |
| 495 | +(such as an express permission to practice a patent or covenant not to |
| 496 | +sue for patent infringement). To "grant" such a patent license to a |
| 497 | +party means to make such an agreement or commitment not to enforce a |
| 498 | +patent against the party. |
| 499 | + |
| 500 | + If you convey a covered work, knowingly relying on a patent license, |
| 501 | +and the Corresponding Source of the work is not available for anyone |
| 502 | +to copy, free of charge and under the terms of this License, through a |
| 503 | +publicly available network server or other readily accessible means, |
| 504 | +then you must either (1) cause the Corresponding Source to be so |
| 505 | +available, or (2) arrange to deprive yourself of the benefit of the |
| 506 | +patent license for this particular work, or (3) arrange, in a manner |
| 507 | +consistent with the requirements of this License, to extend the patent |
| 508 | +license to downstream recipients. "Knowingly relying" means you have |
| 509 | +actual knowledge that, but for the patent license, your conveying the |
| 510 | +covered work in a country, or your recipient's use of the covered work |
| 511 | +in a country, would infringe one or more identifiable patents in that |
| 512 | +country that you have reason to believe are valid. |
| 513 | + |
| 514 | + If, pursuant to or in connection with a single transaction or |
| 515 | +arrangement, you convey, or propagate by procuring conveyance of, a |
| 516 | +covered work, and grant a patent license to some of the parties |
| 517 | +receiving the covered work authorizing them to use, propagate, modify |
| 518 | +or convey a specific copy of the covered work, then the patent license |
| 519 | +you grant is automatically extended to all recipients of the covered |
| 520 | +work and works based on it. |
| 521 | + |
| 522 | + A patent license is "discriminatory" if it does not include within |
| 523 | +the scope of its coverage, prohibits the exercise of, or is |
| 524 | +conditioned on the non-exercise of one or more of the rights that are |
| 525 | +specifically granted under this License. You may not convey a covered |
| 526 | +work if you are a party to an arrangement with a third party that is |
| 527 | +in the business of distributing software, under which you make payment |
| 528 | +to the third party based on the extent of your activity of conveying |
| 529 | +the work, and under which the third party grants, to any of the |
| 530 | +parties who would receive the covered work from you, a discriminatory |
| 531 | +patent license (a) in connection with copies of the covered work |
| 532 | +conveyed by you (or copies made from those copies), or (b) primarily |
| 533 | +for and in connection with specific products or compilations that |
| 534 | +contain the covered work, unless you entered into that arrangement, |
| 535 | +or that patent license was granted, prior to 28 March 2007. |
| 536 | + |
| 537 | + Nothing in this License shall be construed as excluding or limiting |
| 538 | +any implied license or other defenses to infringement that may |
| 539 | +otherwise be available to you under applicable patent law. |
| 540 | + |
| 541 | + 12. No Surrender of Others' Freedom. |
| 542 | + |
| 543 | + If conditions are imposed on you (whether by court order, agreement or |
| 544 | +otherwise) that contradict the conditions of this License, they do not |
| 545 | +excuse you from the conditions of this License. If you cannot convey a |
| 546 | +covered work so as to satisfy simultaneously your obligations under this |
| 547 | +License and any other pertinent obligations, then as a consequence you may |
| 548 | +not convey it at all. For example, if you agree to terms that obligate you |
| 549 | +to collect a royalty for further conveying from those to whom you convey |
| 550 | +the Program, the only way you could satisfy both those terms and this |
| 551 | +License would be to refrain entirely from conveying the Program. |
| 552 | + |
| 553 | + 13. Use with the GNU Affero General Public License. |
| 554 | + |
| 555 | + Notwithstanding any other provision of this License, you have |
| 556 | +permission to link or combine any covered work with a work licensed |
| 557 | +under version 3 of the GNU Affero General Public License into a single |
| 558 | +combined work, and to convey the resulting work. The terms of this |
| 559 | +License will continue to apply to the part which is the covered work, |
| 560 | +but the special requirements of the GNU Affero General Public License, |
| 561 | +section 13, concerning interaction through a network will apply to the |
| 562 | +combination as such. |
| 563 | + |
| 564 | + 14. Revised Versions of this License. |
| 565 | + |
| 566 | + The Free Software Foundation may publish revised and/or new versions of |
| 567 | +the GNU General Public License from time to time. Such new versions will |
| 568 | +be similar in spirit to the present version, but may differ in detail to |
| 569 | +address new problems or concerns. |
| 570 | + |
| 571 | + Each version is given a distinguishing version number. If the |
| 572 | +Program specifies that a certain numbered version of the GNU General |
| 573 | +Public License "or any later version" applies to it, you have the |
| 574 | +option of following the terms and conditions either of that numbered |
| 575 | +version or of any later version published by the Free Software |
| 576 | +Foundation. If the Program does not specify a version number of the |
| 577 | +GNU General Public License, you may choose any version ever published |
| 578 | +by the Free Software Foundation. |
| 579 | + |
| 580 | + If the Program specifies that a proxy can decide which future |
| 581 | +versions of the GNU General Public License can be used, that proxy's |
| 582 | +public statement of acceptance of a version permanently authorizes you |
| 583 | +to choose that version for the Program. |
| 584 | + |
| 585 | + Later license versions may give you additional or different |
| 586 | +permissions. However, no additional obligations are imposed on any |
| 587 | +author or copyright holder as a result of your choosing to follow a |
| 588 | +later version. |
| 589 | + |
| 590 | + 15. Disclaimer of Warranty. |
| 591 | + |
| 592 | + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY |
| 593 | +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT |
| 594 | +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY |
| 595 | +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, |
| 596 | +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 597 | +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM |
| 598 | +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF |
| 599 | +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
| 600 | + |
| 601 | + 16. Limitation of Liability. |
| 602 | + |
| 603 | + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
| 604 | +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS |
| 605 | +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY |
| 606 | +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE |
| 607 | +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF |
| 608 | +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD |
| 609 | +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), |
| 610 | +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |
| 611 | +SUCH DAMAGES. |
| 612 | + |
| 613 | + 17. Interpretation of Sections 15 and 16. |
| 614 | + |
| 615 | + If the disclaimer of warranty and limitation of liability provided |
| 616 | +above cannot be given local legal effect according to their terms, |
| 617 | +reviewing courts shall apply local law that most closely approximates |
| 618 | +an absolute waiver of all civil liability in connection with the |
| 619 | +Program, unless a warranty or assumption of liability accompanies a |
| 620 | +copy of the Program in return for a fee. |
| 621 | + |
| 622 | + END OF TERMS AND CONDITIONS |
| 623 | + |
| 624 | + How to Apply These Terms to Your New Programs |
| 625 | + |
| 626 | + If you develop a new program, and you want it to be of the greatest |
| 627 | +possible use to the public, the best way to achieve this is to make it |
| 628 | +free software which everyone can redistribute and change under these terms. |
| 629 | + |
| 630 | + To do so, attach the following notices to the program. It is safest |
| 631 | +to attach them to the start of each source file to most effectively |
| 632 | +state the exclusion of warranty; and each file should have at least |
| 633 | +the "copyright" line and a pointer to where the full notice is found. |
| 634 | + |
| 635 | + <one line to give the program's name and a brief idea of what it does.> |
| 636 | + Copyright (C) <year> <name of author> |
| 637 | + |
| 638 | + This program is free software: you can redistribute it and/or modify |
| 639 | + it under the terms of the GNU General Public License as published by |
| 640 | + the Free Software Foundation, either version 3 of the License, or |
| 641 | + (at your option) any later version. |
| 642 | + |
| 643 | + This program is distributed in the hope that it will be useful, |
| 644 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 645 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 646 | + GNU General Public License for more details. |
| 647 | + |
| 648 | + You should have received a copy of the GNU General Public License |
| 649 | + along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 650 | + |
| 651 | +Also add information on how to contact you by electronic and paper mail. |
| 652 | + |
| 653 | + If the program does terminal interaction, make it output a short |
| 654 | +notice like this when it starts in an interactive mode: |
| 655 | + |
| 656 | + <program> Copyright (C) <year> <name of author> |
| 657 | + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
| 658 | + This is free software, and you are welcome to redistribute it |
| 659 | + under certain conditions; type `show c' for details. |
| 660 | + |
| 661 | +The hypothetical commands `show w' and `show c' should show the appropriate |
| 662 | +parts of the General Public License. Of course, your program's commands |
| 663 | +might be different; for a GUI interface, you would use an "about box". |
| 664 | + |
| 665 | + You should also get your employer (if you work as a programmer) or school, |
| 666 | +if any, to sign a "copyright disclaimer" for the program, if necessary. |
| 667 | +For more information on this, and how to apply and follow the GNU GPL, see |
| 668 | +<http://www.gnu.org/licenses/>. |
| 669 | + |
| 670 | + The GNU General Public License does not permit incorporating your program |
| 671 | +into proprietary programs. If your program is a subroutine library, you |
| 672 | +may consider it more useful to permit linking proprietary applications with |
| 673 | +the library. If this is what you want to do, use the GNU Lesser General |
| 674 | +Public License instead of this License. But first, please read |
| 675 | +<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
\ No newline at end of file |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.min.js |
— | — | @@ -0,0 +1,15 @@ |
| 2 | +/** |
| 3 | + * flowplayer.js 3.0.0-rc2. The Flowplayer API. |
| 4 | + * |
| 5 | + * This file is part of Flowplayer, http://flowplayer.org |
| 6 | + * |
| 7 | + * Author: Tero Piirainen, <support@flowplayer.org> |
| 8 | + * Copyright (c) 2008 Flowplayer Ltd |
| 9 | + * |
| 10 | + * Released under the MIT License: |
| 11 | + * http://www.opensource.org/licenses/mit-license.php |
| 12 | + * |
| 13 | + * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:52 GMT-0000 (GMT+00:00) |
| 14 | + */ |
| 15 | +(function(){function log(args){if(typeof opera=='object'){opera.postError("$f.fireEvent: "+args.join(" | "));}else if(typeof console=='object'){console.log("$f.fireEvent",[].slice.call(args));}}function clone(obj){if(!obj||typeof obj!='object'){return obj;}var temp=new obj.constructor();for(var key in obj){if(obj.hasOwnProperty(key)){temp[key]=clone(obj[key]);}}return temp;}function each(obj,fn){if(!obj){return;}var name,i=0,length=obj.length;if(length===undefined){for(name in obj){if(fn.call(obj[name],name,obj[name])===false){break;}}}else{for(var value=obj[0];i<length&&fn.call(value,i,value)!==false;value=obj[++i]){}}return obj;}function el(id){return document.getElementById(id);}function extend(to,from,skipFuncs){if(to&&from){each(from,function(name,value){if(!skipFuncs||typeof value!='function'){to[name]=value;}});}}function select(query){var index=query.indexOf(".");if(index!=-1){var tag=query.substring(0,index)||"*";var klass=query.substring(index+1,query.length);var els=[];each(document.getElementsByTagName(tag),function(){if(this.className&&this.className.indexOf(klass)!=-1){els.push(this);}});return els;}}function stopEvent(e){e=e||window.event;if(e.preventDefault){e.stopPropagation();e.preventDefault();}else{e.returnValue=false;e.cancelBubble=true;}return false;}function bind(to,evt,fn){to[evt]=to[evt]||[];to[evt].push(fn);}function makeId(){return"_"+(""+Math.random()).substring(2,10);}var Clip=function(json,index,player){var self=this;var cuepoints={};var listeners={};this.index=index;if(typeof json=='string'){json={url:json};}extend(this,json,true);each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),function(){var evt="on"+this;if(evt.indexOf("*")!=-1){evt=evt.substring(0,evt.length-1);var before="onBefore"+evt.substring(2);self[before]=function(fn){bind(listeners,before,fn);return self;};}self[evt]=function(fn){bind(listeners,evt,fn);return self;};if(index==-1){if(self[before]){player[before]=self[before];}if(self[evt]){player[evt]=self[evt];}}});extend(this,{onCuepoint:function(points,fn){if(arguments.length==1){cuepoints.embedded=[null,points];return self;}if(typeof points=='number'){points=[points];}var fnId=makeId();cuepoints[fnId]=[points,fn];if(player.isLoaded()){player._api().fp_addCuepoints(points,index,fnId);}return self;},update:function(json){extend(self,json);if(player.isLoaded()){player._api().fp_updateClip(json,index);}var conf=player._config();var clip=(index==-1)?conf.clip:conf.playlist[index];extend(clip,json,true);},_fireEvent:function(evt,arg1,arg2,target){if(evt=='onLoad'){each(cuepoints,function(key,val){player._api().fp_addCuepoints(val[0],index,key);});return false;}if(index!=-1){target=self;}if(evt=='onCuepoint'){var fn=cuepoints[arg1];if(fn){return fn[1].call(player,target,arg2);}}if(evt=='onMetaData'||evt=='onUpdate'){extend(target,arg1);if(!target.duration){target.duration=arg1.metaData.duration;}else{target.fullDuration=arg1.metaData.duration;}}var ret=true;each(listeners[evt],function(){ret=this.call(player,target,arg1);});return ret;}});if(json.onCuepoint){self.onCuepoint.apply(self,json.onCuepoint);delete json.onCuepoint;}each(json,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete json[key];}});if(index==-1){player.onCuepoint=this.onCuepoint;}};var Plugin=function(name,json,player,fn){var listeners={};var self=this;var hasMethods=false;if(fn){extend(listeners,fn);}each(json,function(key,val){if(typeof val=='function'){listeners[key]=val;delete json[key];}});extend(this,{animate:function(props,speed,fn){if(!props){return self;}if(typeof speed=='function'){fn=speed;speed=500;}if(typeof props=='string'){var key=props;props={};props[key]=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}if(speed===undefined){speed=500;}json=player._api().fp_animate(name,props,speed,fnId);return self;},css:function(props,val){if(val!==undefined){var css={};css[props]=val;props=css;}json=player._api().fp_css(name,props);extend(self,json);return self;},show:function(){this.display='block';player._api().fp_showPlugin(name);return self;},hide:function(){this.display='none';player._api().fp_hidePlugin(name);return self;},toggle:function(){this.display=player._api().fp_togglePlugin(name);return self;},fadeTo:function(o,speed,fn){if(typeof speed=='function'){fn=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}this.display=player._api().fp_fadeTo(name,o,speed,fnId);this.opacity=o;return self;},fadeIn:function(speed,fn){return self.fadeTo(1,speed,fn);},fadeOut:function(speed,fn){return self.fadeTo(0,speed,fn);},getName:function(){return name;},_fireEvent:function(evt,arg){if(evt=='onUpdate'){var json=arg||player._api().fp_getPlugin(name);if(!json){return;}extend(self,json);delete self.methods;if(!hasMethods){each(json.methods,function(){var method=""+this;self[method]=function(){var a=[].slice.call(arguments);var ret=player._api().fp_invoke(name,method,a);return ret=='undefined'?self:ret;};});hasMethods=true;}}var fn=listeners[evt];if(fn){fn.call(self,arg);if(evt.substring(0,1)=="_"){delete listeners[evt];}}}});};function Player(wrapper,params,conf){var |
| 16 | +self=this,api=null,html,commonClip,playlist=[],plugins={},listeners={},playerId,apiId,activeIndex,swfHeight;extend(self,{id:function(){return playerId;},isLoaded:function(){return(api!==null);},getParent:function(){return wrapper;},hide:function(){if(api){api.style.height="0px";}return self;},show:function(){if(api){api.style.height=swfHeight+"px";}return self;},isHidden:function(){return api&&parseInt(api.style.height,10)===0;},load:function(fn){if(!api&&self._fireEvent("onBeforeLoad")!==false){each(players,function(){this.unload();});html=wrapper.innerHTML;flashembed(wrapper,params,{config:conf});if(fn){fn.cached=true;bind(listeners,"onLoad",fn);}}return self;},unload:function(){if(api&&html.replace(/\s/g,'')!==''&&!api.fp_isFullscreen()&&self._fireEvent("onBeforeUnload")!==false){api.fp_close();wrapper.innerHTML=html;self._fireEvent("onUnload");api=null;}return self;},getClip:function(index){if(index===undefined){index=activeIndex;}return playlist[index];},getCommonClip:function(){return commonClip;},getPlaylist:function(){return playlist;},getPlugin:function(name){var plugin=plugins[name];if(!plugin&&self.isLoaded()){var json=self._api().fp_getPlugin(name);if(json){plugin=new Plugin(name,json,self);plugins[name]=plugin;}}return plugin;},getScreen:function(){return self.getPlugin("screen");},getControls:function(){return self.getPlugin("controls");},getConfig:function(){return clone(conf);},getFlashParams:function(){return params;},loadPlugin:function(name,url,props,fn){if(typeof props=='function'){fn=props;props={};}var fnId=fn?makeId():"_";self._api().fp_loadPlugin(name,url,props,fnId);var arg={};arg[fnId]=fn;var p=new Plugin(name,null,self,arg);plugins[name]=p;return p;},getState:function(){return api?api.fp_getState():-1;},play:function(clip){function play(){if(clip!==undefined){self._api().fp_play(clip);}else{self._api().fp_play();}}if(api){play();}else{self.load(function(){play();});}return self;},getVersion:function(){var js="flowplayer.js 3.0.0-rc2";if(api){var ver=api.fp_getVersion();ver.push(js);return ver;}return js;},_api:function(){if(!api){throw"Flowplayer "+self.id()+" not loaded. Try moving your call to player's onLoad event";}return api;},_config:function(){return conf;}});each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),function(){var name="on"+this;if(name.indexOf("*")!=-1){name=name.substring(0,name.length-1);var name2="onBefore"+name.substring(2);self[name2]=function(fn){bind(listeners,name2,fn);return self;};}self[name]=function(fn){bind(listeners,name,fn);return self;};});each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),function(){var name=this;self[name]=function(arg){if(!api){return self;}var ret=(arg===undefined)?api["fp_"+name]():api["fp_"+name](arg);return ret=='undefined'?self:ret;};});self._fireEvent=function(evt,arg0,arg1,arg2){if(conf.debug){log(arguments);}if(evt=='onLoad'&&!api){api=api||el(apiId);swfHeight=api.clientHeight;each(playlist,function(){this._fireEvent("onLoad");});each(plugins,function(name,p){p._fireEvent("onUpdate");});commonClip._fireEvent("onLoad");}if(evt=='onContextMenu'){each(conf.contextMenu[arg0],function(key,fn){fn.call(self);});return;}if(evt=='onPluginEvent'){var name=arg0.name||arg0;var p=plugins[name];if(p){if(arg0.name){p._fireEvent("onUpdate",arg0);}p._fireEvent(arg1);}return;}if(evt=='onPlaylistReplace'){playlist=[];var index=0;each(arg0,function(){playlist.push(new Clip(this,index++));});}var ret=true;if(arg0===0||(arg0&&arg0>=0)){activeIndex=arg0;var clip=playlist[arg0];if(!clip||clip._fireEvent(evt,arg1,arg2)!==false){ret=commonClip._fireEvent(evt,arg1,arg2,clip);}}var i=0;each(listeners[evt],function(){ret=this.call(self,arg0);if(this.cached){listeners[evt].splice(i,1);}if(ret===false){return false;}i++;});return ret;};function init(){if($f(wrapper)){return null;}players.push(self);if(typeof params=='string'){params={src:params};}playerId=wrapper.id||"fp"+makeId();apiId=params.id||playerId+"_api";params.id=apiId;conf.playerId=playerId;if(typeof conf=='string'){conf={clip:{url:conf}};}conf.clip=conf.clip||{};commonClip=new Clip(conf.clip,-1,self);if(wrapper.getAttribute("href")){conf.playlist=[{url:wrapper.getAttribute("href",2)}];}conf.playlist=conf.playlist||[conf.clip];var index=0;each(conf.playlist,function(){var clip=this;if(typeof clip=='object'&&clip.length){clip=""+clip;}if(!clip.url&&typeof clip=='string'){clip={url:clip};}extend(clip,conf.clip,true);conf.playlist[index]=clip;clip=new Clip(clip,index,self);playlist.push(clip);index++;});each(conf,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete conf[key];}});each(conf.plugins,function(name,val){if(val){plugins[name]=new Plugin(name,val,self);}});if(!conf.plugins||conf.plugins.controls===undefined){plugins.controls=new Plugin("controls",null,self);}params.bgcolor=params.bgcolor||"#000000";params.version=params.version||[9,0];params.expressInstall='http://www.flowplayer.org/swf/expressinstall.swf';function doClick(e){if(self._fireEvent("onBeforeClick")!==false){self.load();}return stopEvent(e);}html=wrapper.innerHTML;if(html.replace(/\s/g,'')!==''){if(wrapper.addEventListener){wrapper.addEventListener("click",doClick,false);}else if(wrapper.attachEvent){wrapper.attachEvent("onclick",doClick);}}else{if(wrapper.addEventListener){wrapper.addEventListener("click",stopEvent,false);}self.load();}}if(typeof wrapper=='string'){flashembed.domReady(function(){var node=el(wrapper);if(!node){throw"Flowplayer cannot access element: "+wrapper;}else{wrapper=node;init();}});}else{init();}}var players=[];function Iterator(arr){this.length=arr.length;this.each=function(fn){each(arr,fn);};this.size=function(){return arr.length;};}window.flowplayer=window.$f=function(){var instance=null;var arg=arguments[0];if(!arguments.length){each(players,function(){if(this.isLoaded()){instance=this;return false;}});return instance||players[0];}if(arguments.length==1){if(typeof arg=='number'){return players[arg];}else{if(arg=='*'){return new Iterator(players);}each(players,function(){if(this.id()==arg.id||this.id()==arg||this.getParent()==arg){instance=this;return false;}});return instance;}}if(arguments.length>1){var swf=arguments[1];var conf=(arguments.length==3)?arguments[2]:{};if(typeof arg=='string'){if(arg.indexOf(".")!=-1){var instances=[];each(select(arg),function(){instances.push(new Player(this,clone(swf),clone(conf)));});return new Iterator(instances);}else{var node=el(arg);return new Player(node!==null?node:arg,swf,conf);}}else if(arg){return new Player(arg,swf,conf);}}return null;};extend(window.$f,{fireEvent:function(id,evt,a0,a1,a2){var p=$f(id);return p?p._fireEvent(evt,a0,a1,a2):null;},addPlugin:function(name,fn){Player.prototype[name]=fn;return $f;},each:each,extend:extend});if(typeof jQuery=='function'){jQuery.prototype.flowplayer=function(params,conf){if(!arguments.length||typeof arguments[0]=='number'){var arr=[];this.each(function(){var p=$f(this);if(p){arr.push(p);}});return arguments.length?arr[arguments[0]]:new Iterator(arr);}return this.each(function(){$f(this,clone(params),conf?clone(conf):{});});};}})();(function(){var jQ=typeof jQuery=='function';function isDomReady(){if(domReady.done){return false;}var d=document;if(d&&d.getElementsByTagName&&d.getElementById&&d.body){clearInterval(domReady.timer);domReady.timer=null;for(var i=0;i<domReady.ready.length;i++){domReady.ready[i].call();}domReady.ready=null;domReady.done=true;}}var domReady=jQ?jQuery:function(f){if(domReady.done){return f();}if(domReady.timer){domReady.ready.push(f);}else{domReady.ready=[f];domReady.timer=setInterval(isDomReady,13);}};function extend(to,from){if(from){for(key in from){if(from.hasOwnProperty(key)){to[key]=from[key];}}}}function concatVars(vars){var out="";for(var key in vars){if(vars[key]){out+=[key]+'='+toString(vars[key])+'&';}}return out.substring(0,out.length-1);}function toString(obj){switch(typeOf(obj)){case'string':obj=obj.replace(new RegExp('(["\\\\])','g'),'\\$1');obj=obj.replace(/^\s?(\d+)%/,"$1pct");return'"'+obj+'"';case'array':return'['+map(obj,function(el){return toString(el);}).join(',')+']';case'function':return'"function()"';case'object':var str=[];for(var prop in obj){if(obj.hasOwnProperty(prop)){str.push('"'+prop+'":'+toString(obj[prop]));}}return'{'+str.join(',')+'}';}return String(obj).replace(/\s/g," ").replace(/\'/g,"\"");}function typeOf(obj){if(obj===null||obj===undefined){return false;}var type=typeof obj;return(type=='object'&&obj.push)?'array':type;}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};});}function map(arr,func){var newArr=[];for(var i in arr){if(arr.hasOwnProperty(i)){newArr[i]=func(arr[i]);}}return newArr;}window.flashembed=function(root,userParams,flashvars){function getHTML(){var html="";if(typeof flashvars=='function'){flashvars=flashvars();}params.src+=((params.src.indexOf("?")!=-1?"&":"?")+Math.random());if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){html='<embed type="application/x-shockwave-flash" ';if(params.id){extend(params,{name:params.id});}for(var key in params){if(params[key]!==null){html+=[key]+'="'+params[key]+'"\n\t';}}if(flashvars){html+='flashvars=\''+concatVars(flashvars)+'\'';}html+='/>';}else{html='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';html+='width="'+params.width+'" height="'+params.height+'"';if(!params.id&&document.all){params.id="_"+(""+Math.random()).substring(5);}if(params.id){html+=' id="'+params.id+'"';}html+='>';html+='\n\t<param name="movie" value="'+params.src+'" />';params.id=params.src=params.width=params.height=null;for(var k in params){if(params[k]!==null){html+='\n\t<param name="'+k+'" value="'+params[k]+'" />';}}if(flashvars){html+='\n\t<param name="flashvars" value=\''+concatVars(flashvars)+'\' />';}html+="</object>";if(debug){alert(html);}}return html;}var params={src:'#',width:'100%',height:'100%',version:null,onFail:null,expressInstall:null,debug:false,allowfullscreen:true,allowscriptaccess:'always',quality:'high',type:'application/x-shockwave-flash',pluginspage:'http://www.adobe.com/go/getflashplayer'};if(typeof userParams=='string'){userParams={src:userParams};}extend(params,userParams);var version=flashembed.getVersion();var required=params.version;var express=params.expressInstall;var debug=params.debug;if(typeof root=='string'){var el=document.getElementById(root);if(el){root=el;}else{domReady(function(){flashembed(root,userParams,flashvars);});return;}}if(!root){return;}if(!required||flashembed.isSupported(required)){params.onFail=params.version=params.expressInstall=params.debug=null;root.innerHTML=getHTML();return root.firstChild;}else if(params.onFail){var ret=params.onFail.call(params,flashembed.getVersion(),flashvars);if(ret===true){root.innerHTML=ret;}}else if(required&&express&&flashembed.isSupported([6,65])){extend(params,{src:express});flashvars={MMredirectURL:location.href,MMplayerType:'PlugIn',MMdoctitle:document.title};root.innerHTML=getHTML();}else{if(root.innerHTML.replace(/\s/g,'')!==''){}else{root.innerHTML="<h2>Flash version "+required+" or greater is required</h2>"+"<h3>"+(version[0]>0?"Your version is "+version:"You have no flash plugin installed")+"</h3>"+"<p>Download latest version from <a href='"+params.pluginspage+"'>here</a></p>";}}return root;};extend(window.flashembed,{getVersion:function(){var version=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var _d=navigator.plugins["Shockwave Flash"].description;if(typeof _d!="undefined"){_d=_d.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var _m=parseInt(_d.replace(/^(.*)\..*$/,"$1"),10);var _r=/r/.test(_d)?parseInt(_d.replace(/^.*r(.*)$/,"$1"),10):0;version=[_m,_r];}}else if(window.ActiveXObject){try{var _a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");version=[6,0];_a.AllowScriptAccess="always";}catch(ee){if(version[0]==6){return;}}try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(eee){}}if(typeof _a=="object"){_d=_a.GetVariable("$version");if(typeof _d!="undefined"){_d=_d.replace(/^\S+\s+(.*)$/,"$1").split(",");version=[parseInt(_d[0],10),parseInt(_d[2],10)];}}}return version;},isSupported:function(version){var now=flashembed.getVersion();var ret=(now[0]>version[0])||(now[0]==version[0]&&now[1]>=version[1]);return ret;},domReady:domReady,toString:toString});if(jQ){jQuery.prototype.flashembed=function(params,flashvars){return this.each(function(){flashembed(this,params,flashvars);});};}})(); |
\ No newline at end of file |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.swf |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.swf |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 17 | + application/octet-stream |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_flashEmbed.js |
— | — | @@ -1,22 +1,1537 @@ |
2 | 2 | /** |
3 | | - * metavid: mv_flashEmbed builds off of: |
4 | | - * |
5 | | - * samples from: flashembed 0.25. Adobe Flash embedding script |
| 3 | + * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file) |
| 4 | + */ |
| 5 | + |
| 6 | + /** |
| 7 | + * flowplayer.js 3.0.0-rc2. The Flowplayer API. |
| 8 | + * |
| 9 | + * This file is part of Flowplayer, http://flowplayer.org |
6 | 10 | * |
7 | | - * http://flowplayer.org/player/flash-embed.html |
| 11 | + * Author: Tero Piirainen, <support@flowplayer.org> |
| 12 | + * Copyright (c) 2008 Flowplayer Ltd |
8 | 13 | * |
9 | | - * Copyright (c) 2008 Tero Piirainen (tero@flowplayer.org) |
| 14 | + * Released under the MIT License: |
| 15 | + * http://www.opensource.org/licenses/mit-license.php |
| 16 | + * |
| 17 | + * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:59 GMT-0000 (GMT+00:00) |
| 18 | + */ |
| 19 | +(function() { |
| 20 | + |
| 21 | +/* |
| 22 | + FEATURES |
| 23 | + -------- |
| 24 | + - handling multiple instances |
| 25 | + - Flowplayer programming API |
| 26 | + - Flowplayer event model |
| 27 | + - player loading / unloading |
| 28 | + - $f() function |
| 29 | + - jQuery support |
| 30 | +*/ |
| 31 | + |
| 32 | + |
| 33 | +/*jslint glovar: true, browser: true */ |
| 34 | +/*global flowplayer, $f */ |
| 35 | + |
| 36 | +// {{{ private utility methods |
| 37 | + |
| 38 | + function log(args) { |
| 39 | + |
| 40 | + // write into opera console |
| 41 | + if (typeof opera == 'object') { |
| 42 | + opera.postError("$f.fireEvent: " + args.join(" | ")); |
| 43 | + |
| 44 | + |
| 45 | + } else if (typeof console == 'object') { |
| 46 | + console.log("$f.fireEvent", [].slice.call(args)); |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + |
| 51 | + // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone |
| 52 | + function clone(obj) { |
| 53 | + if (!obj || typeof obj != 'object') { return obj; } |
| 54 | + var temp = new obj.constructor(); |
| 55 | + for (var key in obj) { |
| 56 | + if (obj.hasOwnProperty(key)) { |
| 57 | + temp[key] = clone(obj[key]); |
| 58 | + } |
| 59 | + } |
| 60 | + return temp; |
| 61 | + } |
| 62 | + |
| 63 | + // stripped from jQuery, thanks John Resig |
| 64 | + function each(obj, fn) { |
| 65 | + if (!obj) { return; } |
| 66 | + |
| 67 | + var name, i = 0, length = obj.length; |
| 68 | + |
| 69 | + // object |
| 70 | + if (length === undefined) { |
| 71 | + for (name in obj) { |
| 72 | + if (fn.call(obj[name], name, obj[name]) === false) { break; } |
| 73 | + } |
| 74 | + |
| 75 | + // array |
| 76 | + } else { |
| 77 | + for (var value = obj[0]; |
| 78 | + i < length && fn.call( value, i, value ) !== false; value = obj[++i]) { |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + return obj; |
| 83 | + } |
| 84 | + |
| 85 | + |
| 86 | + // convenience |
| 87 | + function el(id) { |
| 88 | + return document.getElementById(id); |
| 89 | + } |
| 90 | + |
| 91 | + |
| 92 | + // used extensively. a very simple implementation. |
| 93 | + function extend(to, from, skipFuncs) { |
| 94 | + if (to && from) { |
| 95 | + each(from, function(name, value) { |
| 96 | + if (!skipFuncs || typeof value != 'function') { |
| 97 | + to[name] = value; |
| 98 | + } |
| 99 | + }); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + // var arr = select("elem.className"); |
| 104 | + function select(query) { |
| 105 | + var index = query.indexOf("."); |
| 106 | + if (index != -1) { |
| 107 | + var tag = query.substring(0, index) || "*"; |
| 108 | + var klass = query.substring(index + 1, query.length); |
| 109 | + var els = []; |
| 110 | + each(document.getElementsByTagName(tag), function() { |
| 111 | + if (this.className && this.className.indexOf(klass) != -1) { |
| 112 | + els.push(this); |
| 113 | + } |
| 114 | + }); |
| 115 | + return els; |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + // fix event inconsistencies across browsers |
| 120 | + function stopEvent(e) { |
| 121 | + e = e || window.event; |
| 122 | + |
| 123 | + if (e.preventDefault) { |
| 124 | + e.stopPropagation(); |
| 125 | + e.preventDefault(); |
| 126 | + |
| 127 | + } else { |
| 128 | + e.returnValue = false; |
| 129 | + e.cancelBubble = true; |
| 130 | + } |
| 131 | + return false; |
| 132 | + } |
| 133 | + |
| 134 | + // push an event listener into existing array of listeners |
| 135 | + function bind(to, evt, fn) { |
| 136 | + to[evt] = to[evt] || []; |
| 137 | + to[evt].push(fn); |
| 138 | + } |
| 139 | + |
| 140 | + |
| 141 | + // generates an unique id |
| 142 | + function makeId() { |
| 143 | + return "_" + ("" + Math.random()).substring(2, 10); |
| 144 | + } |
| 145 | + |
| 146 | +//}}} |
| 147 | + |
| 148 | + |
| 149 | +// {{{ Clip |
| 150 | + |
| 151 | + var Clip = function(json, index, player) { |
| 152 | + |
| 153 | + // private variables |
| 154 | + var self = this; |
| 155 | + var cuepoints = {}; |
| 156 | + var listeners = {}; |
| 157 | + this.index = index; |
| 158 | + |
| 159 | + // instance variables |
| 160 | + if (typeof json == 'string') { |
| 161 | + json = {url:json}; |
| 162 | + } |
| 163 | + |
| 164 | + extend(this, json, true); |
| 165 | + |
| 166 | + // event handling |
| 167 | + each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","), |
| 168 | + function() { |
| 169 | + |
| 170 | + var evt = "on" + this; |
| 171 | + |
| 172 | + // before event |
| 173 | + if (evt.indexOf("*") != -1) { |
| 174 | + evt = evt.substring(0, evt.length -1); |
| 175 | + var before = "onBefore" + evt.substring(2); |
| 176 | + |
| 177 | + self[before] = function(fn) { |
| 178 | + bind(listeners, before, fn); |
| 179 | + return self; |
| 180 | + }; |
| 181 | + } |
| 182 | + |
| 183 | + self[evt] = function(fn) { |
| 184 | + bind(listeners, evt, fn); |
| 185 | + return self; |
| 186 | + }; |
| 187 | + |
| 188 | + |
| 189 | + // set common clip event listeners to player level |
| 190 | + if (index == -1) { |
| 191 | + if (self[before]) { |
| 192 | + player[before] = self[before]; |
| 193 | + } |
| 194 | + if (self[evt]) { |
| 195 | + player[evt] = self[evt]; |
| 196 | + } |
| 197 | + } |
| 198 | + |
| 199 | + }); |
| 200 | + |
| 201 | + extend(this, { |
| 202 | + |
| 203 | + |
| 204 | + onCuepoint: function(points, fn) { |
| 205 | + |
| 206 | + // embedded cuepoints |
| 207 | + if (arguments.length == 1) { |
| 208 | + cuepoints.embedded = [null, points]; |
| 209 | + return self; |
| 210 | + } |
| 211 | + |
| 212 | + if (typeof points == 'number') { |
| 213 | + points = [points]; |
| 214 | + } |
| 215 | + |
| 216 | + var fnId = makeId(); |
| 217 | + cuepoints[fnId] = [points, fn]; |
| 218 | + |
| 219 | + if (player.isLoaded()) { |
| 220 | + player._api().fp_addCuepoints(points, index, fnId); |
| 221 | + } |
| 222 | + |
| 223 | + return self; |
| 224 | + }, |
| 225 | + |
| 226 | + update: function(json) { |
| 227 | + extend(self, json); |
| 228 | + |
| 229 | + if (player.isLoaded()) { |
| 230 | + player._api().fp_updateClip(json, index); |
| 231 | + } |
| 232 | + var conf = player._config(); |
| 233 | + var clip = (index == -1) ? conf.clip : conf.playlist[index]; |
| 234 | + extend(clip, json, true); |
| 235 | + }, |
| 236 | + |
| 237 | + |
| 238 | + // internal event for performing clip tasks. should be made private someday |
| 239 | + _fireEvent: function(evt, arg1, arg2, target) { |
| 240 | + |
| 241 | + if (evt == 'onLoad') { |
| 242 | + each(cuepoints, function(key, val) { |
| 243 | + player._api().fp_addCuepoints(val[0], index, key); |
| 244 | + }); |
| 245 | + return false; |
| 246 | + } |
| 247 | + |
| 248 | + // target clip we are working against |
| 249 | + if (index != -1) { |
| 250 | + target = self; |
| 251 | + } |
| 252 | + |
| 253 | + if (evt == 'onCuepoint') { |
| 254 | + var fn = cuepoints[arg1]; |
| 255 | + if (fn) { |
| 256 | + return fn[1].call(player, target, arg2); |
| 257 | + } |
| 258 | + } |
| 259 | + |
| 260 | + if (evt == 'onMetaData' || evt == 'onUpdate') { |
| 261 | + |
| 262 | + extend(target, arg1); |
| 263 | + |
| 264 | + if (!target.duration) { |
| 265 | + target.duration = arg1.metaData.duration; |
| 266 | + } else { |
| 267 | + target.fullDuration = arg1.metaData.duration; |
| 268 | + } |
| 269 | + } |
| 270 | + |
| 271 | + var ret = true; |
| 272 | + each(listeners[evt], function() { |
| 273 | + ret = this.call(player, target, arg1); |
| 274 | + }); |
| 275 | + return ret; |
| 276 | + } |
| 277 | + |
| 278 | + }); |
| 279 | + |
| 280 | + |
| 281 | + // get cuepoints from config |
| 282 | + if (json.onCuepoint) { |
| 283 | + self.onCuepoint.apply(self, json.onCuepoint); |
| 284 | + delete json.onCuepoint; |
| 285 | + } |
| 286 | + |
| 287 | + // get other events |
| 288 | + each(json, function(key, val) { |
| 289 | + if (typeof val == 'function') { |
| 290 | + bind(listeners, key, val); |
| 291 | + delete json[key]; |
| 292 | + } |
| 293 | + }); |
| 294 | + |
| 295 | + |
| 296 | + // setup common clip event callbacks for Player object too (shortcuts) |
| 297 | + if (index == -1) { |
| 298 | + player.onCuepoint = this.onCuepoint; |
| 299 | + } |
| 300 | + |
| 301 | + }; |
| 302 | + |
| 303 | +//}}} |
| 304 | + |
| 305 | + |
| 306 | +// {{{ Plugin |
| 307 | + |
| 308 | + var Plugin = function(name, json, player, fn) { |
| 309 | + |
| 310 | + var listeners = {}; |
| 311 | + var self = this; |
| 312 | + var hasMethods = false; |
| 313 | + |
| 314 | + if (fn) { |
| 315 | + extend(listeners, fn); |
| 316 | + } |
| 317 | + |
| 318 | + // custom callback functions in configuration |
| 319 | + each(json, function(key, val) { |
| 320 | + if (typeof val == 'function') { |
| 321 | + listeners[key] = val; |
| 322 | + delete json[key]; |
| 323 | + } |
| 324 | + }); |
| 325 | + |
| 326 | + // core plugin methods |
| 327 | + extend(this, { |
| 328 | + |
| 329 | + animate: function(props, speed, fn) { |
| 330 | + if (!props) { |
| 331 | + return self; |
| 332 | + } |
| 333 | + |
| 334 | + if (typeof speed == 'function') { |
| 335 | + fn = speed; |
| 336 | + speed = 500; |
| 337 | + } |
| 338 | + |
| 339 | + if (typeof props == 'string') { |
| 340 | + var key = props; |
| 341 | + props = {}; |
| 342 | + props[key] = speed; |
| 343 | + speed = 500; |
| 344 | + } |
| 345 | + |
| 346 | + if (fn) { |
| 347 | + var fnId = makeId(); |
| 348 | + listeners[fnId] = fn; |
| 349 | + } |
| 350 | + |
| 351 | + if (speed === undefined) { speed = 500; } |
| 352 | + json = player._api().fp_animate(name, props, speed, fnId); |
| 353 | + return self; |
| 354 | + }, |
| 355 | + |
| 356 | + css: function(props, val) { |
| 357 | + if (val !== undefined) { |
| 358 | + var css = {}; |
| 359 | + css[props] = val; |
| 360 | + props = css; |
| 361 | + } |
| 362 | + json = player._api().fp_css(name, props); |
| 363 | + extend(self, json); |
| 364 | + return self; |
| 365 | + }, |
| 366 | + |
| 367 | + show: function() { |
| 368 | + this.display = 'block'; |
| 369 | + player._api().fp_showPlugin(name); |
| 370 | + return self; |
| 371 | + }, |
| 372 | + |
| 373 | + hide: function() { |
| 374 | + this.display = 'none'; |
| 375 | + player._api().fp_hidePlugin(name); |
| 376 | + return self; |
| 377 | + }, |
| 378 | + |
| 379 | + toggle: function() { |
| 380 | + this.display = player._api().fp_togglePlugin(name); |
| 381 | + return self; |
| 382 | + }, |
| 383 | + |
| 384 | + fadeTo: function(o, speed, fn) { |
| 385 | + |
| 386 | + if (typeof speed == 'function') { |
| 387 | + fn = speed; |
| 388 | + speed = 500; |
| 389 | + } |
| 390 | + |
| 391 | + if (fn) { |
| 392 | + var fnId = makeId(); |
| 393 | + listeners[fnId] = fn; |
| 394 | + } |
| 395 | + this.display = player._api().fp_fadeTo(name, o, speed, fnId); |
| 396 | + this.opacity = o; |
| 397 | + return self; |
| 398 | + }, |
| 399 | + |
| 400 | + fadeIn: function(speed, fn) { |
| 401 | + return self.fadeTo(1, speed, fn); |
| 402 | + }, |
| 403 | + |
| 404 | + fadeOut: function(speed, fn) { |
| 405 | + return self.fadeTo(0, speed, fn); |
| 406 | + }, |
| 407 | + |
| 408 | + getName: function() { |
| 409 | + return name; |
| 410 | + }, |
| 411 | + |
| 412 | + |
| 413 | + // internal method not meant to be used by clients |
| 414 | + _fireEvent: function(evt, arg) { |
| 415 | + |
| 416 | + |
| 417 | + // update plugins properties & methods |
| 418 | + if (evt == 'onUpdate') { |
| 419 | + var json = arg || player._api().fp_getPlugin(name); |
| 420 | + if (!json) { return; } |
| 421 | + |
| 422 | + extend(self, json); |
| 423 | + delete self.methods; |
| 424 | + |
| 425 | + if (!hasMethods) { |
| 426 | + each(json.methods, function() { |
| 427 | + var method = "" + this; |
| 428 | + |
| 429 | + self[method] = function() { |
| 430 | + var a = [].slice.call(arguments); |
| 431 | + var ret = player._api().fp_invoke(name, method, a); |
| 432 | + return ret == 'undefined' ? self : ret; |
| 433 | + }; |
| 434 | + }); |
| 435 | + hasMethods = true; |
| 436 | + } |
| 437 | + } |
| 438 | + |
| 439 | + // plugin callbacks |
| 440 | + var fn = listeners[evt]; |
| 441 | + |
| 442 | + if (fn) { |
| 443 | + |
| 444 | + fn.call(self, arg); |
| 445 | + |
| 446 | + // "one-shot" callback |
| 447 | + if (evt.substring(0, 1) == "_") { |
| 448 | + delete listeners[evt]; |
| 449 | + } |
| 450 | + } |
| 451 | + } |
| 452 | + |
| 453 | + }); |
| 454 | + |
| 455 | + }; |
| 456 | + |
| 457 | + |
| 458 | +//}}} |
| 459 | + |
| 460 | + |
| 461 | +function Player(wrapper, params, conf) { |
| 462 | + |
| 463 | + // private variables (+ arguments) |
| 464 | + var |
| 465 | + self = this, |
| 466 | + api = null, |
| 467 | + html, |
| 468 | + commonClip, |
| 469 | + playlist = [], |
| 470 | + plugins = {}, |
| 471 | + listeners = {}, |
| 472 | + playerId, |
| 473 | + apiId, |
| 474 | + activeIndex, |
| 475 | + swfHeight; |
| 476 | + |
| 477 | + |
| 478 | +// {{{ public methods |
| 479 | + |
| 480 | + extend(self, { |
| 481 | + |
| 482 | + id: function() { |
| 483 | + return playerId; |
| 484 | + }, |
| 485 | + |
| 486 | + isLoaded: function() { |
| 487 | + return (api !== null); |
| 488 | + }, |
| 489 | + |
| 490 | + getParent: function() { |
| 491 | + return wrapper; |
| 492 | + }, |
| 493 | + |
| 494 | + hide: function() { |
| 495 | + if (api) { api.style.height = "0px"; } |
| 496 | + return self; |
| 497 | + }, |
| 498 | + |
| 499 | + show: function() { |
| 500 | + if (api) { api.style.height = swfHeight + "px"; } |
| 501 | + return self; |
| 502 | + }, |
| 503 | + |
| 504 | + isHidden: function() { |
| 505 | + return api && parseInt(api.style.height, 10) === 0; |
| 506 | + }, |
| 507 | + |
| 508 | + |
| 509 | + load: function(fn) { |
| 510 | + |
| 511 | + if (!api && self._fireEvent("onBeforeLoad") !== false) { |
| 512 | + |
| 513 | + // unload all instances |
| 514 | + each(players, function() { |
| 515 | + this.unload(); |
| 516 | + }); |
| 517 | + |
| 518 | + html = wrapper.innerHTML; |
| 519 | + flashembed(wrapper, params, {config: conf}); |
| 520 | + |
| 521 | + // function argument |
| 522 | + if (fn) { |
| 523 | + fn.cached = true; |
| 524 | + bind(listeners, "onLoad", fn); |
| 525 | + } |
| 526 | + } |
| 527 | + |
| 528 | + return self; |
| 529 | + }, |
| 530 | + |
| 531 | + unload: function() { |
| 532 | + |
| 533 | + if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() && |
| 534 | + self._fireEvent("onBeforeUnload") !== false) { |
| 535 | + api.fp_close(); |
| 536 | + wrapper.innerHTML = html; |
| 537 | + self._fireEvent("onUnload"); |
| 538 | + api = null; |
| 539 | + } |
| 540 | + |
| 541 | + return self; |
| 542 | + }, |
| 543 | + |
| 544 | + getClip: function(index) { |
| 545 | + if (index === undefined) { |
| 546 | + index = activeIndex; |
| 547 | + } |
| 548 | + return playlist[index]; |
| 549 | + }, |
| 550 | + |
| 551 | + |
| 552 | + getCommonClip: function() { |
| 553 | + return commonClip; |
| 554 | + }, |
| 555 | + |
| 556 | + getPlaylist: function() { |
| 557 | + return playlist; |
| 558 | + }, |
| 559 | + |
| 560 | + getPlugin: function(name) { |
| 561 | + var plugin = plugins[name]; |
| 562 | + |
| 563 | + // create plugin if nessessary |
| 564 | + if (!plugin && self.isLoaded()) { |
| 565 | + var json = self._api().fp_getPlugin(name); |
| 566 | + if (json) { |
| 567 | + plugin = new Plugin(name, json, self); |
| 568 | + plugins[name] = plugin; |
| 569 | + } |
| 570 | + } |
| 571 | + return plugin; |
| 572 | + }, |
| 573 | + |
| 574 | + getScreen: function() { |
| 575 | + return self.getPlugin("screen"); |
| 576 | + }, |
| 577 | + |
| 578 | + getControls: function() { |
| 579 | + return self.getPlugin("controls"); |
| 580 | + }, |
| 581 | + |
| 582 | + getConfig: function() { |
| 583 | + return clone(conf); |
| 584 | + }, |
| 585 | + |
| 586 | + getFlashParams: function() { |
| 587 | + return params; |
| 588 | + }, |
| 589 | + |
| 590 | + loadPlugin: function(name, url, props, fn) { |
| 591 | + |
| 592 | + // properties not supplied |
| 593 | + if (typeof props == 'function') { |
| 594 | + fn = props; |
| 595 | + props = {}; |
| 596 | + } |
| 597 | + |
| 598 | + // if fn not given, make a fake id so that plugin's onUpdate get's fired |
| 599 | + var fnId = fn ? makeId() : "_"; |
| 600 | + self._api().fp_loadPlugin(name, url, props, fnId); |
| 601 | + |
| 602 | + // create new plugin |
| 603 | + var arg = {}; |
| 604 | + arg[fnId] = fn; |
| 605 | + var p = new Plugin(name, null, self, arg); |
| 606 | + plugins[name] = p; |
| 607 | + return p; |
| 608 | + }, |
| 609 | + |
| 610 | + |
| 611 | + getState: function() { |
| 612 | + return api ? api.fp_getState() : -1; |
| 613 | + }, |
| 614 | + |
| 615 | + // "lazy" play |
| 616 | + play: function(clip) { |
| 617 | + |
| 618 | + function play() { |
| 619 | + if (clip !== undefined) { |
| 620 | + self._api().fp_play(clip); |
| 621 | + } else { |
| 622 | + if(typeof self._api().fp_play == 'function') |
| 623 | + self._api().fp_play(); |
| 624 | + } |
| 625 | + } |
| 626 | + |
| 627 | + if (api) { |
| 628 | + play(); |
| 629 | + |
| 630 | + } else { |
| 631 | + self.load(function() { |
| 632 | + play(); |
| 633 | + }); |
| 634 | + } |
| 635 | + |
| 636 | + return self; |
| 637 | + }, |
| 638 | + |
| 639 | + getVersion: function() { |
| 640 | + var js = "flowplayer.js 3.0.0-rc2"; |
| 641 | + if (api) { |
| 642 | + var ver = api.fp_getVersion(); |
| 643 | + ver.push(js); |
| 644 | + return ver; |
| 645 | + } |
| 646 | + return js; |
| 647 | + }, |
| 648 | + |
| 649 | + _api: function() { |
| 650 | + if (!api) { |
| 651 | + throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event"; |
| 652 | + } |
| 653 | + return api; |
| 654 | + }, |
| 655 | + |
| 656 | + _config: function() { |
| 657 | + return conf; |
| 658 | + } |
| 659 | + |
| 660 | + }); |
| 661 | + |
| 662 | + |
| 663 | + // event handlers |
| 664 | + each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","), |
| 665 | + function() { |
| 666 | + var name = "on" + this; |
| 667 | + |
| 668 | + // before event |
| 669 | + if (name.indexOf("*") != -1) { |
| 670 | + name = name.substring(0, name.length -1); |
| 671 | + var name2 = "onBefore" + name.substring(2); |
| 672 | + self[name2] = function(fn) { |
| 673 | + bind(listeners, name2, fn); |
| 674 | + return self; |
| 675 | + }; |
| 676 | + } |
| 677 | + |
| 678 | + // normal event |
| 679 | + self[name] = function(fn) { |
| 680 | + bind(listeners, name, fn); |
| 681 | + return self; |
| 682 | + }; |
| 683 | + } |
| 684 | + ); |
| 685 | + |
| 686 | + |
| 687 | + // core API methods |
| 688 | + each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","), |
| 689 | + function() { |
| 690 | + var name = this; |
| 691 | + |
| 692 | + self[name] = function(arg) { |
| 693 | + if (!api) { return self; } |
| 694 | + var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg); |
| 695 | + return ret == 'undefined' ? self : ret; |
| 696 | + }; |
| 697 | + } |
| 698 | + ); |
| 699 | + |
| 700 | +//}}} |
| 701 | + |
| 702 | + |
| 703 | +// {{{ public method: _fireEvent |
| 704 | + |
| 705 | + self._fireEvent = function(evt, arg0, arg1, arg2) { |
| 706 | + |
| 707 | + if (conf.debug) { |
| 708 | + log(arguments); |
| 709 | + } |
| 710 | + |
| 711 | + // internal onLoad |
| 712 | + if (evt == 'onLoad' && !api) { |
| 713 | + |
| 714 | + api = api || el(apiId); |
| 715 | + swfHeight = api.clientHeight; |
| 716 | + |
| 717 | + each(playlist, function() { |
| 718 | + this._fireEvent("onLoad"); |
| 719 | + }); |
| 720 | + |
| 721 | + each(plugins, function(name, p) { |
| 722 | + p._fireEvent("onUpdate"); |
| 723 | + }); |
| 724 | + |
| 725 | + |
| 726 | + commonClip._fireEvent("onLoad"); |
| 727 | + } |
| 728 | + |
| 729 | + if (evt == 'onContextMenu') { |
| 730 | + each(conf.contextMenu[arg0], function(key, fn) { |
| 731 | + fn.call(self); |
| 732 | + }); |
| 733 | + return; |
| 734 | + } |
| 735 | + |
| 736 | + if (evt == 'onPluginEvent') { |
| 737 | + var name = arg0.name || arg0; |
| 738 | + var p = plugins[name]; |
| 739 | + if (p) { |
| 740 | + if (arg0.name) { |
| 741 | + p._fireEvent("onUpdate", arg0); |
| 742 | + } |
| 743 | + p._fireEvent(arg1); |
| 744 | + } |
| 745 | + return; |
| 746 | + } |
| 747 | + |
| 748 | + // onPlaylistReplace |
| 749 | + if (evt == 'onPlaylistReplace') { |
| 750 | + playlist = []; |
| 751 | + var index = 0; |
| 752 | + each(arg0, function() { |
| 753 | + playlist.push(new Clip(this, index++)); |
| 754 | + }); |
| 755 | + } |
| 756 | + |
| 757 | + var ret = true; |
| 758 | + |
| 759 | + // clip event |
| 760 | + if (arg0 === 0 || (arg0 && arg0 >= 0)) { |
| 761 | + |
| 762 | + activeIndex = arg0; |
| 763 | + var clip = playlist[arg0]; |
| 764 | + |
| 765 | + if (!clip || clip._fireEvent(evt, arg1, arg2) !== false) { |
| 766 | + |
| 767 | + // clip argument is given for common clip, because it behaves as the target |
| 768 | + ret = commonClip._fireEvent(evt, arg1, arg2, clip); |
| 769 | + } |
| 770 | + } |
| 771 | + |
| 772 | + // player event |
| 773 | + var i = 0; |
| 774 | + each(listeners[evt], function() { |
| 775 | + ret = this.call(self, arg0); |
| 776 | + |
| 777 | + // remove cached entry |
| 778 | + if (this.cached) { |
| 779 | + listeners[evt].splice(i, 1); |
| 780 | + } |
| 781 | + |
| 782 | + // break loop |
| 783 | + if (ret === false) { return false; } |
| 784 | + i++; |
| 785 | + |
| 786 | + }); |
| 787 | + |
| 788 | + return ret; |
| 789 | + }; |
| 790 | + |
| 791 | +//}}} |
| 792 | + |
| 793 | + |
| 794 | +// {{{ init |
| 795 | + |
| 796 | + function init() { |
| 797 | + |
| 798 | + if ($f(wrapper)) { |
| 799 | + return null; |
| 800 | + } |
| 801 | + |
| 802 | + // register this player into global array of instances |
| 803 | + players.push(self); |
| 804 | + |
| 805 | + |
| 806 | + // flashembed parameters |
| 807 | + if (typeof params == 'string') { |
| 808 | + params = {src: params}; |
| 809 | + } |
| 810 | + |
| 811 | + // playerId |
| 812 | + playerId = wrapper.id || "fp" + makeId(); |
| 813 | + apiId = params.id || playerId + "_api"; |
| 814 | + params.id = apiId; |
| 815 | + conf.playerId = playerId; |
| 816 | + |
| 817 | + |
| 818 | + // plain url is given as config |
| 819 | + if (typeof conf == 'string') { |
| 820 | + conf = {clip:{url:conf}}; |
| 821 | + } |
| 822 | + |
| 823 | + // common clip is always there |
| 824 | + conf.clip = conf.clip || {}; |
| 825 | + commonClip = new Clip(conf.clip, -1, self); |
| 826 | + |
| 827 | + |
| 828 | + // wrapper href as playlist |
| 829 | + if (wrapper.getAttribute("href")) { |
| 830 | + conf.playlist = [{url:wrapper.getAttribute("href", 2)}]; |
| 831 | + } |
| 832 | + |
| 833 | + // playlist |
| 834 | + conf.playlist = conf.playlist || [conf.clip]; |
| 835 | + |
| 836 | + var index = 0; |
| 837 | + each(conf.playlist, function() { |
| 838 | + |
| 839 | + var clip = this; |
| 840 | + |
| 841 | + // clip is an array, we don't allow that |
| 842 | + if (typeof clip == 'object' && clip.length) { |
| 843 | + clip = "" + clip; |
| 844 | + } |
| 845 | + |
| 846 | + if (!clip.url && typeof clip == 'string') { |
| 847 | + clip = {url: clip}; |
| 848 | + } |
| 849 | + |
| 850 | + // populate common clip properties to each clip |
| 851 | + extend(clip, conf.clip, true); |
| 852 | + |
| 853 | + // modify configuration playlist |
| 854 | + conf.playlist[index] = clip; |
| 855 | + |
| 856 | + // populate playlist array |
| 857 | + clip = new Clip(clip, index, self); |
| 858 | + playlist.push(clip); |
| 859 | + index++; |
| 860 | + }); |
| 861 | + |
| 862 | + |
| 863 | + // event listeners |
| 864 | + each(conf, function(key, val) { |
| 865 | + if (typeof val == 'function') { |
| 866 | + bind(listeners, key, val); |
| 867 | + delete conf[key]; |
| 868 | + } |
| 869 | + }); |
| 870 | + |
| 871 | + |
| 872 | + // plugins |
| 873 | + each(conf.plugins, function(name, val) { |
| 874 | + if (val) { |
| 875 | + plugins[name] = new Plugin(name, val, self); |
| 876 | + } |
| 877 | + }); |
| 878 | + |
| 879 | + |
| 880 | + // setup controlbar plugin if not explicitly defined |
| 881 | + if (!conf.plugins || conf.plugins.controls === undefined) { |
| 882 | + plugins.controls = new Plugin("controls", null, self); |
| 883 | + } |
| 884 | + |
| 885 | + // Flowplayer uses black background by default |
| 886 | + params.bgcolor = params.bgcolor || "#000000"; |
| 887 | + |
| 888 | + |
| 889 | + // setup default settings for express install |
| 890 | + params.version = params.version || [9,0]; |
| 891 | + params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf'; |
| 892 | + |
| 893 | + |
| 894 | + // click function |
| 895 | + function doClick(e) { |
| 896 | + if (self._fireEvent("onBeforeClick") !== false) { |
| 897 | + self.load(); |
| 898 | + } |
| 899 | + return stopEvent(e); |
| 900 | + } |
| 901 | + |
| 902 | + // defer loading upon click |
| 903 | + html = wrapper.innerHTML; |
| 904 | + if (html.replace(/\s/g, '') !== '') { |
| 905 | + |
| 906 | + if (wrapper.addEventListener) { |
| 907 | + wrapper.addEventListener("click", doClick, false); |
| 908 | + |
| 909 | + } else if (wrapper.attachEvent) { |
| 910 | + wrapper.attachEvent("onclick", doClick); |
| 911 | + } |
| 912 | + |
| 913 | + // player is loaded upon page load |
| 914 | + } else { |
| 915 | + |
| 916 | + // prevent default action from wrapper (safari problem) loaded |
| 917 | + if (wrapper.addEventListener) { |
| 918 | + wrapper.addEventListener("click", stopEvent, false); |
| 919 | + } |
| 920 | + |
| 921 | + // load player |
| 922 | + self.load(); |
| 923 | + } |
| 924 | + |
| 925 | + } |
| 926 | + |
| 927 | + // possibly defer initialization until DOM get's loaded |
| 928 | + if (typeof wrapper == 'string') { |
| 929 | + flashembed.domReady(function() { |
| 930 | + var node = el(wrapper); |
| 931 | + |
| 932 | + if (!node) { |
| 933 | + throw "Flowplayer cannot access element: " + wrapper; |
| 934 | + } else { |
| 935 | + wrapper = node; |
| 936 | + init(); |
| 937 | + } |
| 938 | + }); |
| 939 | + |
| 940 | + // we have a DOM element so page is already loaded |
| 941 | + } else { |
| 942 | + init(); |
| 943 | + } |
| 944 | + |
| 945 | + |
| 946 | +//}}} |
| 947 | + |
| 948 | + |
| 949 | +} |
| 950 | + |
| 951 | + |
| 952 | +// {{{ flowplayer() & statics |
| 953 | + |
| 954 | +// container for player instances |
| 955 | +var players = []; |
| 956 | + |
| 957 | + |
| 958 | +// this object is returned when multiple player's are requested |
| 959 | +function Iterator(arr) { |
| 960 | + |
| 961 | + this.length = arr.length; |
| 962 | + |
| 963 | + this.each = function(fn) { |
| 964 | + each(arr, fn); |
| 965 | + }; |
| 966 | + |
| 967 | + this.size = function() { |
| 968 | + return arr.length; |
| 969 | + }; |
| 970 | +} |
| 971 | + |
| 972 | +// these two variables are the only global variables |
| 973 | +window.flowplayer = window.$f = function() { |
| 974 | + |
| 975 | + var instance = null; |
| 976 | + var arg = arguments[0]; |
| 977 | + |
| 978 | + |
| 979 | + // $f() |
| 980 | + if (!arguments.length) { |
| 981 | + each(players, function() { |
| 982 | + if (this.isLoaded()) { |
| 983 | + instance = this; |
| 984 | + return false; |
| 985 | + } |
| 986 | + }); |
| 987 | + |
| 988 | + return instance || players[0]; |
| 989 | + } |
| 990 | + |
| 991 | + if (arguments.length == 1) { |
| 992 | + |
| 993 | + // $f(index); |
| 994 | + if (typeof arg == 'number') { |
| 995 | + return players[arg]; |
| 996 | + |
| 997 | + |
| 998 | + // $f(wrapper || 'containerId' || '*'); |
| 999 | + } else { |
| 1000 | + |
| 1001 | + // $f("*"); |
| 1002 | + if (arg == '*') { |
| 1003 | + return new Iterator(players); |
| 1004 | + } |
| 1005 | + |
| 1006 | + // $f(wrapper || 'containerId'); |
| 1007 | + each(players, function() { |
| 1008 | + if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) { |
| 1009 | + instance = this; |
| 1010 | + return false; |
| 1011 | + } |
| 1012 | + }); |
| 1013 | + |
| 1014 | + return instance; |
| 1015 | + } |
| 1016 | + } |
| 1017 | + |
| 1018 | + // instance builder |
| 1019 | + if (arguments.length > 1) { |
| 1020 | + |
| 1021 | + var swf = arguments[1]; |
| 1022 | + var conf = (arguments.length == 3) ? arguments[2] : {}; |
| 1023 | + |
| 1024 | + if (typeof arg == 'string') { |
| 1025 | + |
| 1026 | + // select arg by classname |
| 1027 | + if (arg.indexOf(".") != -1) { |
| 1028 | + var instances = []; |
| 1029 | + |
| 1030 | + each(select(arg), function() { |
| 1031 | + instances.push(new Player(this, clone(swf), clone(conf))); |
| 1032 | + }); |
| 1033 | + |
| 1034 | + return new Iterator(instances); |
| 1035 | + |
| 1036 | + // select node by id |
| 1037 | + } else { |
| 1038 | + var node = el(arg); |
| 1039 | + return new Player(node !== null ? node : arg, swf, conf); |
| 1040 | + } |
| 1041 | + |
| 1042 | + |
| 1043 | + // arg is a DOM element |
| 1044 | + } else if (arg) { |
| 1045 | + return new Player(arg, swf, conf); |
| 1046 | + } |
| 1047 | + |
| 1048 | + } |
| 1049 | + |
| 1050 | + return null; |
| 1051 | +}; |
| 1052 | + |
| 1053 | +extend(window.$f, { |
| 1054 | + |
| 1055 | + // called by Flash External Interface |
| 1056 | + fireEvent: function(id, evt, a0, a1, a2) { |
| 1057 | + var p = $f(id); |
| 1058 | + return p ? p._fireEvent(evt, a0, a1, a2) : null; |
| 1059 | + }, |
| 1060 | + |
| 1061 | + |
| 1062 | + // create plugins by modifying Player's prototype |
| 1063 | + addPlugin: function(name, fn) { |
| 1064 | + Player.prototype[name] = fn; |
| 1065 | + return $f; |
| 1066 | + }, |
| 1067 | + |
| 1068 | + // utility methods for plugin developers |
| 1069 | + each: each, |
| 1070 | + |
| 1071 | + extend: extend |
| 1072 | + |
| 1073 | +}); |
| 1074 | + |
| 1075 | +//}}} |
| 1076 | + |
| 1077 | + |
| 1078 | +//{{{ jQuery support |
| 1079 | + |
| 1080 | +if (typeof jQuery == 'function') { |
| 1081 | + |
| 1082 | + jQuery.prototype.flowplayer = function(params, conf) { |
| 1083 | + |
| 1084 | + // select instances |
| 1085 | + if (!arguments.length || typeof arguments[0] == 'number') { |
| 1086 | + var arr = []; |
| 1087 | + this.each(function() { |
| 1088 | + var p = $f(this); |
| 1089 | + if (p) { |
| 1090 | + arr.push(p); |
| 1091 | + } |
| 1092 | + }); |
| 1093 | + return arguments.length ? arr[arguments[0]] : new Iterator(arr); |
| 1094 | + } |
| 1095 | + |
| 1096 | + // create flowplayer instances |
| 1097 | + return this.each(function() { |
| 1098 | + $f(this, clone(params), conf ? clone(conf) : {}); |
| 1099 | + }); |
| 1100 | + |
| 1101 | + }; |
| 1102 | + |
| 1103 | +} |
| 1104 | + |
| 1105 | +//}}} |
| 1106 | + |
| 1107 | + |
| 1108 | +})(); |
| 1109 | +/** |
| 1110 | + * flashembed 0.33. Adobe Flash embedding script |
| 1111 | + * |
| 1112 | + * http://flowplayer.org/tools/flash-embed.html |
10 | 1113 | * |
| 1114 | + * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org) |
| 1115 | + * |
11 | 1116 | * Released under the MIT License: |
12 | 1117 | * http://www.opensource.org/licenses/mit-license.php |
| 1118 | + * |
| 1119 | + * >> Basically you can do anything you want but leave this header as is << |
13 | 1120 | * |
14 | | - * = Basically you can do anything but leave this header as is |
15 | | - * |
16 | | - */ |
| 1121 | + * first version 0.01 - 03/11/2008 |
| 1122 | + * version 0.33 - Mon Nov 03 2008 15:37:15 GMT-0000 (GMT+00:00) |
| 1123 | + */ |
| 1124 | +(function() { |
| 1125 | + |
| 1126 | +//{{{ utility functions |
| 1127 | + |
| 1128 | +var jQ = typeof jQuery == 'function'; |
| 1129 | + |
| 1130 | + |
| 1131 | +// from "Pro JavaScript techniques" by John Resig |
| 1132 | +function isDomReady() { |
| 1133 | + if (domReady.done) { return false; } |
| 1134 | + |
| 1135 | + var d = document; |
| 1136 | + if (d && d.getElementsByTagName && d.getElementById && d.body) { |
| 1137 | + clearInterval(domReady.timer); |
| 1138 | + domReady.timer = null; |
| 1139 | + |
| 1140 | + for (var i = 0; i < domReady.ready.length; i++) { |
| 1141 | + domReady.ready[i].call(); |
| 1142 | + } |
| 1143 | + |
| 1144 | + domReady.ready = null; |
| 1145 | + domReady.done = true; |
| 1146 | + } |
| 1147 | +} |
| 1148 | + |
| 1149 | +// if jQuery is present, use it's more effective domReady method |
| 1150 | +var domReady = jQ ? jQuery : function(f) { |
| 1151 | + |
| 1152 | + if (domReady.done) { |
| 1153 | + return f(); |
| 1154 | + } |
| 1155 | + |
| 1156 | + if (domReady.timer) { |
| 1157 | + domReady.ready.push(f); |
| 1158 | + |
| 1159 | + } else { |
| 1160 | + domReady.ready = [f]; |
| 1161 | + domReady.timer = setInterval(isDomReady, 13); |
| 1162 | + } |
| 1163 | +}; |
| 1164 | + |
| 1165 | + |
| 1166 | +// override extend params function |
| 1167 | +function extend(to, from) { |
| 1168 | + if (from) { |
| 1169 | + for (key in from) { |
| 1170 | + if (from.hasOwnProperty(key)) { |
| 1171 | + to[key] = from[key]; |
| 1172 | + } |
| 1173 | + } |
| 1174 | + } |
| 1175 | +} |
| 1176 | + |
| 1177 | + |
| 1178 | +function concatVars(vars) { |
| 1179 | + var out = ""; |
| 1180 | + |
| 1181 | + for (var key in vars) { |
| 1182 | + if (vars[key]) { |
| 1183 | + out += [key] + '=' + toString(vars[key]) + '&'; |
| 1184 | + } |
| 1185 | + } |
| 1186 | + return out.substring(0, out.length -1); |
| 1187 | +} |
| 1188 | + |
| 1189 | + |
| 1190 | + |
| 1191 | +// JSON.toString() function |
| 1192 | +function toString(obj) { |
| 1193 | + |
| 1194 | + switch (typeOf(obj)){ |
| 1195 | + case 'string': |
| 1196 | + obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1'); |
| 1197 | + |
| 1198 | + // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit) |
| 1199 | + obj = obj.replace(/^\s?(\d+)%/, "$1pct"); |
| 1200 | + return '"' +obj+ '"'; |
| 1201 | + |
| 1202 | + case 'array': |
| 1203 | + return '['+ map(obj, function(el) { |
| 1204 | + return toString(el); |
| 1205 | + }).join(',') +']'; |
| 1206 | + |
| 1207 | + case 'function': |
| 1208 | + return '"function()"'; |
| 1209 | + |
| 1210 | + case 'object': |
| 1211 | + var str = []; |
| 1212 | + for (var prop in obj) { |
| 1213 | + if (obj.hasOwnProperty(prop)) { |
| 1214 | + str.push('"'+prop+'":'+ toString(obj[prop])); |
| 1215 | + } |
| 1216 | + } |
| 1217 | + return '{'+str.join(',')+'}'; |
| 1218 | + } |
| 1219 | + |
| 1220 | + // replace ' --> " and remove spaces |
| 1221 | + return String(obj).replace(/\s/g, " ").replace(/\'/g, "\""); |
| 1222 | +} |
| 1223 | + |
| 1224 | + |
| 1225 | +// private functions |
| 1226 | +function typeOf(obj) { |
| 1227 | + if (obj === null || obj === undefined) { return false; } |
| 1228 | + var type = typeof obj; |
| 1229 | + return (type == 'object' && obj.push) ? 'array' : type; |
| 1230 | +} |
| 1231 | + |
| 1232 | + |
| 1233 | +// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/) |
| 1234 | +if (window.attachEvent) { |
| 1235 | + window.attachEvent("onbeforeunload", function() { |
| 1236 | + __flash_unloadHandler = function() {}; |
| 1237 | + __flash_savedUnloadHandler = function() {}; |
| 1238 | + }); |
| 1239 | +} |
| 1240 | + |
| 1241 | +function map(arr, func) { |
| 1242 | + var newArr = []; |
| 1243 | + for (var i in arr) { |
| 1244 | + if (arr.hasOwnProperty(i)) { |
| 1245 | + newArr[i] = func(arr[i]); |
| 1246 | + } |
| 1247 | + } |
| 1248 | + return newArr; |
| 1249 | +} |
| 1250 | + |
| 1251 | +//}}} |
| 1252 | + |
| 1253 | + |
| 1254 | +window.flashembed = function(root, userParams, flashvars) { |
| 1255 | + |
| 1256 | + |
| 1257 | +//{{{ getHTML |
| 1258 | + |
| 1259 | + function getHTML() { |
| 1260 | + |
| 1261 | + var html = ""; |
| 1262 | + if (typeof flashvars == 'function') { flashvars = flashvars(); } |
| 1263 | + |
| 1264 | + |
| 1265 | + // sometimes ie fails to load flash if it's on cache |
| 1266 | + params.src += ((params.src.indexOf("?") != -1 ? "&" : "?") + Math.random()); |
| 1267 | + |
| 1268 | + |
| 1269 | + // mozilla |
| 1270 | + if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { |
| 1271 | + |
| 1272 | + html = '<embed type="application/x-shockwave-flash" '; |
| 1273 | + |
| 1274 | + if (params.id) { |
| 1275 | + extend(params, {name:params.id}); |
| 1276 | + } |
| 1277 | + |
| 1278 | + for (var key in params) { |
| 1279 | + if (params[key] !== null) { |
| 1280 | + html += [key] + '="' +params[key]+ '"\n\t'; |
| 1281 | + } |
| 1282 | + } |
| 1283 | + |
| 1284 | + if (flashvars) { |
| 1285 | + html += 'flashvars=\'' + concatVars(flashvars) + '\''; |
| 1286 | + } |
| 1287 | + |
| 1288 | + // thanks Tom Price (07/17/2008) |
| 1289 | + html += '/>'; |
| 1290 | + |
| 1291 | + // ie |
| 1292 | + } else { |
| 1293 | + |
| 1294 | + html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '; |
| 1295 | + html += 'width="' + params.width + '" height="' + params.height + '"'; |
| 1296 | + |
| 1297 | + // force id for IE. otherwise embedded Flash object cannot be returned |
| 1298 | + if (!params.id && document.all) { |
| 1299 | + params.id = "_" + ("" + Math.random()).substring(5); |
| 1300 | + } |
| 1301 | + |
| 1302 | + if (params.id) { |
| 1303 | + html += ' id="' + params.id + '"'; |
| 1304 | + } |
| 1305 | + |
| 1306 | + html += '>'; |
| 1307 | + html += '\n\t<param name="movie" value="'+ params.src +'" />'; |
| 1308 | + |
| 1309 | + params.id = params.src = params.width = params.height = null; |
| 1310 | + |
| 1311 | + for (var k in params) { |
| 1312 | + if (params[k] !== null) { |
| 1313 | + html += '\n\t<param name="'+ k +'" value="'+ params[k] +'" />'; |
| 1314 | + } |
| 1315 | + } |
| 1316 | + |
| 1317 | + if (flashvars) { |
| 1318 | + html += '\n\t<param name="flashvars" value=\'' + concatVars(flashvars) + '\' />'; |
| 1319 | + } |
| 1320 | + |
| 1321 | + html += "</object>"; |
| 1322 | + if (debug) { |
| 1323 | + alert(html); |
| 1324 | + } |
| 1325 | + |
| 1326 | + } |
| 1327 | + |
| 1328 | + return html; |
| 1329 | + } |
| 1330 | + |
| 1331 | + //}}} |
| 1332 | + |
| 1333 | + |
| 1334 | +//{{{ construction |
| 1335 | + |
| 1336 | + // setup params |
| 1337 | + var params = { |
| 1338 | + |
| 1339 | + // very common params |
| 1340 | + src: '#', |
| 1341 | + width: '100%', |
| 1342 | + height: '100%', |
| 1343 | + |
| 1344 | + // flashembed specific options |
| 1345 | + version:null, |
| 1346 | + onFail:null, |
| 1347 | + expressInstall:null, |
| 1348 | + debug: false, |
| 1349 | + |
| 1350 | + // flashembed defaults |
| 1351 | + // bgcolor: 'transparent', |
| 1352 | + allowfullscreen: true, |
| 1353 | + allowscriptaccess: 'always', |
| 1354 | + quality: 'high', |
| 1355 | + type: 'application/x-shockwave-flash', |
| 1356 | + pluginspage: 'http://www.adobe.com/go/getflashplayer' |
| 1357 | + }; |
| 1358 | + |
| 1359 | + |
| 1360 | + if (typeof userParams == 'string') { |
| 1361 | + userParams = {src: userParams}; |
| 1362 | + } |
| 1363 | + |
| 1364 | + extend(params, userParams); |
| 1365 | + |
| 1366 | + var version = flashembed.getVersion(); |
| 1367 | + var required = params.version; |
| 1368 | + var express = params.expressInstall; |
| 1369 | + var debug = params.debug; |
| 1370 | + |
| 1371 | + |
| 1372 | + if (typeof root == 'string') { |
| 1373 | + var el = document.getElementById(root); |
| 1374 | + if (el) { |
| 1375 | + root = el; |
| 1376 | + } else { |
| 1377 | + domReady(function() { |
| 1378 | + flashembed(root, userParams, flashvars); |
| 1379 | + }); |
| 1380 | + return; |
| 1381 | + } |
| 1382 | + } |
| 1383 | + |
| 1384 | + if (!root) { return; } |
| 1385 | + |
| 1386 | + |
| 1387 | + // is supported |
| 1388 | + if (!required || flashembed.isSupported(required)) { |
| 1389 | + params.onFail = params.version = params.expressInstall = params.debug = null; |
| 1390 | + |
| 1391 | + // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99 |
| 1392 | + // thanks to: Ryan Rud |
| 1393 | + // var tmp = document.createElement("extradiv"); |
| 1394 | + // tmp.innerHTML = getHTML(); |
| 1395 | + // root.appendChild(tmp); |
| 1396 | + |
| 1397 | + root.innerHTML = getHTML(); |
| 1398 | + |
| 1399 | + // return our API |
| 1400 | + return root.firstChild; |
| 1401 | + |
| 1402 | + // custom fail event |
| 1403 | + } else if (params.onFail) { |
| 1404 | + var ret = params.onFail.call(params, flashembed.getVersion(), flashvars); |
| 1405 | + if (ret === true) { root.innerHTML = ret; } |
| 1406 | + |
| 1407 | + |
| 1408 | + // express install |
| 1409 | + } else if (required && express && flashembed.isSupported([6,65])) { |
| 1410 | + |
| 1411 | + extend(params, {src: express}); |
| 1412 | + |
| 1413 | + flashvars = { |
| 1414 | + MMredirectURL: location.href, |
| 1415 | + MMplayerType: 'PlugIn', |
| 1416 | + MMdoctitle: document.title |
| 1417 | + }; |
| 1418 | + |
| 1419 | + root.innerHTML = getHTML(); |
| 1420 | + |
| 1421 | + // not supported |
| 1422 | + } else { |
| 1423 | + |
| 1424 | + // minor bug fixed here 08.04.2008 (thanks JRodman) |
| 1425 | + |
| 1426 | + if (root.innerHTML.replace(/\s/g, '') !== '') { |
| 1427 | + // custom content was supplied |
| 1428 | + |
| 1429 | + } else { |
| 1430 | + root.innerHTML = |
| 1431 | + "<h2>Flash version " + required + " or greater is required</h2>" + |
| 1432 | + "<h3>" + |
| 1433 | + (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") + |
| 1434 | + "</h3>" + |
| 1435 | + "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>"; |
| 1436 | + } |
| 1437 | + } |
| 1438 | + |
| 1439 | + return root; |
| 1440 | + |
| 1441 | +//}}} |
| 1442 | + |
| 1443 | + |
| 1444 | +}; |
| 1445 | + |
| 1446 | + |
| 1447 | +//{{{ static methods |
| 1448 | + |
| 1449 | +extend(window.flashembed, { |
| 1450 | + |
| 1451 | + // arr[major, minor, fix] |
| 1452 | + getVersion: function() { |
| 1453 | + |
| 1454 | + var version = [0, 0]; |
| 1455 | + |
| 1456 | + if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") { |
| 1457 | + var _d = navigator.plugins["Shockwave Flash"].description; |
| 1458 | + if (typeof _d != "undefined") { |
| 1459 | + _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); |
| 1460 | + var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10); |
| 1461 | + var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0; |
| 1462 | + version = [_m, _r]; |
| 1463 | + } |
| 1464 | + |
| 1465 | + } else if (window.ActiveXObject) { |
| 1466 | + |
| 1467 | + try { // avoid fp 6 crashes |
| 1468 | + var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); |
| 1469 | + |
| 1470 | + } catch(e) { |
| 1471 | + try { |
| 1472 | + _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); |
| 1473 | + version = [6, 0]; |
| 1474 | + _a.AllowScriptAccess = "always"; // throws if fp < 6.47 |
| 1475 | + |
| 1476 | + } catch(ee) { |
| 1477 | + if (version[0] == 6) { return; } |
| 1478 | + } |
| 1479 | + try { |
| 1480 | + _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); |
| 1481 | + } catch(eee) { |
| 1482 | + |
| 1483 | + } |
| 1484 | + |
| 1485 | + } |
| 1486 | + |
| 1487 | + if (typeof _a == "object") { |
| 1488 | + _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23 |
| 1489 | + if (typeof _d != "undefined") { |
| 1490 | + _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(","); |
| 1491 | + version = [parseInt(_d[0], 10), parseInt(_d[2], 10)]; |
| 1492 | + } |
| 1493 | + } |
| 1494 | + } |
| 1495 | + |
| 1496 | + return version; |
| 1497 | + }, |
| 1498 | + |
| 1499 | + isSupported: function(version) { |
| 1500 | + var now = flashembed.getVersion(); |
| 1501 | + var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]); |
| 1502 | + return ret; |
| 1503 | + }, |
| 1504 | + |
| 1505 | + domReady: domReady, |
| 1506 | + |
| 1507 | + // returns a String representation from JSON object |
| 1508 | + toString: toString |
| 1509 | + |
| 1510 | +}); |
| 1511 | + |
| 1512 | +//}}} |
| 1513 | + |
| 1514 | + |
| 1515 | +// setup jquery support |
| 1516 | +if (jQ) { |
| 1517 | + |
| 1518 | + jQuery.prototype.flashembed = function(params, flashvars) { |
| 1519 | + return this.each(function() { |
| 1520 | + flashembed(this, params, flashvars); |
| 1521 | + }); |
| 1522 | + }; |
| 1523 | + |
| 1524 | +} |
| 1525 | + |
| 1526 | +})(); |
| 1527 | + |
| 1528 | +/************************************************ |
| 1529 | +********* mv_embed extension to flowplayer.js *** |
| 1530 | +************************************************/ |
17 | 1531 | var flashEmbed = { |
18 | 1532 | instanceOf:'flashEmbed', |
19 | 1533 | monitorTimerId : 0, |
20 | | - startedTimedPlayback:false, |
| 1534 | + old_pid:0, |
| 1535 | + startedTimedPlayback:false, |
21 | 1536 | supports: { |
22 | 1537 | 'play_head':true, |
23 | 1538 | 'play_or_pause':true, |
— | — | @@ -24,125 +1539,69 @@ |
25 | 1540 | //'fullscreen':true, |
26 | 1541 | 'time_display':true, |
27 | 1542 | //'volume_control':true, |
28 | | - 'overlay':false |
29 | | - }, |
30 | | - flashParams : { |
31 | | - // very common params |
32 | | - src: '#', |
33 | | - width: 400, |
34 | | - height:300, |
35 | | - |
36 | | - // flashembed defaults |
37 | | - allowfullscreen: true, |
38 | | - allowscriptaccess: 'always', |
39 | | - quality: 'high', |
40 | | - bgcolor: '#ffffff', |
41 | | - type: 'application/x-shockwave-flash', |
42 | | - pluginspage: 'http://www.adobe.com/go/getflashplayer' |
43 | | - }, |
44 | | - flashVars :{ |
45 | | - config: { autoPlay: true, |
46 | | - hideControls: true, |
47 | | - initialScale:'fit', |
48 | | - bufferLength:60, |
49 | | - startingBufferLength:5, |
50 | | - loop:false |
51 | | - } |
52 | | - }, |
| 1543 | + 'overlay':false, |
| 1544 | + 'fullscreen':false |
| 1545 | + }, |
53 | 1546 | getEmbedHTML: function (){ |
54 | 1547 | setTimeout('document.getElementById(\''+this.id+'\').postEmbedJS()', 150); |
55 | 1548 | return this.wrapEmebedContainer( this.getEmbedObj() ); |
56 | 1549 | }, |
57 | 1550 | getEmbedObj:function(){ |
58 | | - if(!this.duration)this.duration=30; |
59 | | - var html = ""; |
60 | | - //set up custom params/config |
61 | | - /* |
62 | | - <embed id="player_api" height="100%" width="100%" |
63 | | - flashvars="config={"playerId":"player","clip":{}, |
64 | | - "playlist":[{"url":"http://www.archive.org/download/mv_senate_proceeding_10-23-08/senate_proceeding_10-23-08_512kb.mp4?start=10"}]}" |
65 | | - name="player_api" bgcolor="#000000" pluginspage="http://www.adobe.com/go/getflashplayer" |
66 | | - type="application/x-shockwave-flash" quality="high" allowscriptaccess="always" |
67 | | - allowfullscreen="true" src="../flowplayer-3.0.0-rc2.swf?0.5720695237577815"/> |
68 | | - */ |
69 | | - this.flashParams.src = mv_embed_path + 'flowplayer-3.0.0-rc2.swf'; |
70 | | - this.flashParams.width = this.width; |
71 | | - this.flashParams.height = this.height; |
72 | | - this.flashParams.id = this.pid; |
73 | | - |
74 | | - //set the id: |
75 | | - this.flashVars.config.playerId = this.pid; |
76 | | - |
77 | | - js_log('set flash videoFile: '+ this.media_element.selected_source.getURI(this.seek_time_sec) ); |
78 | | - this.flashVars.config.playlist = new Array({"url":this.media_element.selected_source.getURI(this.seek_time_sec)}); |
79 | | - |
80 | | - if(this.muted) |
81 | | - this.flashVars.config.initialVolumePercentage=0; |
82 | | - |
83 | | - // mozilla |
84 | | - if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { |
85 | | - html = '<embed ' + |
86 | | - 'id="'+this.pid+'" '; |
87 | | - for(var key in this.flashParams) { |
88 | | - if (this.flashParams[key] != null) |
89 | | - html += [key] + '="' +this.flashParams[key]+ '"\n\t'; |
90 | | - } |
91 | | - if (this.flashVars) { |
92 | | - html += 'flashvars=\''; |
93 | | - var and = ''; |
94 | | - for(var key in this.flashVars) { |
95 | | - html +=and+ [key] + '=' + asString(this.flashVars[key]); |
96 | | - and = '&'; |
97 | | - } |
98 | | - html += '\''; |
99 | | - } |
100 | | - html += '/>'; |
101 | | - // ie |
102 | | - } else { |
103 | | - html = '<object id="'+this.pid+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '; |
104 | | - html += 'width="' + this.flashParams.width + '" height="' + this.flashParams.height + '"'; |
105 | | - if ( this.flashParams.id) html += ' id="' + this.pid + '"'; |
106 | | - html += '>'; |
107 | | - html += '\n\t<param name="movie" value="'+ this.flashParams.src +'" />'; |
108 | | - this.flashParams.id = this.flashParams.src = this.flashParams.width = this.flashParams.height = null; |
109 | | - for (var key in this.flashParams) { |
110 | | - if (this.flashParams[key] != null) |
111 | | - html += '\n\t<param name="'+ key +'" value="'+ this.flashParams[key] +'" />'; |
112 | | - } |
113 | | - if (this.flashVars) { |
114 | | - html += '\n\t<param name="flashvars" value=\''; |
115 | | - var and = ''; |
116 | | - for(var key in this.flashVars) { |
117 | | - html += and + [key] + '=' + asString(this.flashVars[key]) ; |
118 | | - and = '&'; |
119 | | - } |
120 | | - html += '\' />'; |
121 | | - } |
122 | | - html += "</object>"; |
123 | | - } |
124 | | - js_log('embed code:'+ html); |
125 | | - return html; |
| 1551 | + /*return '<a href="' + this.media_element.selected_source.getURI(this.seek_time_sec) +'" '+ |
| 1552 | + 'style="display:block;width:' + this.width + 'px;height:' + this.height + 'px" '+ |
| 1553 | + 'id="' + this.pid + '"> rewrite me'+ |
| 1554 | + '</a>';*/ |
| 1555 | + //give the embed element a unique pid (work around for flowplayer persistence) |
| 1556 | + if( this.old_pid!=0 ){ |
| 1557 | + this.pid = this.pid +'_'+ this.old_pid; |
| 1558 | + } |
| 1559 | + return '<a '+ |
| 1560 | + 'href="'+this.media_element.selected_source.getURI(this.seek_time_sec)+'" '+ |
| 1561 | + 'style="display:block;width:400px;height:300px" '+ |
| 1562 | + 'id="'+this.pid+'">'+ |
| 1563 | + '</a>'; |
126 | 1564 | }, |
127 | 1565 | postEmbedJS: function() |
128 | 1566 | { |
129 | | - this.getFLA(); |
130 | | - if(this.fla){ |
131 | | - setTimeout('$j(\'#'+this.id+'\').get(0).monitor()', 250); |
132 | | - }else{ |
133 | | - js_log('flash not ready'); |
134 | | - setTimeout('$j(\'#'+this.id+'\').get(0).postEmbedJS()',250); |
135 | | - } |
136 | | - }, |
| 1567 | + var _this = this; |
| 1568 | + //js_log('postEmbedJS: ' + mv_embed_path + 'flowplayer/flowplayer-3.0.0-rc2.swf' ) ; |
| 1569 | + $f(this.pid, "/flowplayer/flowplayer-3.0.0-rc2.swf", { |
| 1570 | + clip: { |
| 1571 | + url: _this.media_element.selected_source.getURI(this.seek_time_sec), |
| 1572 | + |
| 1573 | + // when this is false playback does not start until play button is pressed |
| 1574 | + autoPlay: true |
| 1575 | + }, |
| 1576 | + plugins: { |
| 1577 | + controls: null |
| 1578 | + } |
| 1579 | + }); |
| 1580 | + //get the this.fla value: |
| 1581 | + this.getFLA(); |
| 1582 | + //set up bindings (for when interacting with the swf causes action: |
| 1583 | + this.fla.onPause(function(){ |
| 1584 | + js_log('flash:onPause'); |
| 1585 | + if(!_this.paused){ |
| 1586 | + _this.pause(); |
| 1587 | + } |
| 1588 | + }) |
| 1589 | + this.fla.onResume(function(){ |
| 1590 | + js_log('flash;onResume'); |
| 1591 | + if(_this.paused){ |
| 1592 | + _this.play(); |
| 1593 | + } |
| 1594 | + }); |
| 1595 | + //start monitor: |
| 1596 | + this.monitor(); |
| 1597 | + this.old_pid++; |
| 1598 | + }, |
137 | 1599 | /* js hooks/controls */ |
138 | 1600 | play: function(){ |
139 | | - this.getFLA(); |
140 | | - if(!this.fla || this.thumbnail_disp) |
141 | | - { |
142 | | - //call the parent |
143 | | - this.parent_play(); |
144 | | - }else{ |
145 | | - this.fla.DoPlay(); |
146 | | - this.paused=false; |
| 1601 | + this.getFLA(); |
| 1602 | + //update play/pause button etc |
| 1603 | + this.parent_play(); |
| 1604 | + if( this.fla ){ |
| 1605 | + this.fla.play(); |
147 | 1606 | setTimeout('$j(\'#'+this.id+'\').get(0).monitor()', 250); |
148 | 1607 | } |
149 | 1608 | }, |
— | — | @@ -157,11 +1616,19 @@ |
158 | 1617 | } |
159 | 1618 | } |
160 | 1619 | }, |
| 1620 | + fullscreen:function(){ |
| 1621 | + if(this.fla){ |
| 1622 | + this.fla.fullscreen(); |
| 1623 | + }else{ |
| 1624 | + js_log('must be playing before you can go fullscreen'); |
| 1625 | + } |
| 1626 | + }, |
161 | 1627 | pause : function() |
162 | 1628 | { |
163 | 1629 | this.getFLA(); |
164 | | - if(this.fla['Pause']) |
165 | | - this.fla.Pause(); |
| 1630 | + this.parent_pause(); |
| 1631 | + if(this.fla['pause']) |
| 1632 | + this.fla.pause(); |
166 | 1633 | //stop updates: |
167 | 1634 | if( this.monitorTimerId != 0 ) |
168 | 1635 | { |
— | — | @@ -178,14 +1645,26 @@ |
179 | 1646 | } |
180 | 1647 | } |
181 | 1648 | this.getFLA(); |
182 | | - if(!this.fla['getTime']) |
183 | | - return js_log('can not monitor without time'); |
184 | | - |
| 1649 | + |
185 | 1650 | var flash_state = this.fla.getStatus(); |
186 | | - js_log('flash state: '+flash_state); |
187 | | - |
188 | | - this.currentTime = this.fla.getTime(); |
189 | 1651 | |
| 1652 | + //simplification of buffer state ... should move to support returning time rages like: |
| 1653 | + //http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object |
| 1654 | + this.bufferedPercent = flash_state.bufferEnd / this.getDuration(); |
| 1655 | + |
| 1656 | + //set the current Time (based on timeFormat) |
| 1657 | + if( this.media_element.selected_source.timeFormat =='anx' ){ |
| 1658 | + this.currentTime = flash_state.time; |
| 1659 | + //js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration()); |
| 1660 | + }else{ |
| 1661 | + this.currentTime = flash_state.time + this.media_element.selected_source.start_offset; |
| 1662 | + //stop buffering if greater than the duration: |
| 1663 | + if( flash_state.bufferEnd > this.getDuration() + 5 ){ |
| 1664 | + js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() ); |
| 1665 | + this.fla.stopBuffering(); |
| 1666 | + } |
| 1667 | + } |
| 1668 | + |
190 | 1669 | var end_ntp = (this.media_element.selected_source.end_ntp)? |
191 | 1670 | this.media_element.selected_source.end_ntp : seconds2ntp(0); |
192 | 1671 | var start_ntp = this.media_element.selected_source.start_ntp; |
— | — | @@ -198,7 +1677,7 @@ |
199 | 1678 | if(this.currentTime > 1 && this.seek_time_sec != 0 && !this.media_element.selected_source.supports_url_time_encoding) |
200 | 1679 | { |
201 | 1680 | js_log('flashEmbed: _local_ Seeking to ' + this.seek_time_sec); |
202 | | - this.fla.Seek(this.seek_time_sec); |
| 1681 | + this.fla.seek( this.seek_time_sec ); |
203 | 1682 | this.seek_time_sec = 0; |
204 | 1683 | } |
205 | 1684 | |
— | — | @@ -214,28 +1693,34 @@ |
215 | 1694 | this.setSliderValue((this.currentTime - ntp2seconds(start_ntp)) / (ntp2seconds(end_ntp)-ntp2seconds(start_ntp)) ); |
216 | 1695 | } |
217 | 1696 | } |
218 | | - |
219 | | - //super hackery to see if we have "probably" reached the end of playback: |
220 | | - if(this.startedTimedPlayback && this.prevTime==this.currentTime && (this.currentTime > (ntp2seconds(end_ntp)-1)) ){ |
221 | | - js_log('probablly reached end of stream: '+this.currentTime); |
| 1697 | + |
| 1698 | + //checks to see if we reached the end of playback: |
| 1699 | + if(this.startedTimedPlayback && |
| 1700 | + ( this.currentTime > (ntp2seconds(end_ntp)+1) |
| 1701 | + || |
| 1702 | + ( this.currentTime > (ntp2seconds(end_ntp)-1) |
| 1703 | + && this.prevTime == this.currentTime) ) |
| 1704 | + ){ |
| 1705 | + js_log('probbaly reached end of stream: '+this.currentTime); |
222 | 1706 | this.onClipDone(); |
223 | | - } |
224 | | - this.prevTime = this.currentTime; |
225 | | - |
| 1707 | + } |
| 1708 | + this.prevTime = this.currentTime; |
226 | 1709 | //js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - ntp2seconds(start_ntp)) +' / ' +(ntp2seconds(end_ntp)-ntp2seconds(start_ntp))); |
227 | 1710 | }, |
228 | 1711 | // get the embed fla object |
229 | 1712 | getFLA : function (){ |
230 | | - this.fla = this.getPluginEmbed(); |
| 1713 | + this.fla = $f(this.pid); |
231 | 1714 | }, |
232 | 1715 | stop : function(){ |
233 | | - js_log('f:flashEmbed:stop'); |
| 1716 | + js_log('f:flashEmbed:stop'); |
234 | 1717 | this.startedTimedPlayback=false; |
235 | 1718 | if (this.monitorTimerId != 0 ) |
236 | 1719 | { |
237 | 1720 | clearInterval(this.monitorTimerId); |
238 | 1721 | this.monitorTimerId = 0; |
239 | 1722 | } |
| 1723 | + if(this.fla) |
| 1724 | + this.fla.unload(); |
240 | 1725 | this.parent_stop(); |
241 | 1726 | }, |
242 | 1727 | onStop: function(){ |
— | — | @@ -256,7 +1741,7 @@ |
257 | 1742 | this.monitor(); |
258 | 1743 | }else{ |
259 | 1744 | js_log('clip done and '+ this.startedTimedPlayback); |
260 | | - //stop the clip if its not stoped already: |
| 1745 | + //stop the clip if its not stopped already: |
261 | 1746 | this.stop(); |
262 | 1747 | this.setStatus("Clip Done..."); |
263 | 1748 | //run the onClip done action: |
— | — | @@ -264,108 +1749,3 @@ |
265 | 1750 | } |
266 | 1751 | } |
267 | 1752 | } |
268 | | -function asString(obj) { |
269 | | - switch (typeOf(obj)){ |
270 | | - case 'string': |
271 | | - return '"'+obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1')+'"'; |
272 | | - case 'array': |
273 | | - return '['+ map(obj, function(el) { |
274 | | - return asString(el); |
275 | | - }).join(',') +']'; |
276 | | - case 'object': |
277 | | - var str = []; |
278 | | - for (var property in obj) { |
279 | | - str.push('"'+property+'":'+ asString(obj[property])); |
280 | | - } |
281 | | - return '{'+str.join(',')+'}'; |
282 | | - } |
283 | | - // replace ' --> " and remove spaces |
284 | | - return String(obj) |
285 | | - .replace(/\s/g, " ") |
286 | | - .replace(/\'/g, "\""); //' |
287 | | -} |
288 | | -function map(arr,func){ |
289 | | - var newArr=[]; |
290 | | - for(var i in arr){ |
291 | | - if(arr.hasOwnProperty(i)){ |
292 | | - newArr[i]=func(arr[i]); |
293 | | - } |
294 | | - } |
295 | | - return newArr; |
296 | | -} |
297 | | - |
298 | | -// private functions |
299 | | -function typeOf(obj){ |
300 | | - if (obj === null || obj === undefined) return false; |
301 | | - var type = typeof obj; |
302 | | - return (type == 'object' && obj.push) ? 'array' : type; |
303 | | -} |
304 | | - |
305 | | -function locateFlashEmbed(clip) |
306 | | -{ |
307 | | - for(var i in global_player_list) |
308 | | - { |
309 | | - var embed = document.getElementById(global_player_list[i]); |
310 | | - if(embed.media_element.selected_source.src.match(clip.fileName)) |
311 | | - { |
312 | | - //js_log('found flash embed'); |
313 | | - return embed; |
314 | | - } |
315 | | - } |
316 | | -} |
317 | | - |
318 | | -/* flowplayer callbacks */ |
319 | | -function onFlowPlayerReady() |
320 | | -{ |
321 | | - js_log('f:flash_CB:onFlowPlayerReady'); |
322 | | -} |
323 | | - |
324 | | -function onClipDone(clip) |
325 | | -{ |
326 | | - js_log('f:flash_CB:onClipDone'); |
327 | | - var embed = locateFlashEmbed(clip); |
328 | | - embed.onClipDone(); |
329 | | -} |
330 | | - |
331 | | -function onLoadBegin(clip) |
332 | | -{ |
333 | | - var embed = locateFlashEmbed(clip); |
334 | | - js_log('f:flash_CB:onLoadBegin'); |
335 | | - embed.setStatus("Loading Begun..."); |
336 | | -} |
337 | | - |
338 | | -function onPlay(clip) |
339 | | -{ |
340 | | - var embed = locateFlashEmbed(clip); |
341 | | - js_log('f:flash_CB:onPlay'); |
342 | | - embed.setStatus("Playing..."); |
343 | | -} |
344 | | - |
345 | | -function onStop(clip) |
346 | | -{ |
347 | | - var embed = locateFlashEmbed(clip); |
348 | | - js_log('f:flash_CB:onStop'); |
349 | | - embed.setStatus("Stopped..."); |
350 | | -} |
351 | | - |
352 | | -function onPause(clip) |
353 | | -{ |
354 | | -// var embed = locateFlashEmbed(clip); |
355 | | - js_log('f:flash_CB:onPause'); |
356 | | -// embed.pause(); |
357 | | - embed.setStatus("Paused..."); |
358 | | -} |
359 | | - |
360 | | -function onResume(clip) |
361 | | -{ |
362 | | - var embed = locateFlashEmbed(clip); |
363 | | - js_log('f:flash_CB:onResume'); |
364 | | - embed.setStatus("Resumed..."); |
365 | | -} |
366 | | - |
367 | | -function onStartBuffering(clip) |
368 | | -{ |
369 | | - var embed = locateFlashEmbed(clip); |
370 | | - js_log('f:flash_CB:onStartBuffering'); |
371 | | - embed.setStatus("Buffering Started..."); |
372 | | -} |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_vlcEmbed.js |
— | — | @@ -83,13 +83,13 @@ |
84 | 84 | } |
85 | 85 | }, |
86 | 86 | doSeek : function(value){ |
87 | | - //if( ! this.inputTrackerIgnoreChange ){ |
| 87 | + if( this.vlc ) { |
88 | 88 | if( (this.vlc.input.state == 3) && (this.vlc.input.position != value) ) |
89 | 89 | { |
90 | 90 | this.vlc.input.position = value; |
91 | | - document.getElementById("info_" + this.id ).innerHTML = 'seeking' |
| 91 | + this.setStatus( 'seeking...' ); |
92 | 92 | } |
93 | | - //} |
| 93 | + } |
94 | 94 | }, |
95 | 95 | playMovieAt : function (order){ |
96 | 96 | //@@todo add clips to playlist after (order) and then play |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/skins/mvpcf/styles.css |
— | — | @@ -245,26 +245,40 @@ |
246 | 246 | width: 100%; |
247 | 247 | height: 12px; |
248 | 248 | position: relative; |
249 | | - z-index: 1; |
| 249 | + z-index: 4; |
250 | 250 | background: url(images/player_seek_left.png) 0 0 no-repeat; |
251 | 251 | } |
252 | 252 | .videoPlayer .seeker .seeker_bar_close { |
253 | 253 | width: 5px; |
254 | 254 | height: 12px; |
255 | 255 | position: relative; |
256 | | - z-index: 1; |
| 256 | + z-index: 4; |
257 | 257 | float: right; |
258 | 258 | display: inline; |
259 | 259 | margin: -13px 0 0 0; |
260 | 260 | background: url(images/player_seek_right.png) 0 0 no-repeat; |
261 | 261 | } |
262 | | - |
| 262 | +.videoPlayer .seeker .mv_progress{ |
| 263 | + width: 0%; |
| 264 | + height: 12px; |
| 265 | + left:0px; |
| 266 | + top:0px; |
| 267 | + position: absolute; |
| 268 | +} |
| 269 | +.videoPlayer .seeker .mv_playback { |
| 270 | + z-index: 3; |
| 271 | + background: #CCC; |
| 272 | +} |
| 273 | +.videoPlayer .seeker .mv_buffer { |
| 274 | + z-index: 2; |
| 275 | + background: #99C; |
| 276 | +} |
263 | 277 | .videoPlayer .seeker .seeker_slider { |
264 | 278 | background: url(images/player_slider.png) 0 0 no-repeat; |
265 | 279 | width: 14px; |
266 | 280 | height: 14px; |
267 | 281 | position: relative; |
268 | | - z-index: 2; |
| 282 | + z-index: 5; |
269 | 283 | margin: -13px 0 0 0px; |
270 | 284 | cursor: pointer; |
271 | 285 | } |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js |
— | — | @@ -15,9 +15,9 @@ |
16 | 16 | * |
17 | 17 | */ |
18 | 18 | |
19 | | -//fix multiple instances of mv_embed (ie include twice from two diffrent servers) |
| 19 | +//fix multiple instances of mv_embed (ie include twice from two different servers) |
20 | 20 | var MV_DO_INIT=true; |
21 | | -if(MV_EMBED_VERSION){ |
| 21 | +if( MV_EMBED_VERSION ){ |
22 | 22 | js_log('mv_embed already included do nothing'); |
23 | 23 | MV_DO_INIT=false; |
24 | 24 | } |
— | — | @@ -496,7 +496,7 @@ |
497 | 497 | { |
498 | 498 | var cookieVal = ''; |
499 | 499 | for(var i in this.preference) |
500 | | - cookieVal = cookieVal + i + '='+ this.preference[i] + '&'; |
| 500 | + cookieVal+= i + '='+ this.preference[i] + '&'; |
501 | 501 | cookieVal=cookieVal.substr(0, cookieVal.length-1); |
502 | 502 | js_log('setting preference cookie to ' + cookieVal); |
503 | 503 | var week = 7*86400*1000; |
— | — | @@ -506,20 +506,21 @@ |
507 | 507 | |
508 | 508 | var getCookie = function ( cookieName ) { |
509 | 509 | var m = document.cookie.match( cookieName + '=(.*?)(;|$)' ); |
| 510 | + js_log('getCookie:' + (m ? unescape( m[1] ) : false)); |
510 | 511 | return m ? unescape( m[1] ) : false; |
511 | | - } |
| 512 | +} |
512 | 513 | |
513 | | -var setCookie = function ( name, value, expiry, path, domain, secure ) { |
514 | | - var expiryDate = false; |
515 | | - if ( expiry ) { |
516 | | - expiryDate = new Date(); |
517 | | - expiryDate.setTime( expiryDate.getTime() + expiry ); |
518 | | - } |
519 | | - document.cookie = name + "=" + escape(value) + |
520 | | - (expiryDate ? ("; expires=" + expiryDate.toGMTString()) : "") + |
521 | | - (path ? ("; path=" + path) : "") + |
522 | | - (domain ? ("; domain=" + domain) : "") + |
523 | | - (secure ? "; secure" : ""); |
| 514 | +function setCookie(name, value, expiry, path, domain, secure) { |
| 515 | + var expiryDate = false; |
| 516 | + if ( expiry ) { |
| 517 | + expiryDate = new Date(); |
| 518 | + expiryDate.setTime( expiryDate.getTime() + expiry ); |
| 519 | + } |
| 520 | + document.cookie = name + "=" + escape(value) + |
| 521 | + (expiryDate ? ("; expires=" + expiryDate.toGMTString()) : "") + |
| 522 | + (path ? ("; path=" + path) : "") + |
| 523 | + (domain ? ("; domain=" + domain) : "") + |
| 524 | + (secure ? "; secure" : ""); |
524 | 525 | } |
525 | 526 | |
526 | 527 | /* |
— | — | @@ -549,13 +550,12 @@ |
550 | 551 | $j('body').append( this.components['mv_embedded_options'].o() ); |
551 | 552 | |
552 | 553 | var o=''; |
553 | | - for(var i in this.components){ |
554 | | - if(this.supports[i]){ |
555 | | - if(this.avaliable_width > this.components[i].w ){ |
| 554 | + for( var i in this.components ){ |
| 555 | + if( this.supports[i] ){ |
| 556 | + if( this.avaliable_width > this.components[i].w ){ |
556 | 557 | //special case with playhead don't add unless we have 60px |
557 | 558 | if( i=='play_head' && ctrlBuilder.avaliable_width < 60 ) |
558 | | - continue; |
559 | | - |
| 559 | + continue; |
560 | 560 | o+=this.components[i].o(); |
561 | 561 | this.avaliable_width -= this.components[i].w; |
562 | 562 | }else{ |
— | — | @@ -591,7 +591,7 @@ |
592 | 592 | $j('#big_play_link_'+id).fadeOut('fast'); |
593 | 593 | //if playlist always start at 0 |
594 | 594 | embedObj.start_time_sec = (embedObj.instanceOf == 'mvPlayList')?0: |
595 | | - _this.start_time_sec = ntp2seconds(embedObj.getTimeReq().split('/')[0]); |
| 595 | + ntp2seconds(embedObj.getTimeReq().split('/')[0]); |
596 | 596 | }, |
597 | 597 | drag:function(e, ui){ |
598 | 598 | //@@todo get the -14 number from the skin somehow |
— | — | @@ -689,6 +689,8 @@ |
690 | 690 | ' <div id="seeker_bar_'+ctrlBuilder.id+'" class="seeker_bar">'+ |
691 | 691 | ' <div class="seeker_bar_outer"></div>'+ |
692 | 692 | ' <div id="mv_seeker_slider_'+ctrlBuilder.id+'" class="seeker_slider"></div>'+ |
| 693 | + ' <div class="mv_progress mv_playback"></div>'+ |
| 694 | + ' <div class="mv_progress mv_buffer"></div>'+ |
693 | 695 | ' <div class="seeker_bar_close"></div>'+ |
694 | 696 | ' </div>'+ |
695 | 697 | ' </div><!--seeker-->' |
— | — | @@ -926,7 +928,7 @@ |
927 | 929 | * $j(document).ready( function(){ */ |
928 | 930 | function init_mv_embed(force){ |
929 | 931 | js_log('f:init_mv_embed'); |
930 | | - if(!force && mv_init_done){ |
| 932 | + if(!force && ( mv_init_done || !MV_DO_INIT ) ){ |
931 | 933 | js_log("mv_init_done do nothing..."); |
932 | 934 | return false; |
933 | 935 | } |
— | — | @@ -1539,14 +1541,14 @@ |
1540 | 1542 | getURI : function(seek_time_sec) |
1541 | 1543 | { |
1542 | 1544 | if( !seek_time_sec || !this.supports_url_time_encoding ) |
1543 | | - return this.src; |
1544 | | - if( this.timeFormat == 'anx' ){ |
| 1545 | + return this.src; |
| 1546 | + if( this.timeFormat == 'anx' ){ |
1545 | 1547 | var new_url = getUpdateTimeURL(this.src, seconds2ntp(seek_time_sec)+'/'+ this.end_ntp); |
1546 | 1548 | }else if(this.timeFormat=='mp4'){ |
1547 | 1549 | var mp4URL = parseUri( this.src ); |
1548 | 1550 | var new_url = mp4URL.protocol+'://'+mp4URL.authority + mp4URL.path + '?start=' |
1549 | 1551 | + ( seek_time_sec + parseInt(mp4URL.queryKey['start']) ); |
1550 | | - } |
| 1552 | + } |
1551 | 1553 | return new_url; |
1552 | 1554 | }, |
1553 | 1555 | /** Title accessor function. |
— | — | @@ -1571,7 +1573,7 @@ |
1572 | 1574 | * supports media_url?t=ntp_start/ntp_end url request format |
1573 | 1575 | */ |
1574 | 1576 | parseURLDuration : function(){ |
1575 | | - js_log('f:parseURLDuration() for:' + this.src); |
| 1577 | + //js_log('f:parseURLDuration() for:' + this.src); |
1576 | 1578 | //check if we have a timeFormat: |
1577 | 1579 | if( this.timeFormat ){ |
1578 | 1580 | if( this.timeFormat == 'anx' ){ |
— | — | @@ -1579,8 +1581,7 @@ |
1580 | 1582 | if( annoURL.queryKey['t'] ){ |
1581 | 1583 | var times = annoURL.queryKey['t'].split('/'); |
1582 | 1584 | this.start_ntp = times[0]; |
1583 | | - this.end_ntp = times[1]; |
1584 | | - |
| 1585 | + this.end_ntp = times[1]; |
1585 | 1586 | } |
1586 | 1587 | } |
1587 | 1588 | if( this.timeFormat == 'mp4' ){ |
— | — | @@ -1893,8 +1894,9 @@ |
1894 | 1895 | supports:{}, |
1895 | 1896 | //for seek thumb updates: |
1896 | 1897 | cur_thumb_seek_time:0, |
1897 | | - thumb_seek_interval:null, |
1898 | | - |
| 1898 | + thumb_seek_interval:null, |
| 1899 | + //set the buffered percent: |
| 1900 | + bufferedPercent:0, |
1899 | 1901 | //utility functions for property values: |
1900 | 1902 | hx : function ( s ) { |
1901 | 1903 | if ( typeof s != 'String' ) { |
— | — | @@ -2222,7 +2224,7 @@ |
2223 | 2225 | var annoURL = parseUri(anno_track_url); |
2224 | 2226 | var times = annoURL.queryKey['t'].split('/'); |
2225 | 2227 | var stime_parts = times[0].split(':'); |
2226 | | - var etime_parts = times[0].split(':'); |
| 2228 | + var etime_parts = times[1].split(':'); |
2227 | 2229 | //zero out the hour: |
2228 | 2230 | var new_start = stime_parts[0]+':'+'0:0'; |
2229 | 2231 | //zero out the end sec |
— | — | @@ -2388,10 +2390,10 @@ |
2389 | 2391 | html_code = '<div id="videoPlayer_'+this.id+'" style="width:'+this.width+'px;" class="videoPlayer">'; |
2390 | 2392 | html_code += '<div style="width:'+parseInt(this.width)+'px;height:'+parseInt(this.height)+'px;" id="mv_embedded_player_'+this.id+'">' + |
2391 | 2393 | this.getThumbnailHTML() + |
2392 | | - '</div>'; |
2393 | | - |
| 2394 | + '</div>'; |
| 2395 | + |
2394 | 2396 | js_log("mvEmbed:controls "+ typeof this.controls); |
2395 | | - |
| 2397 | + |
2396 | 2398 | if(this.controls) |
2397 | 2399 | { |
2398 | 2400 | js_log("f:getHTML:AddControls"); |
— | — | @@ -2823,47 +2825,35 @@ |
2824 | 2826 | }else{ |
2825 | 2827 | this.doEmbedHTML(); |
2826 | 2828 | this.onClipDone_disp=false; |
2827 | | - this.paused=false; |
| 2829 | + this.paused=false; |
2828 | 2830 | } |
2829 | 2831 | }else{ |
2830 | 2832 | //the plugin is already being displayed |
2831 | 2833 | js_log("we are already playing..." ); |
2832 | 2834 | this.paused=false; //make sure we are not "paused" |
2833 | 2835 | } |
2834 | | - //update "paused state" |
2835 | | - js_log("SHOULD UPDATE play BUTTON"); |
2836 | | - $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button'); |
| 2836 | + $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button'); |
2837 | 2837 | }, |
2838 | | - toggleMute:function(){ |
2839 | | - var this_id = (this.pc!=null)?this.pc.pp.id:this.id; |
2840 | | - js_log('f:toggleMute'); |
2841 | | - if(this.muted){ |
2842 | | - this.muted=false; |
2843 | | - $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on'); |
2844 | | - }else{ |
2845 | | - this.muted=true; |
2846 | | - $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off'); |
2847 | | - } |
2848 | | - }, |
| 2838 | + /* |
| 2839 | + * base embed pause |
| 2840 | + * there is no general way to pause the video |
| 2841 | + * must be overwritten by embed object to support this functionality. |
| 2842 | + */ |
| 2843 | + pause : function(){ |
| 2844 | + js_log('mv_embed:do pause'); |
| 2845 | + var this_id = (this.pc!=null)?this.pc.pp.id:this.id; |
| 2846 | + //(playing) do pause |
| 2847 | + this.paused=true; |
| 2848 | + //update "paused state" |
| 2849 | + $j("#mv_play_pause_button_"+this_id).attr('class', 'play_button'); |
| 2850 | + }, |
2849 | 2851 | play_or_pause : function(){ |
2850 | 2852 | js_log('embed:f:play_or_pause'); |
2851 | | - var this_id = (this.pc!=null)?this.pc.pp.id:this.id; |
2852 | | - |
2853 | 2853 | //check state and set play or pause |
2854 | 2854 | if(this.paused){ |
2855 | | - js_log('mv_embed:do play'); |
2856 | | - //(paused) do play |
2857 | | - this.play(); |
2858 | | - this.paused=false; |
2859 | | - //update "paused state" onPlay |
2860 | | - $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button'); |
2861 | | - }else{ |
2862 | | - js_log('mv_embed:do pause'); |
2863 | | - //(playing) do pause |
| 2855 | + this.play(); |
| 2856 | + }else{ |
2864 | 2857 | this.pause(); |
2865 | | - this.paused=true; |
2866 | | - //update "paused state" |
2867 | | - $j("#mv_play_pause_button_"+this_id).attr('class', 'play_button'); |
2868 | 2858 | } |
2869 | 2859 | }, |
2870 | 2860 | //called when we play to the end of a stream (load the thumbnail) |
— | — | @@ -2874,18 +2864,10 @@ |
2875 | 2865 | } |
2876 | 2866 | }, |
2877 | 2867 | /* |
2878 | | - * base embed pause |
2879 | | - * there is no general way to pause the video |
2880 | | - * must be overwritten by embed object to support this functionality. |
2881 | | - */ |
2882 | | - pause : function(){ |
2883 | | - return null |
2884 | | - }, |
2885 | | - /* |
2886 | 2868 | * base embed stop (can be overwritten by the plugin) |
2887 | 2869 | */ |
2888 | 2870 | stop: function(){ |
2889 | | - js_log('mvEmbed:stop:'+this.id); |
| 2871 | + js_log('mvEmbed:stop:'+this.id); |
2890 | 2872 | //check if thumbnail is being displayed in which case do nothing |
2891 | 2873 | if(this.thumbnail_disp){ |
2892 | 2874 | //already in stooped state |
— | — | @@ -2893,8 +2875,9 @@ |
2894 | 2876 | }else{ |
2895 | 2877 | //rewrite the html to thumbnail disp |
2896 | 2878 | this.doThumbnailHTML(); |
| 2879 | + this.bufferedPercent=0; //reset buffer state |
2897 | 2880 | this.setSliderValue(0); |
2898 | | - this.setStatus(this.getTimeReq()); |
| 2881 | + this.setStatus( this.getTimeReq() ); |
2899 | 2882 | } |
2900 | 2883 | if(this.update_interval) |
2901 | 2884 | { |
— | — | @@ -2902,6 +2885,17 @@ |
2903 | 2886 | this.update_interval = null; |
2904 | 2887 | } |
2905 | 2888 | }, |
| 2889 | + toggleMute:function(){ |
| 2890 | + var this_id = (this.pc!=null)?this.pc.pp.id:this.id; |
| 2891 | + js_log('f:toggleMute'); |
| 2892 | + if(this.muted){ |
| 2893 | + this.muted=false; |
| 2894 | + $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on'); |
| 2895 | + }else{ |
| 2896 | + this.muted=true; |
| 2897 | + $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off'); |
| 2898 | + } |
| 2899 | + }, |
2906 | 2900 | fullscreen:function(){ |
2907 | 2901 | js_log('fullscreen not supported for this plugin type'); |
2908 | 2902 | }, |
— | — | @@ -2911,6 +2905,9 @@ |
2912 | 2906 | if(this.thumbnail_disp){ |
2913 | 2907 | //in stoped state |
2914 | 2908 | return false; |
| 2909 | + }else if( this.paused ){ |
| 2910 | + //paused state |
| 2911 | + return false; |
2915 | 2912 | }else{ |
2916 | 2913 | return true; |
2917 | 2914 | } |
— | — | @@ -2918,6 +2915,9 @@ |
2919 | 2916 | isPaused : function(){ |
2920 | 2917 | return this.isPlaying() && this.paused; |
2921 | 2918 | }, |
| 2919 | + isStoped : function(){ |
| 2920 | + return this.thumbnail_disp; |
| 2921 | + }, |
2922 | 2922 | playlistSupport:function(){ |
2923 | 2923 | //by default not supported (implemented in js) |
2924 | 2924 | return false; |
— | — | @@ -2948,6 +2948,20 @@ |
2949 | 2949 | if(val > ($j('#mv_seeker_'+this_id).width() -this.mv_seeker_width) ) |
2950 | 2950 | val = $j('#mv_seeker_'+this_id).width() -this.mv_seeker_width ; |
2951 | 2951 | $j('#mv_seeker_slider_'+this_id).css('left', (val)+'px' ); |
| 2952 | + |
| 2953 | + //update the playback progress bar |
| 2954 | + $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", Math.round( val + (this.mv_seeker_width*.5) ) + 'px' ); |
| 2955 | + |
| 2956 | + //update the buffer progress bar (if available ) |
| 2957 | + if( this.bufferedPercent!=0 ){ |
| 2958 | + //js_log('bufferedPercent: ' + this.bufferedPercent); |
| 2959 | + if(this.bufferedPercent > 1) |
| 2960 | + this.bufferedPercent=1; |
| 2961 | + $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", (this.bufferedPercent*100) +'%' ); |
| 2962 | + }else{ |
| 2963 | + $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", '0px' ); |
| 2964 | + } |
| 2965 | + |
2952 | 2966 | //js_log('set#mv_seeker_slider_'+this_id + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+this_id).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) ); |
2953 | 2967 | //js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')'); |
2954 | 2968 | }, |
— | — | @@ -2958,21 +2972,6 @@ |
2959 | 2973 | } |
2960 | 2974 | } |
2961 | 2975 | |
2962 | | -/* returns html for a transparent png (for ie<7) |
2963 | | - * not currently used: |
2964 | | -function getTransparentPng(image){ |
2965 | | - if(!image.style)image.style=''; |
2966 | | - if( embedTypes.msie ){ |
2967 | | - return '<span id="'+image.id+'" style="display:inline-block;width:'+image.width+'px;height:'+image.height+'px;' + |
2968 | | - 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' + |
2969 | | - '(src=\''+image.src+'\', sizingMethod=\'scale\');"></span>'; |
2970 | | - }else{ |
2971 | | - return '<img id="'+image.id+'" style="'+image.style+'" width="'+image.width+'" height="'+image.height+'" border="0" src="'+ |
2972 | | - image.src + '">'; |
2973 | | - } |
2974 | | -} |
2975 | | -*/ |
2976 | | - |
2977 | 2976 | /* |
2978 | 2977 | * utility functions: |
2979 | 2978 | */ |
— | — | @@ -2997,6 +2996,9 @@ |
2998 | 2997 | |
2999 | 2998 | function seconds2ntp(sec){ |
3000 | 2999 | var sec = parseInt(sec); |
| 3000 | + if( isNaN( sec ) ){ |
| 3001 | + return '0:0:0'; |
| 3002 | + } |
3001 | 3003 | var hours = Math.floor(sec/ 3600); |
3002 | 3004 | var minutes = Math.floor((sec/60) % 60); |
3003 | 3005 | var seconds = sec % 60; |
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_remote_media_search.js |
— | — | @@ -12,7 +12,7 @@ |
13 | 13 | num_req:0, |
14 | 14 | |
15 | 15 | result_display_mode:'box', //box or list |
16 | | - api_mode:'metavid', //api mode (mediawiki api or metavid enhanced wiki api) |
| 16 | + api_mode:'mediawiki', //api mode (mediawiki api or metavid enhanced wiki api) |
17 | 17 | resultsObj:{}, |
18 | 18 | //init the object: |
19 | 19 | init:function( initObj ){ |