update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
296343bf3b
commit
d885a4baa9
5833 changed files with 418860 additions and 226988 deletions
|
|
@ -0,0 +1,86 @@
|
|||
/*!
|
||||
* 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('QuickAccessController', QuickAccessController);
|
||||
|
||||
QuickAccessController.$inject = ['$scope', '$filter', 'siteSelectorModel'];
|
||||
|
||||
function QuickAccessController($scope, $filter, siteSelectorModel){
|
||||
|
||||
this.menuItems = [];
|
||||
this.numMenuItems = 0;
|
||||
this.sitesModel = siteSelectorModel;
|
||||
|
||||
this.onKeypress = function (event) {
|
||||
var areSearchResultsDisplayed = $scope.search && $scope.search.term && $scope.view && $scope.view.searchActive;
|
||||
var isTabKey = 9 == event.which
|
||||
var isEscKey = 27 == event.which
|
||||
|
||||
if (38 == event.which) {
|
||||
$scope.highlightPreviousItem();
|
||||
event.preventDefault();
|
||||
} else if (40 == event.which) {
|
||||
$scope.highlightNextItem();
|
||||
event.preventDefault();
|
||||
} else if (13 == event.which) {
|
||||
$scope.clickQuickAccessMenuItem();
|
||||
} else if (isTabKey && areSearchResultsDisplayed) {
|
||||
$scope.deactivateSearch();
|
||||
} else if (isEscKey && areSearchResultsDisplayed) {
|
||||
$scope.deactivateSearch();
|
||||
}
|
||||
};
|
||||
|
||||
this.searchMenu = function (searchTerm) {
|
||||
searchTerm = searchTerm.toLowerCase();
|
||||
|
||||
var index = -1;
|
||||
var menuItemsIndex = {};
|
||||
var menuItems = [];
|
||||
|
||||
var moveToCategory = function (i, submenuItem) {
|
||||
submenuItem = angular.copy(submenuItem); // force rerender of element to prevent weird side effects
|
||||
submenuItem.menuIndex = ++index; // needed for proper highlighting with arrow keys
|
||||
|
||||
var category = submenuItem.category;
|
||||
if (!(category in menuItemsIndex)) {
|
||||
menuItems.push({title: category, items: []});
|
||||
menuItemsIndex[category] = menuItems.length - 1;
|
||||
}
|
||||
|
||||
var indexOfCategory = menuItemsIndex[category];
|
||||
menuItems[indexOfCategory].items.push(submenuItem);
|
||||
};
|
||||
|
||||
$scope.resetSearchIndex();
|
||||
|
||||
if ($scope.hasSitesSelector) {
|
||||
this.sitesModel.searchSite(searchTerm);
|
||||
}
|
||||
|
||||
var topMenuItems = $filter('filter')($scope.getTopMenuItems(), searchTerm);
|
||||
var leftMenuItems = $filter('filter')($scope.getLeftMenuItems(), searchTerm);
|
||||
var segmentItems = $filter('filter')($scope.getSegmentItems(), searchTerm);
|
||||
|
||||
$.each(topMenuItems, moveToCategory);
|
||||
$.each(leftMenuItems, moveToCategory);
|
||||
$.each(segmentItems, moveToCategory);
|
||||
|
||||
this.numMenuItems = topMenuItems.length + leftMenuItems.length + segmentItems.length;
|
||||
this.menuItems = menuItems;
|
||||
};
|
||||
|
||||
this.selectSite = function (idsite) {
|
||||
this.sitesModel.loadSite(idsite);
|
||||
};
|
||||
|
||||
this.selectMenuItem = function (index) {
|
||||
$scope.selectMenuItem(index);
|
||||
};
|
||||
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<div class="quick-access"
|
||||
ng-class="{active: view.searchActive, expanded: view.searchActive}"
|
||||
piwik-focus-anywhere-but-here="view.searchActive = false;">
|
||||
<span class="icon-search" ng-hide="search.term || view.searchActive"
|
||||
ng-mouseenter="view.searchActive=true"></span>
|
||||
<input class="s"
|
||||
title="{{ quickAccessTitle }}"
|
||||
ng-keydown="quickAccess.onKeypress($event)"
|
||||
ng-change="view.searchActive=true;quickAccess.searchMenu(search.term)"
|
||||
ng-focus="view.searchActive=true"
|
||||
ng-model="search.term" piwik-focus-if="view.searchActive"
|
||||
type="text" tabindex="2"/>
|
||||
<ul ng-hide="!search.term || !view.searchActive || (quickAccess.numMenuItems > 0) || (quickAccess.sitesModel.sites | length)">
|
||||
<li class="no-result">{{ 'General_SearchNoResults' | translate }}</li>
|
||||
</ul>
|
||||
<ul ng-show="search.term && view.searchActive" ng-repeat="subcategory in quickAccess.menuItems">
|
||||
<li class="quick-access-category"
|
||||
ng-click="search.term = subcategory.title;quickAccess.searchMenu(search.term)">{{ subcategory.title }}</li>
|
||||
<li class="result"
|
||||
ng-class="{selected: submenuEntry.menuIndex == search.index}"
|
||||
ng-mouseenter="search.index=submenuEntry.menuIndex"
|
||||
ng-click="quickAccess.selectMenuItem(submenuEntry.index)"
|
||||
ng-repeat="submenuEntry in subcategory.items"><a>{{ submenuEntry.name | trim }}</a></li>
|
||||
</ul>
|
||||
<ul ng-show="search.term && view.searchActive">
|
||||
<li class="quick-access-category websiteCategory"
|
||||
ng-show="hasSitesSelector && ((quickAccess.sitesModel.sites | length) || quickAccess.sitesModel.isLoading)"
|
||||
>{{ 'SitesManager_Sites' | translate }}</li>
|
||||
<li class="no-result"
|
||||
ng-show="hasSitesSelector && quickAccess.sitesModel.isLoading">{{ 'MultiSites_LoadingWebsites' | translate }}</li>
|
||||
<li class="result"
|
||||
ng-show="hasSitesSelector && !quickAccess.sitesModel.isLoading"
|
||||
ng-mouseenter="search.index=(quickAccess.numMenuItems + $index)"
|
||||
ng-class="{selected: (quickAccess.numMenuItems + $index) == search.index}"
|
||||
ng-click="quickAccess.selectSite(site.idsite)"
|
||||
ng-repeat="site in quickAccess.sitesModel.sites"><a ng-bind-html="site.name"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* <div piwik-dialog="showDialog">...</div>
|
||||
* Will show dialog once showDialog evaluates to true.
|
||||
*
|
||||
* Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('piwikQuickAccess', QuickAccessDirective);
|
||||
|
||||
QuickAccessDirective.$inject = ['$rootElement', '$timeout', 'piwik', '$filter'];
|
||||
|
||||
function QuickAccessDirective ($rootElement, $timeout, piwik, $filter) {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: true,
|
||||
scope: {},
|
||||
templateUrl: 'plugins/CoreHome/angularjs/quick-access/quick-access.directive.html?cb=' + piwik.cacheBuster,
|
||||
controller: 'QuickAccessController',
|
||||
controllerAs: 'quickAccess',
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
var menuIndex = -1; // the menu index is used to identify which element to click
|
||||
var topMenuItems = []; // cache for top menu items
|
||||
var leftMenuItems = []; // cache for left menu items
|
||||
var segmentItems = []; // cache for segment items
|
||||
var hasSegmentSelector = angular.element('.segmentEditorPanel').length;
|
||||
scope.hasSitesSelector = angular.element('.top_controls [piwik-siteselector]').length;
|
||||
|
||||
|
||||
var translate = $filter('translate');
|
||||
var searchAreasTitle = '';
|
||||
var searchAreas = [translate('CoreHome_MenuEntries')]
|
||||
|
||||
if (hasSegmentSelector) {
|
||||
searchAreas.push(translate('CoreHome_Segments'))
|
||||
}
|
||||
|
||||
if (scope.hasSitesSelector) {
|
||||
searchAreas.push(translate('SitesManager_Sites'))
|
||||
}
|
||||
|
||||
while (searchAreas.length) {
|
||||
searchAreasTitle += searchAreas.shift();
|
||||
if (searchAreas.length >= 2) {
|
||||
searchAreasTitle += ', ';
|
||||
} else if (searchAreas.length === 1) {
|
||||
searchAreasTitle += ' ' + translate('General_And') + ' ';
|
||||
}
|
||||
}
|
||||
|
||||
scope.quickAccessTitle = translate('CoreHome_QuickAccessTitle', searchAreasTitle);
|
||||
|
||||
function trim(str) {
|
||||
return str.replace(/^\s+|\s+$/g,'');
|
||||
}
|
||||
|
||||
scope.getTopMenuItems = function()
|
||||
{
|
||||
if (topMenuItems && topMenuItems.length) {
|
||||
return topMenuItems;
|
||||
}
|
||||
|
||||
var category = _pk_translate('CoreHome_Menu');
|
||||
|
||||
$rootElement.find('#topRightBar .navbar-right li > a').each(function (index, element) {
|
||||
var $element = $(element);
|
||||
|
||||
if ($element.is('#topmenu-usersmanager')) {
|
||||
// ignore languages manager
|
||||
return;
|
||||
}
|
||||
|
||||
var text = trim($element.text());
|
||||
|
||||
if (!text) {
|
||||
text = trim($element.attr('title')); // possibly a icon, use title instead
|
||||
}
|
||||
|
||||
if (text) {
|
||||
topMenuItems.push({name: text, index: ++menuIndex, category: category});
|
||||
$element.attr('quick_access', menuIndex);
|
||||
}
|
||||
});
|
||||
|
||||
return topMenuItems;
|
||||
};
|
||||
|
||||
scope.getLeftMenuItems = function ()
|
||||
{
|
||||
if (leftMenuItems && leftMenuItems.length) {
|
||||
return leftMenuItems;
|
||||
}
|
||||
|
||||
$rootElement.find('#secondNavBar .menuTab').each(function (index, element) {
|
||||
var $element = angular.element(element);
|
||||
var category = trim($element.find('> .item').text());
|
||||
|
||||
if (category && -1 !== category.lastIndexOf("\n")) {
|
||||
// remove "\n\nMenu"
|
||||
category = trim(category.substr(0, category.lastIndexOf("\n")));
|
||||
}
|
||||
|
||||
$element.find('li .item').each(function (i, element) {
|
||||
var $element = angular.element(element);
|
||||
var text = trim($element.text());
|
||||
|
||||
if (text) {
|
||||
leftMenuItems.push({name: text, category: category, index: ++menuIndex});
|
||||
$element.attr('quick_access', menuIndex);
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
return leftMenuItems;
|
||||
};
|
||||
|
||||
scope.getSegmentItems = function()
|
||||
{
|
||||
if (!hasSegmentSelector) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (segmentItems && segmentItems.length) {
|
||||
return segmentItems;
|
||||
}
|
||||
|
||||
var category = _pk_translate('CoreHome_Segments');
|
||||
|
||||
$rootElement.find('.segmentList [data-idsegment]').each(function (index, element) {
|
||||
var $element = angular.element(element);
|
||||
var text = trim($element.find('.segname').text());
|
||||
|
||||
if (text) {
|
||||
segmentItems.push({name: text, category: category, index: ++menuIndex});
|
||||
$element.attr('quick_access', menuIndex);
|
||||
}
|
||||
});
|
||||
|
||||
return segmentItems;
|
||||
};
|
||||
|
||||
scope.activateSearch = function()
|
||||
{
|
||||
scope.$eval('view.searchActive = true');
|
||||
$timeout(function () {
|
||||
scope.$apply();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
scope.deactivateSearch = function()
|
||||
{
|
||||
scope.$eval('search.term = ""');
|
||||
scope.$eval('view.searchActive = false');
|
||||
element.find('input').blur();
|
||||
$timeout(function () {
|
||||
scope.$apply();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
function isElementInViewport(element) {
|
||||
|
||||
var rect = element.getBoundingClientRect();
|
||||
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
rect.left >= 0 &&
|
||||
rect.bottom <= $(window).height() &&
|
||||
rect.right <= $(window).width()
|
||||
);
|
||||
}
|
||||
|
||||
function getCurrentlySelectedElement(index)
|
||||
{
|
||||
var results = element.find('li.result');
|
||||
if (results && results.length && results[scope.search.index]) {
|
||||
return $(results[scope.search.index]);
|
||||
}
|
||||
}
|
||||
|
||||
function makeSureSelectedItemIsInViewport() {
|
||||
var element = getCurrentlySelectedElement();
|
||||
|
||||
if (element && element[0] && !isElementInViewport(element[0])) {
|
||||
scrollFirstElementIntoView(element);
|
||||
}
|
||||
}
|
||||
|
||||
function scrollFirstElementIntoView(element)
|
||||
{
|
||||
if (element && element[0] && element[0].scrollIntoView) {
|
||||
// make sure search is visible
|
||||
element[0].scrollIntoView();
|
||||
}
|
||||
}
|
||||
|
||||
scope.highlightPreviousItem = function()
|
||||
{
|
||||
if (0 >= (scope.search.index - 1)) {
|
||||
scope.search.index = 0;
|
||||
} else {
|
||||
scope.search.index--;
|
||||
}
|
||||
makeSureSelectedItemIsInViewport();
|
||||
};
|
||||
|
||||
scope.resetSearchIndex = function () {
|
||||
scope.search.index = 0;
|
||||
makeSureSelectedItemIsInViewport();
|
||||
};
|
||||
|
||||
scope.highlightNextItem = function()
|
||||
{
|
||||
var numTotal = element.find('li.result').length;
|
||||
|
||||
if (numTotal <= (scope.search.index + 1)) {
|
||||
scope.search.index = numTotal - 1;
|
||||
} else {
|
||||
scope.search.index++;
|
||||
}
|
||||
|
||||
makeSureSelectedItemIsInViewport();
|
||||
};
|
||||
|
||||
scope.clickQuickAccessMenuItem = function()
|
||||
{
|
||||
var selectedMenuElement = getCurrentlySelectedElement();
|
||||
if (selectedMenuElement) {
|
||||
$timeout(function () {
|
||||
selectedMenuElement.click();
|
||||
}, 20);
|
||||
}
|
||||
};
|
||||
|
||||
scope.selectMenuItem = function(index)
|
||||
{
|
||||
var target = $rootElement.find('[quick_access=' + index + ']');
|
||||
|
||||
if (target && target.length && target[0]) {
|
||||
scope.deactivateSearch();
|
||||
|
||||
var actualTarget = target[0];
|
||||
|
||||
var href = $(actualTarget).attr('href');
|
||||
|
||||
if (href && href.length > 10 && actualTarget && actualTarget.click) {
|
||||
try {
|
||||
actualTarget.click();
|
||||
} catch (e) {
|
||||
$(actualTarget).click();
|
||||
}
|
||||
} else {
|
||||
$(actualTarget).click();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Mousetrap.bind('f', function(event) {
|
||||
if (event.preventDefault) {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
event.returnValue = false; // IE
|
||||
}
|
||||
|
||||
scrollFirstElementIntoView(element);
|
||||
|
||||
scope.activateSearch();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
.quick-access {
|
||||
position: relative;
|
||||
|
||||
li {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
li a {
|
||||
padding: 10px 19px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.icon-search {
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
|
||||
}
|
||||
input {
|
||||
width:100%;
|
||||
height: 100%;
|
||||
border: 0 !important;
|
||||
box-shadow: 0 0 !important;
|
||||
border-radius: 0 !important;
|
||||
font-size: 11px;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.selected {
|
||||
background-color: @theme-color-background-tinyContrast !important;
|
||||
}
|
||||
.quick-access-category {
|
||||
text-align: left !important;
|
||||
font-size: 11px;
|
||||
padding: 5px 5px 5px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.result {
|
||||
cursor: pointer;
|
||||
}
|
||||
.quick-access-category:hover {
|
||||
background: none !important;
|
||||
}
|
||||
.no-result {
|
||||
padding: 10px 19px;
|
||||
cursor: default;
|
||||
}
|
||||
.websiteCategory {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue