PDF rausgenommen
This commit is contained in:
@ -0,0 +1,142 @@
|
||||
var SegmentedVisitorLog = function() {
|
||||
|
||||
function getDataTableFromApiMethod(apiMethod)
|
||||
{
|
||||
var div = $(require('piwik/UI').DataTable.getDataTableByReport(apiMethod));
|
||||
if (div.length && div.data('uiControlObject')) {
|
||||
return div.data('uiControlObject');
|
||||
}
|
||||
}
|
||||
|
||||
function getLabelFromTr ($tr, apiMethod) {
|
||||
var label;
|
||||
|
||||
if (apiMethod && 0 === apiMethod.indexOf('Actions.')) {
|
||||
// for now only use this for Actions... I know a hack :( Otherwise in Search Engines
|
||||
// it would show "http://www.searchenginename.org" instead of "SearchEngineName"
|
||||
label = $tr.attr('data-url-label');
|
||||
}
|
||||
|
||||
if (!label) {
|
||||
label = $tr.find('.label .value').text();
|
||||
}
|
||||
|
||||
if (label) {
|
||||
label = $.trim(label);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
function getDimensionFromApiMethod(apiMethod)
|
||||
{
|
||||
if (!apiMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dataTable = getDataTableFromApiMethod(apiMethod);
|
||||
var metadata = getMetadataFromDataTable(dataTable);
|
||||
|
||||
if (metadata && metadata.dimension) {
|
||||
return metadata.dimension;
|
||||
}
|
||||
}
|
||||
|
||||
function getMetadataFromDataTable(dataTable)
|
||||
{
|
||||
if (dataTable) {
|
||||
|
||||
return dataTable.getReportMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
function findTitleOfRowHavingRawSegmentValue(apiMethod, rawSegmentValue)
|
||||
{
|
||||
var $tr = $('[data-report="' + apiMethod + '"] tr[data-segment-filter="' + rawSegmentValue + '"]').first();
|
||||
|
||||
return getLabelFromTr($tr, apiMethod);
|
||||
}
|
||||
|
||||
function setPopoverTitle(apiMethod, segment, index) {
|
||||
var dataTable = getDataTableFromApiMethod(apiMethod);
|
||||
|
||||
if (!dataTable) {
|
||||
if (index < 15) {
|
||||
// this is needed when the popover is opened before the dataTable is there which can often
|
||||
// happen when opening the popover directly via URL (broadcast.popoverHandler)
|
||||
setTimeout(function () {
|
||||
setPopoverTitle(apiMethod, segment, index + 1);
|
||||
}, 150);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var segmentName = getDimensionFromApiMethod(apiMethod);
|
||||
var segmentValue = findTitleOfRowHavingRawSegmentValue(apiMethod, segment);
|
||||
|
||||
if (!segmentName || (segment && segment.indexOf(';') > 0)) {
|
||||
segmentName = _pk_translate('General_Segment');
|
||||
var segmentParts = segment.split(';');
|
||||
segmentValue = segmentParts.join(' ' + _pk_translate('General_And') + ' ');
|
||||
}
|
||||
|
||||
segmentName = piwikHelper.escape(segmentName);
|
||||
segmentName = piwikHelper.htmlEntities(segmentName);
|
||||
segmentValue = piwikHelper.escape(segmentValue);
|
||||
segmentValue = piwikHelper.htmlEntities(segmentValue);
|
||||
segmentName = segmentName.replace(/(&)(#[0-9]{2,5};)/g, '&$2');
|
||||
segmentValue = segmentValue.replace(/(&)(#[0-9]{2,5};)/g, '&$2');
|
||||
|
||||
var title = _pk_translate('Live_SegmentedVisitorLogTitle', [segmentName, segmentValue]);
|
||||
|
||||
Piwik_Popover.setTitle(title);
|
||||
}
|
||||
|
||||
function show(apiMethod, segment, extraParams) {
|
||||
|
||||
// open the popover
|
||||
var box = Piwik_Popover.showLoading('Segmented Visit Log');
|
||||
box.addClass('segmentedVisitorLogPopover');
|
||||
|
||||
|
||||
var callback = function (html) {
|
||||
Piwik_Popover.setContent(html);
|
||||
|
||||
// remove title returned from the server
|
||||
var title = box.find('h2[piwik-enriched-headline]');
|
||||
var defaultTitle = title.text();
|
||||
|
||||
if (title.length) {
|
||||
title.remove();
|
||||
}
|
||||
|
||||
Piwik_Popover.setTitle(defaultTitle);
|
||||
|
||||
setPopoverTitle(apiMethod, segment, 0);
|
||||
};
|
||||
|
||||
// prepare loading the popover contents
|
||||
var requestParams = {
|
||||
module: 'Live',
|
||||
action: 'indexVisitorLog',
|
||||
segment: encodeURIComponent(segment),
|
||||
disableLink: 1,
|
||||
small: 1,
|
||||
enableAddNewSegment: 1,
|
||||
};
|
||||
|
||||
$.extend(requestParams, extraParams);
|
||||
|
||||
var ajaxRequest = new ajaxHelper();
|
||||
ajaxRequest.addParams(requestParams, 'get');
|
||||
ajaxRequest.setCallback(callback);
|
||||
ajaxRequest.setFormat('html');
|
||||
ajaxRequest.send();
|
||||
}
|
||||
|
||||
return {
|
||||
show: show
|
||||
}
|
||||
}();
|
||||
|
361
msd2/tracking/piwik/plugins/Live/javascripts/live.js
Normal file
361
msd2/tracking/piwik/plugins/Live/javascripts/live.js
Normal file
@ -0,0 +1,361 @@
|
||||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* jQueryUI widget for Live visitors widget
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
$.widget('piwik.liveWidget', {
|
||||
|
||||
/**
|
||||
* Default settings for widgetPreview
|
||||
*/
|
||||
options:{
|
||||
// Maximum numbers of rows to display in widget
|
||||
maxRows: 10,
|
||||
// minimal time in microseconds to wait between updates
|
||||
interval: 3000,
|
||||
// maximum time to wait between requests
|
||||
maxInterval: 300000,
|
||||
// url params to use for data request
|
||||
dataUrlParams: null,
|
||||
// callback triggered on a successful update (content of widget changed)
|
||||
onUpdate: null,
|
||||
// speed for fade animation
|
||||
fadeInSpeed: 'slow'
|
||||
},
|
||||
|
||||
/**
|
||||
* current updateInterval used
|
||||
*/
|
||||
currentInterval: null,
|
||||
|
||||
/**
|
||||
* identifies if content has updated (eg new visits/views)
|
||||
*/
|
||||
updated: false,
|
||||
|
||||
/**
|
||||
* window timeout interval
|
||||
*/
|
||||
updateInterval: null,
|
||||
|
||||
/**
|
||||
* identifies if the liveWidget ist started or not
|
||||
*/
|
||||
isStarted: true,
|
||||
|
||||
/**
|
||||
* Update the widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
_update: function () {
|
||||
|
||||
this.updated = false;
|
||||
|
||||
var that = this;
|
||||
|
||||
var ajaxRequest = new ajaxHelper();
|
||||
ajaxRequest.addParams(this.options.dataUrlParams, 'GET');
|
||||
ajaxRequest.setFormat('html');
|
||||
ajaxRequest.setCallback(function (r) {
|
||||
if (that.options.replaceContent) {
|
||||
$(that.element).html(r);
|
||||
if (that.options.fadeInSpeed) {
|
||||
$(that.element).effect("highlight", {}, that.options.fadeInSpeed);
|
||||
}
|
||||
} else {
|
||||
that._parseResponse(r);
|
||||
}
|
||||
|
||||
// add default interval to last interval if not updated or reset to default if so
|
||||
if (!that.updated) {
|
||||
that.currentInterval += that.options.interval;
|
||||
} else {
|
||||
that.currentInterval = that.options.interval;
|
||||
if (that.options.onUpdate) that.options.onUpdate();
|
||||
}
|
||||
|
||||
// check new interval doesn't reach the defined maximum
|
||||
if (that.options.maxInterval < that.currentInterval) {
|
||||
that.currentInterval = that.options.maxInterval;
|
||||
}
|
||||
|
||||
if (that.isStarted) {
|
||||
window.clearTimeout(that.updateInterval);
|
||||
if (that.element.length && $.contains(document, that.element[0])) {
|
||||
that.updateInterval = window.setTimeout(function() { that._update() }, that.currentInterval);
|
||||
}
|
||||
}
|
||||
});
|
||||
ajaxRequest.send();
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses the given response and updates the widget if newer content is available
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
_parseResponse: function (data) {
|
||||
if (!data || !data.length) {
|
||||
this.updated = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var items = $('li.visit', $(data));
|
||||
for (var i = items.length; i--;) {
|
||||
this._parseItem(items[i]);
|
||||
}
|
||||
|
||||
this._initTooltips();
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the icon tooltips
|
||||
*/
|
||||
_initTooltips: function() {
|
||||
$('li.visit').tooltip({
|
||||
items: '.visitorLogIconWithDetails',
|
||||
track: true,
|
||||
show: false,
|
||||
hide: false,
|
||||
content: function() {
|
||||
return $('<ul>').html($('ul', $(this)).html());
|
||||
},
|
||||
tooltipClass: 'small'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses the given item and updates or adds an entry to the list
|
||||
*
|
||||
* @param item to parse
|
||||
* @return void
|
||||
*/
|
||||
_parseItem: function (item) {
|
||||
var visitId = $(item).attr('id');
|
||||
if ($('#' + visitId, this.element).length) {
|
||||
if ($('#' + visitId, this.element).html() != $(item).html()) {
|
||||
this.updated = true;
|
||||
}
|
||||
$('#' + visitId, this.element).remove();
|
||||
$(this.element).prepend(item);
|
||||
} else {
|
||||
this.updated = true;
|
||||
$(item).hide();
|
||||
$(this.element).prepend(item);
|
||||
$(item).fadeIn(this.options.fadeInSpeed);
|
||||
}
|
||||
// remove rows if there are more than the maximum
|
||||
$('li.visit:gt(' + (this.options.maxRows - 1) + ')', this.element).remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
_create: function () {
|
||||
|
||||
if (!this.options.dataUrlParams) {
|
||||
console && console.error('liveWidget error: dataUrlParams needs to be defined in settings.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentInterval = this.options.interval;
|
||||
|
||||
var self = this;
|
||||
|
||||
window.setTimeout(function() { self._initTooltips(); }, 250);
|
||||
|
||||
this.updateInterval = window.setTimeout(function() { self._update(); }, this.currentInterval);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops requests if widget is destroyed
|
||||
*/
|
||||
_destroy: function () {
|
||||
|
||||
this.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers an update for the widget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
update: function () {
|
||||
this._update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the automatic update cycle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
start: function () {
|
||||
this.isStarted = true;
|
||||
this.currentInterval = 0;
|
||||
this._update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the automatic update cycle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
stop: function () {
|
||||
this.isStarted = false;
|
||||
window.clearTimeout(this.updateInterval);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true in case widget is started.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
started: function() {
|
||||
return this.isStarted;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the interval for refresh
|
||||
*
|
||||
* @param {int} interval new interval for refresh
|
||||
* @return void
|
||||
*/
|
||||
setInterval: function (interval) {
|
||||
this.currentInterval = interval;
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
$(function() {
|
||||
var refreshWidget = function (element, refreshAfterXSecs) {
|
||||
// if the widget has been removed from the DOM, abort
|
||||
if (!element.length || !$.contains(document, element[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
function scheduleAnotherRequest()
|
||||
{
|
||||
setTimeout(function () { refreshWidget(element, refreshAfterXSecs); }, refreshAfterXSecs * 1000);
|
||||
}
|
||||
|
||||
if (Visibility.hidden()) {
|
||||
scheduleAnotherRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
var lastMinutes = $(element).attr('data-last-minutes') || 3,
|
||||
translations = JSON.parse($(element).attr('data-translations'));
|
||||
|
||||
var ajaxRequest = new ajaxHelper();
|
||||
ajaxRequest.addParams({
|
||||
module: 'API',
|
||||
method: 'Live.getCounters',
|
||||
format: 'json',
|
||||
lastMinutes: lastMinutes
|
||||
}, 'get');
|
||||
ajaxRequest.setFormat('json');
|
||||
ajaxRequest.setCallback(function (data) {
|
||||
data = data[0];
|
||||
|
||||
// set text and tooltip of visitors count metric
|
||||
var visitors = data['visitors'];
|
||||
if (visitors == 1) {
|
||||
var visitorsCountMessage = translations['one_visitor'];
|
||||
}
|
||||
else {
|
||||
var visitorsCountMessage = sprintf(translations['visitors'], visitors);
|
||||
}
|
||||
$('.simple-realtime-visitor-counter', element)
|
||||
.attr('title', visitorsCountMessage)
|
||||
.find('div').text(visitors);
|
||||
|
||||
// set text of individual metrics spans
|
||||
var metrics = $('.simple-realtime-metric', element);
|
||||
|
||||
var visitsText = data['visits'] == 1
|
||||
? translations['one_visit'] : sprintf(translations['visits'], data['visits']);
|
||||
$(metrics[0]).text(visitsText);
|
||||
|
||||
var actionsText = data['actions'] == 1
|
||||
? translations['one_action'] : sprintf(translations['actions'], data['actions']);
|
||||
$(metrics[1]).text(actionsText);
|
||||
|
||||
var lastMinutesText = lastMinutes == 1
|
||||
? translations['one_minute'] : sprintf(translations['minutes'], lastMinutes);
|
||||
$(metrics[2]).text(lastMinutesText);
|
||||
|
||||
scheduleAnotherRequest();
|
||||
});
|
||||
ajaxRequest.send();
|
||||
};
|
||||
|
||||
var exports = require("piwik/Live");
|
||||
exports.initSimpleRealtimeVisitorWidget = function () {
|
||||
$('.simple-realtime-visitor-widget').each(function() {
|
||||
var $this = $(this),
|
||||
refreshAfterXSecs = $this.attr('data-refreshAfterXSecs');
|
||||
if ($this.attr('data-inited')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this.attr('data-inited', 1);
|
||||
|
||||
setTimeout(function() { refreshWidget($this, refreshAfterXSecs ); }, refreshAfterXSecs * 1000);
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
function onClickPause() {
|
||||
$('#pauseImage').hide();
|
||||
$('#playImage').show();
|
||||
return $('#visitsLive').liveWidget('stop');
|
||||
}
|
||||
function onClickPlay() {
|
||||
$('#playImage').hide();
|
||||
$('#pauseImage').show();
|
||||
return $('#visitsLive').liveWidget('start');
|
||||
}
|
||||
|
||||
(function () {
|
||||
if (!Visibility.isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isStoppedByBlur = false;
|
||||
|
||||
function isStarted()
|
||||
{
|
||||
return $('#visitsLive').liveWidget('started');
|
||||
}
|
||||
|
||||
function onTabBlur() {
|
||||
if (isStarted()) {
|
||||
isStoppedByBlur = true;
|
||||
onClickPause();
|
||||
}
|
||||
}
|
||||
|
||||
function onTabFocus() {
|
||||
if (isStoppedByBlur && !isStarted()) {
|
||||
isStoppedByBlur = false;
|
||||
onClickPlay();
|
||||
}
|
||||
}
|
||||
|
||||
Visibility.change(function (event, state) {
|
||||
if (Visibility.hidden()) {
|
||||
onTabBlur();
|
||||
} else {
|
||||
onTabFocus();
|
||||
}
|
||||
});
|
||||
})();
|
185
msd2/tracking/piwik/plugins/Live/javascripts/rowaction.js
Normal file
185
msd2/tracking/piwik/plugins/Live/javascripts/rowaction.js
Normal file
@ -0,0 +1,185 @@
|
||||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file registers the Overlay row action on the pages report.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
|
||||
var actionName = 'SegmentVisitorLog';
|
||||
|
||||
function getRawSegmentValueFromRow(tr)
|
||||
{
|
||||
return $(tr).attr('data-segment-filter');
|
||||
}
|
||||
|
||||
function getDataTableFromApiMethod(apiMethod)
|
||||
{
|
||||
var div = $(require('piwik/UI').DataTable.getDataTableByReport(apiMethod));
|
||||
if (div.length && div.data('uiControlObject')) {
|
||||
return div.data('uiControlObject');
|
||||
}
|
||||
}
|
||||
|
||||
function getMetadataFromDataTable(dataTable)
|
||||
{
|
||||
if (dataTable) {
|
||||
|
||||
return dataTable.getReportMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
function getDimensionFromApiMethod(apiMethod)
|
||||
{
|
||||
if (!apiMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dataTable = getDataTableFromApiMethod(apiMethod);
|
||||
var metadata = getMetadataFromDataTable(dataTable);
|
||||
|
||||
if (metadata && metadata.dimension) {
|
||||
return metadata.dimension;
|
||||
}
|
||||
}
|
||||
|
||||
function DataTable_RowActions_SegmentVisitorLog(dataTable) {
|
||||
this.dataTable = dataTable;
|
||||
this.actionName = actionName;
|
||||
|
||||
// has to be overridden in subclasses
|
||||
this.trEventName = 'piwikTriggerSegmentVisitorLogAction';
|
||||
}
|
||||
|
||||
DataTable_RowActions_SegmentVisitorLog.prototype = new DataTable_RowAction();
|
||||
|
||||
DataTable_RowActions_SegmentVisitorLog.prototype.openPopover = function (apiMethod, segment, extraParams) {
|
||||
var urlParam = apiMethod + ':' + encodeURIComponent(segment) + ':' + encodeURIComponent(JSON.stringify(extraParams));
|
||||
|
||||
broadcast.propagateNewPopoverParameter('RowAction', actionName + ':' + urlParam);
|
||||
};
|
||||
|
||||
DataTable_RowActions_SegmentVisitorLog.prototype.trigger = function (tr, e, subTableLabel) {
|
||||
var segment = getRawSegmentValueFromRow(tr);
|
||||
|
||||
if (this.dataTable.param.segment) {
|
||||
segment = decodeURIComponent(this.dataTable.param.segment) + ';' + segment;
|
||||
}
|
||||
|
||||
if (this.dataTable.props.segmented_visitor_log_segment_suffix) {
|
||||
segment = segment + ';' + this.dataTable.props.segmented_visitor_log_segment_suffix;
|
||||
}
|
||||
|
||||
this.performAction(segment, tr, e);
|
||||
};
|
||||
|
||||
DataTable_RowActions_SegmentVisitorLog.prototype.performAction = function (segment, tr, e) {
|
||||
|
||||
var apiMethod = this.dataTable.param.module + '.' + this.dataTable.param.action;
|
||||
|
||||
var extraParams = {};
|
||||
if (this.dataTable.param.date && this.dataTable.param.period) {
|
||||
extraParams = {date: this.dataTable.param.date, period: this.dataTable.param.period};
|
||||
}
|
||||
|
||||
$.each(this.dataTable.param, function (index, value) {
|
||||
// we automatically add fields like idDimension, idGoal etc.
|
||||
if (index !== 'idSite' && index.indexOf('id') === 0 && $.isNumeric(value)) {
|
||||
extraParams[index] = value;
|
||||
}
|
||||
});
|
||||
|
||||
this.openPopover(apiMethod, segment, extraParams);
|
||||
};
|
||||
|
||||
DataTable_RowActions_SegmentVisitorLog.prototype.doOpenPopover = function (urlParam) {
|
||||
var urlParamParts = urlParam.split(':');
|
||||
|
||||
var apiMethod = urlParamParts.shift();
|
||||
var segment = decodeURIComponent(urlParamParts.shift());
|
||||
|
||||
var extraParamsString = urlParamParts.shift(),
|
||||
extraParams = {}; // 0/1 or "0"/"1"
|
||||
|
||||
try {
|
||||
extraParams = JSON.parse(decodeURIComponent(extraParamsString));
|
||||
} catch (e) {
|
||||
// assume the parameter is an int/string describing whether to use multi row evolution
|
||||
}
|
||||
|
||||
SegmentedVisitorLog.show(apiMethod, segment, extraParams);
|
||||
};
|
||||
|
||||
DataTable_RowActions_Registry.register({
|
||||
|
||||
name: actionName,
|
||||
|
||||
dataTableIcon: 'icon-segmented-visits-log',
|
||||
|
||||
order: 30,
|
||||
|
||||
dataTableIconTooltip: [
|
||||
_pk_translate('Live_RowActionTooltipTitle'),
|
||||
_pk_translate('Live_RowActionTooltipDefault')
|
||||
],
|
||||
|
||||
isAvailableOnReport: function (dataTableParams, undefined) {
|
||||
return true;
|
||||
},
|
||||
|
||||
isAvailableOnRow: function (dataTableParams, tr) {
|
||||
var value = getRawSegmentValueFromRow(tr)
|
||||
if ('undefined' === (typeof value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var reportTitle = null;
|
||||
|
||||
var apiMethod = $(tr).parents('div.dataTable').last().attr('data-report');
|
||||
var dimension = getDimensionFromApiMethod(apiMethod);
|
||||
|
||||
if (dimension) {
|
||||
reportTitle = _pk_translate('Live_RowActionTooltipWithDimension', [dimension])
|
||||
} else {
|
||||
reportTitle = _pk_translate('Live_RowActionTooltipDefault');
|
||||
}
|
||||
|
||||
this.dataTableIconTooltip[1] = reportTitle;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
createInstance: function (dataTable, param) {
|
||||
if (dataTable !== null && typeof dataTable.segmentVisitorLogInstance != 'undefined') {
|
||||
return dataTable.segmentVisitorLogInstance;
|
||||
}
|
||||
|
||||
if (dataTable === null && param) {
|
||||
// when segmented visitor log is triggered from the url (not a click on the data table)
|
||||
// we look for the data table instance in the dom
|
||||
var report = param.split(':')[0];
|
||||
var tempTable = getDataTableFromApiMethod(report);
|
||||
if (tempTable) {
|
||||
dataTable = tempTable;
|
||||
if (typeof dataTable.segmentVisitorLogInstance != 'undefined') {
|
||||
return dataTable.segmentVisitorLogInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var instance = new DataTable_RowActions_SegmentVisitorLog(dataTable);
|
||||
if (dataTable !== null) {
|
||||
dataTable.segmentVisitorLogInstance = instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* Actions list in Visitor Log and Profile
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
function initializeVisitorActions(elem) {
|
||||
|
||||
var tooltipIsOpened = false;
|
||||
|
||||
$('a', elem).on('focus', function () {
|
||||
// see https://github.com/piwik/piwik/issues/4099
|
||||
if (tooltipIsOpened) {
|
||||
elem.tooltip('close');
|
||||
}
|
||||
});
|
||||
|
||||
elem.tooltip({
|
||||
items: '[title],.visitorLogIconWithDetails',
|
||||
track: true,
|
||||
show: false,
|
||||
hide: false,
|
||||
content: function() {
|
||||
if ($(this).hasClass('visitorLogIconWithDetails')) {
|
||||
return $('<ul>').html($('ul', $(this)).html());
|
||||
}
|
||||
var title = $(this).attr('title');
|
||||
return $('<a>').text( title ).html().replace(/\n/g, '<br />');
|
||||
},
|
||||
tooltipClass: 'small',
|
||||
open: function() { tooltipIsOpened = true; },
|
||||
close: function() { tooltipIsOpened = false; }
|
||||
});
|
||||
|
||||
// show refresh icon for duplicate page views in a row
|
||||
$("ol.visitorLog", elem).each(function () {
|
||||
var prevelement;
|
||||
var prevhtml;
|
||||
var counter = 0, duplicateCounter = 0;
|
||||
$(this).find("> li").each(function () {
|
||||
counter++;
|
||||
$(this).val(counter);
|
||||
var current = $(this).html();
|
||||
|
||||
if (current == prevhtml) {
|
||||
duplicateCounter++;
|
||||
$(this).find('>div').prepend($("<span>"+(duplicateCounter+1)+"</span>").attr({'class': 'repeat icon-refresh', 'title': _pk_translate('Live_PageRefreshed')}));
|
||||
prevelement.addClass('duplicate');
|
||||
|
||||
} else {
|
||||
duplicateCounter = 0;
|
||||
}
|
||||
|
||||
prevhtml = current;
|
||||
prevelement = $(this);
|
||||
|
||||
var $this = $(this);
|
||||
var tooltipIsOpened = false;
|
||||
|
||||
$('a', $this).on('focus', function () {
|
||||
// see https://github.com/piwik/piwik/issues/4099
|
||||
if (tooltipIsOpened) {
|
||||
$this.tooltip('close');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
$("ol.visitorLog > li:not(.duplicate)", elem).each(function(){
|
||||
if (!$('.icon-refresh', $(this)).length) {
|
||||
return;
|
||||
}
|
||||
$(this).attr('origtitle', $(this).attr('title'));
|
||||
$(this).attr('title', _pk_translate('Live_ClickToViewAllActions'));
|
||||
$(this).click(function(e){
|
||||
e.preventDefault();
|
||||
$(this).prevUntil('li:not(.duplicate)').removeClass('duplicate').find('.icon-refresh').hide();
|
||||
var elem = $(this);
|
||||
window.setTimeout(function() {
|
||||
elem.attr('title', elem.attr('origtitle'));
|
||||
elem.attr('origtitle', null);
|
||||
}, 150);
|
||||
$(this).off('click').find('.icon-refresh').hide();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
75
msd2/tracking/piwik/plugins/Live/javascripts/visitorLog.js
Normal file
75
msd2/tracking/piwik/plugins/Live/javascripts/visitorLog.js
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* Visitor profile popup control.
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
(function ($, require) {
|
||||
|
||||
var exports = require('piwik/UI'),
|
||||
DataTable = exports.DataTable,
|
||||
dataTablePrototype = DataTable.prototype;
|
||||
|
||||
/**
|
||||
* DataTable UI class for jqPlot graph datatable visualizations.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
exports.VisitorLog = function (element) {
|
||||
DataTable.call(this, element);
|
||||
};
|
||||
|
||||
$.extend(exports.VisitorLog.prototype, dataTablePrototype, {
|
||||
|
||||
handleColumnHighlighting: function () {
|
||||
|
||||
},
|
||||
|
||||
setFixWidthToMakeEllipsisWork: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes this class.
|
||||
*/
|
||||
init: function () {
|
||||
dataTablePrototype.init.call(this);
|
||||
|
||||
var self = this;
|
||||
initializeVisitorActions(this.$element);
|
||||
|
||||
// launch visitor profile on visitor profile link click
|
||||
this.$element.on('click', '.visitor-log-visitor-profile-link', function (e) {
|
||||
e.preventDefault();
|
||||
broadcast.propagateNewPopoverParameter('visitorProfile', $(this).attr('data-visitor-id'));
|
||||
return false;
|
||||
});
|
||||
|
||||
this.$element.on('click', '.addSegmentToMatomo.dataTableAction', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var url = window.location.href;
|
||||
url = broadcast.updateParamValue('addSegmentAsNew=' + decodeURIComponent(self.param.segment), url);
|
||||
url = broadcast.updateParamValue('segment=', url);
|
||||
url = broadcast.updateParamValue('popover=', url);
|
||||
|
||||
window.open(url, "_blank");
|
||||
});
|
||||
},
|
||||
|
||||
_destroy: function () {
|
||||
try {
|
||||
this.$element.tooltip('destroy');
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
dataTablePrototype._destroy.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, require);
|
266
msd2/tracking/piwik/plugins/Live/javascripts/visitorProfile.js
Normal file
266
msd2/tracking/piwik/plugins/Live/javascripts/visitorProfile.js
Normal file
@ -0,0 +1,266 @@
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* Visitor profile popup control.
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
(function ($, require) {
|
||||
|
||||
var piwik = require('piwik'),
|
||||
exports = require('piwik/UI'),
|
||||
UIControl = exports.UIControl;
|
||||
|
||||
/**
|
||||
* Sets up and handles events for the visitor profile popup.
|
||||
*
|
||||
* @param {Element} element The HTML element returned by the Live.getVisitorLog controller
|
||||
* action. Should have the CSS class 'visitor-profile'.
|
||||
* @constructor
|
||||
*/
|
||||
var VisitorProfileControl = function (element) {
|
||||
UIControl.call(this, element);
|
||||
this._setupControl();
|
||||
this._bindEventCallbacks();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes all elements w/ the .visitor-profile CSS class as visitor profile popups,
|
||||
* if the element has not already been initialized.
|
||||
*/
|
||||
VisitorProfileControl.initElements = function () {
|
||||
UIControl.initElements(this, '.visitor-profile');
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the visitor profile popover for a visitor ID. This should not be called directly.
|
||||
* Instead broadcast.propagateNewPopoverParameter('visitorProfile', visitorId) should be
|
||||
* called. This would make sure the popover would be opened if the URL is copied and pasted
|
||||
* in a new tab/window.
|
||||
*
|
||||
* @param {String} visitorId The string visitor ID.
|
||||
*/
|
||||
VisitorProfileControl.showPopover = function (visitorId, idSite) {
|
||||
var url = 'module=Live&action=getVisitorProfilePopup&visitorId=' + encodeURIComponent(visitorId);
|
||||
if (idSite) {
|
||||
url += '&idSite=' + idSite;
|
||||
}
|
||||
|
||||
// if there is already a map shown on the screen, do not show the map in the popup. kartograph seems
|
||||
// to only support showing one map at a time.
|
||||
if ($('.RealTimeMap').length > 0) {
|
||||
url += '&showMap=0';
|
||||
}
|
||||
|
||||
var ajaxRequest = new ajaxHelper();
|
||||
ajaxRequest.removeDefaultParameter('segment');
|
||||
|
||||
Piwik_Popover.createPopupAndLoadUrl(url, _pk_translate('Live_VisitorProfile'), 'visitor-profile-popup', ajaxRequest);
|
||||
};
|
||||
|
||||
$.extend(VisitorProfileControl.prototype, UIControl.prototype, {
|
||||
|
||||
_setupControl: function () {
|
||||
// focus the popup so it will accept key events
|
||||
this.$element.focus();
|
||||
},
|
||||
|
||||
_bindEventCallbacks: function () {
|
||||
var self = this,
|
||||
$element = this.$element;
|
||||
|
||||
$element.on('click', '.visitor-profile-close', function (e) {
|
||||
e.preventDefault();
|
||||
try {
|
||||
$element.tooltip('destroy');
|
||||
} catch (e) {}
|
||||
broadcast.propagateNewPopoverParameter(false);
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-toggle-actions', function (e) {
|
||||
e.preventDefault();
|
||||
$(this).toggleClass('minimized');
|
||||
if ($(this).hasClass('minimized')) {
|
||||
$('.visitor-profile-actions', $element).slideUp();
|
||||
} else {
|
||||
$('.visitor-profile-actions', $element).slideDown();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-more-info>a', function (e) {
|
||||
e.preventDefault();
|
||||
self._loadMoreVisits();
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-visit-title', function () {
|
||||
$('.visitor-profile-visit-details-extended', $(this).parents('li')).slideToggle();
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-show-actions', function () {
|
||||
$('.visitor-profile-actions', $(this).parents('li')).slideToggle();
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-prev-visitor', function (e) {
|
||||
e.preventDefault();
|
||||
self._loadPreviousVisitor();
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-next-visitor', function (e) {
|
||||
e.preventDefault();
|
||||
self._loadNextVisitor();
|
||||
return false;
|
||||
});
|
||||
|
||||
$element.on('keydown', function (e) {
|
||||
if (e.which == 37 && !e.altKey) { // on <- key press, load previous visitor
|
||||
self._loadPreviousVisitor();
|
||||
} else if (e.which == 39 && !e.altKey) { // on -> key press, load next visitor
|
||||
self._loadNextVisitor();
|
||||
}
|
||||
});
|
||||
|
||||
$element.on('click', '.visitor-profile-show-map', function (e) {
|
||||
e.preventDefault();
|
||||
self.toggleMap();
|
||||
return false;
|
||||
});
|
||||
|
||||
// append token_auth dynamically to export link
|
||||
$element.on('mousedown', '.visitor-profile-export', function (e) {
|
||||
var url = $(this).attr('href');
|
||||
if (url.indexOf('&token_auth=') == -1) {
|
||||
$(this).attr('href', url + '&token_auth=' + piwik.token_auth);
|
||||
}
|
||||
});
|
||||
|
||||
initializeVisitorActions($element);
|
||||
},
|
||||
|
||||
toggleMap: function () {
|
||||
var $element = this.$element,
|
||||
$map = $('.visitor-profile-map', $element);
|
||||
if (!$map.children().length) { // if the map hasn't been loaded, load it
|
||||
this._loadMap($map);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($map.is(':hidden')) { // show the map if it is hidden
|
||||
if ($map.height() < 1) {
|
||||
$map.resize();
|
||||
}
|
||||
|
||||
$map.slideDown('slow');
|
||||
var newLabel = 'Live_HideMap';
|
||||
|
||||
piwikHelper.lazyScrollTo($('.visitor-profile-location', $element)[0], 400);
|
||||
} else { // hide the map if it is shown
|
||||
$map.slideUp('slow');
|
||||
var newLabel = 'Live_ShowMap';
|
||||
}
|
||||
|
||||
newLabel = _pk_translate(newLabel).replace(' ', '\xA0');
|
||||
$('.visitor-profile-show-map', $element).text('(' + newLabel + ')');
|
||||
},
|
||||
|
||||
_loadMap: function ($map) {
|
||||
var self = this;
|
||||
|
||||
var ajax = new ajaxHelper();
|
||||
ajax.setUrl($map.attr('data-href'));
|
||||
ajax.setCallback(function (response) {
|
||||
$map.html(response);
|
||||
self.toggleMap();
|
||||
});
|
||||
ajax.setFormat('html');
|
||||
ajax.setLoadingElement($('.visitor-profile-location > p > .loadingPiwik', self.$element));
|
||||
ajax.send();
|
||||
},
|
||||
|
||||
_loadMoreVisits: function () {
|
||||
var self = this,
|
||||
$element = this.$element;
|
||||
|
||||
var loading = $('.visitor-profile-more-info > .loadingPiwik', $element);
|
||||
loading.show();
|
||||
|
||||
var ajax = new ajaxHelper();
|
||||
ajax.removeDefaultParameter('segment');
|
||||
ajax.addParams({
|
||||
module: 'Live',
|
||||
action: 'getVisitList',
|
||||
period: '',
|
||||
date: '',
|
||||
visitorId: $element.attr('data-visitor-id'),
|
||||
filter_offset: $('.visitor-profile-visits>li', $element).length,
|
||||
start_number: $('.visitor-profile-visits>li:last', $element).data('number') - 1
|
||||
}, 'GET');
|
||||
ajax.setCallback(function (response) {
|
||||
if (response == "") { // no more visits left
|
||||
self._showNoMoreVisitsSpan();
|
||||
} else {
|
||||
response = $(response);
|
||||
loading.hide();
|
||||
|
||||
$('.visitor-profile-visits', $element).append(response);
|
||||
if (response.filter('li').length < 10) {
|
||||
self._showNoMoreVisitsSpan();
|
||||
}
|
||||
|
||||
piwikHelper.lazyScrollTo($(response)[0], 400, true);
|
||||
}
|
||||
});
|
||||
ajax.setFormat('html');
|
||||
ajax.send();
|
||||
},
|
||||
|
||||
_showNoMoreVisitsSpan: function () {
|
||||
var noMoreSpan = $('<span/>').text(_pk_translate('Live_NoMoreVisits')).addClass('visitor-profile-no-visits');
|
||||
$('.visitor-profile-more-info', this.$element).html(noMoreSpan);
|
||||
},
|
||||
|
||||
_loadPreviousVisitor: function () {
|
||||
this._gotoAdjacentVisitor(this.$element.attr('data-prev-visitor'));
|
||||
},
|
||||
|
||||
_loadNextVisitor: function () {
|
||||
this._gotoAdjacentVisitor(this.$element.attr('data-next-visitor'));
|
||||
},
|
||||
|
||||
_gotoAdjacentVisitor: function (idVisitor) {
|
||||
if (!idVisitor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._inPopover()) {
|
||||
broadcast.propagateNewPopoverParameter('visitorProfile', idVisitor);
|
||||
} else if (this._inWidget()) {
|
||||
this.$element.closest('[widgetid]').dashboardWidget('reload', false, true, {visitorId: idVisitor});
|
||||
}
|
||||
},
|
||||
|
||||
_getFirstVisitId: function () {
|
||||
return $('.visitor-profile-visits>li:first-child>h2', this.$element).attr('data-idvisit');
|
||||
},
|
||||
|
||||
_inPopover: function () {
|
||||
return !! this.$element.closest('#Piwik_Popover').length;
|
||||
},
|
||||
|
||||
_inWidget: function () {
|
||||
return !! this.$element.closest('.widget').length;
|
||||
}
|
||||
});
|
||||
|
||||
exports.VisitorProfileControl = VisitorProfileControl;
|
||||
|
||||
// add the popup handler that creates a visitor profile
|
||||
broadcast.addPopoverHandler('visitorProfile', VisitorProfileControl.showPopover);
|
||||
|
||||
})(jQuery, require);
|
Reference in New Issue
Block a user