PageSourceSearch

https://www.smspower.org/pub/nicetitle.js

js smspower.org collected 2026-10-01 11:26:49 UTC 12,283 bytes, 325 lines download raw bytes

1/* =================================================================================================
2* NiceTitles
3* 20th September 2004
4* http://neo.dzygn.com/code/nicetitles
5*
6* NiceTitles turns your boring (X)HTML tags into a dynamic experience
7* Modified by Kevin Hale for unfoldedorigami.com use. Nicetitles now works with images and follows the mouse.
8*
9* Copyright (c) 2003 - 2004 Stuart Langridge, Paul McLanahan, Peter Janes, Brad Choate, Dunstan Orchard, Ethan Marcotte, Mark Wubben, Kevin Hale
10* 
11*
12* Licensed under MIT - http://www.opensource.org/licenses/mit-license.php
13==================================================================================================*/
14
15function NiceTitles(sTemplate, nDelay, nStringMaxLength, nMarginX, nMarginY, sContainerID, sClassName){
16	var oTimer;
17	var isActive = false;
18	var showingAlready = false; //added var to start cursor tracking only AFTER delay occurs in show();
19	var sNameSpaceURI = "http://www.w3.org/1999/xhtml";
20	
21	if(!sTemplate){ sTemplate = "attr(nicetitle)";}
22	if(!nDelay || nDelay <= 0){ nDelay = false;}
23	if(!nStringMaxLength){ nStringMaxLength = 255; }
24	if(!nMarginX){ nMarginX = 10; }
25	if(!nMarginY){ nMarginY = 20; }
26	if(!sContainerID){ sContainerID = "nicetitlecontainer";}
27	if(!sClassName){ sClassName = "nicetitle";}
28
29	var oContainer = document.getElementById(sContainerID);
30	if(!oContainer){
31		oContainer = document.createElementNS ? document.createElementNS(sNameSpaceURI, "div") : document.createElement("div");
32		oContainer.setAttribute("id", sContainerID);
33		oContainer.className = sClassName;
34		oContainer.style.display = "none";
35		document.getElementsByTagName("body").item(0).appendChild(oContainer);
36	}
37	
38	//=====================================================================
39	// Method addElements (Public)
40	//=====================================================================
41	this.addElements = function addElements(collNodes, sAttribute){
42		var currentNode, sTitle;
43		
44		for(var i = 0; i < collNodes.length; i++){
45			currentNode = collNodes[i];
46		
47			sTitle = currentNode.getAttribute(sAttribute);
48			if(sTitle){
49				currentNode.setAttribute("nicetitle", sTitle);
50				currentNode.removeAttribute(sAttribute);
51				addEvent(currentNode, 'mouseover', show);
52				addEvent(currentNode, 'mouseout', hide);
53				addEvent(currentNode, 'mousemove', reposition); //added to allow cursor tracking
54				addEvent(currentNode, 'focus', show);
55				addEvent(currentNode, 'blur', hide);
56			}
57		}
58
59	}
60	
61	//=====================================================================
62	// Other Methods (All Private)
63	//=====================================================================
64	function show(e){
65		if (isActive){ hide(); }
66		
67		var oNode = window.event ? window.event.srcElement : e.currentTarget;
68		if(!oNode.getAttribute("nicetitle")){ 
69			while(oNode.parentNode){
70				oNode = oNode.parentNode; // immediately goes to the parent, thus we can only have element nodes
71				if(oNode.getAttribute("nicetitle")){ break;	}
72			}
73		}
74
75		var sOutput = parseTemplate(oNode);
76		setContainerContent(sOutput);
77		var oPosition = getPosition(e, oNode);
78		oContainer.style.left = oPosition.x;
79		oContainer.style.top = oPosition.y;
80
81		//added showingAlready. cursor tracks only after delay occurs
82		if(nDelay){	
83			oTimer = setTimeout(function(){oContainer.style.display = "block"; showingAlready = true;}, nDelay);
84		} else {
85			oContainer.style.display = "block";
86		}
87
88		isActive = true;		
89		// Let's put this event to a halt before it starts messing things up
90		window.event ? window.event.cancelBubble = true : e.stopPropagation();
91	}
92	
93	function hide(){
94		clearTimeout(oTimer);
95		oContainer.style.display = "none";
96		removeContainerContent();
97		isActive = false;
98		showingAlready = false;
99	}
100	
101	//function added to allow cursor tracking
102	function reposition(e){
103		var oNode = window.event ? window.event.srcElement : e.currentTarget;
104
105		var oPosition = getPosition(e, oNode);
106		oContainer.style.left = oPosition.x;
107		oContainer.style.top = oPosition.y;
108		
109		if(showingAlready){
110		oContainer.style.display = "block";}
111		else{
112		oContainer.style.display = "none";}
113		
114		isActive = true;
115		// Let's put this event to a halt before it starts messing things up
116		window.event ? window.event.cancelBubble = true : e.stopPropagation();
117	}
118
119	function setContainerContent(sOutput){
120		sOutput = sOutput.replace(/&/g, "&amp;").replace(/\n/g, "<br/>");
121		if(document.createElementNS && window.DOMParser){
122			var oXMLDoc = (new DOMParser()).parseFromString("<root xmlns=\""+sNameSpaceURI+"\">"+sOutput+"</root>", "text/xml");
123			var oOutputNode = document.importNode(oXMLDoc.documentElement, true);
124			var oChild = oOutputNode.firstChild;
125			var nextChild;
126			while(oChild){
127				nextChild = oChild.nextSibling; // Once the child is appended, the nextSibling reference is gone
128				oContainer.appendChild(oChild);
129				oChild = nextChild;
130			}
131		} else {
132			oContainer.innerHTML = sOutput;
133		}
134	}
135	
136	function removeContainerContent(){
137		var oChild = oContainer.firstChild;
138		var nextChild;
139
140		if(!oChild){ return; }
141		while(oChild){
142			nextChild = oChild.nextSibling;
143			oContainer.removeChild(oChild);
144			oChild =  nextChild;
145		}
146	}
147	
148	function getPosition(e, oNode){
149		var oViewport = getViewport();
150		var oCoords;
151		var commonEventInterface = window.event ? window.event : e;
152
153		if(commonEventInterface.type == "focus"){
154			oCoords = getNodePosition(oNode);	
155			oCoords.x += nMarginX;
156			oCoords.y += nMarginY;			
157		} else {
158			oCoords = { x : commonEventInterface.clientX + oViewport.x + nMarginX, y : commonEventInterface.clientY + oViewport.y + nMarginY};
159		}
160		
161		// oContainer needs to be displayed before width and height can be retrieved
162		if(showingAlready == false) // if statement prevents flickering in os x firefox when tracking cursor
163			{oContainer.style.visiblity = "hidden"; 
164			 oContainer.style.display =  "block";}
165		var containerWidth = oContainer.offsetWidth;
166		var containerHeight = oContainer.offsetHeight;
167		if(showingAlready == false)
168			{oContainer.style.display = "none"; 
169			 oContainer.style.visiblity = "visible";}
170
171		if(oCoords.x + containerWidth + 10 >= oViewport.width + oViewport.x){
172			oCoords.x = oViewport.width + oViewport.x - containerWidth - 10;
173		}
174		if(oCoords.y + containerHeight + 10 >= oViewport.height + oViewport.y){
175			oCoords.y = oViewport.height + oViewport.y - containerHeight - oNode.offsetHeight - 10;
176		}
177
178		oCoords.x += "px";
179		oCoords.y += "px";
180
181		return oCoords;
182	}
183
184	function parseTemplate(oNode){
185		var sAttribute, collOptionalAttributes;
186		var oFound = {};
187		var sResult = sTemplate;
188		
189		if(sResult.match(/content\(\)/)){
190			sResult = sResult.replace(/content\(\)/g, getContentOfNode(oNode));
191		}
192		
193		var collSearch = sResult.split(/attr\(/);
194		for(var i = 1; i < collSearch.length; i++){
195			sAttribute = collSearch[i].split(")")[0];
196			oFound[sAttribute] = oNode.getAttribute(sAttribute);
197			if(oFound[sAttribute] && oFound[sAttribute].length > nStringMaxLength){
198				oFound[sAttribute] = oFound[sAttribute].substring(0, nStringMaxLength) + "...";
199			}
200		}
201		
202		var collOptional = sResult.split("?")
203		for(var i = 1; i < collOptional.length; i += 2){
204			collOptionalAttributes = collOptional[i].split("attr(");
205			for(var j = 1; j < collOptionalAttributes.length; j++){
206				sAttribute = collOptionalAttributes[j].split(")")[0];
207
208				if(!oFound[sAttribute]){ sResult = sResult.replace(new RegExp("\\?[^\\?]*attr\\("+sAttribute+"\\)[^\\?]*\\?", "g"), "");	}
209			}
210		}
211		sResult = sResult.replace(/\?/g, "");
212		
213		for(sAttribute in oFound){
214			sResult = sResult.replace("attr\("+sAttribute+"\)", oFound[sAttribute]);
215		}
216		
217		return sResult;
218	}	
219		
220	function getContentOfNode(oNode){
221		var sContent = "";
222		var oSearch = oNode.firstChild;
223
224		while(oSearch){
225			if(oSearch.nodeType == 3){
226				sContent += oSearch.nodeValue;
227			} else if(oSearch.nodeType == 1 && oSearch.hasChildNodes){
228				sContent += getContentOfNode(oSearch);
229			}
230			oSearch = oSearch.nextSibling
231		}
232
233		return sContent;
234	}
235	
236	function getNodePosition(oNode){
237		var x = 0;
238		var y = 0;
239
240		do {
241			if(oNode.offsetLeft){ x += oNode.offsetLeft }
242			if(oNode.offsetTop){ y += oNode.offsetTop }
243		}	while((oNode = oNode.offsetParent) && !document.all) // IE gets the offset 'right' from the start
244
245		return {x : x, y : y}
246	}
247	
248	// Idea from 13thParallel: http://13thparallel.net/?issue=2002.06&title=viewport
249	function getViewport(){
250		var width = 0;
251		var height = 0;
252		var x = 0;
253		var y = 0;
254		
255		if(document.documentElement && document.documentElement.clientWidth){
256			width = document.documentElement.clientWidth;
257			height = document.documentElement.clientHeight;
258			x = document.documentElement.scrollLeft;
259			y = document.documentElement.scrollTop;
260		} else if(document.body && document.body.clientWidth){
261			width = document.body.clientWidth;
262			height = document.body.clientHeight;
263			x = document.body.scrollLeft;
264			y = document.body.scrollTop;
265		}
266		// we don't use an else if here, since Opera 7 tends to get the height on the documentElement wrong
267		if(window.innerWidth){ 
268			width = window.innerWidth - 18;
269			height = window.innerHeight - 18;
270		}
271
272		x = window.pageXOffset ? window.pageXOffset : window.scrollX ? window.scrollX : x;
273		y = window.pageYOffset ? window.pageYOffset : window.scrollY ? window.scrollY : y;
274		
275		return {width : width, height : height, x : x, y : y };		
276	}
277}
278
279//=====================================================================
280// Event Listener
281// by Scott Andrew - http://scottandrew.com
282// edited by Mark Wubben, <useCapture> is now set to false
283//=====================================================================
284function addEvent(obj, evType, fn){
285	if(obj.addEventListener){
286		obj.addEventListener(evType, fn, false); 
287		return true;
288	} else if (obj.attachEvent){
289		var r = obj.attachEvent('on'+evType, fn);
290		return r;
291	} else {
292		return false;
293	}
294}
295
296//=====================================================================
297// Here the default nice titles are created
298//=====================================================================
299NiceTitles.autoCreation = function(){
300	if(!document.getElementsByTagName){ return; }
301
302	NiceTitles.autoCreated = new Object();
303
304	var delay = 1;
305
306	NiceTitles.autoCreated.anchors = new NiceTitles("<p class=\"titletext\">attr(nicetitle)? <span class=\"accesskey\">[attr(accesskey)]</span>?</p><p class=\"destination\">attr(href)</p>", delay);
307	NiceTitles.autoCreated.acronyms = new NiceTitles("<p class=\"titletext\">content(): attr(nicetitle)</p>", delay);
308	//for image nicetitles based off alt tags
309	NiceTitles.autoCreated.images = new NiceTitles("<p class=\"titletext\">attr(nicetitle)</p>", delay);
310	//for form nicetitles. just add title to input and textarea tags
311	NiceTitles.autoCreated.input = new NiceTitles("<p class=\"titletext\">attr(nicetitle)</p><p class=\"destination\">? <span class=\"accesskey\">Accesskey : [attr(accesskey)]</span>?</p>", delay);
312	NiceTitles.autoCreated.simple = new NiceTitles("<p class=\"titletext\">attr(nicetitle)</p>", delay);
313	
314	NiceTitles.autoCreated.anchors.addElements(document.getElementsByTagName("a"), "title");
315	NiceTitles.autoCreated.images.addElements(document.getElementsByTagName("img"), "title"); //added
316//	NiceTitles.autoCreated.acronyms.addElements(document.getElementsByTagName("acronym"), "title");
317//	NiceTitles.autoCreated.acronyms.addElements(document.getElementsByTagName("abbr"), "title");
318//	NiceTitles.autoCreated.input.addElements(document.getElementsByTagName("input"), "id"); //added
319//	NiceTitles.autoCreated.input.addElements(document.getElementsByTagName("textarea"), "id"); //added
320	NiceTitles.autoCreated.simple.addElements(document.getElementsByTagName("div"), "title");
321	NiceTitles.autoCreated.simple.addElements(document.getElementsByTagName("span"), "title");
322	NiceTitles.autoCreated.simple.addElements(document.getElementsByTagName("button"), "title");
323}
324
325addEvent(window, "load", NiceTitles.autoCreation);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.