diff --git a/config/global.ini.php b/config/global.ini.php index 16abb38e2bd1d4cb1b329da7132ad3eaaf237f90..af26509b60ebcd34581bee0d77d677877c441846 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -315,13 +315,9 @@ graphs_default_period_to_plot_when_period_range = day ; a view of the current page. The value X can be set here. overlay_following_pages_limit = 300 -; With this option, you can disable the framed mode of the Overlay plugin. If set to 1, the Page Overlay session -; will be started in a new tab instead of the iframe. +; With this option, you can disable the framed mode of the Overlay plugin. Use it if your website contains a framebuster. overlay_disable_framed_mode = 0 -; If this option is set, the links in the pages reports will not be opened in a new tab but will launch Page Overlay instead. -overlay_launch_from_pages_report = 0 - [Tracker] ; Piwik uses first party cookies by default. If set to 1, ; the visit ID cookie will be set on the Piwik server domain as well diff --git a/core/ViewDataTable/HtmlTable.php b/core/ViewDataTable/HtmlTable.php index f23f356ef7c7028a58ffa9a314dbd7e31de139c5..88d646460c56eb5ce656a61e9d36e5efb680aef8 100644 --- a/core/ViewDataTable/HtmlTable.php +++ b/core/ViewDataTable/HtmlTable.php @@ -234,12 +234,4 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable $this->variablesDefault['disable_row_actions'] = true; } - /** - * Use this method to open links in Overlay instead of a new tab - */ - public function openLinksInOverlay() - { - $this->variablesDefault['open_links_in_overlay'] = true; - } - } diff --git a/lang/en.php b/lang/en.php index b197f5c2b08dc94ca8dd85f71556903ae6135363..d1bda3933fdd30889e38e63974244f37220a30df 100644 --- a/lang/en.php +++ b/lang/en.php @@ -597,6 +597,8 @@ $translations = array( 'CoreHome_RowEvolutionRowActionTooltip_js' => 'See how the metrics for this row changed over time', 'CoreHome_TransitionsRowActionTooltipTitle_js' => 'Open Transitions', 'CoreHome_TransitionsRowActionTooltip_js' => 'See what visitors did before and after viewing this page', + 'CoreHome_OverlayRowActionTooltipTitle_js' => 'Open Page Overlay', + 'CoreHome_OverlayRowActionTooltip_js' => 'See analytics data directly on your website (opens new tab)', 'CorePluginsAdmin_PluginDescription' => 'Plugins Administration Interface.', 'CorePluginsAdmin_Plugins' => 'Plugins', 'CorePluginsAdmin_PluginsManagement' => 'Plugins Management', @@ -1821,19 +1823,18 @@ And thank you for using Piwik!', 'Transitions_ErrorBack' => 'Go back to the previous action', 'Overlay_Overlay' => 'Page Overlay', 'Overlay_PluginDescription' => 'See analytics data as an overlay on your actual website.', - 'Overlay_Page' => 'Page', + 'Overlay_Location' => 'Location', 'Overlay_MainMetrics' => 'Main metrics', 'Overlay_NoData' => 'There is no data for this page during the selected period.', - 'Overlay_OpenFullScreen' => 'Go full screen with sidebar', - 'Overlay_CloseFullScreen' => 'Close full screen', + 'Overlay_OpenFullScreen' => 'Go full screen (no sidebar)', 'Overlay_OneClick' => '1 click', 'Overlay_Clicks' => '%s clicks', 'Overlay_ClicksFromXLinks' => '%1$s clicks from one of %2$s links', 'Overlay_Link' => 'Link', - 'Overlay_OpenNewTab' => 'Open Overlay in new tab', - 'Overlay_RedirectUrlError' => 'You are attempting to open Page Overlay for the URL "%s". %s None of the URLs from the Piwik settings matches the link. Please add the domain there.', + 'Overlay_RedirectUrlError' => 'You are attempting to open Page Overlay for the URL "%s". %s None of the domains from the Piwik settings matches the link.', + 'Overlay_RedirectUrlErrorUser' => 'Ask your administrator to add the domain as an additional URL.', + 'Overlay_RedirectUrlErrorAdmin' => 'You can add the domain as an additional URL %sin the settings%s.', 'Overlay_Domain' => 'Domain', - 'Overlay_NoFrameModeText' => 'The page overlay session will be launched in a new tab. %s If opening the tab doesn\'t work automatically, please %sclick here%s.', 'Overlay_ErrorNotLoading' => 'The Page Overlay session couldn\'t be launched yet.', 'Overlay_ErrorNotLoadingDetails' => 'Maybe the page loaded on the right doesn\'t have the Piwik tracker code. In this case, try launching Overlay for a different page from the pages report.', 'Overlay_ErrorNotLoadingDetailsSSL' => 'Since you\'re using Piwik over https, the most likely cause is that your website doesn\'t support SSL. Try using Piwik over http.', diff --git a/plugins/Actions/Controller.php b/plugins/Actions/Controller.php index 14af64b0872780bcc15dafce3bf952e363a15f9e..0493c4ac55edbe0e3bdda17468540897421e2d9c 100644 --- a/plugins/Actions/Controller.php +++ b/plugins/Actions/Controller.php @@ -24,9 +24,6 @@ class Piwik_Actions_Controller extends Piwik_Controller $view = Piwik_ViewDataTable::factory(); $view->init($this->pluginName, $currentAction, $apiAction, $controllerActionSubtable); $view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageURL')); - if (Piwik_Config::getInstance()->General['overlay_launch_from_pages_report']) { - $view->openLinksInOverlay(); - } return $view; } diff --git a/plugins/CoreHome/templates/broadcast.js b/plugins/CoreHome/templates/broadcast.js index e38a399ac081330c5781a03f0456aa0ad328a4f0..dfcaad53a4029f2a9531542afbe135ce02899b57 100644 --- a/plugins/CoreHome/templates/broadcast.js +++ b/plugins/CoreHome/templates/broadcast.js @@ -47,11 +47,6 @@ var broadcast = { */ forceReload: false, - /** - * Ignore the hash location change once - */ - ignoreHashChange: false, - /** * Initializes broadcast object * @return {void} @@ -81,18 +76,6 @@ var broadcast = { */ pageload: function( hash ) { - if (broadcast.ignoreHashChange == hash) { - // ignoreHashChange is set in propagateAjax() when the parameter disableHistory - // is used. we don't trigger the callbacks for the hash change in this case but - // we need to reset the current urls to make sure that when the back button is - // used, the callbacks are triggered. - broadcast.ignoreHashChange = false; - broadcast.currentHashUrl = false; - broadcast.currentPopoverParameter = false; - return; - } - broadcast.ignoreHashChange = false; - broadcast.init(); // Unbind any previously attached resize handlers @@ -170,10 +153,9 @@ var broadcast = { * NOTE: this method will only make ajax call and replacing main content. * * @param {string} ajaxUrl querystring with parameters to be updated - * @param {boolean} disableHistory the hash change won't be available in the browser history * @return {void} */ - propagateAjax: function (ajaxUrl, disableHistory) + propagateAjax: function (ajaxUrl) { broadcast.init(); @@ -183,10 +165,7 @@ var broadcast = { // available in global scope var currentHashStr = broadcast.getHash(); - // remove overlayUrl: the parameter should never be there unless it is set in the ajaxUrl parameter - currentHashStr = broadcast.updateParamValue('overlayUrl=', currentHashStr); - - ajaxUrl = ajaxUrl.replace(/^\?|&#/,''); + ajaxUrl = ajaxUrl.replace(/^\?|&#/,''); var params_vals = ajaxUrl.split("&"); for( var i=0; i<params_vals.length; i++ ) @@ -208,21 +187,9 @@ var broadcast = { currentHashStr = broadcast.updateParamValue('idDashboard=', currentHashStr); } - if (disableHistory) - { - // make sure the change doesn't trigger the location change callbacks - broadcast.ignoreHashChange = currentHashStr; - var newLocation = window.location.href.split('#')[0] + '#' + currentHashStr; - // window.location.replace changes the current url without pushing it on the - // browser history stack. - window.location.replace(newLocation); - } - else - { - // Let history know about this new Hash and load it. - broadcast.forceReload = true; - $.history.load(currentHashStr); - } + // Let history know about this new Hash and load it. + broadcast.forceReload = true; + $.history.load(currentHashStr); }, /** diff --git a/plugins/CoreHome/templates/datatable.css b/plugins/CoreHome/templates/datatable.css index a2ba59678c1f38982305475dafe0561c6766ce7b..126451750cdbda7132a89a45514a2dec158ac194 100644 --- a/plugins/CoreHome/templates/datatable.css +++ b/plugins/CoreHome/templates/datatable.css @@ -592,16 +592,16 @@ table.dataTable .dataTableRowActions { table.dataTable .dataTableRowActions a { display: block; float: left; - padding: 6px 6px 6px 0; + padding: 6px 4px 6px 0; margin: 0; } table.dataTable .dataTableRowActions a.leftmost { - padding-left: 6px; + padding-left: 4px; } table.dataTable .dataTableRowActions a.rightmost { - padding-right: 10px; + padding-right: 8px; } table.dataTable .dataTableRowActions a img { diff --git a/plugins/CoreHome/templates/datatable.js b/plugins/CoreHome/templates/datatable.js index 1426dbea83178d04f4aba00727df18a1a84e69a4..c91cd5d52d626c5f37a4144944cddeb49d900dea 100644 --- a/plugins/CoreHome/templates/datatable.js +++ b/plugins/CoreHome/templates/datatable.js @@ -1315,7 +1315,7 @@ dataTable.prototype = } // if there are row actions, make sure the first column is not too narrow - td.css('minWidth', '130px'); + td.css('minWidth', '145px'); // show actions that are available for the row on hover var actionsDom = null; @@ -1338,21 +1338,6 @@ dataTable.prototype = actionsDom.hide(); } }); - - if (typeof self.param.open_links_in_overlay != 'undefined' && self.param.open_links_in_overlay) - { - var link = td.find('a'); - link.click(function() - { - var rowUrl = $(this).attr('href'); - var newUrl = 'module=Overlay&action=index&overlayUrl=' + encodeURIComponent(rowUrl).replace(/%/g, '$'); - - $('ul.nav').trigger('piwikSwitchPage'); - broadcast.propagateAjax(newUrl); - - return false; - }); - } }); }, @@ -1379,17 +1364,20 @@ dataTable.prototype = actionEl.addClass('rightmost'); } - actionEl.click((function(action) + actionEl.click((function(action, el) { return function(e) { $(this).blur(); container.hide(); Piwik_Tooltip.hide(); + if (typeof actionInstances[action.name].onClick == 'function') { + return actionInstances[action.name].onClick(el, tr, e); + } actionInstances[action.name].trigger(tr, e); return false; } - })(action)); + })(action, actionEl)); if (typeof action.dataTableIconHover != 'undefined') { diff --git a/plugins/CoreHome/templates/datatable_rowactions.js b/plugins/CoreHome/templates/datatable_rowactions.js index 9acb517da2ec162d4d60781ce68c22f9b8907048..cbdc9765db18880ca13b366ed3b4cd224daae3a4 100644 --- a/plugins/CoreHome/templates/datatable_rowactions.js +++ b/plugins/CoreHome/templates/datatable_rowactions.js @@ -37,6 +37,9 @@ var DataTable_RowActions_Registry = { available.push(this.registry[i]); } } + available.sort(function(a, b) { + return b.order - a.order; + }); return available; }, @@ -58,6 +61,8 @@ DataTable_RowActions_Registry.register({ dataTableIcon: 'themes/default/images/row_evolution.png', dataTableIconHover: 'themes/default/images/row_evolution_hover.png', + + order: 50, dataTableIconTooltip: [ _pk_translate('CoreHome_RowEvolutionRowActionTooltipTitle_js'), diff --git a/plugins/CoreHome/templates/header.tpl b/plugins/CoreHome/templates/header.tpl index da4c206e6bb881cc5247d8da3b155d498c9da4ab..7eaa264671c132400730325fd154394c9c5f0761 100644 --- a/plugins/CoreHome/templates/header.tpl +++ b/plugins/CoreHome/templates/header.tpl @@ -16,6 +16,7 @@ <link rel="stylesheet" type="text/css" href="themes/default/ieonly.css" /> <![endif]--> {include file="CoreHome/templates/iframe_buster_header.tpl"} +{if isset($addToHead)}{$addToHead}{/if} </head> <body> {include file="CoreHome/templates/iframe_buster_body.tpl"} diff --git a/plugins/Overlay/Controller.php b/plugins/Overlay/Controller.php index 45839e0da00a4662677484158eb91cf84cfabff4..0c10d1e230029699d9e9cc1558e0098f2561ae52 100644 --- a/plugins/Overlay/Controller.php +++ b/plugins/Overlay/Controller.php @@ -24,17 +24,17 @@ class Piwik_Overlay_Controller extends Piwik_Controller } $view = Piwik_View::factory($template); + + $this->setGeneralVariablesView($view); + $view->showTopMenu = false; + $view->showSitesSelection = false; + $view->addToHead = '<script type="text/javascript" src="plugins/Overlay/templates/index.js"></script>' + . '<link rel="stylesheet" type="text/css" href="plugins/Overlay/templates/index.css" />'; + $view->idSite = $this->idSite; $view->date = Piwik_Common::getRequestVar('date', 'today'); $view->period = Piwik_Common::getRequestVar('period', 'day'); - // the % signs in the encoded url have been replaced with $ to make sure that - // browsers can't break the exact encoding. we need to reverse this here. - // see javascript Piwik_Overlay.setCurrentUrl() - $url = Piwik_Common::getRequestVar('overlayUrl', ''); - $url = urldecode(str_replace('$', '%', $url)); - $view->targetUrl = $url; - $view->ssl = $this->usingSsl(); echo $view->render(); @@ -115,7 +115,6 @@ class Piwik_Overlay_Controller extends Piwik_Controller $view->idSite = $idSite; $view->period = $period; $view->date = $date; - $view->currentUrl = $currentUrl; echo $view->render(); } @@ -146,10 +145,6 @@ class Piwik_Overlay_Controller extends Piwik_Controller return url.replace(/http(s)?:\/\/(www\.)?/i, ""); } - function htmlEntities(str) { - return String(str).replace(/&/g, \'&\').replace(/</g, \'<\').replace(/>/g, \'>\').replace(/"/g, \'"\'); - } - if (window.location.hash) { var match = false; @@ -167,10 +162,10 @@ class Piwik_Overlay_Controller extends Piwik_Controller } if (!match) { - var error = "'.htmlentities(Piwik_Translate('Overlay_RedirectUrlError')).'"; - error = error.replace(/%s/, htmlEntities(urlToRedirect)); - error = error.replace(/%s/, "<br />"); - document.write(error); + var idSite = window.location.href.match(/idSite=([0-9]+)/i)[1]; + window.location.href = "index.php?module=Overlay&action=showErrorWrongDomain" + + "&idSite=" + idSite + + "&url=" + encodeURIComponent(urlToRedirect); } } else { @@ -180,6 +175,38 @@ class Piwik_Overlay_Controller extends Piwik_Controller '; } + /** + * This method is called when the JS from startOverlaySession() detects that the target domain + * is not configured for the current site. + */ + public function showErrorWrongDomain() + { + $idSite = Piwik_Common::getRequestVar('idSite', 0, 'int'); + Piwik::checkUserHasViewAccess($idSite); + + $url = Piwik_Common::getRequestVar('url', ''); + $url = Piwik_Common::unsanitizeInputValue($url); + + $message = Piwik_Translate('Overlay_RedirectUrlError', array($url, "\n")); + $message = nl2br(htmlentities($message)); + + $view = Piwik_View::factory('error_wrong_domain'); + $view->message = $message; + + if (Piwik::isUserHasAdminAccess($idSite)) { + // TODO use $idSite to link to the correct row. This is tricky because the #rowX ids don't match + // the site ids when sites have been deleted. + $url = 'index.php?module=SitesManager&action=index'; + $troubleshoot = htmlentities(Piwik_Translate('Overlay_RedirectUrlErrorAdmin')); + $troubleshoot = sprintf($troubleshoot, '<a href="' . $url . '" target="_top">', '</a>'); + $view->troubleshoot = $troubleshoot; + } else { + $view->troubleshoot = htmlentities(Piwik_Translate('Overlay_RedirectUrlErrorUser')); + } + + echo $view->render(); + } + /** * This method is used to pass information from the iframe back to Piwik. * Due to the same origin policy, we can't do that directly, so we inject diff --git a/plugins/Overlay/Overlay.php b/plugins/Overlay/Overlay.php index 8d2a010c6c76229304c3a08d4e11a9ff093b0339..317c3820e5077858731ce93b71b4558a729d1fa0 100644 --- a/plugins/Overlay/Overlay.php +++ b/plugins/Overlay/Overlay.php @@ -21,33 +21,19 @@ class Piwik_Overlay extends Piwik_Plugin 'version' => Piwik_Version::VERSION, ); } - - public function getListHooksRegistered() + + function getListHooksRegistered() { return array( - 'AssetManager.getCssFiles' => 'getCssFiles', - 'AssetManager.getJsFiles' => 'getJsFiles', - 'Menu.add' => 'addMenu', + 'AssetManager.getJsFiles' => 'getJsFiles' ); } - - public function getCssFiles($notification) - { - $cssFiles = &$notification->getNotificationObject(); - $cssFiles[] = "plugins/Overlay/templates/index.css"; - } - + public function getJsFiles($notification) { $jsFiles = &$notification->getNotificationObject(); - $jsFiles[] = "plugins/Overlay/templates/index.js"; - } - - public function addMenu() - { - Piwik_AddMenu('Actions_Actions', 'Overlay_Overlay', - array('module' => 'Overlay', 'action' => 'index'), - $display = true, $order = 99); + $jsFiles[] = 'plugins/Overlay/templates/rowaction.js'; + $jsFiles[] = 'plugins/Overlay/templates/helper.js'; } } diff --git a/plugins/Overlay/templates/error_wrong_domain.tpl b/plugins/Overlay/templates/error_wrong_domain.tpl new file mode 100644 index 0000000000000000000000000000000000000000..49bd01ed2082e1d897862c909545526d2b2949d6 --- /dev/null +++ b/plugins/Overlay/templates/error_wrong_domain.tpl @@ -0,0 +1,36 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title></title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="generator" content="Piwik - Open Source Web Analytics" /> + <link rel="shortcut icon" href="plugins/CoreHome/templates/images/favicon.ico" /> + + <style type="text/css"> + {literal} + body { + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + color: black; + background: white; + margin: 15px; + padding: 0; + } + + p { + margin: 0 0 10px 0; + padding: 0; + } + + a { + color: #255792; + } + {/literal} + </style> + +</head> +<body> + <p><b>{$message}</b></p> + <p>{$troubleshoot}</p> +</body> +</html> \ No newline at end of file diff --git a/plugins/Overlay/templates/helper.js b/plugins/Overlay/templates/helper.js new file mode 100644 index 0000000000000000000000000000000000000000..de98b26851946267a574ec590ed7c67d2bb64aab --- /dev/null +++ b/plugins/Overlay/templates/helper.js @@ -0,0 +1,30 @@ +/*! + * Piwik - Web Analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +var Overlay_Helper = { + + /** Encode the iframe url to put it behind the hash in sidebar mode */ + encodeFrameUrl: function(url) { + // make sure there's only one hash in the resulting url + return url.replace(/#/g, '%23') + }, + + /** Decode the url after reading it from the hash */ + decodeFrameUrl: function(url) { + return url.replace(/%23/g, '#'); + }, + + /** Get the url to launch overlay */ + getOverlayLink: function(idSite, period, date, link) { + var url = 'index.php?module=Overlay&period=' + period + '&date=' + date + '&idSite=' + idSite; + if (link) { + url += '#' + Overlay_Helper.encodeFrameUrl(link); + } + return url; + } + +}; \ No newline at end of file diff --git a/plugins/Overlay/templates/index.css b/plugins/Overlay/templates/index.css index 2135e39015228c756657bfc683bf293dd2a0044e..afc28828d0a4bd6af17d837a3cb4bd394bbc7543 100644 --- a/plugins/Overlay/templates/index.css +++ b/plugins/Overlay/templates/index.css @@ -1,60 +1,38 @@ -#Overlay_Container { - margin-top: 9px; - height: 300px; - position: relative; +body #header { + margin-left: -12px; } -#Overlay_Container.Overlay_FullScreen { - position: fixed; - width: 100%; - height: 100%; - top: 0; - left: 0; - background: white; - z-index: 100000; - margin: 0; - padding: 0; +body #logo { + margin-top: 5px; } -#Overlay_Location { - color: #7E7363; - padding-left: 220px; - padding-bottom: 7px; - font-size: 12px; - cursor: default; +body h1 { + font-size: 15px; + font-weight: normal; + margin: -3px 0 0 0; + padding: 0 0 0 5px; } -#Overlay_Container.Overlay_FullScreen #Overlay_Location { - float: left; - width: 180px; - position: relative; - margin: 15px 0 30px 20px; - font-size: 11px; - padding: 0; +#Overlay_Location { + width: 200px; + padding: 30px 0; + margin-left: 5px; + font-size: 12px; } #Overlay_Loading { background: url(../../../themes/default/images/loading-blue.gif) no-repeat center 10px; - float: left; width: 190px; - position: relative; - clear: left; - padding-top: 35px; + padding-top: 30px; + margin-top: 30px; text-align: center; display: none; } #Overlay_Sidebar { - float: left; width: 200px; - position: relative; - clear: left; -} - -#Overlay_Container.Overlay_FullScreen #Overlay_Sidebar { - width: 180px; - margin-left: 20px; + margin-left: 5px; } #Overlay_Sidebar h2 { @@ -64,55 +42,29 @@ color: #255792; } -#Overlay_Sidebar a.Overlay_FullScreen, -#Overlay_Sidebar a.Overlay_NewTab { +a#Overlay_FullScreen { display: block; color: #255792; font-size: 13px; line-height: 15px; - margin-top: 20px; + margin: 20px 0 0 5px; padding: 8px 0 3px 22px; background: url(../../../themes/default/images/fullscreen.png) no-repeat 0 8px; text-decoration: none; } -#Overlay_Sidebar a.Overlay_NewTab { - margin-top: 0; - background: url(../../../themes/default/images/newtab.png) no-repeat 0 7px; -} - -#Overlay_Sidebar a.Overlay_FullScreen:hover, -#Overlay_Sidebar a.Overlay_NewTab:hover { +a#Overlay_FullScreen:hover { color: #E87500; } -#Overlay_Sidebar span.Overlay_CloseFullScreen { - display: none; -} - -#Overlay_Container.Overlay_FullScreen #Overlay_Sidebar span.Overlay_OpenFullScreen { - display: none; -} - -#Overlay_Container.Overlay_FullScreen #Overlay_Sidebar span.Overlay_CloseFullScreen { - display: inline; -} - #Overlay_Main { margin-left: 220px; - position: relative; + position: absolute; + top: 0; } #Overlay_Iframe { - width: 100%; - height: 100%; - border: 2px solid #ddd; -} - -#Overlay_Container.Overlay_FullScreen #Overlay_Iframe { - border-top: 0; - border-right: 0; - border-bottom: 0; + border-left: 2px solid #ddd; } .Overlay_Metric { @@ -144,11 +96,10 @@ body .piwik-tooltip.Overlay_Tooltip { } #Overlay_Error_NotLoading { - float: left; width: 190px; - position: relative; - clear: left; display: none; + margin: 20px 0 0 5px; + font-size: 14px; } #Overlay_Error_NotLoading span { diff --git a/plugins/Overlay/templates/index.js b/plugins/Overlay/templates/index.js index 60e3bd8441b78d954cf7d6a2bcf7cdec3a0090b2..67948a985518ef9b16d7dbc2646acfbb961db981 100644 --- a/plugins/Overlay/templates/index.js +++ b/plugins/Overlay/templates/index.js @@ -1,135 +1,166 @@ +/*! + * Piwik - Web Analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + var Piwik_Overlay = (function() { + + var $body, $iframe, $sidebar, $main, $location, $loading, $errorNotLoading, $fullScreenLink; - var $container, $iframe, $sidebar, $main, $location, $loading, $errorNotLoading; - - var isFullScreen = false; + var errorTimeout = false; + var iframeSrcBase; var iframeDomain = ''; + var iframeCurrentPage = ''; + var updateComesFromInsideFrame = false; - var errorTimeout; - + /** Load the sidebar for a url */ function loadSidebar(currentUrl) { - $sidebar.hide(); - $location.html(' '); - $loading.show(); + showLoading(); + $location.html(' ').unbind('mouseenter').unbind('mouseleave'); + + iframeCurrentPage = currentUrl; iframeDomain = currentUrl.match(/http(s)?:\/\/(www\.)?([^\/]*)/i)[3]; - + + piwikHelper.abortQueueAjax(); piwikHelper.ajaxCall('Overlay', 'renderSidebar', { currentUrl: currentUrl }, function(response) { - var $response = $(response); + hideLoading(); + var $response = $(response); + var $responseLocation = $response.find('.Overlay_Location'); var $url = $responseLocation.find('span'); $url.html(piwikHelper.addBreakpointsToUrl($url.text())); $location.html($responseLocation.html()).show(); $responseLocation.remove(); - + $location.find('span').hover(function() { if (iframeDomain) { // use addBreakpointsToUrl because it also encoded html entities - Piwik_Tooltip.show('<b>' + Piwik_Overlay_Translations.domain + ':</b> ' + + Piwik_Tooltip.show('<b>' + Piwik_Overlay_Translations.domain + ':</b> ' + piwikHelper.addBreakpointsToUrl(iframeDomain), 'Overlay_Tooltip'); } }, function() { Piwik_Tooltip.hide(); }); - + $sidebar.empty().append($response).show(); - $loading.hide(); - - var $fullScreen = $sidebar.find('a.Overlay_FullScreen'); - $fullScreen.click(function() { - handleFullScreen(); - return false; - }); }, 'html'); } + + /** Adjust the dimensions of the iframe */ + function adjustDimensions() { + $iframe.height($(window).height()); + $iframe.width($body.width()); + } - /** Adjust the height of the iframe */ - function adjustHeight() { - var height, iframeHeight; - if (isFullScreen) { - iframeHeight = height = $(window).height(); - } else { - height = $(window).height() - $main.offset().top - 25; - iframeHeight = height - 4; + /** Display the loading message and hide other containers */ + function showLoading() { + $loading.show(); + + $sidebar.hide(); + $location.hide(); + $fullScreenLink.hide(); + $errorNotLoading.hide(); + + // Start a timeout that shows an error when nothing is loaded + if (errorTimeout) { + window.clearTimeout(errorTimeout); } - height = Math.max(300, height); - $container.height(height); - $iframe.height(iframeHeight); + errorTimeout = window.setTimeout(function() { + hideLoading(); + $errorNotLoading.show(); + }, 9000); } - /** Handle full screen */ - function handleFullScreen() { - if (!isFullScreen) { - // open full screen - isFullScreen = true; - $container.addClass('Overlay_FullScreen'); - adjustHeight(); - } else { - // close full screen - isFullScreen = false; - $container.removeClass('Overlay_FullScreen'); - adjustHeight(); + /** Hide the loading message */ + function hideLoading() { + if (errorTimeout) { + window.clearTimeout(errorTimeout); + errorTimeout = false; } + $loading.hide(); + $fullScreenLink.show(); } - return { + /** $.history callback for hash change */ + function hashChangeCallback(currentUrl) { + if (!updateComesFromInsideFrame) { + var iframeUrl = iframeSrcBase; + if (currentUrl) { + iframeUrl += '#' + Overlay_Helper.decodeFrameUrl(currentUrl); + } + $iframe.attr('src', iframeUrl); + showLoading(); + } else { + loadSidebar(currentUrl); + } + updateComesFromInsideFrame = false; + } + + return { + /** This method is called when Overlay loads (from index.tpl) */ - init: function() { - $container = $('#Overlay_Container'); - $iframe = $container.find('iframe'); + init: function(iframeSrc) { + iframeSrcBase = iframeSrc; + + $body = $('body'); + $iframe = $('#Overlay_Iframe'); $sidebar = $('#Overlay_Sidebar'); $location = $('#Overlay_Location'); $main = $('#Overlay_Main'); $loading = $('#Overlay_Loading'); $errorNotLoading = $('#Overlay_Error_NotLoading'); - - adjustHeight(); - - $loading.show(); - + $fullScreenLink = $('#Overlay_FullScreen'); + + adjustDimensions(); + + showLoading(); + window.setTimeout(function() { // sometimes the frame is too high at first - adjustHeight(); + adjustDimensions(); }, 50); - - // this callback is unbound in broadcast.pageload + $(window).resize(function() { - adjustHeight(); + adjustDimensions(); }); - errorTimeout = window.setTimeout(function() { - $loading.hide(); - $errorNotLoading.show(); - }, 8000); + $.history.init(hashChangeCallback, {unescape: true}); + + $fullScreenLink.click(function() { + var href = iframeSrcBase; + if (iframeCurrentPage) { + href += '#' + iframeCurrentPage.replace(/#/g, '%23'); + } + window.location.href = href; + return false; + }); }, /** This callback is used from within the iframe */ setCurrentUrl: function(currentUrl) { - window.clearTimeout(errorTimeout); - $loading.show(); - $errorNotLoading.hide(); - + showLoading(); + // put the current iframe url in the main url to enable refresh and deep linking. - // to prevent browsers from braking the encoding, we replace the % with a $. - var urlValue = encodeURIComponent(currentUrl).replace(/%/g, '$'); + var location = window.location.href; + var newLocation = location.split('#')[0] + '#' + Overlay_Helper.encodeFrameUrl(currentUrl); - // the overlayUrl parameter is removed when the location changes in broadcast.propagateAjax() - var urlKeyValue = 'overlayUrl=' + urlValue; - - var urlOldValue = broadcast.getValueFromHash('overlayUrl', window.location.href); - if (urlOldValue != urlValue) { - // we don't want the location in the browser history because the back and - // forward buttons should trigger a change in the iframe. - // so we use disableHistory = true - broadcast.propagateAjax(urlKeyValue, true); + // location.replace() changes the current url without pushing on the browsers history + // stack. this way, the back and forward buttons can be used on the iframe, which in + // turn notifies the parent about the location change. + if (newLocation != location) { + updateComesFromInsideFrame = true; + window.location.replace(newLocation); } - + // load the sidebar for the current url loadSidebar(currentUrl); } diff --git a/plugins/Overlay/templates/index.tpl b/plugins/Overlay/templates/index.tpl index d011875161fe06712460b7517050bfb7746b6732..bc29db000ee600c9e7d13d272122084c3deaa080 100644 --- a/plugins/Overlay/templates/index.tpl +++ b/plugins/Overlay/templates/index.tpl @@ -1,42 +1,49 @@ +{include file="CoreHome/templates/header.tpl"} +<h1>{'Overlay_Overlay'|translate|escape:'html'}</h1> -<div id="Overlay_Container"> +<div id="Overlay_Error_NotLoading"> + <p> + <span>{'Overlay_ErrorNotLoading'|translate|escape:'html'}</span> + </p> + <p> + {if $ssl} + {'Overlay_ErrorNotLoadingDetailsSSL'|translate|escape:'html'} + {else} + {'Overlay_ErrorNotLoadingDetails'|translate|escape:'html'} + {/if} + </p> + <p> + <a href="#">{'Overlay_ErrorNotLoadingLink'|translate|escape:'html'}</a> + </p> +</div> - <div id="Overlay_Location"> </div> - - <div id="Overlay_Sidebar"></div> - - <div id="Overlay_Error_NotLoading"> - <p> - <span>{'Overlay_ErrorNotLoading'|translate|escape:'html'}</span> - </p> - <p> - {if $ssl} - {'Overlay_ErrorNotLoadingDetailsSSL'|translate|escape:'html'} - {else} - {'Overlay_ErrorNotLoadingDetails'|translate|escape:'html'} - {/if} - </p> - <p> - <a href="#">{'Overlay_ErrorNotLoadingLink'|translate|escape:'html'}</a> - </p> - </div> - - <div id="Overlay_Loading">{'General_Loading_js'|translate|escape:'html'}</div> - - <div id="Overlay_Main"> - <iframe - id="Overlay_Iframe" - src="index.php?module=Overlay&action=startOverlaySession&idsite={$idSite}&period={$period}&date={$date}{if $targetUrl}#{$targetUrl}{/if}"> - </iframe> - </div> - +<div id="Overlay_Location"> </div> + +<div id="Overlay_Loading">{'General_Loading_js'|translate|escape:'html'}</div> + +<div id="Overlay_Sidebar"></div> + +<a id="Overlay_FullScreen" href="#"> + {'Overlay_OpenFullScreen'|translate|escape:'html'} +</a> + + +<div id="Overlay_Main"> + <iframe id="Overlay_Iframe" src=""></iframe> </div> <script type="text/javascript"> - Piwik_Overlay.init(); + var iframeSrc = 'index.php?module=Overlay&action=startOverlaySession&idsite={$idSite}&period={$period}&date={$date}'; + Piwik_Overlay.init(iframeSrc); Piwik_Overlay_Translations = {literal}{{/literal} domain: "{'Overlay_Domain'|translate|escape:'html'}" {literal}}{/literal}; -</script> \ No newline at end of file +</script> + + +<!-- close tag opened in header.tpl --> +</div> +</body> +</html> \ No newline at end of file diff --git a/plugins/Overlay/templates/index_noframe.tpl b/plugins/Overlay/templates/index_noframe.tpl index 867f2a7dc02358d1038bf8e6380e78f1f8a0e734..ec2008c5d317bd27096514fded4f9301440a3912 100644 --- a/plugins/Overlay/templates/index_noframe.tpl +++ b/plugins/Overlay/templates/index_noframe.tpl @@ -1,13 +1,26 @@ +{include file="CoreHome/templates/header.tpl"} +<h1>{'Overlay_Overlay'|translate|escape:'html'}</h1> <div id="Overlay_NoFrame"> - - {capture name="link"}index.php?module=Overlay&action=startOverlaySession&idsite={$idSite}&period={$period}&date={$date}{if $targetUrl}#{$targetUrl}{/if}{/capture} - {capture name="linkTag"}<a id="Overlay_Link" href="{$smarty.capture.link}" target="_blank">{/capture} - - {'Overlay_NoFrameModeText'|translate|escape:'html'|sprintf:'<br />':$smarty.capture.linkTag:'</a>'} <script type="text/javascript"> - window.open('{$smarty.capture.link}', '_newtab'); + var newLocation = 'index.php?module=Overlay&action=startOverlaySession&idsite={$idSite}&period={$period}&date={$date}'; + + {literal} + + var loactionParts = window.location.href.split('#'); + if (loactionParts.length > 1) { + newLocation += '#' + loactionParts[1]; + } + + window.location.href = newLocation; + + {/literal} </script> -</div> \ No newline at end of file +</div> + +<!-- close tag opened in header.tpl --> +</div> +</body> +</html> \ No newline at end of file diff --git a/plugins/Overlay/templates/overlay_icon.png b/plugins/Overlay/templates/overlay_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..a960d1bbc93db114663dfad5cb0bad40d1f0b1d7 Binary files /dev/null and b/plugins/Overlay/templates/overlay_icon.png differ diff --git a/plugins/Overlay/templates/overlay_icon_hover.png b/plugins/Overlay/templates/overlay_icon_hover.png new file mode 100755 index 0000000000000000000000000000000000000000..10296ef3925bb03495ff3afa52effc631602685a Binary files /dev/null and b/plugins/Overlay/templates/overlay_icon_hover.png differ diff --git a/plugins/Overlay/templates/rowaction.js b/plugins/Overlay/templates/rowaction.js new file mode 100644 index 0000000000000000000000000000000000000000..24ccb803503ddadc07d1ef71cdf625fd8c71b828 --- /dev/null +++ b/plugins/Overlay/templates/rowaction.js @@ -0,0 +1,62 @@ +/*! + * Piwik - Web Analytics + * + * @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 DataTable_RowActions_Overlay(dataTable) { + this.dataTable = dataTable; +} + +DataTable_RowActions_Overlay.prototype = new DataTable_RowAction; + +DataTable_RowActions_Overlay.prototype.onClick = function(actionA, tr, e) { + if (!actionA.data('overlay-manipulated')) { + actionA.data('overlay-manipulated', 1); + + var link = tr.find('> td:first > a').attr('href'); + link = $('<textarea>').html(link).val(); // remove html entities + + actionA.attr({ + target: '_blank', + href: Overlay_Helper.getOverlayLink(this.dataTable.param.idSite, this.dataTable.param.period, + this.dataTable.param.date, link) + }); + } + + return true; +}; + +DataTable_RowActions_Registry.register({ + + name: 'Overlay', + + dataTableIcon: 'plugins/Overlay/templates/overlay_icon.png', + dataTableIconHover: 'plugins/Overlay/templates/overlay_icon_hover.png', + + order: 30, + + dataTableIconTooltip: [ + _pk_translate('CoreHome_OverlayRowActionTooltipTitle_js'), + _pk_translate('CoreHome_OverlayRowActionTooltip_js') + ], + + createInstance: function(dataTable) { + return new DataTable_RowActions_Overlay(dataTable); + }, + + isAvailableOnReport: function(dataTableParams) { + return DataTable_RowActions_Transitions.isPageUrlReport(dataTableParams.module, dataTableParams.action); + }, + + isAvailableOnRow: function(dataTableParams, tr) { + var transitions = DataTable_RowActions_Registry.getActionByName('Transitions'); + return transitions.isAvailableOnRow(dataTableParams, tr); + } + +}); diff --git a/plugins/Overlay/templates/sidebar.tpl b/plugins/Overlay/templates/sidebar.tpl index 612bb497d43c21be665bc22d618840332e349ab6..9f3f4ca7e0d2eb716bfafa63f9524703edc627c7 100644 --- a/plugins/Overlay/templates/sidebar.tpl +++ b/plugins/Overlay/templates/sidebar.tpl @@ -2,7 +2,7 @@ <!-- This div is removed by JS and the content is put in the location div --> <div class="Overlay_Location"> - <b>{'Overlay_Page'|translate|escape:'html'}:</b> + <b>{'Overlay_Location'|translate|escape:'html'}:</b> <span>{$location|escape:'html'}</span> </div> @@ -17,12 +17,4 @@ <div class="Overlay_NoData">{'Overlay_NoData'|translate|escape:'html'}</div> {/if} - <a class="Overlay_FullScreen" href="#"> - <span class="Overlay_OpenFullScreen">{'Overlay_OpenFullScreen'|translate|escape:'html'}</span> - <span class="Overlay_CloseFullScreen">{'Overlay_CloseFullScreen'|translate|escape:'html'}</span> - </a> - <a class="Overlay_NewTab" href="index.php?module=Overlay&action=startOverlaySession&idsite={$idSite}&period={$period}&date={$date}#{$currentUrl|escape:'html'}" target="_blank"> - {'Overlay_OpenNewTab'|translate|escape:'html'} - </a> - </div> \ No newline at end of file diff --git a/plugins/Transitions/templates/transitions.js b/plugins/Transitions/templates/transitions.js index bf2f3bed9048953bb6d0493666cee7fe6431eb1e..6ceb292f69d48dd94cac4dea9ec12344a22c2559 100644 --- a/plugins/Transitions/templates/transitions.js +++ b/plugins/Transitions/templates/transitions.js @@ -75,6 +75,8 @@ DataTable_RowActions_Registry.register({ dataTableIcon: 'plugins/Transitions/templates/transitions_icon.png', dataTableIconHover: 'plugins/Transitions/templates/transitions_icon_hover.png', + + order: 20, dataTableIconTooltip: [ _pk_translate('CoreHome_TransitionsRowActionTooltipTitle_js'),