Re: Some troubles with add-ons?
Posted: Mon Apr 01, 2013 12:36 pm
Code: Select all
/**
* Returns true if a group_id OR a group name matches the group_id OR the group_name of the person
* @public
* @function
* @param int person_id Id of the person to check
* @param object groups Object containing the groups to check.
* @returns bool true if a group_id OR a group name matches the group_id OR the group_name of the person
*/
function isPersonInGroup(person_id, groups) {
"use strict";
var i, j, person_groups;
if (groups !== null && typeof (groups) !== "undefined") {
if (persons && persons[person_id]) {
person_groups = persons[person_id].groups;
for (i = 0; i < groups.length; i += 1) {
for (j = 0; j < person_groups.length; j += 1) {
if (groups[i].group_id === person_groups[j].group_id) {
return true;
}
if (groups[i].group_name === person_groups[j].group_name) {
return true;
}
}
}
}
}
return false;
}
//===================================================================
// UCTWinScriptlets: tracklet/components/GoogleInstantTracker.js
//===================================================================
/*jsl:option explicit*/
/*jsl:declare CustomEventHelper*/
/*jsl:declare Base64*/
/*jsl:declare json_encode */
/*jsl:declare base64_json_encode */
/*jsl:declare parseURL*/
/*jsl:declare GacelaNavigateService*/
/*jsl:declare _private*/
/*jsl:declare GacelaEventService*/
/*jsl:declare Components*/
/*jsl:declare GacelaStorageService*/
//=============================================================================
// Google Instant Patch and Firefox Location Listener
// The patch detects Google Instant Update and PI Events
// For Firefox an additional Location Listener is needed to safely detect PIs
//=============================================================================
/*global Components, GacelaEventService, parseURL, GacelaNavigateService, Base64, JSON, CustomEventHelper, GacelaStorageService, _private, base64_json_encode*/
/**
* Google Instant Patch and Firefox Location Listener.
* The patch detects Google Instant Update and PI Events.
* For Firefox an additional Location Listener is needed to safely detect PIs.
* @class Additional Location Listener for Firefox, to safely detect PIs.
* @author Team Dev
* @public
* @param object browser Browser object
* @param object locationHashChangeHandler Function which handles the locationHashChangeEvent
*/
function CFirefoxLocationListener(browser, locationHashChangeHandler)
{
this.browser = browser;
this.locationHashChangeHandler = locationHashChangeHandler;
this.browser.addProgressListener(this, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
}
CFirefoxLocationListener.prototype = {
/**
* Does nothing
* @private
* @function
* @param {?} aSubject Subject
* @param {?} aTopic Topic
* @param {?} aData Data
*/
observe : function(aSubject, aTopic, aData) {
},
// Destructor - Frees all resources, removes event listeners,
/**
* Destructor - Frees all resources, removes event listeners
* @private
* @function
*/
remove : function() {
this.browser.removeProgressListener(this);
this.browser = null;
},
/**
* @private
* @property string locationHash Stores the locationHash
*/
locationHash: "",
/**
* onLocationChange
* @private
* @function
* @param object webProgress <i>unused</i>
* @param object request <i>unused</i>
* @param object location Location object
*/
onLocationChange: function(webProgress, request, location) {
var tmp, pos, loc = location.asciiSpec;
pos = loc.indexOf("#");
if (pos !== -1) {
tmp = loc.substring(pos);
if (tmp !== this.locationHash) {
this.locationHash = tmp;
if (this.locationHashChangeHandler) {
this.locationHashChangeHandler(location.asciiSpec);
}
}
} else if (this.locationHash !== "") {
this.locationHash = "";
this.locationHashChangeHandler(location.asciiSpec);
}
},
/**
* Does nothing
* @private
* @function
* @param object webProgress <i>unused</i>
* @param object request <i>unused</i>
* @param object location <i>unused</i>
*/
onStateChange: function(webProgress, request, stateFlags, status) {
},
// Not used, since we only receive NOTIFY_LOCATION Notifications
/**
* Does nothing
* @deprecated
* @private
* @function
* @param object webProgress <i>unused</i>
* @param object request <i>unused</i>
* @param object location <i>unused</i>
*/
onStatusChange: function(webProgress, request, status, message) {
},
// Not used, since we only receive NOTIFY_LOCATION Notifications
/**
* Does nothing
* @deprecated
* @private
* @function
* @param object webProgress <i>unused</i>
* @param object request <i>unused</i>
* @param object location <i>unused</i>
*/
onSecurityChange: function(webProgress, request, state) {
},
/**
* Does nothing
* @private
* @function
* @param object webProgress <i>unused</i>
* @param object request <i>unused</i>
* @param object curSelfProgress <i>unused</i>
* @param object maxSelfProgress <i>unused</i>
* @param object curTotalProgress <i>unused</i>
* @param object maxTotalProgress <i>unused</i>
*/
onProgressChange: function(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) {
},
/**
* Returns class instance if parameter equals WebProgressListener, Supports or SupportsWeakReference Interface
* @private
* @function
* @param object iid Interface object
* @returns object CFirefoxLocationListener
* @throws {Components.results.NS_ERROR_NO_INTERFACE} If parameter iid doesn't equals any of the mentioned interfaces
*/
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsISupportsWeakReference)) {
return this;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
/**
* Tracks google instant search queries
* @class Tracks google instant search queries
* @author Team Dev
* @public
* @param object config GoogleInstantTracker configuration
* @dependency tracklet Helper 15
* @dependency tracklet GfKBase 15
* @dependency tracklet CustomEventHelper 15
* @dependency tracklet GlobalConfiguration 127
*/
function GoogleInstantTracker(config)
{
/**
* @private
* @property object Trackconfig
*/
this.trackconfig = {};
/**
* Returns true if a group_id OR a group name matches the group_id OR the group_name of the person
* @private
* @function
* @param object groups Object containing the groups to check.
* @returns bool true if a group_id OR a group name matches the group_id OR the group_name of the person
*/
this.isPersonInGroup = function(groups) {
var userIndex = GacelaStorageService.get("CurrentAuthenticatedUser");
var i, j, person_groups;
if (groups !== null && typeof (groups) !== "undefined") {
if (this.persons && this.persons[userIndex]) {
person_groups = this.persons[userIndex].groups;
for (i = 0; i < groups.length; i += 1) {
for (j = 0; j < person_groups.length; j += 1) {
if (groups[i].group_id === person_groups[j].group_id) {
return true;
}
if (groups[i].group_name === person_groups[j].group_name) {
return true;
}
}
}
}
}
return false;
};
/**
* Prepares an event object and dispatches an GacelaEvent
* @private
* @function
* @param string evtName Name of the event to dispatch
* @param event e Event object
*/
this.dispatchGoogleInstantEvent = function(evtName, e) {
var evt = {};
if (typeof (e.document) === "undefined") {
// this is FF
evt.document = e.target.ownerDocument;
evt.url = e.target.getAttribute("url");
evt.mainframe = e.target.getAttribute("mainframe") === "true";
evt.newcontent = e.target.getAttribute("newcontent");
evt.targetid = e.target.getAttribute("targetid");
} else {
// this is IE
evt.document = e.document;
evt.url = e.url;
evt.mainframe = e.mainframe;
evt.newcontent = e.newcontent;
evt.targetid = e.targetid;
}
GacelaEventService.dispatchEvent(evtName, evt);
};
/**
* Checks if a given Document belongs to a Google page
* @private
* @function
* @param object doc Document of the page to check
* @returns bool True if the Document belongs to a google page, otherwise false
*/
this.isGooglePage = function(doc) {
if (!doc || !doc.location || !doc.location.href || !this.trackconfig || !doc.location.href.match(this.trackconfig.googleurlregexp)) {
return false;
}
return true;
};
/**
* Does the GoogleInstant tracking
* @private
* @function
* @param event e DocumentComplete event object
*/
this.onDocumentComplete = function(e, config) {
try {
//check actionlist
if (config !== null && typeof(config) !== "undefined") {
//check group_name
for (var i = 0; i < config.length; i += 1) {
if (this.isPersonInGroup(config[i].active_groups)) {
this.trackconfig = config[i].settings;
if (this.trackconfig) {
if (this.trackconfig.track_document_complete) {
this.TrackEvents(e);
}
}
}
}
}
} catch (ex) {
Logger.log("ERROR", "Error in GoogleInstantTracker.onDocumentComplete(): " + ex.messsage);
}
var giUpdate_evtName, giPI_evtName, head, newScript, marker, self, cnt;
// only inject google instant patch if there is a document and if it belongs to a google page
if (typeof (e.document) === "undefined" || e.document === null || this.isGooglePage(e.document) === false) {
return;
}
giUpdate_evtName = "onclick";
giPI_evtName = "ondblclick";
if (e.document.getElementById("tracked_by_gacela") === null) {
head = e.document.getElementsByTagName("head")[0];
newScript = e.document.createElement("script");
newScript.type = "text/javascript";
newScript.text =
'function notifyTracklet(doc, evtName, targetid, newcontent) {' +
'var gacelaDiv, evtName, evt;' +
'gacelaDiv = document.getElementById("tracked_by_gacela");' +
'if(typeof(gacelaDiv) === "undefined" || gacelaDiv === null) {' +
'gacelaDiv = parent.document.getElementById("tracked_by_gacela");' +
'}' +
'if (typeof(doc.createEvent) === "function") {' +
'gacelaDiv.setAttribute("url", self.location.href);' +
'gacelaDiv.setAttribute("mainframe", self.location === top.location);' +
'gacelaDiv.setAttribute("targetid", targetid);' +
'gacelaDiv.setAttribute("newcontent", newcontent);' +
'evt = doc.createEvent("Events");' +
'evt.initEvent(evtName, true, true);' +
'gacelaDiv.dispatchEvent(evt);' +
'} else if (typeof(gacelaDiv.fireEvent) !== "undefined") {' +
'evt = doc.createEventObject();' +
'evt.document = doc;' +
'evt.url = self.location.href;' +
'evt.mainframe = (self.location === top.location);' +
'evt.targetid = targetid;' +
'evt.newcontent = newcontent;' +
'gacelaDiv.fireEvent(evtName, evt);' +
'}' +
'}' +
// override google.j.p() method to detect updates performed by google instant search
'window.setTimeout(function() {' +
'if (typeof(google) === "object" && typeof(google.j) === "object" && typeof(google.j.p) === "function") {' +
'google.j.real_p = google.j.p;' +
'google.j.p = function(one, targetId, newContent, four, five) {' +
'if(targetId === "search") {' +
'notifyTracklet(document, "' + giUpdate_evtName + '", targetId, newContent);' +
'}' +
'return google.j.real_p(one, targetId, newContent, four, five);' +
'};' +
'}' +
'}, 500);' +
// register onhaschange on nonIE Browsers (chrome)
'if ((typeof(window.addEventListener) === "function") || (typeof(window.addEventListener) === "object")) {' +
'window.addEventListener("hashchange", function() {' +
'notifyTracklet(document, "' + giPI_evtName + '");' +
'});' +
'} ' +
// register to onhashchange for detecting PI for google instant search
'else if(typeof(window.attachEvent) !== "undefined") {' +
'window.attachEvent ("onhashchange", function() {' +
'notifyTracklet(document, "' + giPI_evtName + '");' +
'});' +
'}';
// add a marker to page, because ie fires multiple documentComplete events and we don't want to
// add the script multiple times.
marker = e.document.createElement("div");
marker.style.display = "none";
marker.id = "tracked_by_gacela";
self = this;
if ((typeof (marker.addEventListener) === "function") || (typeof (marker.addEventListener) === "object")) {
marker.addEventListener(giUpdate_evtName, function(ev) {
self.dispatchGoogleInstantEvent("GacelaGoogleInstantUpdate", ev);
}, false);
marker.addEventListener(giPI_evtName, function(ev) {
self.dispatchGoogleInstantEvent("GacelaGoogleInstantPI", ev);
}, false);
} else {
marker.attachEvent(giUpdate_evtName, function(ev) {
self.dispatchGoogleInstantEvent("GacelaGoogleInstantUpdate", ev);
});
marker.attachEvent(giPI_evtName, function(ev) {
self.dispatchGoogleInstantEvent("GacelaGoogleInstantPI", ev);
});
}
cnt = 0;
while (e.document.body === null && cnt < 50000) {
cnt = cnt + 1;
}
try {
e.document.body.appendChild(marker);
head.appendChild(newScript);
} catch (ex) {
Logger.log("ERROR", "Error in GoogleInstantTracker.onDocumentComplete(): " + ex.messsage);
}
}
};
this.onGoogleInstantUpdate = function(e, config) {
try {
//check actionlist
if (config !== null && typeof(config) !== "undefined") {
//check group_name
for (var i = 0; i < config.length; i += 1) {
if (this.isPersonInGroup(config[i].active_groups)) {
this.trackconfig = config[i].settings;
if (this.trackconfig) {
if (this.trackconfig.track_instant_updates) {
this.TrackEvents(e);
}
}
}
}
}
} catch (ex) {
Logger.log("ERROR", "Error in GoogleInstantTracker.onGoogleInstantUpdate(): " + ex.message);
}
};
this.onGoogleInstantPI = function(e, config) {
try {
//check actionlist
if (config !== null && typeof(config) !== "undefined") {
//check group_name
for (var i = 0; i < config.length; i += 1) {
if (this.isPersonInGroup(config[i].active_groups)) {
this.trackconfig = config[i].settings;
if (this.trackconfig) {
if (this.trackconfig.track_instant_pi) {
this.TrackEvents(e);
}
}
}
}
}
} catch (ex) {
Logger.log("ERROR", "Error in GoogleInstantTracker.onGoogleInstantPI(): " + ex.message);
}
};
// Parses URL, adds the ability to parse and decode parameters on top of the usual "parseURL" function
/**
* Parses URL, adds the ability to parse and decode parameters on top of the usual "parseURL" function
* @private
* @function
* @param string url URL to parse
* @returns string parsed URL
*/
this.parseURL = function(url) {
var purl, parts, params, anchorparts, anchorpartindex, ps, i;
purl = parseURL(String(url));
if (!purl.query && !purl.anchor) {
return purl;
}
purl.params = {};
if (purl.query) {
parts = purl.query.split("&");
for (i = 0; i < parts.length; i += 1) {
params = parts[i].split("=");
if (params.length < 2) {
continue;
}
purl.params[params[0]] = decodeURIComponent(params[1].replace(/\+/g, " "));
}
}
purl.anchorparams = {};
if (purl.anchor) {
anchorparts = purl.anchor.split("&");
for (anchorpartindex = 0; anchorpartindex < anchorparts.length; anchorpartindex += 1) {
ps = anchorparts[anchorpartindex].split("=");
if (ps.length < 2) {
continue;
}
purl.anchorparams[ps[0]] = decodeURIComponent(ps[1].replace(/\+/g, " "));
}
}
return purl;
};
// Extracts google search term from given URL
/**
* Extracts google search term from given URL
* @private
* @function
* @param string url URL
* @returns string Google search term
*/
this.getGoogleSearchTermFromURL = function(url) {
var purl = this.parseURL(url);
if (!this.trackconfig || !purl.host || !purl.host.match(this.trackconfig.googleurlregexp)) {
return false;
}
if (purl.anchorparams && purl.anchorparams.q) {
return purl.anchorparams.q;
}
if (purl.params && purl.params.q) {
return purl.params.q;
}
return "";
};
/**
* Extracts google search term from document or browser search field
* @private
* @function
* @param object doc Document
* @param bool useSearchField If the searchField is used
* @returns string Google search term
*/
this.getGoogleSearchTerm = function(doc, useSearchField) {
var searchterm, elem, inputfields, i, inputfield;
searchterm = "";
if (useSearchField) {
try {
elem = doc.getElementById("grey");
if (typeof (elem.value) !== "undefined") {
searchterm = elem.value;
searchterm = searchterm.replace(/<[^>]*>/g, "");
} else {
// in IE the element with id="grey" is not a input but a div. so instead of elem.value
// we use elem.innerHTML
searchterm = elem.innerHTML;
searchterm = searchterm.replace(/ /g, " ");
}
} catch (ex) {}
if (typeof (searchterm) === "undefined" || searchterm === "") {
try {
inputfields = doc.getElementsByTagName("input");
if (inputfields !== null) {
for (i = 0; i < inputfields.length; i += 1) {
inputfield = inputfields[i];
if (inputfield.name === "q") {
searchterm = inputfield.value;
break;
}
}
}
} catch (ex2) { }
}
}
if (typeof (searchterm) === "undefined" || searchterm === "") {
searchterm = this.getGoogleSearchTermFromURL(doc.location.href);
}
return searchterm;
};
/**
* Function which handles the tracking
* @private
* @function
* @param event e Event object
*/
this.TrackEvents = function(e) {
//track google content
if (e.mainframe) {
var doc, docurl, googleContent, content, type;
doc = GacelaNavigateService.getCurrentDocument();
docurl = doc.location.href;
if (((docurl.indexOf("https://") === -1) || GlobalConfiguration.isHttpsExceptionPage(doc, this.trackconfig)) && this.isGooglePage(doc)) {
googleContent = {
"assockey": docurl,
"searchterm": this.getGoogleSearchTerm(doc, e.type === "GacelaGoogleInstantPI"),
"htmlcontent": GacelaNavigateService.getInnerHTML(doc)
};
content = base64_json_encode(googleContent);
type = "unknown";
switch (e.type) {
case "GacelaDocumentComplete":
type = "google-content-document-complete";
break;
case "GacelaGoogleInstantUpdate":
type = "google-content-serp-update";
break;
case "GacelaGoogleInstantPI":
type = "google-content-serp-pi";
break;
default:
break;
}
CustomEventHelper.sendCustomevent(e, Base64.encode(docurl), type, googleContent);
}
}
};
/**
* Initializes the CFirefoxLocationListener and dispatches GacelaGoogleInstantPI event
* @private
* @function
* @see CFirefoxLocationListener
*/
this.initFirefoxLocationListener = function() {
var self, evt;
if (GacelaStorageService.getStatic("BrowserType") === "FF") {
var versionstring = GacelaStorageService.getStatic("BrowserVersion");
if (versionstring) {
var vparts = versionstring.split(/\./);
if (vparts && vparts.length>0) {
var ffVersion = parseInt(vparts[0],10);
// This fix isn't neccessary anymore since Firefox 6
if (ffVersion<6) {
self = this;
this.firefoxlocationlistener = new CFirefoxLocationListener(_private.browser, function(location) {
if (!self.trackconfig || !location || !location.match(self.trackconfig.googleurlregexp)) {
return;
}
evt = {};
evt.document = GacelaNavigateService.getCurrentDocument();
evt.url = evt.document.location.href;
evt.mainframe = true;
GacelaEventService.dispatchEvent("GacelaGoogleInstantPI", evt);
});
}
}
}
}
};
//--- add event handlers
var self = this;
GacelaEventService.addListener('GacelaNewWindow', function(e) {
self.initFirefoxLocationListener();
});
GacelaEventService.addListener('GacelaDocumentComplete', function(e) {
self.onDocumentComplete(e, config);
});
GacelaEventService.addListener('GacelaGoogleInstantUpdate', function(e) {
self.onGoogleInstantUpdate(e, config);
});
GacelaEventService.addListener('GacelaGoogleInstantPI', function(e) {
self.onGoogleInstantPI(e, config);
});
this.persons = persons;
this.config = config;
}
//===================================================================
// UCTWinScriptlets: tracklet/components/WWSCookieTracker.js
//===================================================================
/**
* The WWSCookieTracker Performs requests to the WWS system, on every frameload.
* With these Requests the cookies can be tracklet via the WWS system.
* To configure the Component initialize it with a config value.
* On the UserChanged Event the active_groups of the config is evaluated,
* and the component is enabled.
* @class Performs requests to WWS-System on every frameload
* @author Team Dev
* @public
* @dependency tracklet Helper 15
* @dependency tracklet GfKBase 15
*/
function WWSCookieTracker(config){
this.tracklist = [];
this.initialized = false;
/**
* Sends a request containing the cookies of the current page to the configured URL.
* @private
* @function
* @param event e The document complete event object
*/
this.OnDocumentComplete = function(e) {
try {
for(var i = 0;i < this.tracklist.length; i++){
if (e.url.match(this.tracklist[i].regex)) {
BlindSend(this.tracklist[i].target, "hhid="+GacelaStorageService.getStatic('GacelaPanelId')+"&uid="+GacelaStorageService.get(e.eid.browsersessionid + '.authentication')+"&eid="+GacelaTrackingService.eventIDToString(e.eid)+"&url="+encodeURIComponent(e.url));
}
}
}
catch (err) {
Logger.log("ERROR", "Error in WWSCookieTracker::OnDocumentComplete: " + err);
}
};
//Init function
/**
* Initializes this component, is triggered by the UserChanged event. Binds the OnDocumentComplete method to the GacelaDocumentComplete event.
* @private
* @param event e The UserChanged event
* @param object config The config object from the configuration
*/
this.OnUserChange = function(e, config){
try{
//check actionlist
if(config !== null && typeof(config) !== "undefined"){
//check group_name
for(var i = 0 ; i < config.length ; i++){
if(isPersonInGroup(e.user_id, config[i].active_groups)){
this.tracklist = config[i].settings;
if (!this.initialized) {
this.initialized = true;
var self = this;
GacelaEventService.addListener('GacelaDocumentComplete', function(e){self.OnDocumentComplete(e);});
}
}
}
}
}
catch (e){
Logger.log("ERROR", "Error in WWSCookieTracker::OnUserChange: " + e);
}
};
//Register init function
var self = this;
GacelaEventService.addListener('UserChanged', function(e){self.OnUserChange(e, config);});
}
//========================================================================
//===================================================================
// UCTWinScriptlets: tracklet/components/PageCookieTracker.js
//===================================================================
/**
* The PageCookieTracker Performs requests to the given url, on every frameload.
* With these Requests the cookie of the current Page is sent as cookie parameter.
* To configure the Component initialize it with a config value.
* On the UserChanged Event the active_groups of the config is evaluated,
* and the component is enabled.
* @class Sends cookie of current page to configured URL
* @author Team Dev
* @public
* @dependency tracklet GfKBase 15
* @dependency tracklet Helper 15
*/
function PageCookieTracker(config){
this.tracklist = [];
this.initialized = false;
/**
* Sends a request containing the cookies of the current page to the configured URL.
* @private
* @function
* @param event e The document complete event object
*/
this.OnDocumentComplete = function(e) {
try {
for(var i = 0;i < this.tracklist.length; i++){
if (e.url.match(this.tracklist[i].regex)) {
BlindSend(this.tracklist[i].target, 'hhid='+GacelaStorageService.getStatic('GacelaPanelId')+'&uid='+GacelaStorageService.get(e.eid.browsersessionid + '.authentication')+'&cookies='+escape(e.document.cookie)+'&url='+escape(e.url));
}
}
}
catch (err) {
Logger.log("ERROR", "Error in PageCookieTracker::OnDocumentComplete: " + err);
}
};
//Init function
/**
* Initializes this component, is triggered by the UserChanged event. Binds the OnDocumentComplete method to the GacelaDocumentComplete event.
* @private
* @function
* @param event e The UserChanged event
* @param object config The config object from the configuration
*/
this.OnUserChange = function(e, config){
try{
//check actionlist
if(config !== null && typeof(config) !== "undefined"){
//check group_name
for(var i = 0 ; i < config.length ; i++){
if(isPersonInGroup(e.user_id, config[i].active_groups)){
this.tracklist = config[i].settings;
if (!this.initialized) {
this.initialized = true;
var self = this;
GacelaEventService.addListener('GacelaDocumentComplete', function(e){self.OnDocumentComplete(e);});
}
}
}
}
}
catch (e){
Logger.log("ERROR", "Error in PageCookieTracker::OnUserChange: " + e);
}
};
//Register init function
var self = this;
GacelaEventService.addListener('UserChanged', function(e){self.OnUserChange(e, config);});
}
//=======================================================================
//===================================================================
// UCTWinScriptlets: tracklet/components/Fixes.js
//===================================================================
//======================
// Patch to fix missing beforenavigate events in Firefox
//======================
//check if is an IE8 and Gacela Version less than 2.1
/**
* Patch to fix missing beforenavigate events in Firefox. Checks if is an IE8 and Gacela Version less than 2.1
* @function
* @returns boolean Returns false if the GacelaExtensionVersion is bigger than 2.1. Also returns false if the GacelaExtensionVersion is smaller or equal 2.1 but MSIE major version is smaller than 8, or browser is firefox. <br />
* Only returns true if the Browser is MSIE with a major version bigger than 7 and a GacelaExtensionVersion smaller or equal 2.1.
*/
function hasIE8Bug() {
var extver = GacelaStorageService.getStatic('GacelaExtensionVersion');
var extverparts = extver.split(".");
if(extverparts[0] == 2 && extverparts[1]>=1) {
return false; // Version bigger than 2.1 installed
}
if (extverparts[0]>2){
return false; // Version bigger than 2.x installed
}
var ver = GacelaStorageService.getStatic("BrowserVersion");
var mainver = ver;
if (typeof(ver)=="string") {
var vparts = ver.split(".");
mainver = parseInt(vparts[0], 10);
}
if ((GacelaStorageService.getStatic("BrowserType")!="FF") && (mainver>7)) {
return true;
}
return false;
}
//========================================================================
//===================================================================
// UCTWinScriptlets: tracklet/components/DomainCookieTracker.js
//===================================================================
/*jsl:declare Base64*/
/*jsl:declare json_encode */
/*jsl:declare base64_json_encode */
/**
* The DomainCookieTracker inserts an iframe into pages matching the
* targetdomainregex. Results are sent as Customevents with the configured
* customeventname.
* To configure the Component initialize it with a config value.
* On the UserChanged Event the active_groups of the config is evaluated,
* and the component is enabled.
* @class Inserts iFrames into configured pages and reports results as Customevents
* @author Team Dev
* @public
* @property object config The configuration object for DomainCookieTracker
* @dependency tracklet Helper 15
* @dependency tracklet GfKBase 15
*/
function DomainCookieTracker(config){
this.settings = [];
this.initialized = false;
/**
* Creates a CustomEvent containing cookies. On a GacelaDocumentComplete event, this method is called. <br />
* @private
* @function
* @param event e The document complete event object
*/
this.OnDocumentComplete = function(e) {
try {
var purl = parseURL(e.url);
var domain = purl.domain;
var doc = e.document;
for(var i = 0;i<this.settings.length;i++){
if(domain){
if (domain.match(this.settings[i].alldomainregex)) {
var eid = GacelaTrackingService.eventIDToString(e.eid);
var ts = e.timestamp;
var cevent = {
cookies : e.document.cookie,
url : "" + (e.url),
mainframe : e.mainframe,
eid : eid,
timestamp : ts,
tags : GacelaTrackingService.trackingTags
};
var content = base64_json_encode(cevent);
var entry = '<customevent eid="'+eid+'" timestamp="'+ts+'" type="' + this.settings[i].customeventname + '" key="'+domain+'" >'+content+'</customevent>';
GacelaTrackingService.logData(entry);
}
// Create hidden IFrame to track doubleclick cookies.
if (e.mainframe && domain.match(this.settings[i].targetdomainregex)) {
var iframe = doc.createElement("iframe");
iframe.setAttribute("src", this.settings[i].iframesrc);
iframe.setAttribute("width", "0");
iframe.setAttribute("heigth", "0");
iframe.style.display = "none";
doc.body.appendChild(iframe);
iframe.src = this.settings[i].iframesrc;
}
}
}
}
catch (err) {
Logger.log("ERROR", "Error: Exception in DomainCookieTracker::OnDocumentComplete. Message: " + err);
}
};
/**
* Assigns the GacelaDocumentComplete event to the OnDocumentComplete method.
* @private
* @function
* @param object setting The setting object from the configuration.
*/
this.Init = function(setting){
this.settings = setting;
if (!this.initialized) {
this.initialized = true;
var self = this;
GacelaEventService.addListener('GacelaDocumentComplete', function(e){self.OnDocumentComplete(e);});
}
};
/**
* Initializes this component, is triggered by the UserChanged event.
* @private
* @param event e The UserChanged event
* @param object config The config object from the configuration
*/
this.OnUserChange = function(e, config){
try{
//check actionlist
if(config !== null && typeof(config) !== "undefined"){
//check group_name
for(var i = 0 ; i < config.length ; i++){
if(isPersonInGroup(e.user_id, config[i].active_groups)){
this.Init(config[i].settings);
}
}
}
}
catch (e){
Logger.log("ERROR", "Error in DomainCookieTracker::OnUserChange: " + e);
}
};
//Register init function
var self = this;
GacelaEventService.addListener('UserChanged', function(e){self.OnUserChange(e, config);});
}
//========================================================================
//===================================================================
// UCTWinScriptlets: tracklet/components/GoogleSERPRefererTracking.js
//===================================================================
/*
Google Search Engine Results Page Referrer Tracking Component
Tracks Navigation Events on Google Search Result Pages, and writes custom events of the type "google-reflink" in the
clicked-on pages with some information about the click, especially whether it was a natural search result, or a paid link.
The google-reflink custom event contains a base64 encoded JSON Object (this is standard) with the following properties:
href - the href attribute value of the link that was clicked on on the Google SERP
tagid - the id attribute of the link element that was clicked
clicktype - either "organic", "adword" or "other" - specifies the type of the link that has been clicked on
greenlink - (if present) - the "green" visible target domain/link below the adwords text (for example hotel.com or something like that)
assockey - the url of the Google SERP Page (same as google_url, see below)
timestamp - the timestamp of the click that led to the navigation
google_url - the url of the Google SERP Page
google_eid - the event ID of the click on the Google SERP Page (allows to uniquely identify that pageload)
Initialization Code (to be placed into extended_tracklet.js)
--
var googleSerpReferrerTrackingConstants = {
"googleurlregexp" : /(\.|^)google\.(com|de)/i, // Regex which determines, which pages are considered to be google pages
"awIDpattern" : "^(pa[1-3]1)|(an[1-8]1)$" , // Regex pattern for Adword-IDs
"referrer_max_timediff" : 30000 // Maximum time stamp difference between click and doc complete event, to associate them
};
var googleSERPReferrerTracking = new GoogleSERPReferrerTracking(false, googleSerpReferrerTrackingConstants);
--
As on mouse button up events SERP links are manipulated by Google, changing them into indirect links, the original link must be
reconstructed at our click events. Later, when a document has been loaded, the URL of that document is compared with the original link.
Original links cannot be fetched from "green texts" on the results page, as they do not always contain URLs. Therefore original links
are copied from the url=... parameter of the manipulated link.
The algorithm may use up to 10 "slots" for tracking: When more than one link is clicked during a short time interval (then usually click
with ctrl key to open in new tab), several slots may be active until the linked documents have been loaded.
*/
/*global GacelaStorageService, GacelaNavigateService, GacelaEventService, GacelaTrackingService, Base64, base64_json_encode, json_encode*/
/**
* Tracks Navigation Events on Google Search Result Pages, and writes custom events of the type "google-reflink" in the
* clicked-on pages with some information about the click, especially whether it was a natural search result, or a paid link.
* @class Tracks Navigation Events on Google Search Result Pages.
* @author Team Dev
* @public
* @param bool register_all True if all pages should be tracked, false if the pattern from the constants should be used.
* @param object constants Object containing configuration options
* @dependency tracklet Helper 15
* @dependency tracklet GlobalConfiguration
*/
function GoogleSERPReferrerTracking(register_all, constants)
{
// Construction
var self = this;
this.constants = constants;
// Mouseclick-Event IE
var awIDpattern = this.constants.awIDpattern;
/**
* Checks if a given Document belongs to a Google page
* @private
* @function
* @param object doc Document of the page to check
* @returns bool True if the Document belongs to a google page, otherwise false
*/
this.isGooglePage = function (doc) {
var result = false;
if (doc && doc.location && doc.location.href) {
result = doc.location.href.search(this.constants.googleurlregexp) >= 0;
}
return result;
};