http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89801

Revision: 89801
Author:   foxtrott
Date:     2011-06-09 21:47:07 +0000 (Thu, 09 Jun 2011)
Log Message:
-----------
Use JS for placement of tooltips

Modified Paths:
--------------
    trunk/extensions/Lingo/Lingo.php
    trunk/extensions/Lingo/LingoBasicBackend.php
    trunk/extensions/Lingo/LingoParser.php

Added Paths:
-----------
    trunk/extensions/Lingo/libs/
    trunk/extensions/Lingo/libs/Lingo.js

Removed Paths:
-------------
    trunk/extensions/Lingo/tooltip.css
    trunk/extensions/Lingo/tooltip.min.js

Modified: trunk/extensions/Lingo/Lingo.php
===================================================================
--- trunk/extensions/Lingo/Lingo.php    2011-06-09 21:31:51 UTC (rev 89800)
+++ trunk/extensions/Lingo/Lingo.php    2011-06-09 21:47:07 UTC (rev 89801)
@@ -44,31 +44,30 @@
 $wgAutoloadClasses[ 'LingoMessageLog' ] = $dir . '/LingoMessageLog.php';
 // $wgAutoloadClasses['SpecialLingoBrowser'] = $dir . 
'/SpecialLingoBrowser.php';
 
-unset ($dir);
-
 $wgHooks[ 'SpecialVersionExtensionTypes' ][ ] = 'fnLingoSetCredits';
-//$wgExtensionFunctions[ ] = 'fnLingoInit';
 $wgHooks[ 'ParserAfterTidy' ][ ] = 'LingoParser::parse';
 
 // register resource modules with the Resource Loader
-$wgResourceModules[ 'ext.Lingo' ] = array(
-       // JavaScript and CSS styles. To combine multiple file, just list them 
as an array.
+$wgResourceModules[ 'ext.Lingo.Styles' ] = array(
+       'localBasePath' => $dir,
+       'remoteExtPath' => 'Lingo',
        // 'scripts' => 'libs/ext.myExtension.js',
        'styles' => 'skins/Lingo.css',
-       // When your module is loaded, these messages will be available to 
mediaWiki.msg()
        // 'messages' => array( 'myextension-hello-world', 
'myextension-goodbye-world' ),
-
-       // If your scripts need code from other modules, list their identifiers 
as dependencies
-       // and ResourceLoader will make sure they're loaded before you.
-       // You don't need to manually list 'mediawiki' or 'jquery', which are 
always loaded.
        // 'dependencies' => array( 'jquery.ui.datepicker' ),
+);
 
-       // ResourceLoader needs to know where your files are; specify your
-       // subdir relative to "extensions" or $wgExtensionAssetsPath
-       'localBasePath' => dirname( __FILE__ ),
-       'remoteExtPath' => 'Lingo'
+$wgResourceModules[ 'ext.Lingo.Scripts' ] = array(
+       'localBasePath' => $dir,
+       'remoteExtPath' => 'Lingo',
+       'scripts' => 'libs/Lingo.js',
+       // 'styles' => 'skins/Lingo.css',
+       // 'messages' => array( 'myextension-hello-world', 
'myextension-goodbye-world' ),
+       // 'dependencies' => array( 'jquery.ui.datepicker' ),
 );
 
+unset ($dir);
+
 /**
  * Deferred setting of extension credits
  * 

Modified: trunk/extensions/Lingo/LingoBasicBackend.php
===================================================================
--- trunk/extensions/Lingo/LingoBasicBackend.php        2011-06-09 21:31:51 UTC 
(rev 89800)
+++ trunk/extensions/Lingo/LingoBasicBackend.php        2011-06-09 21:47:07 UTC 
(rev 89801)
@@ -31,13 +31,13 @@
                // Get Terminology page
                $title = Title::newFromText( $page );
                if ( $title->getInterwiki() ) {
-                       $this->getMessageLog()->addError( wfMsgForContent( 
'lingo-terminologypagenotlocal' , array($page) ) );
+                       $this->getMessageLog()->addError( wfMsgForContent( 
'lingo-terminologypagenotlocal' , $page ) );
                        return false;
                }
 
                $rev = Revision::newFromTitle( $title );
                if ( !$rev ) {
-                       $this->getMessageLog()->addWarning( wfMsgForContent( 
'lingo-noterminologypage' , array($page) ) );
+                       $this->getMessageLog()->addWarning( wfMsgForContent( 
'lingo-noterminologypage' , $page ) );
                        return false;
                }
 

Modified: trunk/extensions/Lingo/LingoParser.php
===================================================================
--- trunk/extensions/Lingo/LingoParser.php      2011-06-09 21:31:51 UTC (rev 
89800)
+++ trunk/extensions/Lingo/LingoParser.php      2011-06-09 21:47:07 UTC (rev 
89801)
@@ -267,20 +267,36 @@
        protected function loadModules( &$parser ) {
                global $wgOut, $wgScriptPath;
 
+               // load scripts
+               if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
+                       if ( !is_null( $parser ) && ( $wgOut->isArticle() ) ) {
+                               $parser->getOutput()->addModules( 
'ext.Lingo.Scripts' );
+                       } else {
+                               $wgOut->addModules( 'ext.Lingo.Scripts' );
+                       }
+               } else {
+                       if ( !is_null( $parser ) && ( $wgOut->isArticle() ) ) {
+                               $parser->getOutput()->addHeadItem( "<script 
src='$wgScriptPath/extensions/Lingo/libs/Lingo.js'></script>\n", 
'ext.Lingo.Scripts' );
+                       } else {
+                               $wgOut->addHeadItem( 'ext.Lingo.Scripts', 
"<script src='$wgScriptPath/extensions/Lingo/libs/Lingo.js'></script>\n" );
+                       }
+               }
+
+               // load styles
                // FIXME: Modules loaded by the ResourceLoader only work on 
JS-enabled
                // browsers. This doesn't make any sense for CSS-only modules 
that don't
                // need any JS. -> Use ResourceLoader if and when Bug 29308 
gets fixed.
 //             if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
-//                     if ( !is_null( $parser ) ) {
-//                             $parser->getOutput()->addModules( 'ext.Lingo' );
+//                     if ( !is_null( $parser )  && ( $wgOut->isArticle() ) ) {
+//                             $parser->getOutput()->addModules( 
'ext.Lingo.Styles' );
 //                     } else {
-//                             $wgOut->addModules( 'ext.Lingo' );
+//                             $wgOut->addModules( 'ext.Lingo.Styles' );
 //                     }
 //             } else {
                if ( !is_null( $parser ) && ( $wgOut->isArticle() ) ) {
-                       $parser->getOutput()->addHeadItem( '<link 
rel="stylesheet" href="' . $wgScriptPath . '/extensions/Lingo/skins/Lingo.css" 
/>', 'ext.Lingo.css' );
+                       $parser->getOutput()->addHeadItem( "<link 
rel='stylesheet' href='$wgScriptPath/extensions/Lingo/skins/Lingo.css' />\n", 
'ext.Lingo.Styles' );
                } else {
-                       $wgOut->addHeadItem( 'ext.Lingo.css', '<link 
rel="stylesheet" href="' . $wgScriptPath . '/extensions/Lingo/skins/Lingo.css" 
/>' );
+                       $wgOut->addHeadItem( 'ext.Lingo.Styles', "<link 
rel='stylesheet' href='$wgScriptPath/extensions/Lingo/skins/Lingo.css' />\n" );
                }
 //             }
        }

Added: trunk/extensions/Lingo/libs/Lingo.js
===================================================================
--- trunk/extensions/Lingo/libs/Lingo.js                                (rev 0)
+++ trunk/extensions/Lingo/libs/Lingo.js        2011-06-09 21:47:07 UTC (rev 
89801)
@@ -0,0 +1,183 @@
+jQuery(function ($){
+       
+       var tooltips = $(".tooltip");
+       //      var tooltip_wrapper = tooltip.find(".tooltip_tipwrapper");
+       //      var tooltip_tip = tooltip_wrapper.find(".tooltip_tip");
+       
+       tooltips
+       .mouseenter(function(){
+
+               var tip = $(this);
+               var wrapper = tip.find(".tooltip_tipwrapper");
+               var tipdef = wrapper.find(".tooltip_tip");
+
+               var maxAvailableWidth = window.innerWidth - 15; // -15 for 
scrollbar
+               var maxAvailableHeightAbove = tip.offset().top - 
$(window).scrollTop() - 5;
+               var maxAvailableHeightBelow = window.innerHeight - 
(tip.offset().top - $(window).scrollTop()) - tip.outerHeight() - 5 - 15;  // 
-15 for scrollbar
+
+               var maxWidthWithoutBreak = maxAvailableWidth / 3;
+
+               wrapper
+               .css({
+                       //                      'visibility': 'hidden',
+                       'visibility': 'visible',
+                       'display': 'block',
+                       'width': '10000000px'
+               });
+       
+               
+               tipdef.css({
+                       'position': 'fixed',
+                       'width': 'auto',
+                       'top': '0px',
+                       'left': '0px'
+               });
+
+               // natural width is the width without any constraints
+               var naturalWidth = tipdef.width();
+               // natural height is the height without any constraints
+               var naturalHeight = tipdef.height();
+
+               var borderWidth = tipdef.outerWidth() - naturalWidth;
+
+               maxAvailableWidth -= borderWidth;
+               maxAvailableHeightAbove -= borderWidth;
+               maxAvailableHeightBelow -= borderWidth;
+               maxWidthWithoutBreak -= borderWidth;
+
+               tipdef.width( maxAvailableWidth );
+
+               //              tipdef.css({
+               //                      'position': 'fixed',
+               //                      'top': '0px',
+               //                      'left': '0px'
+               //              });
+               //      if constrained to the window width, i.e.
+               // the minimum width necessary if the full window width were 
available
+               var heightAtMaxWidth = tipdef.height();
+
+               // The tooltip will be placed above the term if it does fit 
above, but
+               // not below. If it is to high for either, it will be put below 
at
+               // maximum width so at least the first part is visible.
+               if ( heightAtMaxWidth > maxAvailableHeightBelow ) {
+                       // will not fit below
+
+                       if ( heightAtMaxWidth > maxAvailableHeightAbove ) {
+                               // will neither fit above nor below
+                               var placeAbove = false;
+                               var tooLarge = true;
+                               var maxAvailableHeight = 
maxAvailableHeightBelow;
+
+                       } else {
+                               // will fit above
+                               var placeAbove = true;
+                               var tooLarge = false;
+                               var maxAvailableHeight = 
maxAvailableHeightAbove;
+                       }
+               } else {
+                       // will fit below
+                       var placeAbove = false;
+                       var tooLarge = false;
+                       var maxAvailableHeight = maxAvailableHeightBelow;
+               }
+
+               if ( tooLarge ) {
+
+                       // if it is too large anyway, just set max available 
width and be
+                       // done with it
+                               wrapper.css({
+                                       'width': maxAvailableWidth + 'px',
+                                       'padding-left': '10px',
+                                       'left': '0px',
+                                       'top': '0px',
+                                       'padding-bottom': '0px',
+                                       'padding-top' : (tip.outerHeight() + 5 
) +'px'
+                               });
+
+               } else {
+
+                       if ( naturalWidth > maxWidthWithoutBreak ) {
+
+                               var width = Math.max( Math.sqrt( 5 * 
naturalWidth * naturalHeight ), maxWidthWithoutBreak );
+                               width = Math.min( width, maxAvailableWidth );
+
+                       } else {
+
+                               var width = naturalWidth;
+
+                       }
+
+                       tipdef.width( width );
+
+                       var rounds = 0;
+
+                       while ( tipdef.height() > maxAvailableHeight && rounds 
< 5 ) {
+                               width = Math.min (width * ( tipdef.height() / 
maxAvailableHeight ), maxAvailableWidth);
+                               tipdef.width ( width );
+                               rounds++;
+                       }
+
+                       wrapper.height(tipdef.height());
+                       
+                       var maxAvailableWidthRight = window.innerWidth - 
(tip.offset().left - $(window).scrollLeft() ) - borderWidth;
+
+                       if ( maxAvailableWidthRight - 10 >= width ) {
+                               // will not bump into right window border
+                               wrapper.css({
+                                       'width': (width + 10) + 'px',
+                                       'padding-left': '10px',
+                                       'left': '0px'
+                               });
+
+                       } else {
+                               // will bump into right window border
+                               var left = maxAvailableWidthRight - width - 
borderWidth;
+                               wrapper.width(width);
+                               wrapper.css({
+                                       'width': width + 'px',
+                                       'padding-left': '0px',
+                                       'left': left + 'px'
+                               });
+                       }
+
+                       if ( placeAbove ) {
+                               wrapper.css({
+                                       'top': ( - tipdef.outerHeight() - 5) + 
'px',
+                                       'padding-bottom': '10px',
+                                       'padding-top' : '0px'
+                               });
+
+                       } else {
+                               wrapper.css({
+                                       //                                      
'position': 'absolute',
+                                       'top': '0px',
+                                       'padding-bottom': '0px',
+                                       'padding-top' : (tip.outerHeight() + 5 
) +'px'
+                               });
+                       }
+
+
+               }
+
+               tipdef.css({
+                       'position': 'relative'
+               });
+
+               
+               wrapper
+               .css({
+                       //                      'width': '100%',
+                       'height': 'auto',
+                       'visibility': 'visible',
+                       'display': 'none'
+               })
+               
+               .fadeIn(200);
+       })
+       
+       .mouseleave(function(){
+               $(".tooltip_tipwrapper", this).fadeOut(200);
+       });
+       
+
+});
\ No newline at end of file


Property changes on: trunk/extensions/Lingo/libs/Lingo.js
___________________________________________________________________
Added: svn:eol-style
   + native

Deleted: trunk/extensions/Lingo/tooltip.css
===================================================================
--- trunk/extensions/Lingo/tooltip.css  2011-06-09 21:31:51 UTC (rev 89800)
+++ trunk/extensions/Lingo/tooltip.css  2011-06-09 21:47:07 UTC (rev 89801)
@@ -1,19 +0,0 @@
-#tooltip {
-       position: absolute;
-       z-index: 3000;
-       border: 1px solid #111;
-       background-color: #eee;
-       padding: 3px;
-       font-size: 1.2em;
-       opacity: 0.85;
-}
-#tooltip h3, #tooltip div { margin: 0; }
-
-.tooltip_hide {
-       display: none;  
-}
-
-.tooltip_abbr {
-       cursor: help;
-       border-bottom: 1px dashed green;        
-}
\ No newline at end of file

Deleted: trunk/extensions/Lingo/tooltip.min.js
===================================================================
--- trunk/extensions/Lingo/tooltip.min.js       2011-06-09 21:31:51 UTC (rev 
89800)
+++ trunk/extensions/Lingo/tooltip.min.js       2011-06-09 21:47:07 UTC (rev 
89801)
@@ -1,28 +0,0 @@
-/*
- * jQuery Tooltip plugin 1.3
- *
- * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
- * http://docs.jquery.com/Plugins/Tooltip
- *
- * Copyright (c) 2006 - 2008 Jörn Zaefferer
- *
- * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
- * 
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- */;(function($){var 
helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,fade:false,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return
 
this.each(function(){$.data(this,"tooltip",settings);this.tOpacity=helper.parent.css("opacity");this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).mouseover(save).mouseout(hide).click(hide);},fixPNG:IE?function(){return
 this.each(function(){var 
image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,
 sizingMethod=crop, src='"+image+"')"}).each(function(){var 
position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return
 this;},unfixPNG:IE?function(){return 
this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return
 this;},hideWhenEmpty:function(){return 
this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return
 this.attr('href')||this.attr('src');}});function 
createHelper(settings){if(helper.parent)return;helper.parent=$('<div 
id="'+settings.id+'"><h3></h3><div class="body"></div><div 
class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function
 settings(element){return $.data(element,"tooltip");}function 
handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
-show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function
 
save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var
 
bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else
 if(settings(this).showBody){var 
parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var
 
i=0,part;(part=parts[i]);i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
-helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function
 
show(){tID=null;if((!IE||!$.fn.bgiframe)&&settings(current).fade){if(helper.parent.is(":animated"))helper.parent.stop().show().fadeTo(settings(current).fade,current.tOpacity);else
-helper.parent.is(':visible')?helper.parent.fadeTo(settings(current).fade,current.tOpacity):helper.parent.fadeIn(settings(current).fade);}else{helper.parent.show();}update();}function
 
update(event){if($.tooltip.blocked)return;if(event&&event.target.tagName=="OPTION"){return;}if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var
 left=helper.parent[0].offsetLeft;var 
top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;var
 
right='auto';if(settings(current).positionLeft){right=$(window).width()-left;left='auto';}helper.parent.css({left:left,right:right,top:top});}var
 
v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function
 
viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function
 
hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;var
 tsettings=settings(this);function 
complete(){helper.parent.removeClass(tsettings.extraClass).hide().css("opacity","");}if((!IE||!$.fn.bgiframe)&&tsettings.fade){if(helper.parent.is(':animated'))helper.parent.stop().fadeTo(tsettings.fade,0,complete);else
-helper.parent.stop().fadeOut(tsettings.fade,complete);}else
-complete();if(settings(this).fixPNG)helper.parent.unfixPNG();}})(jQuery);
- 
-jQuery(function() {
-       jQuery(".tooltip_abbr").tooltip( {
-               bodyHandler : function() {
-                       return jQuery("span", this).html();
-               },
-               showURL : false
-       });
-});
\ No newline at end of file


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to