PageSourceSearch

https://webtribute.ch/components/com_extrawatch/js/extrawatch.js

js webtribute.ch collected 2026-10-08 18:32:57 UTC 14,087 bytes, 379 lines download raw bytes

1/**
2 * ExtraWatch - A real-time ajax monitor and live stats
3 * @license http://www.gnu.org/licenses/gpl-3.0.txt     GNU General Public License v3
4 * @copyright (C) by CodeGravity.com - All rights reserved!
5 * @website http://www.codegravity.com
6 */
7
8var ew_Utf8Encoder = { //added ex_ to avoid conflicts
9    /** Credits: http://www.webtoolkit.info/javascript-url-decode-encode.html **/
10
11// URL utf-8 encoding  	 	    	    		  	 	  	 	  		 	 		    	 			 	   		  	 	 		 	 	   	      	  	 		 		 				 			 		  		    	 		 		  
12    encode : function (str) {
13        return escape(ew_Utf8Encoder._utf8_encode(str));
14    },
15
16// UTF-8 encoding
17    _utf8_encode : function (str) {
18        str = str.replace(/\r\n/g,"\n");
19        var encoded_str = "";
20
21        for (var n = 0; n < str.length; n++) {
22            var c = str.charCodeAt(n);
23            if (c < 128) {
24                encoded_str += String.fromCharCode(c);
25            }
26            else if((c > 127) && (c < 2048)) {
27                encoded_str += String.fromCharCode((c >> 6) | 192);
28                encoded_str += String.fromCharCode((c & 63) | 128);
29            } else {
30                encoded_str += String.fromCharCode((c >> 12) | 224);
31                encoded_str += String.fromCharCode(((c >> 6) & 63) | 128);
32                encoded_str += String.fromCharCode((c & 63) | 128);
33            }
34        }
35        return encoded_str;
36    },
37
38    /** prevent restricted %2F in paths */
39    ew_encodeURIComponent : function (str) {
40        str = str.replace("/","_SLASH_");
41        str = encodeURIComponent(str);
42        return str;
43    }
44
45}
46
47var ew_Helper = {   /* helper functions which can be used anywhere*/
48    replaceString: function (_str, _search, _replace) {
49        var re = new RegExp(_search, 'g')
50        return _str.replace(re, _replace);
51    },
52
53    getQueryVariable: function (variable) {
54        var query = window.location.search.substring(1);
55        var vars = query.split("&");
56        for (var i = 0; i < vars.length; i++) {
57            var pair = vars[i].split("=");
58            if (pair[0] == variable) {
59                return pair[1];
60            }
61        }
62    },
63    endsWith: function (str, suffix) {
64		if (str == null || suffix == null) {
65			return false;
66		}
67        return str.indexOf(suffix, str.length - suffix.length) !== -1;
68    },
69    startsWith : function(str, prefix) {
70		if (str == null || prefix == null) {
71			return false;
72		}
73		return str.indexOf(prefix) === 0;
74    }
75}
76
77
78function extrawatch_createRequestObject() {
79    var ro;
80    if(window.ActiveXObject){
81        ro = new ActiveXObject("Microsoft.XMLHTTP");
82    }else{
83        ro = new XMLHttpRequest();
84    }
85    return ro;
86}
87
88
89
90var ew_Heatmap = {
91
92    extraWatch_click : function(evt, frontendTokenToPass, uri2titleId) {
93
94        var positionFromEvent = ew_Heatmap.getPositionFromEvent(evt);
95        var xpath = ew_Heatmap.createXPathFromElement(evt.target);
96
97        var scrollx = window.pageXOffset == undefined ? clickDoc.scrollLeft : window.pageXOffset;
98        var scrolly = window.pageYOffset == undefined ? clickDoc.scrollTop : window.pageYOffset;
99
100        /* Is the click in the viewing area? Not on scrollbars. The problem still exists for FF on the horizontal scrollbar */
101        var url = urlBase + "&params=" + encodeURIComponent("&action=click&uri2titleId=" + uri2titleId + "&x=" + positionFromEvent[0] + "&y=" + positionFromEvent[1] + "&w=" + w + "&h=" + h + "&xpath=" + encodeURIComponent(encodeURIComponent(xpath)));
102
103
104        if(ew_Heatmap.checkIfDoSynchronousClick(evt))	  {
105            downloadUrl(url, function (e) {}, true, false);	//download it synchronously
106        } else {
107			setTimeout(function() {
108				downloadUrl(url, function (e) {}, true);
109			}, 100);	//we had to add some delay so that this call is last one. If it was called first, it was causing some problems with some shopping cart ajax calls
110        }
111
112
113		},
114    keyListener: function (evt) {
115        var evt = (evt) ? evt : ((event) ? event : null);
116        var key = (evt) ? evt.which : event.keyCode;
117
118        if (String.fromCharCode(key) == "p") {
119            ew_Heatmap.changeDayInUrl(-1);
120        } else if (String.fromCharCode(key) == "n") {
121            ew_Heatmap.changeDayInUrl(1);
122        } else if (String.fromCharCode(key) == "t") {
123            ew_Heatmap.toggleHeatmap();
124        }
125    },
126
127    changeDayInUrl: function (_increment) {
128        var dayVariable = "extraWatchDay";	//todo - move to constants
129        var location = document.location.href;
130        var extraWatchDay = ew_Helper.getQueryVariable(dayVariable);
131        var prevDay = parseInt(extraWatchDay) + _increment;
132        var newLocationString = ew_Helper.replaceString(location, extraWatchDay, prevDay);
133        document.location.href = newLocationString;
134    },
135
136    toggleHeatmap: function () {
137        xx.toggleDisplay();
138    },
139
140
141    /**
142     source and thanks to: http://nickthecoder.wordpress.com/2013/02/26/offsetx-and-offsety-in-firefox/
143     */
144    ew_getOffset: function (evt) {
145        if (evt.offsetX != undefined)
146            return {x: evt.offsetX, y: evt.offsetY};
147
148        var el = evt.target;
149        var offset = {x: 0, y: 0};
150
151        while (el.offsetParent) {
152            offset.x += el.offsetLeft;
153            offset.y += el.offsetTop;
154            el = el.offsetParent;
155        }
156
157        offset.x = evt.pageX - offset.x;
158        offset.y = evt.pageY - offset.y;
159
160        return offset;
161    },
162
163    /* attach click event listener on onclick event */
164    attachExtraWatchClickListener: function (frontendTokenToPass, uri2titleId) {
165
166		if(false) {	//bugfix: binding via jquery was taking too long, using rather native js addEventListener //registering click listener via jQuery if it's loaded
167			jQuery(document).bind("click", function (event) {
168                ew_Heatmap.extraWatch_click(event, frontendTokenToPass, uri2titleId);
169				});
170		} else {
171			window.document.onclick = function (evt) {
172				if (window.addEventListener) {
173					window.addEventListener("onclick", ew_Heatmap.extraWatch_click(evt, frontendTokenToPass, uri2titleId), false);
174				} else if (window.attachEvent) {
175					window.attachEvent("onclick", ew_Heatmap.extraWatch_click(evt, frontendTokenToPass, uri2titleId));
176				} else {
177					window.addEventListener("onclick", ew_Heatmap.extraWatch_click(evt, frontendTokenToPass, uri2titleId), false);
178				}
179			}
180		}
181    },
182
183
184    extraWatch_decorateLinksWithCustomHandler: function (extraWatchLinkElementsList, frontendTokenToPass, uri2titleId) {
185		for (i = 0; i < extraWatchLinkElementsList.length; i++) {
186            try {
187                if (extraWatchLinkElementsList[i].onclick != null) {    /* go through all onclick methods */
188                    var replaceOnClick= ["javascript:",""];
189					window.ewTemp_frontendTokenToPass = frontendTokenToPass;
190					window.ewTemp_uri2titleId = uri2titleId;
191                    replaceOnClick.forEach(function(entry) {    /* for each search pattern */
192                            var searchMask = entry + "(.*)";
193                            var regEx = new RegExp(searchMask, "i");
194                            if (extraWatchLinkElementsList[i].outerHTML.match(regEx) != null) {  /* if outer HTML matches pattern */
195                                var replaceMask = entry + "ew_Heatmap.extraWatch_click\(event, window.ewTemp_frontendTokenToPass, window.ewTemp_uri2titleId\);$1;";  /* inserting click method before original onclick method content */
196								var originalOnClick = extraWatchLinkElementsList[i].getAttribute('onclick');
197								var decoratedOnClick = originalOnClick.replace(regEx, replaceMask);
198								extraWatchLinkElementsList[i].setAttribute('onclick', decoratedOnClick);
199                                return true;
200                            }
201                    });
202                }
203            } catch (e) {
204            }
205        }
206    },
207
208    findPos: function (obj) {
209        var curtop = 0;
210        if (obj.offsetParent) {
211            do {
212                curtop += obj.offsetTop;
213            } while (obj = obj.offsetParent);
214            return [curtop];
215        }
216    },
217
218    createXPathFromElement: function (elm) {
219        var allNodes = document.getElementsByTagName('*');
220        for (segs = []; elm && elm.nodeType == 1; elm = elm.parentNode) {
221            if (elm.hasAttribute('id')) {
222                var uniqueIdCount = 0;
223                for (var n = 0; n < allNodes.length; n++) {
224                    if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++;
225                    if (uniqueIdCount > 1) break;
226                }
227                ;
228                if (uniqueIdCount == 1) {
229                    //segs.unshift('id("' + elm.getAttribute('id') + '")');
230                    segs.unshift('//*[@id="' + elm.getAttribute('id') + '"]');
231                    return segs.join('/');
232                } else {
233                    segs.unshift(elm.localName.toLowerCase() + '[@id="' + elm.getAttribute('id') + '"]');
234                }
235            } else if (elm.hasAttribute('class')) {
236                segs.unshift(elm.localName.toLowerCase() + '[@class="' + elm.getAttribute('class') + '"]');
237            } else {
238                for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) {
239                    if (sib.localName == elm.localName)  i++;
240                }
241                ;
242                segs.unshift(elm.localName.toLowerCase() + '[' + i + ']');
243            }
244            ;
245        }
246        ;
247        return segs.length ? '/' + segs.join('/') : null;
248    },
249
250    isTargetElementNavigatingAway: function (target) {
251
252        switch (target.localName) {
253            case "a": {
254                /* if there's A element and contains # or javascript: in href="..." we are assuming that we are not navigating away */
255                if (target.href == "" || ew_Helper.endsWith(target.href,"#") || ew_Helper.startsWith(target.href, 'javascript:')) {
256                    return false;
257                }
258                return true;
259                break;
260            }
261            case "input": {
262				 switch (target.type) {
263						 
264					 case "button": {
265		                return false;	//we assume that all buttons are not navigating away, most of them are on site
266					 }
267					
268					 default : {	 
269                		if (target.type == "submit") {
270                    		return true;
271                		} else {
272                    		return false;
273                		}
274						break;
275					 }
276				}	 
277						 
278            }
279            case "submit": {
280                /* in case of submit and form buttons we'll assume this is navigating away */
281                return true;
282            }
283            default: {
284                return false;
285            }
286        }
287
288
289    },
290
291    checkIfElementContainsHrefWithHttp: function (targetElement, domain) {
292        while(targetElement != null) {  /* go through all parent elements */
293            if (targetElement.href != null && ew_Helper.startsWith(targetElement.href,"http") || ew_Helper.startsWith(targetElement.href,"https") /* && !(targetElement.href.indexOf(domain) > 0) */) {
294                return true;
295            }
296            targetElement = targetElement.parentElement;
297        };
298        return false;
299    },
300
301   checkIfElementContainsHash: function (targetElement, domain) {
302        while(targetElement != null) {  /* go through all parent elements */
303            if (targetElement.href != null && targetElement.href.indexOf("#") != -1) {
304                return true;
305            }
306            targetElement = targetElement.parentElement;
307        };
308        return false;
309    },
310
311
312    checkIfDoSynchronousClick: function (evt) {
313		var currentDomain = null;
314		if (window.location && window.location.href && window.location.href.split('/') && (window.location.href.split('/').length > 0)) {
315			currentDomain = window.location.href.split('/')[2];
316		}
317		if (evt.target != null && evt.target.type != null && evt.target.type == "submit") {	/* shopping cart submit buttons etc. */
318			return true;
319		}
320		if (evt.target != null && ew_Heatmap.checkIfElementContainsHash(evt.target, currentDomain)) {	//only for links which have http://
321			return false;
322		}
323
324		if (evt.target != null && ew_Heatmap.checkIfElementContainsHrefWithHttp(evt.target, currentDomain)) {	//only for links which have http://
325			return true;
326		}
327		
328        return false;    /* do synchronous click if navigating away */
329    },
330
331
332    getPositionFromEvent : function (evt) {
333        var pos = window.h337.util.mousePosition(evt); //relative position to element
334        if (evt.offsetX == null || evt.offsetY == null) {
335            var calculatedOffset = ew_Heatmap.ew_getOffset(evt);
336            var x = calculatedOffset.x;
337            var y = calculatedOffset.y;
338        } else {
339            var x = evt.offsetX; // offset relative within the element
340            var y = evt.offsetY;
341        }
342        return [x,y];
343    },
344
345    highlightElementsByXPath: function(xpathElements, document){
346        var xpath = null;
347        var length = xpathElements.length;
348
349        for (var i = 0; i < length; i++) {
350            xpath = xpathElements[i];
351            try {
352                var elementFound = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
353                var element = elementFound.singleNodeValue;
354                if (element != null) {
355                    element.style.border="2px solid " + xpathElementColors[i];
356                    element.style.backgroundColor=xpathElementColors[i];
357                }
358            } catch (e) {
359                //suppress if no element was found
360            }
361        }
362    },
363
364
365    renderHeatmap : function (randHash, data) {
366		try {
367			var ip = ew_Helper.getQueryVariable('ip');
368			var obj = eval( data );
369			xx.displayLoading
370			xx.store.setDataSet(obj);
371		} catch (e) {
372			alert("There was problem loading ExtraWatch Heatmap. This is not fault of ExtraWatch but fact that you might have some other javascript errors on your website.\n\nError:\n" + e.message + "\nStack:\n" + e.stack);
373		}
374    }
375
376
377
378}
379

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.