PDF rausgenommen

This commit is contained in:
aschwarz
2023-01-23 11:03:31 +01:00
parent 82d562a322
commit a6523903eb
28078 changed files with 4247552 additions and 2 deletions

View File

@ -0,0 +1,145 @@
/**
* Reset styles
*/
#PIS_StatusBar,
#PIS_StatusBar .PIS_Item,
#PIS_StatusBar .PIS_Loading,
.PIS_LinkTag,
.PIS_LinkHighlightBoxTop,
.PIS_LinkHighlightBoxRight,
.PIS_LinkHighlightBoxLeft,
.PIS_LinkHighlightBoxText {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: normal;
font-style: normal;
font-size: 11px;
font-family: Arial, Helvetica, sans-serif;
vertical-align: baseline;
line-height: 1.4em;
text-indent: 0;
text-decoration: none;
text-transform: none;
cursor: default;
text-align: left;
float: none;
color: #333;
}
/**
* Link Tags
*/
.PIS_LinkTag {
position: absolute;
top: 0;
left: 0;
z-index: 999999;
width: 36px;
height: 21px;
text-align: left;
background: url(./linktags_lessshadow.png) no-repeat 0 -21px;
overflow: hidden;
transform-origin: 100% 50%;
transition: 0.2s ease-in-out;
}
.PIS_LinkTag span {
position: absolute;
width: 31px;
height: 14px;
font-size: 10px;
text-align: center;
font-weight: bold;
line-height: 14px;
margin-left: 1px;
}
.PIS_LinkTag.PIS_Highlighted {
z-index: 1000002;
}
.PIS_LinkTag.PIS_Highlighted span {
color: #E87500;
}
.PIS_LinkTag.PIS_Right {
background-position: -36px -21px;
transform-origin: 0% 50%;
}
.PIS_LinkTag.PIS_Right span,
.PIS_LinkTag.PIS_BottomRight span {
margin-left: 5px;
}
.PIS_LinkTag.PIS_Bottom {
background-position: 0 0;
transform-origin: 100% 50%;
}
.PIS_LinkTag.PIS_Bottom span,
.PIS_LinkTag.PIS_BottomRight span {
margin-top: 4px;
}
.PIS_LinkTag.PIS_BottomRight {
background-position: -36px 0;
transform-origin: 0% 50%;
}
/**
* Link Highlights
*/
.PIS_LinkHighlightBoxTop,
.PIS_LinkHighlightBoxRight,
.PIS_LinkHighlightBoxText,
.PIS_LinkHighlightBoxLeft {
position: absolute;
z-index: 1000001;
overflow: hidden;
width: 2px;
height: 2px;
background: #E87500;
}
.PIS_LinkHighlightBoxText {
line-height: 20px;
height: 20px;
font-size: 11px;
color: white;
width: auto;
}
/**
* Status bar
*/
#PIS_StatusBar {
padding: 10px 0;
position: fixed;
z-index: 1000020;
bottom: 0;
right: 0;
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
background: #fbfbfb;
border-radius: 6px 0 0;
}
#PIS_StatusBar .PIS_Item {
text-align: right;
padding: 3px 5px 0 0;
margin: 0 15px 0 20px;
font-weight: bold;
}
#PIS_StatusBar .PIS_Loading {
background: url(./loading.gif) no-repeat right center;
padding-right: 30px;
}

View File

@ -0,0 +1,258 @@
var Piwik_Overlay_Client = (function () {
var DOMAIN_PARSE_REGEX = /^http(s)?:\/\/(www\.)?([^\/]*)/i;
/** jQuery */
var $;
/** Url of the Piwik root */
var piwikRoot;
/** protocol and domain of Piwik root */
var piwikOrigin;
/** Piwik idsite */
var idSite;
/** The current period and date */
var period, date, segment;
/** Reference to the status bar DOM element */
var statusBar;
/** Counter for request IDs for postMessage based API requests. */
var lastRequestId = 0;
/** Map of callbacks for postMessage based API requests. */
var requestCallbacks = {};
/** Load the client CSS */
function loadCss() {
var css = c('link').attr({
rel: 'stylesheet',
type: 'text/css',
href: piwikRoot + '/plugins/Overlay/client/client.css'
});
$('head').append(css);
}
/**
* This method loads jQuery, if it is not there yet.
* The callback is triggered after jQuery is loaded.
*/
function loadJQuery(callback) {
if (typeof jQuery != 'undefined') {
$ = jQuery;
callback();
}
else {
Piwik_Overlay_Client.loadScript('libs/bower_components/jquery/dist/jquery.min.js', function () {
$ = jQuery;
jQuery.noConflict();
callback();
});
}
}
/**
* Notify Piwik of the current iframe location.
* This way, we can display additional metrics on the side of the iframe.
*/
function notifyPiwikOfLocation() {
// check whether the session has been opened in a new tab (instead of an iframe)
if (window != window.top) {
var iframe = c('iframe', false, {
src: piwikRoot + '/index.php?module=Overlay&action=notifyParentIframe#' + window.location.href
}).css({width: 0, height: 0, border: 0});
$('body').append(iframe);
}
}
/** Create a jqueryfied DOM element */
function c(tagName, className, attributes) {
var el = $(document.createElement(tagName));
if (className) {
if (className.substring(0, 1) == '#') {
var id = className.substring(1, className.length);
id = 'PIS_' + id;
el.attr('id', id);
}
else {
className = 'PIS_' + className;
el.addClass(className);
}
}
if (attributes) {
el.attr(attributes);
}
return el;
}
function nextRequestId() {
var nextId = lastRequestId + 1;
lastRequestId = nextId;
return nextId;
}
function handlePostMessages() {
window.addEventListener("message", function (event) {
if (event.origin !== piwikOrigin) {
return;
}
var strData = event.data.split(':', 3);
if (strData[0] !== 'overlay.response') {
return;
}
var requestId = strData[1];
if (!requestCallbacks[requestId]) {
return;
}
var callback = requestCallbacks[requestId];
delete requestCallbacks[requestId];
var data = JSON.parse(decodeURIComponent(strData[2]));
if (typeof data.result !== 'undefined'
&& data.result === 'error'
) {
alert('Error: ' + data.message);
} else {
callback(data);
}
}, false);
}
return {
/** Initialize in-site analytics */
initialize: function (pPiwikRoot, pIdSite, pPeriod, pDate, pSegment) {
piwikRoot = pPiwikRoot;
piwikOrigin = piwikRoot.match(DOMAIN_PARSE_REGEX)[0];
idSite = pIdSite;
period = pPeriod;
date = pDate;
segment = pSegment;
var load = this.loadScript;
var loading = this.loadingNotification;
loadJQuery(function () {
handlePostMessages();
notifyPiwikOfLocation();
loadCss();
// translations
load('plugins/Overlay/client/translations.js', function () {
Piwik_Overlay_Translations.initialize(function () {
// following pages
var finishPages = loading('Loading following pages');
load('plugins/Overlay/client/followingpages.js', function () {
Piwik_Overlay_FollowingPages.initialize(finishPages);
});
});
});
});
},
/** Create a jqueryfied DOM element */
createElement: function (tagName, className, attributes) {
return c(tagName, className, attributes);
},
/** Load a script and wait for it to be loaded */
loadScript: function (relativePath, callback) {
var loaded = false;
var onLoad = function () {
if (!loaded) {
loaded = true;
callback();
}
};
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState == 'loaded' || this.readyState == 'complete') {
onLoad();
}
};
script.onload = onLoad;
script.src = piwikRoot + '/' + relativePath + '?v=1';
head.appendChild(script);
},
/** Piwik Overlay API Request */
api: function (method, callback, additionalParams) {
var url = piwikRoot + '/index.php?module=API&method=Overlay.' + method
+ '&idSite=' + idSite + '&period=' + period + '&date=' + date + '&format=JSON&filter_limit=-1';
if (segment) {
url += '&segment=' + segment;
}
if (additionalParams) {
url += '&' + additionalParams;
}
var requestId = nextRequestId();
requestCallbacks[requestId] = callback;
var matomoFrame = window.parent;
matomoFrame.postMessage('overlay.call:' + requestId + ':' + encodeURIComponent(url), piwikOrigin);
},
/**
* Initialize a notification
* To hide the notification use the returned callback
*/
notification: function (message, addClass) {
if (!statusBar) {
statusBar = c('div', '#StatusBar').css('opacity', .8);
$('body').prepend(statusBar);
}
var item = c('div', 'Item').html(message);
if (addClass) {
item.addClass('PIS_' + addClass);
}
statusBar.show().append(item);
return function () {
item.remove();
if (!statusBar.children().length) {
statusBar.hide();
}
};
},
/** Hide all notifications with a certain class */
hideNotifications: function (className) {
statusBar.find('.PIS_' + className).remove();
if (!statusBar.children().length) {
statusBar.hide();
}
},
/**
* Initialize a loading notification
* To hide the notification use the returned callback
*/
loadingNotification: function (message) {
return Piwik_Overlay_Client.notification(message, 'Loading');
}
};
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

View File

@ -0,0 +1,561 @@
var Piwik_Overlay_FollowingPages = (function () {
/** jQuery */
var $ = jQuery;
/** Info about the following pages */
var followingPages = [];
/** List of excluded get parameters */
var excludedParams = [];
/** Index of the links on the page */
var linksOnPage = {};
/** Reference to create element function */
var c;
/** Counter for the largest clickRate on the page */
var maxClickRate = 0;
/** Load the following pages */
function load(callback) {
// normalize current location
var location = window.location.href;
location = Piwik_Overlay_UrlNormalizer.normalize(location);
location = (("https:" == document.location.protocol) ? 'https' : 'http') + '://' + location;
var excludedParamsLoaded = false;
var followingPagesLoaded = false;
// load excluded params
Piwik_Overlay_Client.api('getExcludedQueryParameters', function (data) {
for (var i = 0; i < data.length; i++) {
if (typeof data[i] == 'object') {
data[i] = data[i][0];
}
}
excludedParams = data;
excludedParamsLoaded = true;
if (followingPagesLoaded) {
callback();
}
});
// load following pages
Piwik_Overlay_Client.api('getFollowingPages', function (data) {
followingPages = data;
processFollowingPages();
followingPagesLoaded = true;
if (excludedParamsLoaded) {
callback();
}
}, 'url=' + encodeURIComponent(location));
}
/** Normalize the URLs of following pages and aggregate some stats */
function processFollowingPages() {
var totalClicks = 0;
for (var i = 0; i < followingPages.length; i++) {
var page = followingPages[i];
// though the following pages are returned without the prefix, downloads
// and outlinks still have it.
page.label = Piwik_Overlay_UrlNormalizer.removeUrlPrefix(page.label);
totalClicks += followingPages[i].referrals;
}
for (i = 0; i < followingPages.length; i++) {
var clickRate = followingPages[i].referrals / totalClicks * 100;
followingPages[i].clickRate = clickRate;
if (clickRate > maxClickRate) maxClickRate = clickRate;
}
}
/**
* Build an index of links on the page.
* This function is passed to $('a').each()
*/
var processLinkDelta = false;
function processLink() {
var a = $(this);
a[0].piwikDiscovered = true;
var href = a.attr('href');
href = Piwik_Overlay_UrlNormalizer.normalize(href);
if (href) {
if (typeof linksOnPage[href] == 'undefined') {
linksOnPage[href] = [a];
}
else {
linksOnPage[href].push(a);
}
}
if (href && processLinkDelta !== false) {
if (typeof processLinkDelta[href] == 'undefined') {
processLinkDelta[href] = [a];
}
else {
processLinkDelta[href].push(a);
}
}
}
var repositionTimeout = false;
var resizeTimeout = false;
function build(callback) {
// build an index of all links on the page
$('a').each(processLink);
// add tags to known following pages
createLinkTags(linksOnPage);
// position the tags
positionLinkTags();
callback();
// check on a regular basis whether new links have appeared.
// we use a timeout instead of an interval to make sure one call is done before
// the next one is triggered
var repositionAfterTimeout;
repositionAfterTimeout = function () {
repositionTimeout = window.setTimeout(function () {
findNewLinks();
positionLinkTags(repositionAfterTimeout);
}, 1800);
};
repositionAfterTimeout();
// reposition link tags on window resize
$(window).resize(function () {
if (repositionTimeout) {
window.clearTimeout(repositionTimeout);
}
if (resizeTimeout) {
window.clearTimeout(resizeTimeout);
}
resizeTimeout = window.setTimeout(function () {
positionLinkTags();
repositionAfterTimeout();
}, 70);
});
}
/** Create a batch of link tags */
function createLinkTags(links) {
var body = $('body');
for (var i = 0; i < followingPages.length; i++) {
var url = followingPages[i].label;
if (typeof links[url] != 'undefined') {
for (var j = 0; j < links[url].length; j++) {
createLinkTag(links[url][j], url, followingPages[i], body);
}
}
}
}
/** Create the link tag element */
function createLinkTag(linkTag, linkUrl, data, body) {
if (typeof linkTag[0].piwikTagElement != 'undefined' && linkTag[0].piwikTagElement !== null) {
// this link tag already has a tag element. happens in rare cases.
return;
}
linkTag[0].piwikTagElement = true;
var rate = data.clickRate;
if( rate < 0.001 ) {
rate = '<0.001';
} else if (rate < 10) {
rate = Math.round(rate * 10) / 10;
} else {
rate = Math.round(rate);
}
var span = c('span').html(rate + '%');
var tagElement = c('div', 'LinkTag').append(span).hide();
tagElement.attr({'data-rateofmax': Math.round(100 * rate/maxClickRate)/100});
body.prepend(tagElement);
linkTag.add(tagElement).hover(function () {
highlightLink(linkTag, linkUrl, data);
}, function () {
unHighlightLink(linkTag, linkUrl);
});
// attach the tag element to the link element. we can't use .data() because jquery
// would remove it when removing the link from the dom. but we still need to find
// the tag element to remove it as well.
linkTag[0].piwikTagElement = tagElement;
}
/** Position the link tags next to the links */
function positionLinkTags(callback) {
var url, linkTag, tagElement, offset, top, left, isRight, hasOneChild, inlineChild;
var tagWidth = 36, tagHeight = 21;
var tagsToRemove = [];
for (var i = 0; i < followingPages.length; i++) {
url = followingPages[i].label;
if (typeof linksOnPage[url] != 'undefined') {
for (var j = 0; j < linksOnPage[url].length; j++) {
linkTag = linksOnPage[url][j];
tagElement = linkTag[0].piwikTagElement;
if (linkTag.closest('html').length == 0 || !tagElement) {
// the link has been removed from the dom
if (tagElement) {
tagElement.hide();
}
// mark for deletion. don't delete it now because we
// are iterating of the array it's in. it will be deleted
// below this for loop.
tagsToRemove.push({
index1: url,
index2: j
});
continue;
}
hasOneChild = checkHasOneChild(linkTag);
inlineChild = false;
if (hasOneChild && linkTag.css('display') != 'block') {
inlineChild = linkTag.children().eq(0);
}
if (getVisibility(linkTag) == 'hidden' || (
// in case of hasOneChild: jquery always returns linkTag.is(':visible')=false
!linkTag.is(':visible') && !(hasOneChild && inlineChild && inlineChild.is(':visible'))
)) {
// link is not visible
tagElement.hide();
continue;
}
tagElement.attr('class', 'PIS_LinkTag'); // reset class
if (tagElement[0].piwikHighlighted) {
tagElement.addClass('PIS_Highlighted');
}
// see comment in highlightLink()
if (hasOneChild && linkTag.find('> img').length === 1) {
offset = linkTag.find('> img').offset();
if (offset.left == 0 && offset.top == 0) {
offset = linkTag.offset();
}
} else if (inlineChild !== false) {
offset = inlineChild.offset();
} else {
offset = linkTag.offset();
}
var zoomFactor = 1 + +tagElement.attr('data-rateofmax');
top = offset.top - tagHeight + 6;
left = offset.left - tagWidth + 10;
if (isRight = (left < zoomFactor * tagWidth - tagWidth ) ) {
tagElement.addClass('PIS_Right');
left = offset.left + linkTag.outerWidth() - 10;
}
if (top < zoomFactor * tagHeight - tagHeight ) {
tagElement.addClass(isRight ? 'PIS_BottomRight' : 'PIS_Bottom');
top = offset.top + linkTag.outerHeight() - 6;
}
tagElement.css({
'-webkit-transform': 'translate(' + left + 'px, ' + top + 'px) scale(' + zoomFactor + ')',
'-moz-transform': 'translate(' + left + 'px, ' + top + 'px) scale(' + zoomFactor + ')',
'-ms-transform': 'translate(' + left + 'px, ' + top + 'px) scale(' + zoomFactor + ')',
'-o-transform': 'translate(' + left + 'px, ' + top + 'px) scale(' + zoomFactor + ')',
'transform': 'translate(' + left + 'px, ' + top + 'px) scale(' + zoomFactor + ')',
'opacity': zoomFactor/2
});
tagElement.show();
}
}
}
// walk tagsToRemove from back to front because it contains the indexes in ascending
// order. removing something from the front will impact the indexes that come after-
// wards. this can be avoided by starting in the back.
for (var k = tagsToRemove.length - 1; k >= 0; k--) {
var tagToRemove = tagsToRemove[k];
linkTag = linksOnPage[tagToRemove.index1][tagToRemove.index2];
// remove the tag element from the dom
if (linkTag && linkTag[0] && linkTag[0].piwikTagElement) {
tagElement = linkTag[0].piwikTagElement;
if (tagElement[0].piwikHighlighted) {
unHighlightLink(linkTag, tagToRemove.index1);
}
tagElement.remove();
linkTag[0].piwikTagElement = null;
}
// remove the link from the index
linksOnPage[tagToRemove.index1].splice(tagToRemove.index2, 1);
if (linksOnPage[tagToRemove.index1].length == 0) {
delete linksOnPage[tagToRemove.index1];
}
}
if (typeof callback == 'function') {
callback();
}
}
/** Get the visibility of an element */
function getVisibility(el) {
var visibility = el.css('visibility');
if (visibility == 'inherit') {
el = el.parent();
if (el.length) {
return getVisibility(el);
}
}
return visibility;
}
/**
* Find out whether a link has only one child. Using .children().length === 1 doesn't work
* because it doesn't take additional text nodes into account.
*/
function checkHasOneChild(linkTag) {
var hasOneChild = (linkTag.children().length === 1);
if (hasOneChild) {
// if the element contains one tag and some text, hasOneChild is set incorrectly
var contents = linkTag.contents();
if (contents.length > 1) {
// find non-empty text nodes
contents = contents.filter(function () {
return this.nodeType == 3 && // text node
$.trim(this.data).length > 0; // contains more than whitespaces
});
if (contents.length) {
hasOneChild = false;
}
}
}
return hasOneChild;
}
/** Check whether new links have been added to the dom */
function findNewLinks() {
var newLinks = $('a').filter(function () {
return typeof this.piwikDiscovered == 'undefined' || this.piwikDiscovered === null;
});
if (!newLinks.length) {
return;
}
processLinkDelta = {};
newLinks.each(processLink);
createLinkTags(processLinkDelta);
processLinkDelta = false;
}
/** Dom elements used for drawing a box around the link */
var highlightElements = [];
/** Highlight a link on hover */
function highlightLink(linkTag, linkUrl, data) {
if (highlightElements.length == 0) {
highlightElements.push(c('div', 'LinkHighlightBoxTop'));
highlightElements.push(c('div', 'LinkHighlightBoxRight'));
highlightElements.push(c('div', 'LinkHighlightBoxLeft'));
highlightElements.push(c('div', 'LinkHighlightBoxText'));
var body = $('body');
for (var i = 0; i < highlightElements.length; i++) {
body.prepend(highlightElements[i].css({display: 'none'}));
}
}
var width = linkTag.outerWidth();
var offset, height;
var hasOneChild = checkHasOneChild(linkTag);
if (hasOneChild && linkTag.find('img').length === 1) {
// if the <a> tag contains only an <img>, the offset and height methods don't work properly.
// as a result, the box around the image link would be wrong. we use the image to derive
// the offset and height instead of the link to get correct values.
var img = linkTag.find('img');
offset = img.offset();
height = img.outerHeight();
}
if (hasOneChild && linkTag.css('display') != 'block') {
// if the <a> tag is not displayed as block and has only one child, using the child to
// derive the offset and dimensions is more robust.
var child = linkTag.children().eq(0);
offset = child.offset();
height = child.outerHeight();
width = child.outerWidth();
} else {
offset = linkTag.offset();
height = linkTag.outerHeight();
}
var numLinks = linksOnPage[linkUrl].length;
putBoxAroundLink(offset, width, height, numLinks, data.referrals);
// highlight tags
for (var j = 0; j < numLinks; j++) {
var tag = linksOnPage[linkUrl][j][0].piwikTagElement;
tag.addClass('PIS_Highlighted');
tag[0].piwikHighlighted = true;
}
// Sometimes it fails to remove the notification when the hovered element is removed.
// To make sure we don't display more than one location at a time, we hide all before showing the new one.
Piwik_Overlay_Client.hideNotifications('LinkLocation');
// we don't use .data() because jquery would remove the callback when the link tag is removed
linkTag[0].piwikHideNotification = Piwik_Overlay_Client.notification(
Piwik_Overlay_Translations.get('link') + ': ' + linkUrl, 'LinkLocation');
}
function putBoxAroundLink(offset, width, height, numLinks, numReferrals) {
var borderWidth = 2;
var padding = 4; // the distance between the link and the border
// top border
highlightElements[0]
.width(width + 2 * padding)
.css({
top: offset.top - borderWidth - padding,
left: offset.left - padding
}).show();
// right border
highlightElements[1]
.height(height + 2 * borderWidth + 2 * padding)
.css({
top: offset.top - borderWidth - padding,
left: offset.left + width + padding
}).show();
// left border
highlightElements[2]
.height(height + 2 * borderWidth + 2 * padding)
.css({
top: offset.top - borderWidth - padding,
left: offset.left - borderWidth - padding
}).show();
// bottom box text
var text;
if (numLinks > 1) {
text = Piwik_Overlay_Translations.get('clicksFromXLinks')
.replace(/%1\$s/, numReferrals)
.replace(/%2\$s/, numLinks);
} else if (numReferrals == 1) {
text = Piwik_Overlay_Translations.get('oneClick');
} else {
text = Piwik_Overlay_Translations.get('clicks')
.replace(/%s/, numReferrals);
}
// bottom box position and dimension
var textPadding = '&nbsp;&nbsp;&nbsp;';
highlightElements[3].html(textPadding + text + textPadding).css({
width: 'auto',
top: offset.top + height + padding,
left: offset.left - borderWidth - padding
}).show();
var minBoxWidth = width + 2 * borderWidth + 2 * padding;
if (highlightElements[3].width() < minBoxWidth) {
// we cannot use minWidth because of IE7
highlightElements[3].width(minBoxWidth);
}
}
/** Remove highlight from link */
function unHighlightLink(linkTag, linkUrl) {
for (var i = 0; i < highlightElements.length; i++) {
highlightElements[i].hide();
}
var numLinks = linksOnPage[linkUrl].length;
for (var j = 0; j < numLinks; j++) {
var tag = linksOnPage[linkUrl][j][0].piwikTagElement;
if (tag) {
tag.removeClass('PIS_Highlighted');
tag[0].piwikHighlighted = false;
}
}
if ((typeof linkTag[0].piwikHideNotification) == 'function') {
linkTag[0].piwikHideNotification();
linkTag[0].piwikHideNotification = null;
}
}
return {
/**
* The main method
*/
initialize: function (finishCallback) {
c = Piwik_Overlay_Client.createElement;
Piwik_Overlay_Client.loadScript('plugins/Overlay/client/urlnormalizer.js', function () {
Piwik_Overlay_UrlNormalizer.initialize();
load(function () {
Piwik_Overlay_UrlNormalizer.setExcludedParameters(excludedParams);
build(function () {
finishCallback();
})
});
});
},
/**
* Remove everything from the dom and terminate timeouts.
* This can be used from the console in order to load a new implementation for debugging afterwards.
* If you add `Piwik_Overlay_FollowingPages.remove();` to the beginning and
* `Piwik_Overlay_FollowingPages.initialize(function(){});` to the end of this file, you can just
* paste it into the console to inject the new implementation.
*/
remove: function () {
for (var i = 0; i < followingPages.length; i++) {
var url = followingPages[i].label;
if (typeof linksOnPage[url] != 'undefined') {
for (var j = 0; j < linksOnPage[url].length; j++) {
var linkTag = linksOnPage[url][j];
var tagElement = linkTag[0].piwikTagElement;
if (tagElement) {
tagElement.remove();
}
linkTag[0].piwikTagElement = null;
$(linkTag).unbind('mouseenter').unbind('mouseleave');
}
}
}
for (i = 0; i < highlightElements.length; i++) {
highlightElements[i].remove();
}
if (repositionTimeout) {
window.clearTimeout(repositionTimeout);
}
if (resizeTimeout) {
window.clearTimeout(resizeTimeout);
}
$(window).unbind('resize');
}
};
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

View File

@ -0,0 +1,30 @@
var Piwik_Overlay_Translations = (function () {
/** Translations strings */
var translations = [];
return {
/**
* Initialize translations module.
* Callback is triggered when data is available.
*/
initialize: function (callback) {
// Load translation data
Piwik_Overlay_Client.api('getTranslations', function (data) {
translations = data[0];
callback();
});
},
/** Get translation string */
get: function (identifier) {
if (typeof translations[identifier] == 'undefined') {
return identifier;
}
return translations[identifier];
}
};
})();

View File

@ -0,0 +1,200 @@
/**
* URL NORMALIZER
* This utility preprocesses both the URLs in the document and
* from the Piwik logs in order to make matching possible.
*/
var Piwik_Overlay_UrlNormalizer = (function () {
/** Base href of the current document */
var baseHref = false;
/** Url of current folder */
var currentFolder;
/** The current domain */
var currentDomain;
/** Regular expressions for parameters to be excluded when matching links on the page */
var excludedParamsRegEx = [];
/**
* Basic normalizations for domain names
* - remove protocol and www from absolute urls
* - add a trailing slash to urls without a path
*
* Returns array
* 0: normalized url
* 1: true, if url was absolute (if not, no normalization was performed)
*/
function normalizeDomain(url) {
if (url === null) {
return '';
}
var absolute = false;
// remove protocol
if (url.substring(0, 7) == 'http://') {
absolute = true;
url = url.substring(7, url.length);
} else if (url.substring(0, 8) == 'https://') {
absolute = true;
url = url.substring(8, url.length);
}
if (absolute) {
// remove www.
url = removeWww(url);
// add slash to domain names
if (url.indexOf('/') == -1) {
url += '/';
}
}
return [url, absolute];
}
/** Remove www. from a domain */
function removeWww(domain) {
if (domain.substring(0, 4) == 'www.') {
return domain.substring(4, domain.length);
}
return domain;
}
return {
initialize: function () {
this.setCurrentDomain(document.location.host);
this.setCurrentUrl(window.location.href);
var head = document.getElementsByTagName('head');
if (head.length) {
var base = head[0].getElementsByTagName('base');
if (base.length && base[0].href) {
this.setBaseHref(base[0].href);
}
}
},
/**
* Explicitly set domain (for testing)
*/
setCurrentDomain: function (pCurrentDomain) {
currentDomain = removeWww(pCurrentDomain);
},
/**
* Explicitly set current url (for testing)
*/
setCurrentUrl: function (url) {
var index = url.lastIndexOf('/');
if (index != url.length - 1) {
currentFolder = url.substring(0, index + 1);
} else {
currentFolder = url;
}
currentFolder = normalizeDomain(currentFolder)[0];
},
/**
* Explicitly set base href (for testing)
*/
setBaseHref: function (pBaseHref) {
if (!pBaseHref) {
baseHref = false;
} else {
baseHref = normalizeDomain(pBaseHref)[0];
}
},
/**
* Set the parameters to be excluded when matching links on the page
*/
setExcludedParameters: function (pExcludedParams) {
excludedParamsRegEx = [];
for (var i = 0; i < pExcludedParams.length; i++) {
var paramString = pExcludedParams[i];
excludedParamsRegEx.push(new RegExp('&' + paramString + '=([^&#]*)', 'ig'));
}
},
/**
* Remove the protocol and the prefix of a URL
*/
removeUrlPrefix: function (url) {
return normalizeDomain(url)[0];
},
/**
* Normalize URL
* Can be an absolute or a relative URL
*/
normalize: function (url) {
if (!url) {
return '';
}
// ignore urls starting with #
if (url.substring(0, 1) == '#') {
return '';
}
// basic normalizations for absolute urls
var normalized = normalizeDomain(url);
url = normalized[0];
var absolute = normalized[1];
if (!absolute) {
/** relative url */
if (url.substring(0, 1) == '/') {
// relative to domain root
url = currentDomain + url;
} else if (baseHref) {
// relative to base href
url = baseHref + url;
} else {
// relative to current folder
url = currentFolder + url;
}
}
// replace multiple / with a single /
url = url.replace(/\/\/+/g, '/');
// handle ./ and ../
var parts = url.split('/');
var urlArr = [];
for (var i = 0; i < parts.length; i++) {
if (parts[i] == '.') {
// ignore
}
else if (parts[i] == '..') {
urlArr.pop();
}
else {
urlArr.push(parts[i]);
}
}
url = urlArr.join('/');
// remove ignored parameters
url = url.replace(/\?/, '?&');
for (i = 0; i < excludedParamsRegEx.length; i++) {
var regEx = excludedParamsRegEx[i];
url = url.replace(regEx, '');
}
url = url.replace(/\?&/, '?');
url = url.replace(/\?#/, '#');
url = url.replace(/\?$/, '');
url = url.replace(/%5B/gi, '[');
url = url.replace(/%5D/gi, ']');
return url;
}
};
})();