r60066 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60065‎ | r60066 | r60067 >
Date:08:07, 15 December 2009
Author:dale
Status:deferred
Tags:
Comment:
* timed text updates
* fixed some edge cases in embedPlayer.monitor
* fixed jQuery.menu to support leading icons
* corrected checkForTextSource() reference to: textSourceExists()
Modified paths:
  • /branches/js2-work/phase3/js2/mwEmbed/example_usage/Player_Timed_Text.html (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.css (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libTimedText/mw.timedText.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/mwEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js (modified) (history)

Diff [purge]

Index: branches/js2-work/phase3/js2/mwEmbed/example_usage/Player_Timed_Text.html
@@ -9,6 +9,7 @@
1010 <h3> mwEmbed Timed Text Examples:</h3>
1111 Click on the little lower right "CC" icon to expose the timed text
1212 <table border="1" cellpadding="6" width="950">
 13+ <!--
1314 <tr>
1415 <td valign="top" width="410">
1516
@@ -31,9 +32,10 @@
3233 </pre><iframe width="600" height="250" src="http://metavid.org/w/index.php?title=Special:MvExportStream&stream_name=House_proceeding_07-18-06_00&t=1:23:16/1:23:44&feed_format=roe" ></iframe> </td>
3334
3435 </tr>
 36+-->
3537 <tr>
3638 <td valign="top" width="410">
37 - <!--
 39+
3840 <video style="width:544;height:304"
3941 poster="http://www.annodex.net/~silvia/itext/elephants_dream/elephant.png"
4042 duration="10:53"
@@ -42,87 +44,86 @@
4345 <source type="video/h264" src="http://www.archive.org/download/ElephantsDream/ed_1024_512kb.mp4"></source>
4446 <itextlist category="SUB" name="Subtitles A-F">
4547 <itext id="video_af" lang="af" charset="ISO-8859-1"
46 - src="media/media/elephants_dream/elephant.afrikaans.srt">
 48+ src="media/elephants_dream/elephant.afrikaans.srt"></itext>
4749 <itext id="video_ar" lang="ar" charset="Windows-1256"
48 - src="media/media/elephants_dream/elephant.arabic.srt">
 50+ src="media/elephants_dream/elephant.arabic.srt"></itext>
4951 <itext id="video_bn" lang="bn" charset="UTF-8"
50 - src="media/elephants_dream/elephant.bangla.srt">
 52+ src="media/elephants_dream/elephant.bangla.srt"></itext>
5153 <itext id="video_br" lang="br" charset="Windows-1252"
52 - src="media/elephants_dream/elephant.breton.srt">
 54+ src="media/elephants_dream/elephant.breton.srt"></itext>
5355 <itext id="video_bg" lang="bg" charset="Windows-1251"
54 - src="media/elephants_dream/elephant.bulgarian.srt">
 56+ src="media/elephants_dream/elephant.bulgarian.srt"></itext>
5557 <itext id="video_ca" lang="ca" charset="UTF-8"
56 - src="media/elephants_dream/elephant.catalan-utf8.srt">
 58+ src="media/elephants_dream/elephant.catalan-utf8.srt"></itext>
5759 <itext id="video_zh" lang="zh" charset="GB18030"
58 - src="media/elephants_dream/elephant.chinese.srt">
 60+ src="media/elephants_dream/elephant.chinese.srt"></itext>
5961 <itext id="video_cz" lang="cs" charset="ISO-8859-1"
60 - src="media/elephants_dream/elephant.czech.srt">
 62+ src="media/elephants_dream/elephant.czech.srt"></itext>
6163 <itext id="video_da" lang="da" charset="ISO-8859-1"
62 - src="media/elephants_dream/elephant.danish.srt">
 64+ src="media/elephants_dream/elephant.danish.srt"></itext>
6365 <itext id="video_nl" lang="nl" charset="ISO-8859-1"
64 - src="media/elephants_dream/elephant.dutch.srt">
 66+ src="media/elephants_dream/elephant.dutch.srt"></itext>
6567 <itext id="video_en" lang="en" charset="ISO-8859-1"
66 - src="media/elephants_dream/elephant.english.srt">
 68+ src="media/elephants_dream/elephant.english.srt"></itext>
6769 <itext id="video_et" lang="et" charset="Windows-1252"
68 - src="media/elephants_dream/elephant.estonian.srt">
 70+ src="media/elephants_dream/elephant.estonian.srt"></itext>
6971 <itext id="video_fi" lang="fi" charset="ISO-8859-1"
70 - src="media/elephants_dream/elephant.finnish.srt">
 72+ src="media/elephants_dream/elephant.finnish.srt"></itext>
7173 <itext id="video_fr" lang="fr" charset="ISO-8859-1"
72 - src="media/elephants_dream/elephant.french.srt">
 74+ src="media/elephants_dream/elephant.french.srt"></itext>
7375 </itextlist>
7476 <itestlist category="SUB" name="Subtitles D-R">
7577 <itext id="video_de" lang="de" charset="ISO-8859-1"
76 - src="media/elephants_dream/elephant.german.srt">
 78+ src="media/elephants_dream/elephant.german.srt"></itext>
7779 <itext id="video_el" lang="el" charset="ISO-8859-7"
78 - src="media/elephants_dream/elephant.greek.srt">
 80+ src="media/elephants_dream/elephant.greek.srt"></itext>
7981 <itext id="video_he" lang="he" charset="Windows-1252"
80 - src="media/elephants_dream/elephant.hebrew.srt">
 82+ src="media/elephants_dream/elephant.hebrew.srt"></itext>
8183 <itext id="video_hu" lang="hu" charset="UTF-8"
82 - src="media/elephants_dream/elephant.hungarian-utf8.srt">
 84+ src="media/elephants_dream/elephant.hungarian-utf8.srt"></itext>
8385 <itext id="video_it" lang="it" charset="UTF-8"
84 - src="media/elephants_dream/elephant.italian.srt">
 86+ src="media/elephants_dream/elephant.italian.srt"></itext>
8587 <itext id="video_ja" lang="ja" charset="UTF-8"
86 - src="media/elephants_dream/elephant.japanese.srt">
 88+ src="media/elephants_dream/elephant.japanese.srt"></itext>
8789 <itext id="video_ja" lang="ja" charset="EUC-JP"
88 - src="media/elephants_dream/elephant.japanese-euc.srt">
 90+ src="media/elephants_dream/elephant.japanese-euc.srt"></itext>
8991 <itext id="video_mt" lang="mt" charset="UTF-8"
90 - src="media/elephants_dream/elephant.maltese_utf8.srt">
 92+ src="media/elephants_dream/elephant.maltese_utf8.srt"></itext>
9193 <itext id="video_nn" lang="nn" charset="ISO-8859-1"
92 - src="media/elephants_dream/elephant.norwegian.srt">
 94+ src="media/elephants_dream/elephant.norwegian.srt"></itext>
9395 <itext id="video_pl" lang="pl" charset="UTF-8"
94 - src="media/elephants_dream/elephant.polish.srt">
 96+ src="media/elephants_dream/elephant.polish.srt"></itext>
9597 <itext id="video_pt" lang="pt" charset="UTF-8"
96 - src="media/elephants_dream/elephant.portuguese.srt">
 98+ src="media/elephants_dream/elephant.portuguese.srt"></itext>
9799 <itext id="video_pt_br" lang="pt-br" charset="ISO-8859-1"
98 - src="media/elephants_dream/elephant.brazilian.srt">
 100+ src="media/elephants_dream/elephant.brazilian.srt"></itext>
99101 <itext id="video_ro" lang="ro" charset="ISO-8859-1"
100 - src="media/elephants_dream/elephant.romanian.srt">
 102+ src="media/elephants_dream/elephant.romanian.srt"></itext>
101103 <itext id="video_ru" lang="ru" charset="Windows-1251"
102 - src="media/elephants_dream/elephant.russian.srt">
 104+ src="media/elephants_dream/elephant.russian.srt"></itext>
103105 </itextlist>
104106 <itextlist category="CC" name="Captions">
105107 <itext id="video_sl" lang="sl" charset="ISO-8859-1"
106 - src="media/elephants_dream/elephant.slovenian.srt">
 108+ src="media/elephants_dream/elephant.slovenian.srt"></itext>
107109 <itext id="video_es" lang="es" charset="ISO-8859-1"
108 - src="media/elephants_dream/elephant.spanish.srt">
 110+ src="media/elephants_dream/elephant.spanish.srt"></itext>
109111 <itext id="video_es_mx" lang="es-mx" charset="ISO-8859-1"
110 - src="media/elephants_dream/elephant.spanish-us.srt">
 112+ src="media/elephants_dream/elephant.spanish-us.srt"></itext>
111113 <itext id="video_sk" lang="sk" charset="Windows-1251"
112 - src="media/elephants_dream/elephant.slovak.srt">
 114+ src="media/elephants_dream/elephant.slovak.srt"></itext>
113115 <itext id="video_sv" lang="sv" charset="ISO-8859-1"
114 - src="media/elephants_dream/elephant.swedish.srt">
 116+ src="media/elephants_dream/elephant.swedish.srt"></itext>
115117 </itextlist>
116118 <itextlist category="TAD" name="Audio Transcript">
117119 <itext id="audiodesc" lang="en" charset="ISO-8859-1"
118 - src="media/elephants_dream/audiodescription.srt">
 120+ src="media/elephants_dream/audiodescription.srt"></itext>
119121 </itextlist>
120122 <itextlist category="CUE" name="Chapters">
121123 <itext id="chapters" lang="en" charset="ISO-8859-1"
122 - src="media/elephants_dream/chapters.srt">
 124+ src="media/elephants_dream/chapters.srt"></itext>
123125 </itextlist>
124126
125127 </video>
126 - -->
127128
128129
129130 </td>
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js
@@ -157,7 +157,7 @@
158158
159159 // If serving an ogg_chop segment use this to offset the presentation time
160160 // ( for some plugins that use ogg page time rather than presentation time )
161 - "startOffset" : null,
 161+ "startOffset" : 0,
162162
163163 //If we should display the play button
164164 "play_button" : true,
@@ -577,6 +577,7 @@
578578 // End time in npt format
579579 end_npt: null,
580580
 581+
581582 /**
582583 * MediaSource constructor:
583584 */
@@ -612,8 +613,11 @@
613614 this.mime_type = this.detectType( this.src );
614615
615616 // Check for parent elements ( supplies catagories in "itext" )
616 - if( $j( element ).parent().attr('category') ){
 617+ if( $j( element ).parent().attr('category') ){
617618 this.category = $j( element ).parent().attr('category');
 619+ mw.log("added category: " + this.category);
 620+ }else{
 621+ mw.log(" had no category" + this.id);
618622 }
619623
620624 // Get the url duration ( if applicable )
@@ -778,7 +782,7 @@
779783 return 'video/h264';
780784 break;
781785 case '.srt':
782 - return 'text/srt';
 786+ return 'text/x-srt';
783787 break;
784788 case '.flv':
785789 return 'video/x-flv';
@@ -865,8 +869,9 @@
866870
867871 // Process all inner <source>, <text> & <itext> elements
868872
869 - $j( video_element ).find( 'source,itext' ).each( function( inx, inner_source ) {
870 - _this.tryAddSource( inner_source );
 873+ $j( video_element ).find( 'source,itext' ).each( function( ) {
 874+ mw.log( 'pcat: ' + $j(this).parent().attr( 'category' ) + ' tagName:' + $j(this).parent().get(0).tagName );
 875+ _this.tryAddSource( this );
871876 } );
872877 },
873878
@@ -891,7 +896,8 @@
892897 */
893898 textSourceExists: function() {
894899 for ( var i = 0; i < this.sources.length; i++ ) {
895 - if ( this.sources[i].mime_type == 'text/cmml' ||
 900+ mw.log( this.sources[i].mime_type );
 901+ if ( this.sources[i].mime_type == 'text/cmml' ||
896902 this.sources[i].mime_type == 'text/x-srt' )
897903 return true;
898904 };
@@ -1092,7 +1098,7 @@
10931099 if ( this.isPlayableType( this.sources[i].mime_type ) ) {
10941100 playable_sources.push( this.sources[i] );
10951101 } else {
1096 - mw.log( "type " + this.sources[i].mime_type + 'is not playable' );
 1102+ //mw.log( "type " + this.sources[i].mime_type + 'is not playable' );
10971103 }
10981104 };
10991105 return playable_sources;
@@ -2777,17 +2783,18 @@
27782784 */
27792785 monitor: function() {
27802786 var _this = this;
2781 - //mw.log(' ct: ' + this.currentTime + ' dur: ' + ( parseInt( this.duration ) + 1 ) + ' is seek: ' + this.seeking );
 2787+ //mw.log(' ct: ' + this.currentTime + ' dur: ' + ( parseInt( this.duration ) + 1 ) + ' is seek: ' + this.seeking );
27822788 if ( this.currentTime && this.currentTime > 0 && this.duration ) {
2783 - if ( !this.userSlide && !this.seeking ) {
 2789+ if ( !this.userSlide && !this.seeking ) {
27842790 if ( parseInt( this.startOffset ) != 0 ) {
27852791 // If start offset include that calculation
27862792 this.updatePlayHead( ( this.currentTime - this.startOffset ) / this.duration );
27872793 var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + mw.seconds2npt( parseFloat( this.startOffset ) + parseFloat( this.duration ) ) : '';
27882794 this.setStatus( mw.seconds2npt( this.currentTime ) + et );
27892795 } else {
2790 - this.updatePlayHead( this.currentTime / this.duration );
2791 - var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + mw.seconds2npt( this.duration ):'';
 2796+ this.updatePlayHead( this.currentTime / this.duration );
 2797+ // Only include the end time if long_time_disp is enabled:
 2798+ var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + mw.seconds2npt( this.duration ) : '';
27922799 this.setStatus( mw.seconds2npt( this.currentTime ) + et );
27932800 }
27942801 }
@@ -3162,7 +3169,7 @@
31633170 * null if no player found
31643171 */
31653172 defaultPlayer : function( mime_type ) {
3166 - mw.log( "get defaultPlayer for " + mime_type );
 3173+ //mw.log( "get defaultPlayer for " + mime_type );
31673174 var mime_players = this.getMIMETypePlayers( mime_type );
31683175 if ( mime_players.length > 0 )
31693176 {
@@ -3175,7 +3182,7 @@
31763183 // (it will be chosen according to the default_players list
31773184 return mime_players[0];
31783185 }
3179 - mw.log( 'No default player found for ' + mime_type );
 3186+ //mw.log( 'No default player found for ' + mime_type );
31803187 return null;
31813188 },
31823189
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js
@@ -396,7 +396,7 @@
397397 */
398398 onloadedmetadata: function() {
399399 this.getPlayerElement();
400 - mw.log( 'f:onloadedmetadata metadata ready (update duration)' );
 400+ mw.log( 'f:onloadedmetadata metadata ready Update duration:' + this.playerElement.duration);
401401 // update duration if not set (for now trust the getDuration more than this.playerElement.duration
402402 if ( this.getDuration() == 0 && ! isNaN( this.playerElement.duration ) ) {
403403 mw.log( 'updaed duration via native video duration: ' + this.playerElement.duration )
Index: branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js
@@ -79,11 +79,10 @@
8080 _this.supports[i] = embedObj.supports[i];
8181 };
8282
83 - // Check for timed Text:
84 - if ( ( embedObj.roe || embedObj.wikiTitleKey ||
85 - ( embedObj.mediaElement.checkForTextSource &&
86 - embedObj.mediaElement.checkForTextSource() )
87 - ) && embedObj.show_meta_link ){
 83+ // Check for timed text
 84+ if ( ( embedObj.roe || embedObj.wikiTitleKey ||
 85+ embedObj.mediaElement.textSourceExists() )
 86+ && embedObj.show_meta_link ){
8887 this.supports['timed_text'] = true;
8988 }
9089
Index: branches/js2-work/phase3/js2/mwEmbed/mwEmbed.js
@@ -1187,8 +1187,8 @@
11881188 mw.log("run getJSON: " + url + ' data: ' + data);
11891189 // Pass off the jQuery getJSON request:
11901190 $j.getJSON( url, data, callback );
1191 - }
1192 -
 1191+ }
 1192+
11931193 /**
11941194 * Metavid spefic roe request helper function
11951195 *
@@ -2099,7 +2099,7 @@
21002100 */
21012101
21022102 /**
2103 - * Default module configuration
 2103+ * Default player module configuration
21042104 */
21052105
21062106 // What tags will be re-written to video player by default
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/mw.timedText.js
@@ -6,20 +6,42 @@
77 * timed text loading request
88 * timed text edit requests
99 * timed text search & seek interface ( version 2 )
 10+ *
 11+ * Some code borrowed from: http://www.annodex.net/~silvia/itext/elephant_no_skin_v2.html
 12+ * ( Licenced under: MPL 1.1/GPL 2.0/LGPL 2.1 )
 13+ * Contributor(s):
 14+ * Silvia Pfeiffer <silvia@siliva-pfeiffer.de>
1015 */
1116
1217 mw.addMessages( {
1318 "mwe-back-btn" : "Back",
1419 "mwe-chose-text" : "Chose text",
 20+
1521 "mwe-layout" : "Layout",
16 - "mwe-ontop-video" : "Ontop of video",
17 - "mwe-bellow-video": "Bellow video",
18 - "mwe-video-off" : "Hide subtitles"
 22+ "mwe-layout-ontop" : "Ontop of video",
 23+ "mwe-layout-below": "Below video",
 24+ "mwe-layout-off" : "Hide subtitles",
1925
 26+ "mwe-key-language": "($1) $2",
 27+
 28+ "mwe-textcat-cc" : "Captions",
 29+ "mwe-textcat-sub" : "Subtitles",
 30+ "mwe-textcat-tad" : "Audio description",
 31+ "mwe-textcat-ktv" : "Karaoke",
 32+ "mwe-textcat-tik" : "Ticker text",
 33+ "mwe-textcat-ar" : "Active regions",
 34+ "mwe-textcat-nb" : "Annotation",
 35+ "mwe-textcat-meta" : "Timed metadata",
 36+ "mwe-textcat-trx" : "Transcript",
 37+ "mwe-textcat-lrc" : "Lyrics",
 38+ "mwe-textcat-lin" : "Linguistic markup",
 39+ "mwe-textcat-cue" : "Cue points"
2040 } );
2141
2242 // Bind to mw (for uncluttered global namespace)
2343 ( function( $ ) {
 44+
 45+
2446 $.timedText = function ( embedPlayer, options ){
2547 return new TimedText( embedPlayer, options );
2648 }
@@ -34,17 +56,46 @@
3557 TimedText.prototype = {
3658
3759 /**
38 - * Prefrences config order is:
 60+ * Prefrences config order is presently:
3961 * 1) user cookie
40 - * 2) media default or layout tags
41 - * 3) defaults provided in the config var:
 62+ * 2) defaults provided in this config var:
4263 */
43 - config : {
 64+ config: {
4465 // Layout for basic "timedText" type can be 'ontop', 'off', 'below'
45 - 'layout': 'below'
 66+ 'layout': 'below',
 67+ //Set the default local ( should be grabbed from the browser )
 68+ 'userLanugage': 'en'
4669 },
47 -
 70+
4871 /**
 72+ * The list of enabled sources
 73+ */
 74+ enabledSources: { },
 75+
 76+ /**
 77+ * Text sources ( a set of textSource objects )
 78+ */
 79+ textSources: [ ],
 80+
 81+ /**
 82+ * Valid "iText" categories
 83+ */
 84+ validCategoriesKeys: [
 85+ "CC",
 86+ "SUB",
 87+ "TAD",
 88+ "KTV",
 89+ "TIK",
 90+ "AR",
 91+ "NB",
 92+ "META",
 93+ "TRX",
 94+ "LRC",
 95+ "LIN",
 96+ "CUE"
 97+ ],
 98+
 99+ /**
49100 * Set of timedText providers
50101 */
51102 timedTextProvider:{
@@ -68,10 +119,19 @@
69120 //Set up embedPlayer monitor hook:
70121 embedPlayer.addHook( 'monitor', function(){
71122 _this.monitor();
72 - })
 123+ } )
 124+ // Load cookie / page prefrences
 125+ //
 126+ // Load textSources
 127+ _this.loadTextSources( function(){
73128
74 - // Load cookie prefrences
 129+ // Enable a default source and issue a request to "load it"
 130+ _this.autoSelectSource();
75131
 132+ // Load and parse the text value of active sources:
 133+ _this.loadActiveSources();
 134+
 135+ } );
76136 },
77137
78138 /**
@@ -82,9 +142,50 @@
83143 },
84144
85145 /**
86 - * Show the timed text menu
87 - * @param {Object} jQuery selector to display the target
 146+ * Loads all the avaliable text sources from the inline embed
 147+ * or from a timedTextProvider
88148 */
 149+ loadTextSources: function( callback ){
 150+ // Get local reference to all timed text sources: ( text/xml, text/x-srt etc )
 151+ var inlineSources = this.embedPlayer.mediaElement.getSources( 'text' );
 152+ //add all the sources to textSources
 153+ for( var i in inlineSources ){
 154+ // make a new textSource:
 155+ var source = new textSource( inlineSources[i] );
 156+ this.textSources.push( source );
 157+ }
 158+ },
 159+
 160+ /**
 161+ * Auto selects a source given the local configuration
 162+ */
 163+ autoSelectSource: function(){
 164+ // Check if any source matches our "local"
 165+ if( this.config.userLanugage ){
 166+ for( var i in this.textSources ){
 167+ var source = this.textSources[ i ];
 168+ if( source.lang == this.config.userLanugage ){
 169+ this.enabledSources.push( source );
 170+ }
 171+ }
 172+ }
 173+ },
 174+
 175+ /**
 176+ * Makes sure all enabled Sources are loaded
 177+ */
 178+ loadActiveSources: function(){
 179+ for(var i in this.enabledSources ){
 180+ var enabledSource = this.enabledSources[ i ];
 181+ if( ! enabledSource.loaded )
 182+ this.loadAndParseSource( enabledSource );
 183+ }
 184+ },
 185+
 186+ /**
 187+ * Show the timed text menu
 188+ * @param {Object} jQuery selector to display the target
 189+ */
89190 showMenu: function( ){
90191 var _this = this;
91192 mw.log("TimedText:ShowMenu");
@@ -113,10 +214,26 @@
114215 * @param {Element} item Item selected
115216 */
116217 selectMenuItem: function( item ){
117 - mw.log("selectMenuItem: " + $j( item ).attr('class') );
 218+ mw.log("selectMenuItem: " + $j( item ).find('a').attr('class') );
118219 },
119220
120221 /**
 222+ * Checks if a source is "on"
 223+ * @return
 224+ * true if source is on
 225+ * false if source is off
 226+ * @type {Boolean}
 227+ */
 228+ isSourceEnabled: function( source ){
 229+ for(var i in this.enabledSources ){
 230+ var enabledSource = this.enabledSources[i];
 231+ if( source.id == enabledSource.id )
 232+ return true;
 233+ }
 234+ return false;
 235+ },
 236+
 237+ /**
121238 * Builds the core timed Text menu
122239 * calls a few sub-functions:
123240 * Basic menu layout:
@@ -134,17 +251,15 @@
135252 //build the source list menu item:
136253
137254 return $j( '<ul>' ).append(
138 - // Chose language option:
139 - _this.getLi( 'mwe-chose-text' ).append(
140 - _this.buildLanguageMenu()
 255+
 256+ // Chose language option:
 257+ _this.getLi( gM( 'mwe-chose-text') ).append(
 258+ _this.getLanguageMenu()
141259 ),
 260+
142261 // Layout Menu option
143 - _this.getLi( 'mwe-layout' ).append(
144 - $j('<ul>').append(
145 - _this.getLi( 'mwe-bellow-video' ),
146 - _this.getLi( 'mwe-ontop-video' ),
147 - _this.getLi( 'mwe-video-off' )
148 - )
 262+ _this.getLi( gM( 'mwe-layout' ) ).append(
 263+ _this.getLayoutMenu()
149264 )
150265 );
151266 },
@@ -154,54 +269,234 @@
155270 * Get menu line item (li) html: <li><a> msgKey </a></li>
156271 *
157272 * @param {String} msgKey Msg key for menu item
158 - */
159 - getLi: function ( msgKey ){
160 - return $j( '<li>' ).append(
 273+ */
 274+
 275+ /**
 276+ * Get line item (li) from source object
 277+ */
 278+ getLiSource: function( source ){
 279+ //See if the source is currently "on"
 280+ var sourceIcon = ( this.isSourceEnabled( source ) )? 'bullet' : 'radio-on';
 281+
 282+ if( source.title )
 283+ return this.getLi( source.title, sourceIcon )
 284+
 285+ if( source.lang ){
 286+ var langKey = source.lang.toLowerCase();
 287+ mw.languages[ langKey ];
 288+ return this.getLi( gM('mwe-key-language',
 289+ [
 290+ langKey,
 291+ unescape( mw.languages[ source.lang ] )
 292+ ] ), sourceIcon
 293+ );
 294+ }
 295+ },
 296+
 297+ /**
 298+ * Get line item ( li ) from text string
 299+ */
 300+ getLi: function( string, icon ){
 301+ var $li = $j( '<li>' ).append(
161302 $j('<a>')
162 - .attr('href', '#')
163 - .text(
164 - gM( msgKey )
165 - )
166 - );
 303+ .attr('href', '#')
 304+ )
 305+ if( icon )
 306+ $li.find( 'a' ).append( $j('<span style="float:left;" class="ui-icon ui-icon-' + icon + '"/>') )
 307+ $li.find( 'a' ).append( $j('<span>').text( string ) );
 308+ return $li;
167309 },
168310
 311+ /**
 312+ * Builds and returns the "layout" menu
 313+ */
 314+ getLayoutMenu: function(){
 315+ var _this = this;
 316+ var layoutOptions = [ 'ontop', 'off', 'below' ];
 317+ $ul = $j('<ul>');
 318+ $j.each(layoutOptions, function( na, layoutMode ){
 319+ var icon = ( _this.config.layout == layoutMode )? 'bullet' : 'radio-on';
 320+ $ul.append( _this.getLi( gM( 'mwe-layout-' + layoutMode), icon ) );
 321+ });
 322+ return $ul;
 323+ },
 324+
169325 /**
170326 * Builds the language source list menu
171327 * checks all text sources for category and language key attribute
172328 */
173 - buildLanguageMenu: function(){
 329+ getLanguageMenu: function(){
174330 var _this = this;
175 - // Get local reference to all timed text sources: ( text/xml, text/x-srt etc )
176 - var sources = this.embedPlayer.mediaElement.getSources( 'text' );
 331+
 332+ // See if we have categories to worry about:
177333
178 - // See if we have categories to worry about:
179 - var categoryBuckets = [ ];
180 - for( var i in sources ) {
181 - var source = sources[ i ];
 334+ var catSourceList = [ ];
 335+ var sourcesWithoutCategory = [ ];
 336+ for( var i in this.textSources ) {
 337+ var source = this.textSources[ i ];
182338 if( source.category ){
183 - if( ! categoryBuckets[ source.category ] )
184 - categoryBuckets[ source.category ] = [ ];
185 - categoryBuckets[ source.category ].push( source )
 339+ var catKey = source.category ;
 340+ // Init Category menu item if it does not already exist:
 341+ if( !catSourceList[ catKey ] ){
 342+ //set up catList pointer:
 343+ catSourceList[ catKey ] = [ ]
 344+ }
 345+ //append to the source category key menu item:
 346+ catSourceList[ catKey ].push(
 347+ _this.getLiSource( source )
 348+ )
 349+ }else{
 350+ sourcesWithoutCategory.push( _this.getLiSource( source ) );
186351 }
187352 }
188 - $langMenu = $j('<ul>');
189 - if( categoryBuckets.length == 0 ){
190 - // No categories just return the source list
191 - for( var i in sources ){
192 - var source = sources [ i ]
193 - $langMenu.append(
194 - $j( '<li>' ).append(
195 - $j('<a>')
196 - .attr('href', '#')
197 - .text(
198 - source.title
199 - ) )
200 - );
 353+ var $langMenu = $j('<ul>')
 354+ for(var catKey in catSourceList){
 355+ $catChildren = $j('<ul>');
 356+ for(var i in catSourceList[ catKey ]){
 357+ $catChildren.append(
 358+ catSourceList[ catKey ][i]
 359+ )
201360 }
 361+ $langMenu.append(
 362+ _this.getLi( gM( 'mwe-textcat-' + catKey.toLowerCase() ) ).append(
 363+ $catChildren
 364+ )
 365+ );
202366 }
 367+ for(var i in sourcesWithoutCategory){
 368+ $langMenu.append( sourcesWithoutCategory[i] )
 369+ }
203370 return $langMenu;
 371+ }
 372+ }
 373+
 374+ /**
 375+ * TextSource object extends a base mediaSource object
 376+ * with some timedText features
 377+ */
 378+ var textSource = function( source ){
 379+ return this.init( source );
 380+ }
 381+ textSource.prototype = {
 382+ //The load state:
 383+ loaded: false,
 384+
 385+ // Container for the captions
 386+ // captions include "start", "end" and "content" fields
 387+ captions: [],
 388+
 389+ /**
 390+ * @constructor Inherits mediaSource from embedPlayer
 391+ * @param {source} Base source element
 392+ */
 393+ init: function( source ){
 394+ for( var i in source){
 395+ this[i] = source[i];
 396+ }
 397+ },
 398+ /**
 399+ * Function to load and parse the source text
 400+ */
 401+ load: function(){
 402+ // Set parser handler:
 403+ switch( this.getMIMEType() ){
 404+ case 'text/x-srt':
 405+ var handler = parseSrt;
 406+ break;
 407+ case 'text/cmml':
 408+ var handler = parseCMML;
 409+ break;
 410+ default:
 411+ var hanlder = null;
 412+ break;
 413+ }
 414+ if( !handler ){
 415+ mw.log("Error: no handler for type: " + this.getMIMEType() );
 416+ return ;
 417+ }
 418+ // Issue the load request ( if we can )
 419+ if ( mw.parseUri( document.URL ).host != mw.parseUri( this.getSrc() ).host ){
 420+ mw.log("Error can't load non-json src via jsonp:" + this.getSrc() )
 421+ return ;
 422+ }
 423+ var XHR = $j.get( this.getSrc(), function(){
 424+ // Parse and load captions:
 425+ _this.captions = handler( data );
 426+ // Update the loaded state:
 427+ _this.loaded = true;
 428+ }, 'text' );
204429 }
 430+ }
 431+ /**
 432+ * srt timed text parse hanndle:
 433+ * @param {String} data Srt string to be parsed
 434+ */
 435+ function parseSrt( data ) {
 436+ var srt = data.replace(/\r+/g, ''); // remove dos newlines
 437+ srt = srt.replace(/^\s+|\s+$/g, ''); // trim white space start and end
 438+ srt = srt.replace(/<[a-zA-Z\/][^>]*>/g, ''); // remove all html tags for security reasons
 439+
 440+ // get captions
 441+ var captions = [ ];
 442+ var caplist = srt.split('\n\n');
 443+ for (var i = 0; i < caplist.length; i=i+1) {
 444+ var caption = "";
 445+ var content, start, end, s;
 446+ caption = caplist[i];
 447+ s = caption.split(/\n/);
 448+ if (s[0].match(/^\d+$/) && s[1].match(/\d+:\d+:\d+/)) {
 449+ // ignore caption number in s[0]
 450+ // parse time string
 451+ var m = s[1].match(/(\d+):(\d+):(\d+)(?:,(\d+))?\s*--?>\s*(\d+):(\d+):(\d+)(?:,(\d+))?/);
 452+ if (m) {
 453+ start =
 454+ (parseInt(m[1], 10) * 60 * 60) +
 455+ (parseInt(m[2], 10) * 60) +
 456+ (parseInt(m[3], 10)) +
 457+ (parseInt(m[4], 10) / 1000);
 458+ end =
 459+ (parseInt(m[5], 10) * 60 * 60) +
 460+ (parseInt(m[6], 10) * 60) +
 461+ (parseInt(m[7], 10)) +
 462+ (parseInt(m[8], 10) / 1000);
 463+ } else {
 464+ // Unrecognized timestring
 465+ continue;
 466+ }
 467+ // concatenate text lines to html text
 468+ content = s.slice(2).join("<br>");
 469+ } else {
 470+ // file format error or comment lines
 471+ continue;
 472+ }
 473+ captions.push({start: start, end: end, content: content});
 474+ }
 475+
 476+ return captions;
 477+ }
 478+ /**
 479+ * CMML parser handle
 480+ * @param {Mixed} data String or XML tree of CMML data to be parsed
 481+ */
 482+ function parseCMML( data ){
 483+ var captions = [ ];
 484+ $j( data ).find( 'clip' ).each( function( inx, clip ) {
 485+ var content, start, end;
 486+ // mw.log(' on clip ' + clip.id);
 487+ start = mw.npt2seconds( $j( clip ).attr( 'start' ).replace( 'npt:', '' ) );
 488+ end = mw.npt2seconds( $j( clip ).attr( 'end' ).replace( 'npt:', '' ) );
 489+
 490+ $j( clip ).find( 'body' ).each( function( binx, bn ) {
 491+ if ( bn.textContent ) {
 492+ content = bn.textContent;
 493+ } else if ( bn.text ) {
 494+ content = bn.text;
 495+ }
 496+ } );
 497+ captions.push({start: start, end: end, content: content});
 498+ } );
205499
 500+ return captions;
206501 }
207502 } )( window.mw );
208503
@@ -226,4 +521,369 @@
227522 embedPlayer.timedText.showMenu();
228523 } );
229524 }
230 -} )( jQuery );
\ No newline at end of file
 525+} )( jQuery );
 526+
 527+
 528+
 529+/**
 530+ * List of all languages mediaWiki supports ( Avoid an api call to get this same info )
 531+ * http://commons.wikimedia.org/w/api.php?action=query&meta=siteinfo&siprop=languages&format=jsonfm
 532+ */
 533+mw.languages = {
 534+ "aa" : "Qaf\u00e1r af",
 535+ "ab" : "\u0410\u04a7\u0441\u0443\u0430",
 536+ "ace" : "Ac\u00e8h",
 537+ "af" : "Afrikaans",
 538+ "ak" : "Akan",
 539+ "aln" : "Geg\u00eb",
 540+ "als" : "Alemannisch",
 541+ "am" : "\u12a0\u121b\u122d\u129b",
 542+ "an" : "Aragon\u00e9s",
 543+ "ang" : "Anglo-Saxon",
 544+ "ar" : "\u0627\u0644\u0639\u0631\u0628\u064a\u0629",
 545+ "arc" : "\u0710\u072a\u0721\u071d\u0710",
 546+ "arn" : "Mapudungun",
 547+ "arz" : "\u0645\u0635\u0631\u0649",
 548+ "as" : "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be",
 549+ "ast" : "Asturianu",
 550+ "av" : "\u0410\u0432\u0430\u0440",
 551+ "avk" : "Kotava",
 552+ "ay" : "Aymar aru",
 553+ "az" : "Az\u0259rbaycan",
 554+ "ba" : "\u0411\u0430\u0448\u04a1\u043e\u0440\u0442",
 555+ "bar" : "Boarisch",
 556+ "bat-smg" : "\u017demait\u0117\u0161ka",
 557+ "bcc" : "\u0628\u0644\u0648\u0686\u06cc \u0645\u06a9\u0631\u0627\u0646\u06cc",
 558+ "bcl" : "Bikol Central",
 559+ "be" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f",
 560+ "be-tarask" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
 561+ "be-x-old" : "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)",
 562+ "bg" : "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438",
 563+ "bh" : "\u092d\u094b\u091c\u092a\u0941\u0930\u0940",
 564+ "bi" : "Bislama",
 565+ "bm" : "Bamanankan",
 566+ "bn" : "\u09ac\u09be\u0982\u09b2\u09be",
 567+ "bo" : "\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42",
 568+ "bpy" : "\u0987\u09ae\u09be\u09b0 \u09a0\u09be\u09b0\/\u09ac\u09bf\u09b7\u09cd\u09a3\u09c1\u09aa\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0",
 569+ "bqi" : "\u0628\u062e\u062a\u064a\u0627\u0631\u064a",
 570+ "br" : "Brezhoneg",
 571+ "bs" : "Bosanski",
 572+ "bug" : "\u1a05\u1a14 \u1a15\u1a18\u1a01\u1a17",
 573+ "bxr" : "\u0411\u0443\u0440\u044f\u0430\u0434",
 574+ "ca" : "Catal\u00e0",
 575+ "cbk-zam" : "Chavacano de Zamboanga",
 576+ "cdo" : "M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304",
 577+ "ce" : "\u041d\u043e\u0445\u0447\u0438\u0439\u043d",
 578+ "ceb" : "Cebuano",
 579+ "ch" : "Chamoru",
 580+ "cho" : "Choctaw",
 581+ "chr" : "\u13e3\u13b3\u13a9",
 582+ "chy" : "Tsets\u00eahest\u00e2hese",
 583+ "ckb" : "Soran\u00ee \/ \u06a9\u0648\u0631\u062f\u06cc",
 584+ "ckb-latn" : "\u202aSoran\u00ee (lat\u00een\u00ee)\u202c",
 585+ "ckb-arab" : "\u202b\u06a9\u0648\u0631\u062f\u06cc (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
 586+ "co" : "Corsu",
 587+ "cr" : "N\u0113hiyaw\u0113win \/ \u14c0\u1426\u1403\u152d\u140d\u140f\u1423",
 588+ "crh" : "Q\u0131r\u0131mtatarca",
 589+ "crh-latn" : "\u202aQ\u0131r\u0131mtatarca (Latin)\u202c",
 590+ "crh-cyrl" : "\u202a\u041a\u044a\u044b\u0440\u044b\u043c\u0442\u0430\u0442\u0430\u0440\u0434\u0436\u0430 (\u041a\u0438\u0440\u0438\u043b\u043b)\u202c",
 591+ "cs" : "\u010cesky",
 592+ "csb" : "Kasz\u00ebbsczi",
 593+ "cu" : "\u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f",
 594+ "cv" : "\u0427\u04d1\u0432\u0430\u0448\u043b\u0430",
 595+ "cy" : "Cymraeg",
 596+ "da" : "Dansk",
 597+ "de" : "Deutsch",
 598+ "de-at" : "\u00d6sterreichisches Deutsch",
 599+ "de-ch" : "Schweizer Hochdeutsch",
 600+ "de-formal" : "Deutsch (Sie-Form)",
 601+ "diq" : "Zazaki",
 602+ "dk" : "Dansk (deprecated:da)",
 603+ "dsb" : "Dolnoserbski",
 604+ "dv" : "\u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0",
 605+ "dz" : "\u0f47\u0f7c\u0f44\u0f0b\u0f41",
 606+ "ee" : "E\u028begbe",
 607+ "el" : "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac",
 608+ "eml" : "Emili\u00e0n e rumagn\u00f2l",
 609+ "en" : "English",
 610+ "en-gb" : "British English",
 611+ "eo" : "Esperanto",
 612+ "es" : "Espa\u00f1ol",
 613+ "et" : "Eesti",
 614+ "eu" : "Euskara",
 615+ "ext" : "Estreme\u00f1u",
 616+ "fa" : "\u0641\u0627\u0631\u0633\u06cc",
 617+ "ff" : "Fulfulde",
 618+ "fi" : "Suomi",
 619+ "fiu-vro" : "V\u00f5ro",
 620+ "fj" : "Na Vosa Vakaviti",
 621+ "fo" : "F\u00f8royskt",
 622+ "fr" : "Fran\u00e7ais",
 623+ "frc" : "Fran\u00e7ais cadien",
 624+ "frp" : "Arpetan",
 625+ "fur" : "Furlan",
 626+ "fy" : "Frysk",
 627+ "ga" : "Gaeilge",
 628+ "gag" : "Gagauz",
 629+ "gan" : "\u8d1b\u8a9e",
 630+ "gan-hans" : "\u8d63\u8bed(\u7b80\u4f53)",
 631+ "gan-hant" : "\u8d1b\u8a9e(\u7e41\u9ad4)",
 632+ "gd" : "G\u00e0idhlig",
 633+ "gl" : "Galego",
 634+ "glk" : "\u06af\u06cc\u0644\u06a9\u06cc",
 635+ "gn" : "Ava\u00f1e'\u1ebd",
 636+ "got" : "\ud800\udf32\ud800\udf3f\ud800\udf44\ud800\udf39\ud800\udf43\ud800\udf3a",
 637+ "grc" : "\u1f08\u03c1\u03c7\u03b1\u03af\u03b1 \u1f11\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u1f74",
 638+ "gsw" : "Alemannisch",
 639+ "gu" : "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0",
 640+ "gv" : "Gaelg",
 641+ "ha" : "\u0647\u064e\u0648\u064f\u0633\u064e",
 642+ "hak" : "Hak-k\u00e2-fa",
 643+ "haw" : "Hawai`i",
 644+ "he" : "\u05e2\u05d1\u05e8\u05d9\u05ea",
 645+ "hi" : "\u0939\u093f\u0928\u094d\u0926\u0940",
 646+ "hif" : "Fiji Hindi",
 647+ "hif-deva" : "\u092b\u093c\u0940\u091c\u0940 \u0939\u093f\u0928\u094d\u0926\u0940",
 648+ "hif-latn" : "Fiji Hindi",
 649+ "hil" : "Ilonggo",
 650+ "ho" : "Hiri Motu",
 651+ "hr" : "Hrvatski",
 652+ "hsb" : "Hornjoserbsce",
 653+ "ht" : "Krey\u00f2l ayisyen",
 654+ "hu" : "Magyar",
 655+ "hy" : "\u0540\u0561\u0575\u0565\u0580\u0565\u0576",
 656+ "hz" : "Otsiherero",
 657+ "ia" : "Interlingua",
 658+ "id" : "Bahasa Indonesia",
 659+ "ie" : "Interlingue",
 660+ "ig" : "Igbo",
 661+ "ii" : "\ua187\ua259",
 662+ "ik" : "I\u00f1upiak",
 663+ "ike-cans" : "\u1403\u14c4\u1483\u144e\u1450\u1466",
 664+ "ike-latn" : "inuktitut",
 665+ "ilo" : "Ilokano",
 666+ "inh" : "\u0413\u0406\u0430\u043b\u0433\u0406\u0430\u0439 \u011eal\u011faj",
 667+ "io" : "Ido",
 668+ "is" : "\u00cdslenska",
 669+ "it" : "Italiano",
 670+ "iu" : "\u1403\u14c4\u1483\u144e\u1450\u1466\/inuktitut",
 671+ "ja" : "\u65e5\u672c\u8a9e",
 672+ "jbo" : "Lojban",
 673+ "jut" : "Jysk",
 674+ "jv" : "Basa Jawa",
 675+ "ka" : "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8",
 676+ "kaa" : "Qaraqalpaqsha",
 677+ "kab" : "Taqbaylit",
 678+ "kg" : "Kongo",
 679+ "ki" : "G\u0129k\u0169y\u0169",
 680+ "kiu" : "Kurmanc\u00ee",
 681+ "kj" : "Kwanyama",
 682+ "kk" : "\u049a\u0430\u0437\u0430\u049b\u0448\u0430",
 683+ "kk-arab" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062a\u0674\u0648\u062a\u06d5)\u202c",
 684+ "kk-cyrl" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u043a\u0438\u0440\u0438\u043b)\u202c",
 685+ "kk-latn" : "\u202aQazaq\u015fa (lat\u0131n)\u202c",
 686+ "kk-cn" : "\u202b\u0642\u0627\u0632\u0627\u0642\u0634\u0627 (\u062c\u06c7\u0646\u06af\u0648)\u202c",
 687+ "kk-kz" : "\u202a\u049a\u0430\u0437\u0430\u049b\u0448\u0430 (\u049a\u0430\u0437\u0430\u049b\u0441\u0442\u0430\u043d)\u202c",
 688+ "kk-tr" : "\u202aQazaq\u015fa (T\u00fcrk\u00efya)\u202c",
 689+ "kl" : "Kalaallisut",
 690+ "km" : "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a",
 691+ "kn" : "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1",
 692+ "ko" : "\ud55c\uad6d\uc5b4",
 693+ "ko-kp" : "\ud55c\uad6d\uc5b4 (\uc870\uc120)",
 694+ "kr" : "Kanuri",
 695+ "kri" : "Krio",
 696+ "krj" : "Kinaray-a",
 697+ "ks" : "\u0915\u0936\u094d\u092e\u0940\u0930\u0940 - (\u0643\u0634\u0645\u064a\u0631\u064a)",
 698+ "ksh" : "Ripoarisch",
 699+ "ku" : "Kurd\u00ee \/ \u0643\u0648\u0631\u062f\u06cc",
 700+ "ku-latn" : "\u202aKurd\u00ee (lat\u00een\u00ee)\u202c",
 701+ "ku-arab" : "\u202b\u0643\u0648\u0631\u062f\u064a (\u0639\u06d5\u0631\u06d5\u0628\u06cc)\u202c",
 702+ "kv" : "\u041a\u043e\u043c\u0438",
 703+ "kw" : "Kernowek",
 704+ "ky" : "\u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430",
 705+ "la" : "Latina",
 706+ "lad" : "Ladino",
 707+ "lb" : "L\u00ebtzebuergesch",
 708+ "lbe" : "\u041b\u0430\u043a\u043a\u0443",
 709+ "lez" : "\u041b\u0435\u0437\u0433\u0438",
 710+ "lfn" : "Lingua Franca Nova",
 711+ "lg" : "Luganda",
 712+ "li" : "Limburgs",
 713+ "lij" : "L\u00edguru",
 714+ "lmo" : "Lumbaart",
 715+ "ln" : "Ling\u00e1la",
 716+ "lo" : "\u0ea5\u0eb2\u0ea7",
 717+ "loz" : "Silozi",
 718+ "lt" : "Lietuvi\u0173",
 719+ "lv" : "Latvie\u0161u",
 720+ "lzh" : "\u6587\u8a00",
 721+ "mai" : "\u092e\u0948\u0925\u093f\u0932\u0940",
 722+ "map-bms" : "Basa Banyumasan",
 723+ "mdf" : "\u041c\u043e\u043a\u0448\u0435\u043d\u044c",
 724+ "mg" : "Malagasy",
 725+ "mh" : "Ebon",
 726+ "mhr" : "\u041e\u043b\u044b\u043a \u041c\u0430\u0440\u0438\u0439",
 727+ "mi" : "M\u0101ori",
 728+ "mk" : "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438",
 729+ "ml" : "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02",
 730+ "mn" : "\u041c\u043e\u043d\u0433\u043e\u043b",
 731+ "mo" : "\u041c\u043e\u043b\u0434\u043e\u0432\u0435\u043d\u044f\u0441\u043a\u044d",
 732+ "mr" : "\u092e\u0930\u093e\u0920\u0940",
 733+ "ms" : "Bahasa Melayu",
 734+ "mt" : "Malti",
 735+ "mus" : "Mvskoke",
 736+ "mwl" : "Mirand\u00e9s",
 737+ "my" : "\u1019\u103c\u1014\u103a\u1019\u102c\u1018\u102c\u101e\u102c",
 738+ "myv" : "\u042d\u0440\u0437\u044f\u043d\u044c",
 739+ "mzn" : "\u0645\u064e\u0632\u0650\u0631\u0648\u0646\u064a",
 740+ "na" : "Dorerin Naoero",
 741+ "nah" : "N\u0101huatl",
 742+ "nan" : "B\u00e2n-l\u00e2m-g\u00fa",
 743+ "nap" : "Nnapulitano",
 744+ "nb" : "\u202aNorsk (bokm\u00e5l)\u202c",
 745+ "nds" : "Plattd\u00fc\u00fctsch",
 746+ "nds-nl" : "Nedersaksisch",
 747+ "ne" : "\u0928\u0947\u092a\u093e\u0932\u0940",
 748+ "new" : "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e",
 749+ "ng" : "Oshiwambo",
 750+ "niu" : "Niu\u0113",
 751+ "nl" : "Nederlands",
 752+ "nn" : "\u202aNorsk (nynorsk)\u202c",
 753+ "no" : "\u202aNorsk (bokm\u00e5l)\u202c",
 754+ "nov" : "Novial",
 755+ "nrm" : "Nouormand",
 756+ "nso" : "Sesotho sa Leboa",
 757+ "nv" : "Din\u00e9 bizaad",
 758+ "ny" : "Chi-Chewa",
 759+ "oc" : "Occitan",
 760+ "om" : "Oromoo",
 761+ "or" : "\u0b13\u0b21\u0b3c\u0b3f\u0b06",
 762+ "os" : "\u0418\u0440\u043e\u043d\u0430\u0443",
 763+ "pa" : "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40",
 764+ "pag" : "Pangasinan",
 765+ "pam" : "Kapampangan",
 766+ "pap" : "Papiamentu",
 767+ "pcd" : "Picard",
 768+ "pdc" : "Deitsch",
 769+ "pdt" : "Plautdietsch",
 770+ "pfl" : "Pf\u00e4lzisch",
 771+ "pi" : "\u092a\u093e\u093f\u0934",
 772+ "pih" : "Norfuk \/ Pitkern",
 773+ "pl" : "Polski",
 774+ "pms" : "Piemont\u00e8is",
 775+ "pnb" : "\u067e\u0646\u062c\u0627\u0628\u06cc",
 776+ "pnt" : "\u03a0\u03bf\u03bd\u03c4\u03b9\u03b1\u03ba\u03ac",
 777+ "ps" : "\u067e\u069a\u062a\u0648",
 778+ "pt" : "Portugu\u00eas",
 779+ "pt-br" : "Portugu\u00eas do Brasil",
 780+ "qu" : "Runa Simi",
 781+ "rif" : "Tarifit",
 782+ "rm" : "Rumantsch",
 783+ "rmy" : "Romani",
 784+ "rn" : "Kirundi",
 785+ "ro" : "Rom\u00e2n\u0103",
 786+ "roa-rup" : "Arm\u00e3neashce",
 787+ "roa-tara" : "Tarand\u00edne",
 788+ "ru" : "\u0420\u0443\u0441\u0441\u043a\u0438\u0439",
 789+ "ruq" : "Vl\u0103he\u015fte",
 790+ "ruq-cyrl" : "\u0412\u043b\u0430\u0445\u0435\u0441\u0442\u0435",
 791+ "ruq-latn" : "Vl\u0103he\u015fte",
 792+ "rw" : "Kinyarwanda",
 793+ "sa" : "\u0938\u0902\u0938\u094d\u0915\u0943\u0924",
 794+ "sah" : "\u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430",
 795+ "sc" : "Sardu",
 796+ "scn" : "Sicilianu",
 797+ "sco" : "Scots",
 798+ "sd" : "\u0633\u0646\u068c\u064a",
 799+ "sdc" : "Sassaresu",
 800+ "se" : "S\u00e1megiella",
 801+ "sei" : "Cmique Itom",
 802+ "sg" : "S\u00e4ng\u00f6",
 803+ "sh" : "Srpskohrvatski \/ \u0421\u0440\u043f\u0441\u043a\u043e\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438",
 804+ "shi" : "Ta\u0161l\u1e25iyt",
 805+ "si" : "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd",
 806+ "simple" : "Simple English",
 807+ "sk" : "Sloven\u010dina",
 808+ "sl" : "Sloven\u0161\u010dina",
 809+ "sli" : "Schl\u00e4sch",
 810+ "sm" : "Gagana Samoa",
 811+ "sma" : "\u00c5arjelsaemien",
 812+ "sn" : "chiShona",
 813+ "so" : "Soomaaliga",
 814+ "sq" : "Shqip",
 815+ "sr" : "\u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski",
 816+ "sr-ec" : "\u0421\u0440\u043f\u0441\u043a\u0438 (\u045b\u0438\u0440\u0438\u043b\u0438\u0446\u0430)",
 817+ "sr-el" : "Srpski (latinica)",
 818+ "srn" : "Sranantongo",
 819+ "ss" : "SiSwati",
 820+ "st" : "Sesotho",
 821+ "stq" : "Seeltersk",
 822+ "su" : "Basa Sunda",
 823+ "sv" : "Svenska",
 824+ "sw" : "Kiswahili",
 825+ "szl" : "\u015al\u016fnski",
 826+ "ta" : "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd",
 827+ "tcy" : "\u0ca4\u0cc1\u0cb3\u0cc1",
 828+ "te" : "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41",
 829+ "tet" : "Tetun",
 830+ "tg" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
 831+ "tg-cyrl" : "\u0422\u043e\u04b7\u0438\u043a\u04e3",
 832+ "tg-latn" : "tojik\u012b",
 833+ "th" : "\u0e44\u0e17\u0e22",
 834+ "ti" : "\u1275\u130d\u122d\u129b",
 835+ "tk" : "T\u00fcrkmen\u00e7e",
 836+ "tl" : "Tagalog",
 837+ "tn" : "Setswana",
 838+ "to" : "lea faka-Tonga",
 839+ "tokipona" : "Toki Pona",
 840+ "tp" : "Toki Pona (deprecated:tokipona)",
 841+ "tpi" : "Tok Pisin",
 842+ "tr" : "T\u00fcrk\u00e7e",
 843+ "ts" : "Xitsonga",
 844+ "tt" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a",
 845+ "tt-cyrl" : "\u0422\u0430\u0442\u0430\u0440\u0447\u0430",
 846+ "tt-latn" : "Tatar\u00e7a",
 847+ "tum" : "chiTumbuka",
 848+ "tw" : "Twi",
 849+ "ty" : "Reo M\u0101`ohi",
 850+ "tyv" : "\u0422\u044b\u0432\u0430 \u0434\u044b\u043b",
 851+ "udm" : "\u0423\u0434\u043c\u0443\u0440\u0442",
 852+ "ug" : "Uyghurche\u200e \/ \u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
 853+ "ug-arab" : "\u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5",
 854+ "ug-latn" : "Uyghurche\u200e",
 855+ "uk" : "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430",
 856+ "ur" : "\u0627\u0631\u062f\u0648",
 857+ "uz" : "O'zbek",
 858+ "ve" : "Tshivenda",
 859+ "vec" : "V\u00e8neto",
 860+ "vep" : "Vepsan kel'",
 861+ "vi" : "Ti\u1ebfng Vi\u1ec7t",
 862+ "vls" : "West-Vlams",
 863+ "vo" : "Volap\u00fck",
 864+ "vro" : "V\u00f5ro",
 865+ "wa" : "Walon",
 866+ "war" : "Winaray",
 867+ "wo" : "Wolof",
 868+ "wuu" : "\u5434\u8bed",
 869+ "xal" : "\u0425\u0430\u043b\u044c\u043c\u0433",
 870+ "xh" : "isiXhosa",
 871+ "xmf" : "\u10db\u10d0\u10e0\u10d2\u10d0\u10da\u10e3\u10e0\u10d8",
 872+ "yi" : "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9",
 873+ "yo" : "Yor\u00f9b\u00e1",
 874+ "yue" : "\u7cb5\u8a9e",
 875+ "za" : "Vahcuengh",
 876+ "zea" : "Ze\u00eauws",
 877+ "zh" : "\u4e2d\u6587",
 878+ "zh-classical" : "\u6587\u8a00",
 879+ "zh-cn" : "\u202a\u4e2d\u6587(\u4e2d\u56fd\u5927\u9646)\u202c",
 880+ "zh-hans" : "\u202a\u4e2d\u6587(\u7b80\u4f53)\u202c",
 881+ "zh-hant" : "\u202a\u4e2d\u6587(\u7e41\u9ad4)\u202c",
 882+ "zh-hk" : "\u202a\u4e2d\u6587(\u9999\u6e2f)\u202c",
 883+ "zh-min-nan" : "B\u00e2n-l\u00e2m-g\u00fa",
 884+ "zh-mo" : "\u202a\u4e2d\u6587(\u6fb3\u9580)\u202c",
 885+ "zh-my" : "\u202a\u4e2d\u6587(\u9a6c\u6765\u897f\u4e9a)\u202c",
 886+ "zh-sg" : "\u202a\u4e2d\u6587(\u65b0\u52a0\u5761)\u202c",
 887+ "zh-tw" : "\u202a\u4e2d\u6587(\u53f0\u7063)\u202c",
 888+ "zh-yue" : "\u7cb5\u8a9e",
 889+ "zu" : "isiZulu"
 890+}
\ No newline at end of file
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.css
@@ -36,7 +36,7 @@
3737 .fg-menu-footer { margin-top: .4em;
3838 padding: .4em;
3939 position:absolute;
40 -bottom:0px;
 40+bottom:2px;
4141 width: 170px;
4242 }
4343 .fg-menu-header { margin-bottom: .4em; padding: .4em; }
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.js
@@ -91,7 +91,8 @@
9292 backLinkText: 'Back',
9393 flyOut: false, // multi-level menus are ipod-style by default; this parameter overrides to make a flyout instead
9494 flyOutOnState: 'ui-state-default',
95 - nextMenuLink: 'ui-icon-triangle-1-e', // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
 95+ // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
 96+ nextMenuLink: 'ui-icon-triangle-1-e',
9697 topLinkText: 'All',
9798 nextCrumbLink: 'ui-icon-carat-1-e'
9899 }, options);
@@ -290,24 +291,27 @@
291292
292293 allSubLists.css({ left: linkWidth, width: linkWidth }).hide();
293294
294 - $(this).find('a:eq(0)').addClass('fg-menu-indicator').html('<span>' + $(this).find('a:eq(0)').text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>').hover(
295 - function(){
296 - clearTimeout(hideTimer);
297 - var subList = $(this).next();
298 - if (!fitVertical(subList, $(this).offset().top)) { subList.css({ top: 'auto', bottom: 0 }); };
299 - if (!fitHorizontal(subList, $(this).offset().left + 100)) { subList.css({ left: 'auto', right: linkWidth, 'z-index': 999 }); };
300 - showTimer = setTimeout(function(){
301 - subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded', 'true');
302 - }, 300);
303 - },
304 - function(){
305 - clearTimeout(showTimer);
306 - var subList = $(this).next();
307 - hideTimer = setTimeout(function(){
308 - subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded', 'false');
309 - }, 400);
310 - }
311 - );
 295+ $(this).find('a:eq(0)').addClass('fg-menu-indicator').html(
 296+ '<span>' + $(this).find('a:eq(0)').html() +
 297+ '</span><span class="ui-icon '+options.nextMenuLink+'"></span>')
 298+ .hover(
 299+ function(){
 300+ clearTimeout(hideTimer);
 301+ var subList = $(this).next();
 302+ if (!fitVertical(subList, $(this).offset().top)) { subList.css({ top: 'auto', bottom: 0 }); };
 303+ if (!fitHorizontal(subList, $(this).offset().left + 100)) { subList.css({ left: 'auto', right: linkWidth, 'z-index': 999 }); };
 304+ showTimer = setTimeout(function(){
 305+ subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded', 'true');
 306+ }, 300);
 307+ },
 308+ function(){
 309+ clearTimeout(showTimer);
 310+ var subList = $(this).next();
 311+ hideTimer = setTimeout(function(){
 312+ subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded', 'false');
 313+ }, 400);
 314+ }
 315+ );
312316
313317 $(this).find('ul a').hover(
314318 function(){
@@ -351,7 +355,7 @@
352356
353357 var checkMenuHeight = function(el){
354358 if (el.height() > options.maxHeight) { el.addClass('fg-menu-scroll') };
355 - el.css({ height: options.maxHeight });
 359+ el.css({ height: options.maxHeight-26 });
356360 };
357361
358362 var resetChildMenu = function(el){ el.removeClass('fg-menu-scroll').removeClass('fg-menu-current').height('auto'); };
@@ -385,7 +389,7 @@
386390 if ($(this).next().is('ul')) {
387391 $(this)
388392 .addClass('fg-menu-indicator')
389 - .each(function(){ $(this).html('<span>' + $(this).text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>'); })
 393+ .each(function(){ $(this).html('<span>' + $(this).html() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>'); })
390394 .click(function(){ // ----- show the next menu
391395 var nextList = $(this).next();
392396 var parentUl = $(this).parents('ul:eq(0)');

Status & tagging log