fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-05-19 06:29 am

[dw-free] Contextual hover menu positioning not always accurate

[commit: http://hg.dwscoalition.org/dw-free/rev/a1a1c6af9228]

http://bugs.dwscoalition.org/show_bug.cgi?id=3684

Replace tooltip.js positioning logic with jquery.ui.position.js, to account
for the positioning not being accurate on some layouts. Also increase
z-index on contextual hover to overcome zindex in fluid measure.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/LJ/S2/EntryPage.pm
  • cgi-bin/ljlib.pl
  • htdocs/js/jquery.ajaxtip.js
  • htdocs/js/jquery.contextualhover.js
  • htdocs/js/tooltip.dynamic.js
  • htdocs/js/tooltip.dynamic.min.js
  • htdocs/js/tooltip.js
  • htdocs/js/tooltip.min.js
  • htdocs/stc/ajaxtip.css
  • htdocs/stc/contextualhover.css
--------------------------------------------------------------------------------
diff -r 1047502ac1c7 -r a1a1c6af9228 cgi-bin/LJ/S2/EntryPage.pm
--- a/cgi-bin/LJ/S2/EntryPage.pm	Thu May 19 00:38:30 2011 +0800
+++ b/cgi-bin/LJ/S2/EntryPage.pm	Thu May 19 14:28:57 2011 +0800
@@ -385,7 +385,7 @@
             js/jquery.ajaxtip.js
             js/jquery.commentmanage.js
             js/tooltip.js
-            js/tooltip.dynamic.js
+            js/jquery/jquery.ui.position.js
             stc/ajaxtip.css
             stc/popup-form.css
         ) );
diff -r 1047502ac1c7 -r a1a1c6af9228 cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Thu May 19 00:38:30 2011 +0800
+++ b/cgi-bin/ljlib.pl	Thu May 19 14:28:57 2011 +0800
@@ -1352,7 +1352,7 @@
 
                     js/jquery.ajaxtip.js
                     js/tooltip.js
-                    js/tooltip.dynamic.js
+                    js/jquery/jquery.ui.position.js
                     stc/ajaxtip.css
 
                     js/jquery.hoverIntent.js
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/jquery.ajaxtip.js
--- a/htdocs/js/jquery.ajaxtip.js	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/js/jquery.ajaxtip.js	Thu May 19 14:28:57 2011 +0800
@@ -29,7 +29,6 @@
                     widget: "ajaxstart"+ns+",ajaxresult"+ns,
                     tooltip: "mouseover,mouseleave"
                 },
-                position: "bottom center",
                 relative: true,
                 effect: "fade",
                 onBeforeShow: function(e) {
@@ -43,11 +42,11 @@
                         tip.empty().append($("<img />", { src: Site.imgprefix + "/ajax-loader.gif" }))
                             .addClass("ajaxresult")
                     }
+
+                    tip.css({position: "absolute", top: "", left: ""})
+                        .position({ my: "left top", at: "left bottom", of: self.element, collision: "fit"})
                 }
             },  self.options.tooltip));
-            if ( self.options.tooltip.dynamic )
-                self.element.dynamic({ classNames: "tip-top tip-right tip-bottom tip-left" });
-
     },
     _init: function() {
         if(this.options.content)
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/jquery.contextualhover.js
--- a/htdocs/js/jquery.contextualhover.js	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/js/jquery.contextualhover.js	Thu May 19 14:28:57 2011 +0800
@@ -79,7 +79,7 @@
             return;
         }
 
-        trigger.ajaxtip({ namespace: "contextualpopup", tooltip: {position: "bottom left",dynamic:false} })
+        trigger.ajaxtip({ namespace: "contextualpopup"})
             .ajaxtip( "load", {
                 endpoint: "ctxpopup",
                 formmethod: "GET",
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/tooltip.dynamic.js
--- a/htdocs/js/tooltip.dynamic.js	Thu May 19 00:38:30 2011 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/**
- * @license 
- * jQuery Tools 1.2.5 / Tooltip Dynamic Positioning
- * 
- * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
- * 
- * http://flowplayer.org/tools/tooltip/dynamic.html
- *
- * Since: July 2009
- * Date:    Wed Sep 22 06:02:10 2010 +0000 
- */
-(function($) { 
-
-	// version number
-	var t = $.tools.tooltip;
-	
-	t.dynamic = {
-		conf: {
-			classNames: "top right bottom left"
-		}
-	};
-		
-	/* 
-	 * See if element is on the viewport. Returns an boolean array specifying which
-	 * edges are hidden. Edges are in following order:
-	 * 
-	 * [top, right, bottom, left]
-	 * 
-	 * For example following return value means that top and right edges are hidden
-	 * 
-	 * [true, true, false, false]
-	 * 
-	 */
-	function getCropping(el) {
-		
-		var w = $(window); 
-		var right = w.width() + w.scrollLeft();
-		var bottom = w.height() + w.scrollTop();		
-		
-		return [
-			el.offset().top <= w.scrollTop(), 						// top
-			right <= el.offset().left + el.width(),				// right
-			bottom <= el.offset().top + el.height(),			// bottom
-			w.scrollLeft() >= el.offset().left 					// left
-		]; 
-	}
-	
-	/*
-		Returns true if all edges of an element are on viewport. false if not
-		
-		@param crop the cropping array returned by getCropping function
-	 */
-	function isVisible(crop) {
-		var i = crop.length;
-		while (i--) {
-			if (crop[i]) { return false; }	
-		}
-		return true;
-	}
-	
-	// dynamic plugin
-	$.fn.dynamic = function(conf) {
-		
-		if (typeof conf == 'number') { conf = {speed: conf}; }
-		
-		conf = $.extend({}, t.dynamic.conf, conf);
-		
-		var cls = conf.classNames.split(/\s/), orig;	
-			
-		this.each(function() {		
-				
-			var api = $(this).tooltip().onBeforeShow(function(e, pos) {				
-
-				// get nessessary variables
-				var tip = this.getTip(), tipConf = this.getConf();  
-
-				/*
-					We store the original configuration and use it to restore back to the original state.
-				*/					
-				if (!orig) {
-					orig = [
-						tipConf.position[0], 
-						tipConf.position[1], 
-						tipConf.offset[0], 
-						tipConf.offset[1], 
-						$.extend({}, tipConf)
-					];
-				}
-				
-				/*
-					display tip in it's default position and by setting visibility to hidden.
-					this way we can check whether it will be on the viewport
-				*/
-				$.extend(tipConf, orig[4]);
-				tipConf.position = [orig[0], orig[1]];
-				tipConf.offset = [orig[2], orig[3]];
-
-				tip.css({
-					visibility: 'hidden',
-					position: 'absolute',
-					top: pos.top,
-					left: pos.left 
-				}).show(); 
-				
-				// now let's see for hidden edges
-				var crop = getCropping(tip);		
-								
-				// possibly alter the configuration
-				if (!isVisible(crop)) {
-					
-					// change the position and add class
-					if (crop[2]) { $.extend(tipConf, conf.top);		tipConf.position[0] = 'top'; 		tip.addClass(cls[0]); }
-					if (crop[3]) { $.extend(tipConf, conf.right);	tipConf.position[1] = 'right'; 	tip.addClass(cls[1]); }					
-					if (crop[0]) { $.extend(tipConf, conf.bottom); 	tipConf.position[0] = 'bottom';	tip.addClass(cls[2]); } 
-					if (crop[1]) { $.extend(tipConf, conf.left);		tipConf.position[1] = 'left'; 	tip.addClass(cls[3]); }					
-					
-					// vertical offset
-					if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; }
-					
-					// horizontal offset
-					if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; }
-				}  
-				
-				tip.css({visibility: 'visible'}).hide();
-		
-			});
-			
-			// restore positioning as soon as possible
-			api.onBeforeShow(function() {
-				var c = this.getConf(), tip = this.getTip();		 
-				setTimeout(function() { 
-					c.position = [orig[0], orig[1]];
-					c.offset = [orig[2], orig[3]];
-				}, 0);
-			});
-			
-			// remove custom class names and restore original effect
-			api.onHide(function() {
-				var tip = this.getTip(); 
-				tip.removeClass(conf.classNames);
-			});
-				
-			ret = api;
-			
-		});
-		
-		return conf.api ? ret : this;
-	};	
-	
-}) (jQuery);
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/tooltip.dynamic.min.js
--- a/htdocs/js/tooltip.dynamic.min.js	Thu May 19 00:38:30 2011 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-/*
- 
- jQuery Tools 1.2.5 / Tooltip Dynamic Positioning
-
- NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
-
- http://flowplayer.org/tools/tooltip/dynamic.html
-
- Since: July 2009
- Date:    Wed Sep 22 06:02:10 2010 +0000 
-*/
-(function(g){function j(a){var c=g(window),d=c.width()+c.scrollLeft(),h=c.height()+c.scrollTop();return[a.offset().top<=c.scrollTop(),d<=a.offset().left+a.width(),h<=a.offset().top+a.height(),c.scrollLeft()>=a.offset().left]}function k(a){for(var c=a.length;c--;)if(a[c])return false;return true}var i=g.tools.tooltip;i.dynamic={conf:{classNames:"top right bottom left"}};g.fn.dynamic=function(a){if(typeof a=="number")a={speed:a};a=g.extend({},i.dynamic.conf,a);var c=a.classNames.split(/\s/),d;this.each(function(){var h=
-g(this).tooltip().onBeforeShow(function(e,f){e=this.getTip();var b=this.getConf();d||(d=[b.position[0],b.position[1],b.offset[0],b.offset[1],g.extend({},b)]);g.extend(b,d[4]);b.position=[d[0],d[1]];b.offset=[d[2],d[3]];e.css({visibility:"hidden",position:"absolute",top:f.top,left:f.left}).show();f=j(e);if(!k(f)){if(f[2]){g.extend(b,a.top);b.position[0]="top";e.addClass(c[0])}if(f[3]){g.extend(b,a.right);b.position[1]="right";e.addClass(c[1])}if(f[0]){g.extend(b,a.bottom);b.position[0]="bottom";e.addClass(c[2])}if(f[1]){g.extend(b,
-a.left);b.position[1]="left";e.addClass(c[3])}if(f[0]||f[2])b.offset[0]*=-1;if(f[1]||f[3])b.offset[1]*=-1}e.css({visibility:"visible"}).hide()});h.onBeforeShow(function(){var e=this.getConf();this.getTip();setTimeout(function(){e.position=[d[0],d[1]];e.offset=[d[2],d[3]]},0)});h.onHide(function(){var e=this.getTip();e.removeClass(a.classNames)});ret=h});return a.api?ret:this}})(jQuery);
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/tooltip.js
--- a/htdocs/js/tooltip.js	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/js/tooltip.js	Thu May 19 14:28:57 2011 +0800
@@ -79,7 +79,7 @@
 		
 	/* calculate tip position relative to the trigger */  	
 	function getPosition(trigger, tip, conf) {	
-
+        return {};
 		
 		// get origin top/left position 
 		var top = conf.relative ? trigger.position().top : trigger.offset().top, 
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/js/tooltip.min.js
--- a/htdocs/js/tooltip.min.js	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/js/tooltip.min.js	Thu May 19 14:28:57 2011 +0800
@@ -9,7 +9,7 @@
  Since: November 2008
  Date:    Wed Sep 22 06:02:10 2010 +0000 
 */
-(function(f){function p(a,b,c){var h=c.relative?a.position().top:a.offset().top,d=c.relative?a.position().left:a.offset().left,i=c.position[0];h-=b.outerHeight()-c.offset[0];d+=a.outerWidth()+c.offset[1];if(/iPad/i.test(navigator.userAgent))h-=f(window).scrollTop();var j=b.outerHeight()+a.outerHeight();if(i=="center")h+=j/2;if(i=="bottom")h+=j;i=c.position[1];a=b.outerWidth()+a.outerWidth();if(i=="center")d-=a/2;if(i=="left")d-=a;return{top:h,left:d}}function u(a,b){var c=this,h=a.add(c),d,i=0,j=
+(function(f){function p(a,b,c){return {};var h=c.relative?a.position().top:a.offset().top,d=c.relative?a.position().left:a.offset().left,i=c.position[0];h-=b.outerHeight()-c.offset[0];d+=a.outerWidth()+c.offset[1];if(/iPad/i.test(navigator.userAgent))h-=f(window).scrollTop();var j=b.outerHeight()+a.outerHeight();if(i=="center")h+=j/2;if(i=="bottom")h+=j;i=c.position[1];a=b.outerWidth()+a.outerWidth();if(i=="center")d-=a/2;if(i=="left")d-=a;return{top:h,left:d}}function u(a,b){var c=this,h=a.add(c),d,i=0,j=
 0,m=a.attr("title"),q=a.attr("data-tooltip"),r=o[b.effect],l,s=a.is(":input"),v=s&&a.is(":checkbox, :radio, select, :button, :submit"),t=a.attr("type"),k=b.events[t]||b.events[s?v?"widget":"input":"def"];if(!r)throw'Nonexistent effect "'+b.effect+'"';k=k.split(/,\s*/);if(k.length!=2)throw"Tooltip: bad events configuration for "+t;a.bind(k[0],function(e){clearTimeout(i);if(b.predelay)j=setTimeout(function(){c.show(e)},b.predelay);else c.show(e)}).bind(k[1],function(e){clearTimeout(j);if(b.delay)i=
 setTimeout(function(){c.hide(e)},b.delay);else c.hide(e)});if(m&&b.cancelDefault){a.removeAttr("title");a.data("title",m)}f.extend(c,{show:function(e){if(!d){if(q)d=f(q);else if(b.tip)d=f(b.tip).eq(0);else if(m)d=f(b.layout).addClass(b.tipClass).appendTo(document.body).hide().append(m);else{d=a.next();d.length||(d=a.parent().next())}if(!d.length)throw"Cannot find tooltip for "+a;}if(c.isShown())return c;d.stop(true,true);var g=p(a,d,b);b.tip&&d.html(a.data("title"));e=e||f.Event();e.type="onBeforeShow";
 h.trigger(e,[g]);if(e.isDefaultPrevented())return c;g=p(a,d,b);d.css({position:"absolute",top:g.top,left:g.left});l=true;r[0].call(c,function(){e.type="onShow";l="full";h.trigger(e)});g=b.events.tooltip.split(/,\s*/);if(!d.data("__set")){d.bind(g[0],function(){clearTimeout(i);clearTimeout(j)});g[1]&&!a.is("input:not(:checkbox, :radio), textarea")&&d.bind(g[1],function(n){n.relatedTarget!=a[0]&&a.trigger(k[1].split(" ")[0])});d.data("__set",true)}return c},hide:function(e){if(!d||!c.isShown())return c;
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/stc/ajaxtip.css
--- a/htdocs/stc/ajaxtip.css	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/stc/ajaxtip.css	Thu May 19 14:28:57 2011 +0800
@@ -1,6 +1,6 @@
 .ajaxtooltip {
     padding: .2em .5em;
-    z-index: 99;
+    z-index: 999;
     text-align: left;
     color: #000;
     background: #fff;
diff -r 1047502ac1c7 -r a1a1c6af9228 htdocs/stc/contextualhover.css
--- a/htdocs/stc/contextualhover.css	Thu May 19 00:38:30 2011 +0800
+++ b/htdocs/stc/contextualhover.css	Thu May 19 14:28:57 2011 +0800
@@ -3,7 +3,7 @@
     margin: 5px 0 0 20px;
     font: normal 11px "Arial", "Verdana", sans-serif !important;
     text-align: left;
-    z-index: 99;
+    z-index: 999;
     }
 
 * html div.ContextualPopup {
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org