update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
9abe039dc8
commit
47263617c5
65 changed files with 418860 additions and 226988 deletions
|
|
@ -0,0 +1,85 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').controller('AjaxFormController', AjaxFormController);
|
||||
|
||||
AjaxFormController.$inject = ['piwikApi', '$filter'];
|
||||
|
||||
function AjaxFormController(piwikApi, $filter) {
|
||||
var vm = this;
|
||||
|
||||
/**
|
||||
* Set to non-null when a form submit request returns successfully. When successful, it will
|
||||
* be the entire JSON parsed response of the request.
|
||||
*
|
||||
* @type {null|string}
|
||||
*/
|
||||
vm.successfulPostResponse = null;
|
||||
|
||||
/**
|
||||
* Set to non-null when a form submit request results in an error. When an error occurs,
|
||||
* it will be set to the string error message.
|
||||
*
|
||||
* @type {null|string}
|
||||
*/
|
||||
vm.errorPostResponse = null;
|
||||
|
||||
/**
|
||||
* true if currently submitting a POST request, false if otherwise.
|
||||
*
|
||||
* @type {bool}
|
||||
*/
|
||||
vm.isSubmitting = false;
|
||||
|
||||
vm.submitForm = submitForm;
|
||||
|
||||
/**
|
||||
* Sends a POST to the configured API method.
|
||||
*/
|
||||
function submitForm() {
|
||||
var postParams;
|
||||
|
||||
vm.successfulPostResponse = null;
|
||||
vm.errorPostResponse = null;
|
||||
|
||||
if (vm.sendJsonPayload) {
|
||||
postParams = {data: JSON.stringify(vm.data)};
|
||||
} else {
|
||||
postParams = vm.data;
|
||||
}
|
||||
|
||||
vm.isSubmitting = true;
|
||||
piwikApi.post(
|
||||
{ // GET params
|
||||
module: 'API',
|
||||
method: vm.submitApiMethod
|
||||
},
|
||||
postParams,
|
||||
{ // request options
|
||||
createErrorNotification: !vm.noErrorNotification
|
||||
}
|
||||
).then(function (response) {
|
||||
vm.successResponse = response;
|
||||
|
||||
if (!vm.noSuccessNotification) {
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show($filter('translate')('General_YourChangesHaveBeenSaved'), {
|
||||
context: 'success',
|
||||
type: 'toast',
|
||||
id: 'ajaxHelper'
|
||||
});
|
||||
notification.scrollToNotification();
|
||||
}
|
||||
})['catch'](function (errorMessage) {
|
||||
vm.errorPostResponse = errorMessage;
|
||||
})['finally'](function () {
|
||||
vm.isSubmitting = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* AngularJS directive that manages an AJAX form.
|
||||
*
|
||||
* This directive will detect inputs & selects defined within an element and when a
|
||||
* submit button is clicked, will post data from the inputs & selects to a Piwik API method.
|
||||
*
|
||||
* When the POST request is finished the result will, by default, be displayed as a
|
||||
* notification.
|
||||
*
|
||||
* This directive accepts the following attributes:
|
||||
*
|
||||
* - **save-api-method**: **required** The Piwik API method that handles the POST request.
|
||||
* - **send-json-payload**: Whether to send the data as a form encoded URL or to send it as JSON.
|
||||
* If sending as JSON, the payload will still be a form encoded value,
|
||||
* but will contain a JSON object like `{data: {...form data...}}`.
|
||||
*
|
||||
* This is for forms with lots of fields where having the same number
|
||||
* of parameters in an API method would not be desired.
|
||||
* - **no-error-notification**: If true, does not display an error notification if the AJAX post
|
||||
* fails.
|
||||
* - **no-success-notification**: If true, does not display an error notification if the AJAX
|
||||
* results in success.
|
||||
*
|
||||
* **Custom Success/Error Handling**
|
||||
*
|
||||
* On success/failure, the response will be stored in controller scope. Child elements of a
|
||||
* piwik-ajax-form element can access this data, and thus, can customize what happens when
|
||||
* a form submit succeeds/fails.
|
||||
*
|
||||
* See the ajax-form.controller.js file for more info.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <div piwik-ajax-form
|
||||
* save-api-method="'MyPlugin.myFormSaveMethod'"
|
||||
* send-json-payload="true"
|
||||
* ng-model="myFormData">
|
||||
*
|
||||
* <h2>My Form</h2>
|
||||
* <input name="myOption" value="myDefaultValue" type="text" />
|
||||
* <input name="myOtherOption" type="checkbox" checked="checked" />
|
||||
* <input type="submit" value="Submit" ng-disabled="ajaxForm.isSubmitting" />
|
||||
*
|
||||
* <div piwik-notification context='error' ng-show="errorPostResponse">ERROR!</div>
|
||||
* </div>
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('piwikAjaxForm', piwikAjaxForm);
|
||||
|
||||
piwikAjaxForm.$inject = ['$parse'];
|
||||
|
||||
function piwikAjaxForm($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
submitApiMethod: '=',
|
||||
sendJsonPayload: '=',
|
||||
noErrorNotification: '=',
|
||||
noSuccessNotification: '=',
|
||||
useCustomDataBinding: '='
|
||||
},
|
||||
require: '?ngModel',
|
||||
controller: 'AjaxFormController',
|
||||
controllerAs: 'ajaxForm',
|
||||
transclude: true,
|
||||
compile: function (element, attrs) {
|
||||
attrs.noErrorNotification = !! attrs.noErrorNotification;
|
||||
|
||||
return function (scope, element, attrs, ngModel, transclude) {
|
||||
if (!scope.submitApiMethod) {
|
||||
throw new Error("submitApiMethod is required");
|
||||
}
|
||||
|
||||
scope.ajaxForm.submitApiMethod = scope.submitApiMethod;
|
||||
scope.ajaxForm.sendJsonPayload = scope.sendJsonPayload;
|
||||
scope.ajaxForm.noErrorNotification = scope.noErrorNotification;
|
||||
scope.ajaxForm.noSuccessNotification = scope.noSuccessNotification;
|
||||
|
||||
scope.ajaxForm.data = {};
|
||||
|
||||
// if a model is supplied, initiate form data w/ model value
|
||||
if (ngModel) {
|
||||
var ngModelGetter = $parse(attrs.ngModel); // probably redundant, but I cannot find another way to
|
||||
// get the ng model value here
|
||||
scope.ajaxForm.data = ngModelGetter(scope.$parent);
|
||||
}
|
||||
|
||||
// on change of any input, change appropriate value in model, but only if requested
|
||||
if (!scope.useCustomDataBinding) {
|
||||
element.on('change', 'input,select', function () {
|
||||
setFormValueFromInput(this);
|
||||
});
|
||||
}
|
||||
|
||||
// on submit call controller submit method
|
||||
element.on('click', 'input[type=submit]', function () {
|
||||
scope.ajaxForm.submitForm();
|
||||
});
|
||||
|
||||
// make sure child elements can access this directive's scope
|
||||
transclude(scope, function(clone, scope) {
|
||||
if (!scope.useCustomDataBinding) {
|
||||
var $inputs = clone.find('input,select').not('[type=submit]');
|
||||
|
||||
// initialize form data to input values (include <select>s
|
||||
$inputs.each(function () {
|
||||
setFormValueFromInput(this, true);
|
||||
});
|
||||
}
|
||||
|
||||
element.append(clone);
|
||||
});
|
||||
|
||||
function setFormValueFromInput(inputElement, skipScopeApply) {
|
||||
var $ = angular.element,
|
||||
name = $(inputElement).attr('name'),
|
||||
val;
|
||||
|
||||
if ($(inputElement).attr('type') == 'checkbox') {
|
||||
val = $(inputElement).is(':checked');
|
||||
} else {
|
||||
val = $(inputElement).val();
|
||||
}
|
||||
|
||||
scope.ajaxForm.data[name] = val;
|
||||
|
||||
if (!skipScopeApply) {
|
||||
scope.$apply();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* See http://dev.piwik.org/trac/ticket/4795 "linking to #hash tag does not work after merging AngularJS"
|
||||
* See https://github.com/piwik/piwik/issues/4795 "linking to #hash tag does not work after merging AngularJS"
|
||||
*/
|
||||
(function () {
|
||||
|
||||
|
|
@ -32,7 +32,12 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var $node = $('#' + hash);
|
||||
try {
|
||||
var $node = $('#' + hash);
|
||||
} catch (err) {
|
||||
// on jquery syntax error, ignore so nothing is logged to the console
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node && $node.length) {
|
||||
scrollToAnchorNode($node);
|
||||
|
|
@ -80,7 +85,9 @@
|
|||
{
|
||||
angular.module('piwikApp').run(['$rootScope', function ($rootScope) {
|
||||
|
||||
$rootScope.$on('$locationChangeStart', function (event, newUrl, oldUrl, $location) {
|
||||
$rootScope.$on('$locationChangeStart', onLocationChangeStart);
|
||||
|
||||
function onLocationChangeStart (event, newUrl, oldUrl, $location) {
|
||||
|
||||
if (!newUrl) {
|
||||
return;
|
||||
|
|
@ -98,7 +105,7 @@
|
|||
var hash = newUrl.substr(hashPos + 2);
|
||||
|
||||
scrollToAnchorIfPossible(hash, event);
|
||||
});
|
||||
}
|
||||
}]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -15,28 +15,39 @@
|
|||
* <div piwik-autocomplete-matched="searchTerm">{{ name }}</div>
|
||||
* <input type="text" ng-model="searchTerm">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikAutocompleteMatched', function() {
|
||||
return function(scope, element, attrs) {
|
||||
var searchTerm;
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikAutocompleteMatched', piwikAutocompleteMatched);
|
||||
|
||||
scope.$watch(attrs.piwikAutocompleteMatched, function(value) {
|
||||
searchTerm = value;
|
||||
updateText();
|
||||
});
|
||||
piwikAutocompleteMatched.$inject = ['piwik', '$sanitize'];
|
||||
|
||||
function updateText () {
|
||||
if (!searchTerm || !element) {
|
||||
return;
|
||||
function piwikAutocompleteMatched(piwik, $sanitize) {
|
||||
|
||||
return {
|
||||
priority: 10, // makes sure to render after other directives, otherwise the content might be overwritten again see https://github.com/piwik/piwik/pull/8467
|
||||
link: function (scope, element, attrs) {
|
||||
var searchTerm;
|
||||
|
||||
scope.$watch(attrs.piwikAutocompleteMatched, function (value) {
|
||||
searchTerm = value;
|
||||
updateText();
|
||||
});
|
||||
|
||||
function updateText() {
|
||||
if (!searchTerm || !element) {
|
||||
return;
|
||||
}
|
||||
|
||||
var content = piwik.helper.htmlEntities(element.text());
|
||||
var startTerm = content.toLowerCase().indexOf(searchTerm.toLowerCase());
|
||||
|
||||
if (-1 !== startTerm) {
|
||||
var word = content.substr(startTerm, searchTerm.length);
|
||||
var escapedword = $sanitize(piwik.helper.htmlEntities(word));
|
||||
content = content.replace(word, '<span class="autocompleteMatched">' + escapedword + '</span>');
|
||||
element.html(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var content = element.html();
|
||||
var startTerm = content.toLowerCase().indexOf(searchTerm.toLowerCase());
|
||||
|
||||
if (-1 !== startTerm) {
|
||||
var word = content.substr(startTerm, searchTerm.length);
|
||||
content = content.replace(word, '<span class="autocompleteMatched">' + word + '</span>');
|
||||
element.html(content);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
describe('piwikAutocompleteMatchedDirective', function() {
|
||||
var $compile;
|
||||
var $rootScope;
|
||||
|
||||
beforeEach(module('piwikApp.directive'));
|
||||
beforeEach(inject(function(_$compile_, _$rootScope_){
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
|
||||
function assertRenderedContentIs(query, expectedResult) {
|
||||
var template = '<div piwik-autocomplete-matched="\'' + query + '\'">My Content</div>';
|
||||
var element = $compile(template)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.html()).to.eql(expectedResult);
|
||||
}
|
||||
|
||||
describe('#piwikAutocompleteMatched()', function() {
|
||||
|
||||
it('should not change anything if query does not match the text', function() {
|
||||
assertRenderedContentIs('Whatever', 'My Content');
|
||||
});
|
||||
|
||||
it('should wrap the matching part and find case insensitive', function() {
|
||||
assertRenderedContentIs('y cont', 'M<span class="autocompleteMatched">y Cont</span>ent');
|
||||
});
|
||||
|
||||
it('should be able to wrap the whole content', function() {
|
||||
assertRenderedContentIs('my content', '<span class="autocompleteMatched">My Content</span>');
|
||||
});
|
||||
|
||||
it('should find matching content case sensitive', function() {
|
||||
assertRenderedContentIs('My Co', '<span class="autocompleteMatched">My Co</span>ntent');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -15,27 +15,36 @@
|
|||
* </div>
|
||||
* Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikDialog', function(piwik) {
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikDialog', piwikDialog);
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
piwikDialog.$inject = ['piwik', '$parse'];
|
||||
|
||||
element.css('display', 'none');
|
||||
function piwikDialog(piwik, $parse) {
|
||||
|
||||
element.on( "dialogclose", function() {
|
||||
scope.$eval(attrs.piwikDialog+'=false');
|
||||
});
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
scope.$watch(attrs.piwikDialog, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
piwik.helper.modalConfirm(element, {yes: function() {
|
||||
if (attrs.yes) {
|
||||
scope.$eval(attrs.yes);
|
||||
}
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
element.css('display', 'none');
|
||||
|
||||
element.on( "dialogclose", function() {
|
||||
setTimeout(function () {
|
||||
scope.$apply($parse(attrs.piwikDialog).assign(scope, false));
|
||||
}, 0);
|
||||
});
|
||||
|
||||
scope.$watch(attrs.piwikDialog, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
piwik.helper.modalConfirm(element, {yes: function() {
|
||||
if (attrs.yes) {
|
||||
scope.$eval(attrs.yes);
|
||||
setTimeout(function () { scope.$apply(); }, 0);
|
||||
}
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.directive', []);
|
||||
})();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -12,29 +12,35 @@
|
|||
* Example:
|
||||
* <div piwik-focus-anywhere-but-here="closeDialog()">my dialog</div>
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikFocusAnywhereButHere', function($document){
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikFocusAnywhereButHere', piwikFocusAnywhereButHere);
|
||||
|
||||
function onClickOutsideElement (event) {
|
||||
if (element.has(event.target).length === 0) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
piwikFocusAnywhereButHere.$inject = ['$document'];
|
||||
|
||||
function piwikFocusAnywhereButHere($document){
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
function onClickOutsideElement (event) {
|
||||
if (element.has(event.target).length === 0) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onEscapeHandler (event) {
|
||||
if (event.which === 27) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
function onEscapeHandler (event) {
|
||||
if (event.which === 27) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$document.on('keyup', onEscapeHandler);
|
||||
$document.on('mouseup', onClickOutsideElement);
|
||||
scope.$on('$destroy', function() {
|
||||
$document.off('mouseup', onClickOutsideElement);
|
||||
$document.off('keyup', onEscapeHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
$document.on('keyup', onEscapeHandler);
|
||||
$document.on('mouseup', onClickOutsideElement);
|
||||
scope.$on('$destroy', function() {
|
||||
$document.off('mouseup', onClickOutsideElement);
|
||||
$document.off('keyup', onEscapeHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -11,17 +11,23 @@
|
|||
* Example:
|
||||
* <input type="text" piwik-focus-if="view.editName">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikFocusIf', function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$watch(attrs.piwikFocusIf, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
$timeout(function () {
|
||||
element[0].focus();
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikFocusIf', piwikFocusIf);
|
||||
|
||||
piwikFocusIf.$inject = ['$timeout'];
|
||||
|
||||
function piwikFocusIf($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$watch(attrs.piwikFocusIf, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
$timeout(function () {
|
||||
element[0].focus();
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -12,10 +12,14 @@
|
|||
* Example
|
||||
* <a piwik-ignore-click ng-click="doSomething()" href="/">my link</a>
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikIgnoreClick', function() {
|
||||
return function(scope, element, attrs) {
|
||||
$(element).click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
};
|
||||
});
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikIgnoreClick', piwikIgnoreClick);
|
||||
|
||||
function piwikIgnoreClick() {
|
||||
return function(scope, element, attrs) {
|
||||
$(element).click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -12,16 +12,20 @@
|
|||
* <div piwik-onenter="save()">
|
||||
* <div piwik-onenter="showList=false">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikOnenter', function() {
|
||||
return function(scope, element, attrs) {
|
||||
element.bind("keydown keypress", function(event) {
|
||||
if(event.which === 13) {
|
||||
scope.$apply(function(){
|
||||
scope.$eval(attrs.piwikOnenter, {'event': event});
|
||||
});
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikOnenter', piwikOnenter);
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
function piwikOnenter() {
|
||||
return function(scope, element, attrs) {
|
||||
element.bind("keydown keypress", function(event) {
|
||||
if(event.which === 13) {
|
||||
scope.$apply(function(){
|
||||
scope.$eval(attrs.piwikOnenter, {'event': event});
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
})();
|
||||
36
www/analytics/plugins/CoreHome/angularjs/common/directives/translate.js
vendored
Normal file
36
www/analytics/plugins/CoreHome/angularjs/common/directives/translate.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Directive for easy & safe complex internationalization. This directive allows
|
||||
* users to embed the sprintf arguments used in internationalization inside an HTML
|
||||
* element. Since the HTML will eventually be sanitized by AngularJS, HTML can be used
|
||||
* within the sprintf args. Using the filter, this is not possible w/o manually sanitizing
|
||||
* and creating trusted HTML, which is not as safe.
|
||||
*
|
||||
* Note: nesting this directive is not supported.
|
||||
*
|
||||
* Usage:
|
||||
* <span piwik-translate="Plugin_TranslationToken">
|
||||
* first arg::<strong>second arg</strong>::{{ unsafeDataThatWillBeSanitized }}
|
||||
* </span>
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.directive').directive('piwikTranslate', piwikTranslate);
|
||||
|
||||
function piwikTranslate() {
|
||||
return {
|
||||
priority: 1,
|
||||
restrict: 'A',
|
||||
compile: function(element, attrs) {
|
||||
var parts = element.html().split('::'),
|
||||
translated = _pk_translate(attrs.piwikTranslate, parts);
|
||||
element.html(translated);
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -1,44 +1,49 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.filter').filter('evolution', evolutionFilter);
|
||||
|
||||
angular.module('piwikApp.filter').filter('evolution', function() {
|
||||
function evolutionFilter() {
|
||||
|
||||
function calculateEvolution(currentValue, pastValue)
|
||||
{
|
||||
pastValue = parseInt(pastValue, 10);
|
||||
currentValue = parseInt(currentValue, 10) - pastValue;
|
||||
function calculateEvolution(currentValue, pastValue)
|
||||
{
|
||||
pastValue = parseInt(pastValue, 10);
|
||||
currentValue = parseInt(currentValue, 10) - pastValue;
|
||||
|
||||
if (currentValue === 0 || isNaN(currentValue)) {
|
||||
evolution = 0;
|
||||
} else if (pastValue === 0 || isNaN(pastValue)) {
|
||||
evolution = 100;
|
||||
} else {
|
||||
evolution = (currentValue / pastValue) * 100;
|
||||
var evolution;
|
||||
|
||||
if (currentValue === 0 || isNaN(currentValue)) {
|
||||
evolution = 0;
|
||||
} else if (pastValue === 0 || isNaN(pastValue)) {
|
||||
evolution = 100;
|
||||
} else {
|
||||
evolution = (currentValue / pastValue) * 100;
|
||||
}
|
||||
|
||||
return evolution;
|
||||
}
|
||||
|
||||
return evolution;
|
||||
}
|
||||
function formatEvolution(evolution)
|
||||
{
|
||||
evolution = Math.round(evolution);
|
||||
|
||||
function formatEvolution(evolution)
|
||||
{
|
||||
evolution = Math.round(evolution);
|
||||
if (evolution > 0) {
|
||||
evolution = '+' + evolution;
|
||||
}
|
||||
|
||||
if (evolution > 0) {
|
||||
evolution = '+' + evolution;
|
||||
evolution += '%';
|
||||
|
||||
return evolution;
|
||||
}
|
||||
|
||||
evolution += '%';
|
||||
return function(currentValue, pastValue) {
|
||||
var evolution = calculateEvolution(currentValue, pastValue);
|
||||
|
||||
return evolution;
|
||||
return formatEvolution(evolution);
|
||||
};
|
||||
}
|
||||
|
||||
return function(currentValue, pastValue) {
|
||||
var evolution = calculateEvolution(currentValue, pastValue);
|
||||
|
||||
return formatEvolution(evolution);
|
||||
};
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
angular.module('piwikApp.filter', []);
|
||||
(function () {
|
||||
angular.module('piwikApp.filter', []);
|
||||
})();
|
||||
26
www/analytics/plugins/CoreHome/angularjs/common/filters/htmldecode.js
vendored
Normal file
26
www/analytics/plugins/CoreHome/angularjs/common/filters/htmldecode.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.filter').filter('htmldecode', htmldecode);
|
||||
|
||||
htmldecode.$inject = ['piwik'];
|
||||
|
||||
/**
|
||||
* Be aware that this filter can cause XSS so only use it when you're sure it is safe.
|
||||
* Eg it should be safe when it is afterwards escaped by angular sanitize again.
|
||||
*/
|
||||
function htmldecode(piwik) {
|
||||
|
||||
return function(text) {
|
||||
if (text && text.length) {
|
||||
return piwik.helper.htmlDecode(text);
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
}
|
||||
})();
|
||||
21
www/analytics/plugins/CoreHome/angularjs/common/filters/length.js
vendored
Normal file
21
www/analytics/plugins/CoreHome/angularjs/common/filters/length.js
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.filter').filter('length', length);
|
||||
|
||||
function length() {
|
||||
|
||||
return function(stringOrArray) {
|
||||
if (stringOrArray && stringOrArray.length) {
|
||||
return stringOrArray.length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
16
www/analytics/plugins/CoreHome/angularjs/common/filters/pretty-url.js
vendored
Normal file
16
www/analytics/plugins/CoreHome/angularjs/common/filters/pretty-url.js
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.filter').filter('prettyUrl', prettyUrl);
|
||||
|
||||
function prettyUrl() {
|
||||
return function(input) {
|
||||
return input.trim().replace('http://', '');
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp.filter').filter('startFrom', startFrom);
|
||||
|
||||
angular.module('piwikApp.filter').filter('startFrom', function() {
|
||||
return function(input, start) {
|
||||
start = +start; //parse to int
|
||||
return input.slice(start);
|
||||
};
|
||||
});
|
||||
function startFrom() {
|
||||
return function(input, start) {
|
||||
start = +start; //parse to int
|
||||
return input.slice(start);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
describe('startFromFilter', function() {
|
||||
var startFrom;
|
||||
|
||||
beforeEach(module('piwikApp.filter'));
|
||||
beforeEach(inject(function($injector) {
|
||||
var $filter = $injector.get('$filter');
|
||||
startFrom = $filter('startFrom');
|
||||
}));
|
||||
|
||||
describe('#startFrom()', function() {
|
||||
|
||||
it('should return all entries if index is zero', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 0);
|
||||
|
||||
expect(result).to.eql([1,2,3]);
|
||||
});
|
||||
|
||||
it('should return only partial entries if filter is higher than zero', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 2);
|
||||
|
||||
expect(result).to.eql([3]);
|
||||
});
|
||||
|
||||
it('should return no entries if start is higher than input length', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 11);
|
||||
|
||||
expect(result).to.eql([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue