r60062 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60061‎ | r60062 | r60063 >
Date:03:26, 15 December 2009
Author:dale
Status:deferred
Tags:
Comment:
* timedText updates ( basic integrated menu )
* added simple hook system
Modified paths:
  • /branches/js2-work/phase3/js2/mwEmbed/example_usage/Multi_Upload.html (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libTimedText/jQuery.menu.css (added) (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)

Diff [purge]

Index: branches/js2-work/phase3/js2/mwEmbed/example_usage/Multi_Upload.html
@@ -6,7 +6,7 @@
77 <script type="text/javascript" src="../mwEmbed.js"></script>
88 </head>
99 <script type="text/javascript">
10 -mwAddOnloadHook(function(){
 10+mw.addOnloadHook(function(){
1111 //bind the upload drag and drop
1212
1313 //bind the multiple Files
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js
@@ -1199,7 +1199,10 @@
12001200 // Set customAttributes if unset:
12011201 if ( !customAttributes )
12021202 customAttributes = { };
1203 -
 1203+
 1204+ //Add a hook system to the embedPlayer
 1205+ mw.addHookSystem( _this );
 1206+
12041207 // Setup the player Interface from supported attributes:
12051208 for ( var attr in default_video_attributes ) {
12061209 if ( customAttributes[ attr ] ){
@@ -1253,7 +1256,7 @@
12541257 }
12551258
12561259 // Add the mediaElement object with the elements sources:
1257 - this.mediaElement = new mediaElement( element );
 1260+ this.mediaElement = new mediaElement( element );
12581261
12591262 // Setup the local "ROE" src pointer if added as media source
12601263 // also see: http://dev.w3.org/html5/spec/Overview.html#the-source-element
@@ -1264,12 +1267,12 @@
12651268 _this.roe = source.src;
12661269 }
12671270 }
1268 - });
1269 -
1270 -
1271 - // Load player skin css:
 1271+ } );
 1272+
 1273+ // Make sure we have the player skin css:
12721274 mw.getStyleSheet( mw.getMwEmbedPath() + 'skins/' + this.skin_name + '/playerSkin.css' );
12731275 },
 1276+
12741277
12751278 /**
12761279 * Set the width & height from css style attribute, element attribute, or by default value
@@ -1286,8 +1289,9 @@
12871290 if( ! this['height'] && ! this['width'] ){
12881291 this['height'] = parseInt( $j(element).attr( 'height' ) );
12891292 this['width'] = parseInt( $j(element).attr( 'width' ) );
1290 - }
 1293+ }
12911294
 1295+
12921296 // Deal with just one height or width being set:
12931297 if( this['height'] && !this['width'] && this.videoAspect ){
12941298 var aspect = this.videoAspect.split( ':' );
@@ -1302,7 +1306,12 @@
13031307 // On load sometimes attr is temporally -1 as we don't have video metadata yet.
13041308 // NOTE: this edge case should be handled by waiting for metadata see: "waitForMeta" in addElement
13051309 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+
13071316 var defaultSize = mw.getConfig( 'video_size' ).split( 'x' );
13081317 this['width'] = defaultSize[0];
13091318 // Special height default for audio tag ( if not set )
@@ -2322,8 +2331,9 @@
23232332 'z-index' : 10,
23242333 'top' : ( loc.top + playerHeight + 4) + 'px',
23252334 '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'
23282338 } ).hide()
23292339 );
23302340 }
@@ -2343,8 +2353,8 @@
23442354 }
23452355
23462356 mw.load( timedTextRequestSet, function(){
2347 - $j( _this ).timedText( {
2348 - 'menu_target': '#timedTextMenu_' + this.id
 2357+ $j( '#' + _this.id ).timedText( {
 2358+ 'targetContainer': '#timedTextMenu_' + _this.id
23492359 } );
23502360 });
23512361
@@ -2817,6 +2827,7 @@
28182828 }, 250 );
28192829 }
28202830 }
 2831+ this.runHook( 'monitor' );
28212832 },
28222833
28232834 /**
Index: branches/js2-work/phase3/js2/mwEmbed/mwEmbed.js
@@ -708,7 +708,57 @@
709709 for ( var i in magicSet )
710710 pMagicSet[ i ] = magicSet[i];
711711 }
 712+
712713 /**
 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+ /**
713763 * The loader prototype:
714764 */
715765 $.loader = {
@@ -805,7 +855,7 @@
806856 }
807857
808858 //possible error?
809 - mw.log( "Error could not handle load request" );
 859+ mw.log( "Error could not handle load request: " + loadRequest );
810860 },
811861
812862
@@ -974,7 +1024,7 @@
9751025
9761026 // Check for any associated style sheets that should be loaded
9771027 if( typeof this.stylePaths[ className ] != 'undefined' ){
978 - $.getStyleSheet( this.stylePaths[ className ] );
 1028+ $.getStyleSheet( mw.getMwEmbedPath() + this.stylePaths[ className ] );
9791029 }
9801030
9811031 // Include class defined check for older browsers
@@ -2091,7 +2141,8 @@
20922142 // Add style sheet dependencies
20932143 mw.addClassStyleSheets( {
20942144 "kskinConfig" : "skins/kskin/playerSkin.css",
2095 - "mvpcfConfig" : "skins/mvpcf/playerSkin.css"
 2145+ "mvpcfConfig" : "skins/mvpcf/playerSkin.css",
 2146+ "$j.menu" : "libTimedText/jQuery.menu.css"
20962147 } );
20972148
20982149 // Add the module loader function:
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/mw.timedText.js
@@ -1,18 +1,29 @@
22 /*
33 * The Core timed Text interface object
44 *
5 - * handles class mapings for:
6 - * menu display ( jquery.ui themable )
 5+ * handles class mappings for:
 6+ * menu display ( jquery.ui themeable )
77 * timed text loading request
88 * timed text edit requests
99 * timed text search & seek interface ( version 2 )
1010 */
1111
 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+
1222 // Bind to mw (for uncluttered global namespace)
1323 ( function( $ ) {
1424 $.timedText = function ( embedPlayer, options ){
1525 return new TimedText( embedPlayer, options );
1626 }
 27+
1728 /**
1829 * Timed Text Object
1930 * @param embedPlayer Host player for timedText interfaces
@@ -21,6 +32,21 @@
2233 return this.init( embedPlayer, options);
2334 }
2435 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+ */
2551 timedTextProvider:{
2652 'commons':{
2753 'api_url': mw.commons_api_url
@@ -33,19 +59,147 @@
3460 *
3561 */
3662 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+
3876 },
3977
4078 /**
 79+ * Monitor video time and update timed text filed[s]
 80+ */
 81+ monitor: function(){
 82+ mw.log(' timedText monitor ');
 83+ },
 84+
 85+ /**
4186 * Show the timed text menu
4287 * @param {Object} jQuery selector to display the target
4388 */
44 - showMenu: function( $target ){
 89+ showMenu: function( ){
 90+ var _this = this;
4591 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;
50204 }
51205
52206 }
@@ -55,13 +209,21 @@
56210 * jQuery entry point for timedText interface:
57211 */
58212 ( 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+ } );
67229 }
68230 } )( 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 @@
1919 (function($) {
2020
2121
22 -$.fn.menu = function(options){
 22+$.fn.menu = function( options ){
2323 var caller = this;
2424 var options = options;
25 - var m = new Menu(caller, options);
26 - allUIMenus.push(m);
2725
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();
3748 };
3849
3950 function Menu(caller, options){
4051 var menu = this;
4152 var caller = $(caller);
42 - var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>');
4353
 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+
4463 this.menuOpen = false;
4564 this.menuExists = false;
4665
4766 var options = jQuery.extend({
4867 content: null,
 68+ autoShow: false,
4969 width: 180, // width of menu container, must be set or passed in to calculate widths of child menus
5070 maxHeight: 180, // max height of menu (if a drilldown: height does not include breadcrumb)
 71+ targetContainer: null,
5172 positionOpts: {
5273 posX: 'left',
5374 posY: 'bottom',
@@ -102,6 +123,7 @@
103124 };
104125
105126 this.showMenu = function(){
 127+ mw.log('$j.menu:: show menu' );
106128 killAllMenus();
107129 if (!menu.menuExists) { menu.create() };
108130 caller
@@ -211,7 +233,7 @@
212234 else { menu.drilldown(container, options); }
213235 }
214236 else {
215 - container.find('a').click(function(){
 237+ container.find('a').click(function(){
216238 menu.chooseItem(this);
217239 return false;
218240 });
@@ -247,10 +269,9 @@
248270 };
249271
250272 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 );
255276 };
256277 };
257278
@@ -649,4 +670,4 @@
650671 return result;
651672 };
652673
653 -})(jQuery);
\ No newline at end of file
 674+} )(jQuery);
\ No newline at end of file

Status & tagging log