Source

scope.bitbucket.org / ui-elements / tooltip / index.html

Full commit
<!doctype html>
<link rel="stylesheet" href="../../resources/ui-scripts/tooltip/tooltip.css">
<style>
html,
body
{
	margin: 0;
	height: 100%;
	overflow: hidden;
}

#viewport
{
	height: 100%;
	overflow: auto;
}

#viewport > div
{
	float: left;
	padding: 10px;
}

h2
{
	width: 150px;
	padding: 10px;
	margin: 0;
	background-color: hsl(0, 0%, 90%);
	border-radius: 5px;
	text-align: center;
}

ul
{
	list-style: none;
	padding: 0;
}

span
{
	border: 1px solid hsl(0, 0%, 95%);
}

span:hover,
.hover
{
	background-color: hsl(210, 100%, 80%);
}

.url-table
{
	border-collapse: collapse;
}

.url-table td
{
	vertical-align: top;
	padding: 0 5px;
	 
}

.url-table td:nth-child(2)
{
	word-wrap: break-word;
}
</style>
<script src="../../resources/scripts/dom.js"></script>
<script src="../../resources/ui-scripts/tooltip/tooltip.js"></script>

<script>

var URL = function(url) {this._init(url)};

URL.PROPS = ["hash",
             "host",
             "hostname",
             "href", 
             "pathname",
             "port",
             "protocol",
             "search"];

URL.prototype = new function()
{

	URL.PROPS.forEach(function(prop)
	{
		this.__defineGetter__(prop, function()
		{
			if (!this._a)
			{
				this._a = document.createElement('a');
				this._a.href = this._url;
			}
			return this._a[prop];
		});
		this.__defineSetter__(prop, function(){});
	}, this);

	this.__defineGetter__('filename', function()
	{
		var pos = this.pathname.lastIndexOf('/');
		return pos > -1 ? this.pathname.slice(pos + 1) : "";
	});

	this.__defineSetter__('filename', function(){});

	this._init = function(url)
	{
		this._url = url;
	}
};

var urls =
[
	"http://www.nzz.ch/images/nzzexecutive_marktplatzteaser_gcp_teaserTopNews_1.4483277.1263198714.jpg",
	"http://www.nzz.ch/file/1.13345026.1321549760!thumb.jpg",
	"http://nzz.wemfbox.ch/cgi-bin/ivw/CP/nzzonline/nachrichten/startseite?r=&d=16476.42141779151&x=1024x768",
	"http://www.nzz.ch/js/swfobject-2.2.js",
	"http://www.nzz.ch/js/jquery-1.4.2.min.js",
	"http://nzz.wemfbox.ch/blank.gif",
	"http://aka-cdn-ns.adtech.de/apps/300/Ad6116652St3Sz154Sq101433066V0Id1/pochrono_realtime_1_300x600_en.swf?targetTAG=_blank&clickTarget=_blank&pathTAG=http%3A//aka-cdn-ns.adtech.de/apps/300/Ad6116652St3Sz154Sq101433066V0Id1/&closeTAG=javascript%3AcloseAdLayer2945478%28%29&openTAG=javascript%3AopenAdLayer2945478%28%29&expandTAG=javascript%3Aexpand2945478%28%29&collapseTAG=javascript%3Acollapse2945478%28%29&clicktarget=_blank&clickTarget=_blank&clickTARGET=_blank&CURRENTDOMAIN=www.nzz.ch",
	"http://www.nzz.ch/js/jquery.scrollto-1.4.2.js",
	"http://www.nzz.ch/js/jquery.fancybox-1.3.1.custom.js",
	"http://www.nzz.ch/js/jquery-ui-1.8.5.custom.min.js",
	"http://www.nzz.ch/js/init-15666.js",
	"http://www.nzz.ch/js/initDepartment-15666.js",
	"http://nzz.wemfbox.ch/2004/01/survey.js",
	"http://www.nzz.ch/statistic?cid=2.138&r=&d=77787.47876330526",
	"http://et.twyn.com/sense?pubid=154290&page=http://www.nzz.ch/",
	"http://nzz01.webtrekk.net/631747235379823/wt?p=312,www_nzz_ch.,1,1024x768,32,1,1321612723532,0,1024x728,1&tz=1&eid=2132161208300845516&one=0&fns=0&la=en&cp1=1_Kategorie_Home&eor=1",
	"http://adserver.adtech.de/bind?ckey1=twynet;cvalue1=NONE;expiresDays=0;adct=204;misc=1321612516271",
	"http://www.google-analytics.com/ga_beta.js",
	"http://www.google-analytics.com/__utm.gif?utmwv=5.2.2&utms=4&utmn=830551340&utmhn=www.nzz.ch&utmcs=utf-8&utmsr=1024x768&utmsc=32-bit&utmul=en&utmje=1&utmfl=10.1%20r102&utmdt=Startseite%20(NZZ%20Online%2C%20Neue%20Z%C3%BCrcher%20Zeitung)&utmhid=1533244502&utmr=-&utmp=%2F&utmac=UA-1925661-1&utmcc=__utma%3D120822999.1564935119.1321612084.1321612084.1321612084.1%3B%2B__utmz%3D120822999.1321612084.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)%3B&utmu=q~",
	"http://cdn.cxense.com/cx.js",
	"http://static.chartbeat.com/js/chartbeat.js",
	"http://ping.chartbeat.net/ping?h=nzz.ch&p=%2F&u=ecnt4hxuukmfg90z.1321612084170&d=nzz.ch&g=8912&n=1&c=0&x=0&y=1&w=728&j=45&R=0&W=0&I=1&r=&b=96&t=fof2qtsygfr8sgpj&i=Startseite%20(NZZ%20Online%2C%20Neue%20Z%C3%BCrcher%20Zeitung)&_",
	"http://comcluster.cxense.com/Repo/rep.html?ver=1&typ=pgv&rnd=irqjy4p8fuls&acc=9222267064078882903&sid=9222267064078882904&pid=0&loc=http%3A%2F%2Fwww.nzz.ch%2F&ref=&gol=&pgn=&ltm=1321612726486&tzo=-60&res=1024x768&jav=1&bln=en&cks=1321612084231477152327&ckp=13216120842311298368390&chs=utf-8&fls=1&flv=Shockwave%20Flash%2010.1%20r102"
].map(function(url){return new URL(url);});

window.onload = function()
{
	var tmpl = [];
	var cur = null;

	tmpl.push(cur = ['div', ['h2', 'default']]);
	for (var i = 1, ul; i < 4; i++)
	{
		cur.push(ul = ['ul']);
		for (var j = 0; j < 7; j++)
			ul.push(['li', 
			        ['span', 'item ' + (i * j),
			                 'data-tooltip', 'test',
			                 'data-tooltip-text', 'test ' + (i * j)]]);
		
	}

	tmpl.push(cur = ['div', ['h2', 'keep on hover']]);
	for (var i = 1, ul; i < 4; i++)
	{
		cur.push(ul = ['ul']);
		for (var j = 0; j < 7; j++)
			ul.push(['li', 
			        ['span', 'item ' + (i * j),
			                 'data-tooltip', 'test2',
			                 'data-tooltip-text', 'test ' + (i * j)]]);
		
	}

	tmpl.push(cur = ['div', ['h2', 'keep on hover with fixed offset']]);
	for (var i = 1, ul; i < 4; i++)
	{
		cur.push(ul = ['ul']);
		for (var j = 0; j < 7; j++)
			ul.push(['li', 
			        ['span', 'item ' + (i * j),
			                 'data-tooltip', 'test3',
			                 'data-tooltip-text', 'test ' + (i * j)]]);
		
	}

	tmpl.push(cur = ['div', ['h2', 'URLs']]);
	cur.push(ul = ['ul']);
	ul.extend(urls.map(function(url, index, urls)
	{
		return ['li', ['span', url.filename, 
		                       'data-tooltip', 'test-url',
		                       'data-index', String(index)]];
	}));
		
	

	document.getElementById('viewport').render(tmpl);
	
	Tooltips.register("test");

	(function()
  {
  	var tooltip = Tooltips.register("test2", true);
  	var last_target = null;
  	var reset_last_target = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  	tooltip.ontooltip = function(event, target)
  	{
  		this.show();
  		last_target = target;
  	};

   	tooltip.ontooltipenter = function()
  	{
  		if (last_target)
  			last_target.addClass('hover');
  	};

  	tooltip.ontooltipleave = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  })();

 	(function()
  {
  	var tooltip = Tooltips.register("test3", true);
  	var last_target = null;
  	var reset_last_target = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  	tooltip.ontooltip = function(event, target)
  	{
  		var box = target.getBoundingClientRect();
  		this.show(null, {top: box.top, 
	  		               bottom: box.bottom,
	  		               left: box.left + 30,
	  		               right: box.left + 10});
  		last_target = target;
  	};

   	tooltip.ontooltipenter = function()
  	{
  		if (last_target)
  			last_target.addClass('hover');
  	};

  	tooltip.ontooltipleave = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  })();

 	(function()
  {
  	var tooltip = Tooltips.register("test-url", true);
  	var last_target = null;
  	var reset_last_target = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  	tooltip.ontooltip = function(event, target)
  	{
  		var box = target.getBoundingClientRect();
  		var url = urls[target.getAttribute('data-index')];
  		var tmpl = ['table'].extend(URL.PROPS.reduce(function(list, prop)
	  	{
	  		if (url[prop])
  				list.push(['tr', ['td', prop], ['td', url[prop]]]);
  			return list;
  		}, []));
  		tmpl.push('class', 'url-table');

  		// this.show(tmpl, {top: box.top, bottom: box.bottom, left: box.left + 30});
  		this.show(tmpl);
  		last_target = target;
  	};

   	tooltip.ontooltipenter = function()
  	{
  		if (last_target)
  			last_target.addClass('hover');
  	};

  	tooltip.ontooltipleave = function()
  	{
  		if (last_target)
  			last_target.removeClass('hover');
  	};

  })();

}
</script>

<div id="viewport"></div>