HTMLElement.prototype.outerHTML getter = function () { var tempDiv = document.createElement("div"); tempDiv.appendChild( this.cloneNode( true ) ); var html = tempDiv.innerHTML; tempDiv = null; return html; } Event.prototype.target getter = function() { return this.srcTarget; } /*===============================*/ /*= GENERAL =*/ /*===============================*/ RegExp.escape = function(text) { if (!arguments.callee.sRE) { var specials = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ]; arguments.callee.sRE = new RegExp( '(\\' + specials.join('|\\') + ')', 'g' ); } return text.replace(arguments.callee.sRE, '\\$1'); } var _CE = { $: function() { var results = [], element; for (var i = 0; i < arguments.length; i++) { element = arguments[i]; if (typeof element == 'string') element = document.getElementById(element); results.push(element); } return results.length < 2 ? results[0] : results; }, registerEvent: function(event_name, listener, target) { if ( !target ) target = window; //Add the listener if (target.addEventListener) { if ( event_name == "unload") event_name = "beforeunload"; target.addEventListener(event_name, listener, false); } else if (target.attachEvent) { if ( target == window && !(event_name == "unload" || event_name == "load")) target = window.document; target.attachEvent("on"+event_name, listener); } }, pos: function(node, target) { var ret = {}; ret.x = ret.y = 0; node = _CE.$(node); if ( !node.nodeName ) return {x: node.posX, y: node.posY}; if ( !node ) return {x:undefined, y:undefined}; if ( node.nodeName == "OPTION" ) { while(node = node.parentNode) { if ( node.nodeName == "SELECT" ) break; } return _CE.pos(node); } if ( !target ) target = document; if ( node.nodeName == "AREA" ) { return _CE.posForArea(node, target); } else { if ( _CE.isIE ) { with( node.getBoundingClientRect() ) { ret.x = left-1; ret.y = top-1; } var st = (target.parentWindow.pageYOffset || target.documentElement.scrollTop || target.body.scrollTop || 0); var sl = (target.parentWindow.pageXOffset || target.documentElement.scrollLeft || target.body.scrollLeft || 0); ret.x += sl; ret.y += st; } else { if( node["offsetParent"] ) { var endNode; if( (_CE.isSafari) && (node.style.getPropertyValue("position") == "absolute") && (node.parentNode == _CE.db)) { endNode = _CE.db; } else { endNode = _CE.db.parentNode; } do { var n = node["offsetLeft"]; ret.x += isNaN(n) ? 0 : n; var m = node["offsetTop"]; ret.y += isNaN(m) ? 0 : m; node = node.offsetParent; } while ( (node != endNode) && (node != null)); } else if ( node["x"]&&node["y"] ) { ret.x += isNaN(node.x) ? 0 : node.x; ret.y += isNaN(node.y) ? 0 : node.y; } } return ret; } }, sumAncestorProperties: function(node, prop, target) { if( !node ){ return 0; } var retVal = 0; while( node ) { var val = node[prop]; if(val){ retVal += val - 0; if( node == target.body){ break; } } node = node.parentNode; } return retVal; }, in_array: function(array, obj) { for ( var i=0; i r ) r = c; } for ( var i=1; i b ) b = c; } result = {left: l, top: t, right: r, bottom: b}; } area.rectDefined = true; area.rLeft = result.left; area.rRight = result.right; area.rTop = result.top; area.rBottom = result.bottom; return result; }, size: function(element) { element = _CE.$(element); if ( element.nodeName == "AREA") return _CE.sizeForArea(element); return { width: element.offsetWidth, height: element.offsetHeight }; }, sizeForArea: function(area) { var rect = _CE.rectForArea(area); return {width: (rect.right-rect.left), height: (rect.bottom-rect.top) }; }, getX: function(obj, target) { return _CE.pos(obj, target).x; }, getY: function(obj, target) { return _CE.pos(obj, target).y; }, getWidth: function(obj) { return _CE.size(obj).width; }, getHeight: function(obj) { return _CE.size(obj).height; }, pointer: function(event) { return {x: _CE.pointerX(event), y: _CE.pointerY(event)}; }, pointerX: function(event) { return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); }, pointerY: function(event) { return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); }, delay: function(millis) { date = new Date(); var curDate = null; do { var curDate = new Date(); } while(curDate-date < millis); }, event_element: function( event ) { if ( event.target || event.srcElement) { var element = (event.target || event.srcElement ); return element; } return null; }, add_elements: function(array, elements) { for ( var i=0; i).*/m,"$1") + result; } else result += ""; if ( !skipSibling || element.parentNode.nodeName.toLowerCase().match(simpleTags)) { if ( location == "before" ) result = this.surrounding_html(element.parentNode, location, true) + result; else { result = result + this.surrounding_html(element.parentNode, location); } } } else { if ( node ) { if ( element.nodeName.toLowerCase().match(simpleTags) || (!skipSibling && node.nodeName.toLowerCase().match(simpleTags) )) { if ( location == "before" ) result = this.surrounding_html(node, location, true) + result; else { result = result + this.surrounding_html(node, location, true); } } } } return result; } _CE.html_after = function(element) { return this.surrounding_html(element, "after"); } _CE.html_before = function(element) { return this.surrounding_html(element, "before"); } _CE.getElementsEquivalentToTagName = function(target, tagName) { if ( tagName == "OBJECT" || tagName == "EMBED" ) { if ( _CE.isMoz ) { return target.getElementsByTagName("embed"); } else { var results = new Array(); var elements = _CE.toArray(target.getElementsByTagName("object")).concat(_CE.toArray(target.getElementsByTagName("object"))); for ( var i=0; i start_x+width ) w = start_x+width - x; if ( y + h > start_y+height ) h = start_y+height - y; cover.style.width = w+"px"; cover.style.height = h+"px"; cover.style.fontSize = "1px"; cover.style.lineHeight = "0"; cover.style.left = x + "px"; cover.style.top = y + "px"; cover.style.padding = 0; cover.style.margin = 0; cover.style.border = "none"; cover.gridOffsetX = x-start_x; cover.gridOffsetY = y-start_y; //cover.style.background = grid_size == this.big_grid_size ? "red" : "blue"; //cover.style.border = "1px solid black"; cover.tracker = this; cover.onmouseover = this.cover_mouseover.ce_bind(cover); results.push(document.body.appendChild(cover)); } } return results; }, cover_untrackable: function(untrackable) { untrackable = _CE.$(untrackable); this.big_grid_size = 20; this.small_grid_size = 4; var size = _CE.size(untrackable); var pos = _CE.pos(untrackable); this.big_grid = this.create_grid(pos.x, pos.y, size.width, size.height, this.big_grid_size); this.small_grid = this.create_grid(pos.x, pos.y, this.big_grid_size, this.big_grid_size, this.small_grid_size); this.hide_small_grid(); untrackable.covered =true; }, hide_small_grid: function() { for ( var i=0; i= pos.x && pointer.y >= pos.y && pointer.x < pos.x+size.width && pointer.y < pos.y+size.height) { cover.style.display="none"; this.tracker.last_cover_moved = cover; break; } } } this.style.display = "none"; } else { //Just make sure we hide the big cover piece underneath this.tracker.last_cover_big_moved.style.display="none"; this.style.display = "none"; this.tracker.last_cover_moved = this; } }, register_event: function(event_name, target) { //Create the listener var listener = this["on"+event_name].ce_bindAsEventListener(this); _CE.registerEvent(event_name, listener, target); }, onunload: function(event) { var padding = 5; if ( this.lastMousePosition ) { //Check if we were "inside" of an untrackable for ( var i=0; i= pos.x-padding && this.lastMousePosition.x <= (pos.x + size.width+padding) && this.lastMousePosition.y >= pos.y-padding && this.lastMousePosition.y <= pos.y+size.height+padding ) { this.register_click(untrackable, relative_click, true, "onunload") } } } }, onmousemove: function(event) { this.lastMousePosition = {x: _CE.pointerX(event), y: _CE.pointerY(event)}; }, oncontextmenu: function(event) { var element; if ( element = _CE.event_element(event)) { this.register_click(element, _CE.click_position(element, event), false, "contextmenu"); } }, onclick: function(event) { var element = null; if ( element = _CE.event_element(event)) { if ( element != this.last_mouse_down_element ) { //Just pretend we did a mousedown on this this.onmousedown(event, true); } } }, onfocus: function(element) { if ( element && element != this.last_mouse_down_element && element != this.last_focus_element ) { this.last_mouse_down_element = null; this.last_focus_element = element; this.register_click(element, {x:0.5, y:0.5}, false, "focus"); } }, onmousedown: function(event,force_delay) { var element = null; if ( element = _CE.event_element(event) ) { if ( element != this.last_focus_element ) { this.last_mouse_down_element = element; this.last_focus_element = null; this.register_click(element, _CE.click_position(element, event), (force_delay || element.nodeName == "A" || element.onclick), "mousedown"); } } }, register_click: function(element, click, delay, event_type) { if ( this.is_trackable(element) ) { var live = this.is_live(element); if ( !live ) return false; var request = this.send_response({ html: element.outerHTML, html_before: _CE.html_before(element), html_after: _CE.html_after(element), time_to_click: this.time_to_click(), click_x: click.x, click_y: click.y, event_type: event_type, live: (live ? "true" : "false") }); var delay_amount = 350; if ( request.parts.length > 1) delay_amount += 150*(request.parts.length-1); if ( request.parts.length > 2) delay_amount += 100*(request.parts.length-2); if ( request.parts.length > 3) delay_amount += 100*(request.parts.length-3); if ( request.parts.length > 4) delay_amount += 50*(request.parts.length-4); if ( request.parts.length > 5) delay_amount += 50*(request.parts.length-5); if ( live && event_type != "contextmenu" && !this.skip_delay(element)) _CE.delay(delay_amount); } }, skip_delay: function(element) { if ( element ) { if ( element.nodeName == "SELECT") return true; } }, time_to_click: function() { var date = new Date(); return date.getTime() - this.start_time }, is_trackable: function(element) { if ( !element ) return false; if ( !element.outerHTML ) return false; if ( element.outerHTML.length > 3000 ) return false; //Check if it is valid tag var untrackable_tags = ["BODY", "OPTION", "HTML"]; for ( var i=0; i _CE.Request.MAX_LENGTH ) { //Save off the buffer this.parts.push(buffer); buffer = ""; } buffer += "&"+key+"=" var value = ""+this.parameters[key]; var start = 0; while(start value.length ) length = value.length - start; buffer += encodeURIComponent(value.substr(start, length)); } start += length; if ( start < value.length-1 ) { //Push to the buffer this.parts.push(buffer); buffer = "&"+key+"="; } } } this.parts.push(buffer); _CE.Request.count += 1; //Get a unique ID var rid = "3121186"+"-"+_CE.Request.count; var date = new Date(); if ( this.parts.length == 1 ) { this.create_transport(this.append(this.url, this.parts[0], "_rt=s", "_rid="+rid, "_ts="+date.getTime())); } else { //Don't send anything with more than 10 parts if ( this.parts.length < 10 ) { for ( var i=0; i