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