Index: branches/js2-work/phase3/js2/mwEmbed/example_usage/Multi_Upload.html |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | <script type="text/javascript" src="../mwEmbed.js"></script> |
8 | 8 | </head> |
9 | 9 | <script type="text/javascript"> |
10 | | -mwAddOnloadHook(function(){ |
| 10 | +mw.addOnloadHook(function(){ |
11 | 11 | //bind the upload drag and drop |
12 | 12 | |
13 | 13 | //bind the multiple Files |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js |
— | — | @@ -1199,7 +1199,10 @@ |
1200 | 1200 | // Set customAttributes if unset: |
1201 | 1201 | if ( !customAttributes ) |
1202 | 1202 | customAttributes = { }; |
1203 | | - |
| 1203 | + |
| 1204 | + //Add a hook system to the embedPlayer |
| 1205 | + mw.addHookSystem( _this ); |
| 1206 | + |
1204 | 1207 | // Setup the player Interface from supported attributes: |
1205 | 1208 | for ( var attr in default_video_attributes ) { |
1206 | 1209 | if ( customAttributes[ attr ] ){ |
— | — | @@ -1253,7 +1256,7 @@ |
1254 | 1257 | } |
1255 | 1258 | |
1256 | 1259 | // Add the mediaElement object with the elements sources: |
1257 | | - this.mediaElement = new mediaElement( element ); |
| 1260 | + this.mediaElement = new mediaElement( element ); |
1258 | 1261 | |
1259 | 1262 | // Setup the local "ROE" src pointer if added as media source |
1260 | 1263 | // also see: http://dev.w3.org/html5/spec/Overview.html#the-source-element |
— | — | @@ -1264,12 +1267,12 @@ |
1265 | 1268 | _this.roe = source.src; |
1266 | 1269 | } |
1267 | 1270 | } |
1268 | | - }); |
1269 | | - |
1270 | | - |
1271 | | - // Load player skin css: |
| 1271 | + } ); |
| 1272 | + |
| 1273 | + // Make sure we have the player skin css: |
1272 | 1274 | mw.getStyleSheet( mw.getMwEmbedPath() + 'skins/' + this.skin_name + '/playerSkin.css' ); |
1273 | 1275 | }, |
| 1276 | + |
1274 | 1277 | |
1275 | 1278 | /** |
1276 | 1279 | * Set the width & height from css style attribute, element attribute, or by default value |
— | — | @@ -1286,8 +1289,9 @@ |
1287 | 1290 | if( ! this['height'] && ! this['width'] ){ |
1288 | 1291 | this['height'] = parseInt( $j(element).attr( 'height' ) ); |
1289 | 1292 | this['width'] = parseInt( $j(element).attr( 'width' ) ); |
1290 | | - } |
| 1293 | + } |
1291 | 1294 | |
| 1295 | + |
1292 | 1296 | // Deal with just one height or width being set: |
1293 | 1297 | if( this['height'] && !this['width'] && this.videoAspect ){ |
1294 | 1298 | var aspect = this.videoAspect.split( ':' ); |
— | — | @@ -1302,7 +1306,12 @@ |
1303 | 1307 | // On load sometimes attr is temporally -1 as we don't have video metadata yet. |
1304 | 1308 | // NOTE: this edge case should be handled by waiting for metadata see: "waitForMeta" in addElement |
1305 | 1309 | if( ( !this['height'] || !this['width'] ) || |
1306 | | - ( this['height'] == -1 || this['width'] == -1 ) ){ |
| 1310 | + ( this['height'] == -1 || this['width'] == -1 ) || |
| 1311 | + // Check for firefox defaults |
| 1312 | + // Note: ideally firefox would not do random guesses at css values |
| 1313 | + ( (this.height == 150 || this.height == 64 ) && this.width == 300 ) |
| 1314 | + ){ |
| 1315 | + |
1307 | 1316 | var defaultSize = mw.getConfig( 'video_size' ).split( 'x' ); |
1308 | 1317 | this['width'] = defaultSize[0]; |
1309 | 1318 | // Special height default for audio tag ( if not set ) |
— | — | @@ -2322,8 +2331,9 @@ |
2323 | 2332 | 'z-index' : 10, |
2324 | 2333 | 'top' : ( loc.top + playerHeight + 4) + 'px', |
2325 | 2334 | 'left' : ( parseInt( loc.left ) + parseInt( _this.width ) - 200) + 'px', |
2326 | | - 'height' : '200px', |
2327 | | - 'width' : '200px' |
| 2335 | + 'height' : '180px', |
| 2336 | + 'width' : '180px', |
| 2337 | + 'font-size' : '12px' |
2328 | 2338 | } ).hide() |
2329 | 2339 | ); |
2330 | 2340 | } |
— | — | @@ -2343,8 +2353,8 @@ |
2344 | 2354 | } |
2345 | 2355 | |
2346 | 2356 | mw.load( timedTextRequestSet, function(){ |
2347 | | - $j( _this ).timedText( { |
2348 | | - 'menu_target': '#timedTextMenu_' + this.id |
| 2357 | + $j( '#' + _this.id ).timedText( { |
| 2358 | + 'targetContainer': '#timedTextMenu_' + _this.id |
2349 | 2359 | } ); |
2350 | 2360 | }); |
2351 | 2361 | |
— | — | @@ -2817,6 +2827,7 @@ |
2818 | 2828 | }, 250 ); |
2819 | 2829 | } |
2820 | 2830 | } |
| 2831 | + this.runHook( 'monitor' ); |
2821 | 2832 | }, |
2822 | 2833 | |
2823 | 2834 | /** |
Index: branches/js2-work/phase3/js2/mwEmbed/mwEmbed.js |
— | — | @@ -708,7 +708,57 @@ |
709 | 709 | for ( var i in magicSet ) |
710 | 710 | pMagicSet[ i ] = magicSet[i]; |
711 | 711 | } |
| 712 | + |
712 | 713 | /** |
| 714 | + * Add a hook system for a target object / interface |
| 715 | + * |
| 716 | + * This can be used as an alternative to heavy inheritance systems. |
| 717 | + * |
| 718 | + * @param {Object} targetObj Interface Object to add hook system to. |
| 719 | + */ |
| 720 | + $.addHookSystem = function( targetObj ){ |
| 721 | + |
| 722 | + // Setup the target object hook holder: |
| 723 | + targetObj[ 'hooks' ] = { }; |
| 724 | + |
| 725 | + /** |
| 726 | + * Adds a hook to the target object |
| 727 | + * |
| 728 | + * Should be called by clients to setup named hooks |
| 729 | + * |
| 730 | + * @param {String} hookName Name of hook to be added |
| 731 | + * @param {Function} hookFunction Function to be called at hook time |
| 732 | + */ |
| 733 | + targetObj.addHook = function( hookName, hookFunction ){ |
| 734 | + if( ! this.hooks[ hookName ] ) |
| 735 | + this.hooks[ hookName ] = [ ]; |
| 736 | + this.hooks[ hookName ].push( hookFunction ) |
| 737 | + } |
| 738 | + |
| 739 | + /** |
| 740 | + * Runs all the hooks by a given name with refrence to the host object |
| 741 | + * |
| 742 | + * Should be called by the host object at named execution points |
| 743 | + * |
| 744 | + * @param {String} hookName Name of hook to be called |
| 745 | + * @return Value of hook result |
| 746 | + * true interface should continue function execution |
| 747 | + * false interface should stop or return from method |
| 748 | + */ |
| 749 | + targetObj.runHook = function( hookName ){ |
| 750 | + if( this.hooks[ hookName ] ){ |
| 751 | + for( var i in this.hooks[ hookName ]){ |
| 752 | + if( typeof( this.hooks[ hookName ][ i ] ) == 'function'){ |
| 753 | + return this.hooks[ hookName ][ i ]( this ); |
| 754 | + } |
| 755 | + } |
| 756 | + } |
| 757 | + } |
| 758 | + } |
| 759 | + |
| 760 | + |
| 761 | + |
| 762 | + /** |
713 | 763 | * The loader prototype: |
714 | 764 | */ |
715 | 765 | $.loader = { |
— | — | @@ -805,7 +855,7 @@ |
806 | 856 | } |
807 | 857 | |
808 | 858 | //possible error? |
809 | | - mw.log( "Error could not handle load request" ); |
| 859 | + mw.log( "Error could not handle load request: " + loadRequest ); |
810 | 860 | }, |
811 | 861 | |
812 | 862 | |
— | — | @@ -974,7 +1024,7 @@ |
975 | 1025 | |
976 | 1026 | // Check for any associated style sheets that should be loaded |
977 | 1027 | if( typeof this.stylePaths[ className ] != 'undefined' ){ |
978 | | - $.getStyleSheet( this.stylePaths[ className ] ); |
| 1028 | + $.getStyleSheet( mw.getMwEmbedPath() + this.stylePaths[ className ] ); |
979 | 1029 | } |
980 | 1030 | |
981 | 1031 | // Include class defined check for older browsers |
— | — | @@ -2091,7 +2141,8 @@ |
2092 | 2142 | // Add style sheet dependencies |
2093 | 2143 | mw.addClassStyleSheets( { |
2094 | 2144 | "kskinConfig" : "skins/kskin/playerSkin.css", |
2095 | | - "mvpcfConfig" : "skins/mvpcf/playerSkin.css" |
| 2145 | + "mvpcfConfig" : "skins/mvpcf/playerSkin.css", |
| 2146 | + "$j.menu" : "libTimedText/jQuery.menu.css" |
2096 | 2147 | } ); |
2097 | 2148 | |
2098 | 2149 | // Add the module loader function: |
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/mw.timedText.js |
— | — | @@ -1,18 +1,29 @@ |
2 | 2 | /* |
3 | 3 | * The Core timed Text interface object |
4 | 4 | * |
5 | | - * handles class mapings for: |
6 | | - * menu display ( jquery.ui themable ) |
| 5 | + * handles class mappings for: |
| 6 | + * menu display ( jquery.ui themeable ) |
7 | 7 | * timed text loading request |
8 | 8 | * timed text edit requests |
9 | 9 | * timed text search & seek interface ( version 2 ) |
10 | 10 | */ |
11 | 11 | |
| 12 | +mw.addMessages( { |
| 13 | + "mwe-back-btn" : "Back", |
| 14 | + "mwe-chose-text" : "Chose text", |
| 15 | + "mwe-layout" : "Layout", |
| 16 | + "mwe-ontop-video" : "Ontop of video", |
| 17 | + "mwe-bellow-video": "Bellow video", |
| 18 | + "mwe-video-off" : "Hide subtitles" |
| 19 | + |
| 20 | +} ); |
| 21 | + |
12 | 22 | // Bind to mw (for uncluttered global namespace) |
13 | 23 | ( function( $ ) { |
14 | 24 | $.timedText = function ( embedPlayer, options ){ |
15 | 25 | return new TimedText( embedPlayer, options ); |
16 | 26 | } |
| 27 | + |
17 | 28 | /** |
18 | 29 | * Timed Text Object |
19 | 30 | * @param embedPlayer Host player for timedText interfaces |
— | — | @@ -21,6 +32,21 @@ |
22 | 33 | return this.init( embedPlayer, options); |
23 | 34 | } |
24 | 35 | TimedText.prototype = { |
| 36 | + |
| 37 | + /** |
| 38 | + * Prefrences config order is: |
| 39 | + * 1) user cookie |
| 40 | + * 2) media default or layout tags |
| 41 | + * 3) defaults provided in the config var: |
| 42 | + */ |
| 43 | + config : { |
| 44 | + // Layout for basic "timedText" type can be 'ontop', 'off', 'below' |
| 45 | + 'layout': 'below' |
| 46 | + }, |
| 47 | + |
| 48 | + /** |
| 49 | + * Set of timedText providers |
| 50 | + */ |
25 | 51 | timedTextProvider:{ |
26 | 52 | 'commons':{ |
27 | 53 | 'api_url': mw.commons_api_url |
— | — | @@ -33,19 +59,147 @@ |
34 | 60 | * |
35 | 61 | */ |
36 | 62 | init: function( embedPlayer, options ){ |
37 | | - this.embedPlayer = embedPlayer; |
| 63 | + var _this = this; |
| 64 | + this.embedPlayer = embedPlayer; |
| 65 | + this.options = $j.extend( { |
| 66 | + 'targetContainer' : null |
| 67 | + }, options ) |
| 68 | + |
| 69 | + //Set up embedPlayer monitor hook: |
| 70 | + embedPlayer.addHook( 'monitor', function(){ |
| 71 | + _this.monitor(); |
| 72 | + }) |
| 73 | + |
| 74 | + // Load cookie prefrences |
| 75 | + |
38 | 76 | }, |
39 | 77 | |
40 | 78 | /** |
| 79 | + * Monitor video time and update timed text filed[s] |
| 80 | + */ |
| 81 | + monitor: function(){ |
| 82 | + mw.log(' timedText monitor '); |
| 83 | + }, |
| 84 | + |
| 85 | + /** |
41 | 86 | * Show the timed text menu |
42 | 87 | * @param {Object} jQuery selector to display the target |
43 | 88 | */ |
44 | | - showMenu: function( $target ){ |
| 89 | + showMenu: function( ){ |
| 90 | + var _this = this; |
45 | 91 | mw.log("TimedText:ShowMenu"); |
46 | | - // Get local refrence to all timed text sources |
47 | | - var cat = this.embedPlayer; |
48 | | - var sources = this.embedPlayer.mediaElement.getSources( 'text' ); |
49 | | - debugger; |
| 92 | + |
| 93 | + // Build out menu with bindings ( with jquery calls ) |
| 94 | + var menuOptions = { |
| 95 | + 'content' : this.buildMenu(), |
| 96 | + 'crumbDefaultText' : ' ', |
| 97 | + 'targetContainer' : this.options.targetContainer, |
| 98 | + 'autoShow' : true, |
| 99 | + 'backLinkText' : gM( 'mwe-back-btn' ), |
| 100 | + 'selectItemCallback' : function( item ){ |
| 101 | + _this.selectMenuItem( item ); |
| 102 | + } |
| 103 | + }; |
| 104 | + var $menuButton = $j('#' + this.embedPlayer.id + ' .timed-text'); |
| 105 | + $menuButton.unbind().menu( |
| 106 | + menuOptions |
| 107 | + ); |
| 108 | + |
| 109 | + }, |
| 110 | + |
| 111 | + /** |
| 112 | + * Selection of a meun item |
| 113 | + * |
| 114 | + * @param {Element} item Item selected |
| 115 | + */ |
| 116 | + selectMenuItem: function( item ){ |
| 117 | + mw.log("selectMenuItem: " + $j( item ).attr('class') ); |
| 118 | + }, |
| 119 | + |
| 120 | + /** |
| 121 | + * Builds the core timed Text menu |
| 122 | + * calls a few sub-functions: |
| 123 | + * Basic menu layout: |
| 124 | + * Chose Language |
| 125 | + * All Subtiles here (if we have categories list them ) |
| 126 | + * Layout |
| 127 | + * Bellow video |
| 128 | + * Ontop video ( only available to supported plugins ) |
| 129 | + * [ Search Text ] |
| 130 | + * [ Chapters ] seek to chapter |
| 131 | + * |
| 132 | + */ |
| 133 | + buildMenu: function(){ |
| 134 | + var _this = this; |
| 135 | + //build the source list menu item: |
| 136 | + |
| 137 | + return $j( '<ul>' ).append( |
| 138 | + // Chose language option: |
| 139 | + _this.getLi( 'mwe-chose-text' ).append( |
| 140 | + _this.buildLanguageMenu() |
| 141 | + ), |
| 142 | + // 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 | + ) |
| 149 | + ) |
| 150 | + ); |
| 151 | + }, |
| 152 | + |
| 153 | + /** |
| 154 | + * Utility function to assist in menu build out: |
| 155 | + * Get menu line item (li) html: <li><a> msgKey </a></li> |
| 156 | + * |
| 157 | + * @param {String} msgKey Msg key for menu item |
| 158 | + */ |
| 159 | + getLi: function ( msgKey ){ |
| 160 | + return $j( '<li>' ).append( |
| 161 | + $j('<a>') |
| 162 | + .attr('href', '#') |
| 163 | + .text( |
| 164 | + gM( msgKey ) |
| 165 | + ) |
| 166 | + ); |
| 167 | + }, |
| 168 | + |
| 169 | + /** |
| 170 | + * Builds the language source list menu |
| 171 | + * checks all text sources for category and language key attribute |
| 172 | + */ |
| 173 | + buildLanguageMenu: function(){ |
| 174 | + 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' ); |
| 177 | + |
| 178 | + // See if we have categories to worry about: |
| 179 | + var categoryBuckets = [ ]; |
| 180 | + for( var i in sources ) { |
| 181 | + var source = sources[ i ]; |
| 182 | + if( source.category ){ |
| 183 | + if( ! categoryBuckets[ source.category ] ) |
| 184 | + categoryBuckets[ source.category ] = [ ]; |
| 185 | + categoryBuckets[ source.category ].push( source ) |
| 186 | + } |
| 187 | + } |
| 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 | + ); |
| 201 | + } |
| 202 | + } |
| 203 | + return $langMenu; |
50 | 204 | } |
51 | 205 | |
52 | 206 | } |
— | — | @@ -55,13 +209,21 @@ |
56 | 210 | * jQuery entry point for timedText interface: |
57 | 211 | */ |
58 | 212 | ( function( $ ) { |
59 | | - $.fn.timedText = function ( options ){ |
60 | | - var embedPlayer = $j( this.selector ).get(0); |
61 | | - if( ! embedPlayer.TimedText ) |
62 | | - embedPlayer.TimedText = new mw.timedText( embedPlayer, options); |
63 | | - // else just apply the options action: |
64 | | - |
65 | | - //do the default "showMenu" action: |
66 | | - embedPlayer.TimedText.showMenu(); |
| 213 | + /** |
| 214 | + * jquery timedText binding. |
| 215 | + * Calls mw.timedText on the given selector |
| 216 | + * |
| 217 | + * @param {Object} options Options for the timed text menu |
| 218 | + */ |
| 219 | + $.fn.timedText = function ( options ){ |
| 220 | + $j( this.selector ).each(function(){ |
| 221 | + var embedPlayer = $j(this).get(0); |
| 222 | + // Setup timed text for the given player: |
| 223 | + if( ! embedPlayer.timedText ) |
| 224 | + embedPlayer.timedText = new mw.timedText( embedPlayer, options); |
| 225 | + |
| 226 | + // Run the default "showMenu" action: |
| 227 | + embedPlayer.timedText.showMenu(); |
| 228 | + } ); |
67 | 229 | } |
68 | 230 | } )( jQuery ); |
\ No newline at end of file |
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.css |
— | — | @@ -0,0 +1,119 @@ |
| 2 | +/* Styles for jQuery menu widget |
| 3 | +Author: Maggie Wachs, maggie@filamentgroup.com |
| 4 | +Date: September 2008 |
| 5 | +*/ |
| 6 | + |
| 7 | + |
| 8 | +/* REQUIRED STYLES - the menus will only render correctly with these rules */ |
| 9 | + |
| 10 | +.fg-menu-container { position: absolute; top:0; left:-999px; padding: .4em; overflow: hidden; } |
| 11 | +.fg-menu-container.fg-menu-flyout { overflow: visible; } |
| 12 | + |
| 13 | +.fg-menu, .fg-menu ul { list-style-type:none; padding: 0; margin:0; } |
| 14 | + |
| 15 | +.fg-menu { position:relative; } |
| 16 | +.fg-menu-flyout .fg-menu { position:static; } |
| 17 | + |
| 18 | +.fg-menu ul { position:absolute; top:0; } |
| 19 | +.fg-menu ul ul { top:-1px; } |
| 20 | + |
| 21 | +.fg-menu-container.fg-menu-ipod .fg-menu-content, |
| 22 | +.fg-menu-container.fg-menu-ipod .fg-menu-content ul { background: none !important; } |
| 23 | + |
| 24 | +.fg-menu.fg-menu-scroll, |
| 25 | +.fg-menu ul.fg-menu-scroll { overflow: scroll; overflow-x: hidden; } |
| 26 | + |
| 27 | +.fg-menu li { clear:both; float:left; width:100%; margin: 0; padding:0; border: 0; } |
| 28 | +.fg-menu li li { font-size:1em; } /* inner li font size must be reset so that they don't blow up */ |
| 29 | + |
| 30 | +.fg-menu-flyout ul ul { padding: .4em; } |
| 31 | +.fg-menu-flyout li { position:relative; } |
| 32 | + |
| 33 | +.fg-menu-scroll { overflow: scroll; overflow-x: hidden; } |
| 34 | + |
| 35 | +.fg-menu-breadcrumb { margin: 0; padding: 0; } |
| 36 | + |
| 37 | +.fg-menu-footer { margin-top: .4em; |
| 38 | +padding: .4em; |
| 39 | +position:absolute; |
| 40 | +bottom:0px; |
| 41 | +width: 170px; |
| 42 | +} |
| 43 | +.fg-menu-header { margin-bottom: .4em; padding: .4em; } |
| 44 | + |
| 45 | +.fg-menu-breadcrumb li { float: left; list-style: none; margin: 0; padding: 0 .2em; font-size: .9em; opacity: .7; } |
| 46 | +.fg-menu-breadcrumb li.fg-menu-prev-list, |
| 47 | +.fg-menu-breadcrumb li.fg-menu-current-crumb { clear: left; float: none; opacity: 1; } |
| 48 | +.fg-menu-breadcrumb li.fg-menu-current-crumb { padding-top: .2em; } |
| 49 | + |
| 50 | +.fg-menu-breadcrumb a, |
| 51 | +.fg-menu-breadcrumb span { float: left; } |
| 52 | + |
| 53 | +.fg-menu-footer a:link, |
| 54 | +.fg-menu-footer a:visited { float:left; width:100%; text-decoration: none; } |
| 55 | +.fg-menu-footer a:hover, |
| 56 | +.fg-menu-footer a:active { } |
| 57 | + |
| 58 | +.fg-menu-footer a span { float:left; cursor: pointer; } |
| 59 | + |
| 60 | +.fg-menu-breadcrumb .fg-menu-prev-list a:link, |
| 61 | +.fg-menu-breadcrumb .fg-menu-prev-list a:visited, |
| 62 | +.fg-menu-breadcrumb .fg-menu-prev-list a:hover, |
| 63 | +.fg-menu-breadcrumb .fg-menu-prev-list a:active { background-image: none; text-decoration:none; } |
| 64 | + |
| 65 | +.fg-menu-breadcrumb .fg-menu-prev-list a { float: left; padding-right: .4em; } |
| 66 | +.fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon { float: left; } |
| 67 | + |
| 68 | +.fg-menu-breadcrumb .fg-menu-current-crumb a:link, |
| 69 | +.fg-menu-breadcrumb .fg-menu-current-crumb a:visited, |
| 70 | +.fg-menu-breadcrumb .fg-menu-current-crumb a:hover, |
| 71 | +.fg-menu-breadcrumb .fg-menu-current-crumb a:active { display:block; background-image:none; font-size:1.3em; text-decoration:none; } |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | +/* REQUIRED LINK STYLES: links are "display:block" by default; if the menu options are split into |
| 76 | + selectable node links and 'next' links, the script floats the node links left and floats the 'next' links to the right */ |
| 77 | + |
| 78 | +.fg-menu a:link, |
| 79 | +.fg-menu a:visited, |
| 80 | +.fg-menu a:hover, |
| 81 | +.fg-menu a:active { float:left; width:92%; padding:.3em 3%; text-decoration:none; outline: 0 !important; } |
| 82 | + |
| 83 | +.fg-menu a { border: 1px dashed transparent; } |
| 84 | + |
| 85 | +.fg-menu a.ui-state-default:link, |
| 86 | +.fg-menu a.ui-state-default:visited, |
| 87 | +.fg-menu a.ui-state-default:hover, |
| 88 | +.fg-menu a.ui-state-default:active, |
| 89 | +.fg-menu a.ui-state-hover:link, |
| 90 | +.fg-menu a.ui-state-hover:visited, |
| 91 | +.fg-menu a.ui-state-hover:hover, |
| 92 | +.fg-menu a.ui-state-hover:active, |
| 93 | +.fg-menu a.ui-state-active:link, |
| 94 | +.fg-menu a.ui-state-active:visited, |
| 95 | +.fg-menu a.ui-state-active:hover, |
| 96 | +.fg-menu a.ui-state-active:active { border-style: solid; font-weight: normal; } |
| 97 | + |
| 98 | +.fg-menu a span { display:block; cursor:pointer; } |
| 99 | + |
| 100 | + |
| 101 | + /* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */ |
| 102 | + |
| 103 | +.fg-menu-indicator span { float:left; } |
| 104 | +.fg-menu-indicator span.ui-icon { float:right; } |
| 105 | + |
| 106 | +.fg-menu-content.ui-widget-content, |
| 107 | +.fg-menu-content ul.ui-widget-content { border:0; } |
| 108 | + |
| 109 | + |
| 110 | +/* ICONS AND DIVIDERS */ |
| 111 | + |
| 112 | +.fg-menu.fg-menu-has-icons a:link, |
| 113 | +.fg-menu.fg-menu-has-icons a:visited, |
| 114 | +.fg-menu.fg-menu-has-icons a:hover, |
| 115 | +.fg-menu.fg-menu-has-icons a:active { padding-left:20px; } |
| 116 | + |
| 117 | +.fg-menu .horizontal-divider hr, .fg-menu .horizontal-divider span { padding:0; margin:5px .6em; } |
| 118 | +.fg-menu .horizontal-divider hr { border:0; height:1px; } |
| 119 | +.fg-menu .horizontal-divider span { font-size:.9em; text-transform: uppercase; padding-left:.2em; } |
| 120 | + |
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.js |
— | — | @@ -18,35 +18,56 @@ |
19 | 19 | (function($) { |
20 | 20 | |
21 | 21 | |
22 | | -$.fn.menu = function(options){ |
| 22 | +$.fn.menu = function( options ){ |
23 | 23 | var caller = this; |
24 | 24 | var options = options; |
25 | | - var m = new Menu(caller, options); |
26 | | - allUIMenus.push(m); |
27 | 25 | |
28 | | - $(this) |
29 | | - .mousedown(function(){ |
30 | | - if (!m.menuOpen) { m.showLoading(); }; |
31 | | - }) |
32 | | - .click(function(){ |
33 | | - if (m.menuOpen == false) { m.showMenu(); } |
34 | | - else { m.kill(); }; |
35 | | - return false; |
36 | | - }); |
| 26 | + if( ! caller.m ){ |
| 27 | + caller.m = new Menu(caller, options); |
| 28 | + allUIMenus.push( caller.m ); |
| 29 | + |
| 30 | + //Check for autoShow menu option |
| 31 | + if( options.autoShow ) |
| 32 | + caller.m.showMenu(); |
| 33 | + |
| 34 | + //Set up bindings: |
| 35 | + $(this) |
| 36 | + .mousedown(function(){ |
| 37 | + if (!caller.m.menuOpen) { caller.m.showLoading(); }; |
| 38 | + }) |
| 39 | + .click(function(){ |
| 40 | + if (caller.m.menuOpen == false) { caller.m.showMenu(); } |
| 41 | + else { caller.m.kill(); }; |
| 42 | + return false; |
| 43 | + }); |
| 44 | + } |
| 45 | + //Else process the request: |
| 46 | + if( options == 'show' ) |
| 47 | + caller.m.showMenu(); |
37 | 48 | }; |
38 | 49 | |
39 | 50 | function Menu(caller, options){ |
40 | 51 | var menu = this; |
41 | 52 | var caller = $(caller); |
42 | | - var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>'); |
43 | 53 | |
| 54 | + mw.log( 'target container: ' + options.targetContainer ); |
| 55 | + |
| 56 | + var callerClassList = 'fg-menu-container ui-widget ui-widget-content ui-corner-all'; |
| 57 | + if( options.targetContainer ){ |
| 58 | + var container = $( options.targetContainer ).addClass( callerClassList ).html( options.content ); |
| 59 | + }else{ |
| 60 | + var container = $('<div>').addClass( callerClassList ).html( options.content ); |
| 61 | + } |
| 62 | + |
44 | 63 | this.menuOpen = false; |
45 | 64 | this.menuExists = false; |
46 | 65 | |
47 | 66 | var options = jQuery.extend({ |
48 | 67 | content: null, |
| 68 | + autoShow: false, |
49 | 69 | width: 180, // width of menu container, must be set or passed in to calculate widths of child menus |
50 | 70 | maxHeight: 180, // max height of menu (if a drilldown: height does not include breadcrumb) |
| 71 | + targetContainer: null, |
51 | 72 | positionOpts: { |
52 | 73 | posX: 'left', |
53 | 74 | posY: 'bottom', |
— | — | @@ -102,6 +123,7 @@ |
103 | 124 | }; |
104 | 125 | |
105 | 126 | this.showMenu = function(){ |
| 127 | + mw.log('$j.menu:: show menu' ); |
106 | 128 | killAllMenus(); |
107 | 129 | if (!menu.menuExists) { menu.create() }; |
108 | 130 | caller |
— | — | @@ -211,7 +233,7 @@ |
212 | 234 | else { menu.drilldown(container, options); } |
213 | 235 | } |
214 | 236 | else { |
215 | | - container.find('a').click(function(){ |
| 237 | + container.find('a').click(function(){ |
216 | 238 | menu.chooseItem(this); |
217 | 239 | return false; |
218 | 240 | }); |
— | — | @@ -247,10 +269,9 @@ |
248 | 270 | }; |
249 | 271 | |
250 | 272 | this.chooseItem = function(item){ |
251 | | - menu.kill(); |
252 | | - // edit this for your own custom function/callback: |
253 | | - $('#menuSelection').text($(item).text()); |
254 | | - // location.href = $(item).attr('href'); |
| 273 | + menu.kill(); |
| 274 | + if( options.selectItemCallback ) |
| 275 | + options.selectItemCallback( item ); |
255 | 276 | }; |
256 | 277 | }; |
257 | 278 | |
— | — | @@ -649,4 +670,4 @@ |
650 | 671 | return result; |
651 | 672 | }; |
652 | 673 | |
653 | | -})(jQuery); |
\ No newline at end of file |
| 674 | +} )(jQuery); |
\ No newline at end of file |