diff options
author | BeezyT <timo@ezdesign.de> | 2012-11-15 14:24:31 +0400 |
---|---|---|
committer | BeezyT <timo@ezdesign.de> | 2012-11-15 14:24:31 +0400 |
commit | 979028ea9b24bd389606ab439c850d1d0e00395d (patch) | |
tree | 8f4be443fda7c3a486dd72b70ecb85b38e0a6c65 | |
parent | 02932327cea7fd8746f658b6a995f10b9dba0be8 (diff) |
refs #2465
* remember the location of the iframe in the l parameter using the core broadcast methods => popoverParam works as well => transitions and row evolution can make use of the back button
* row evolution and transitions get a static launch method that is used in overlay to trigger the popovers without any knowledge of their implementation
* broadcast.propagateAjax() gets the disableHistory parameter back but the handling is much easier this time
* remove full screen link for now because we might want to do that differently - i'll add some details to the ticket later
* two fixes for sanitized urls
git-svn-id: http://dev.piwik.org/svn/trunk@7477 59fd770c-687e-43c8-a1e3-f5a4ff64c105
-rw-r--r-- | plugins/CoreHome/templates/broadcast.js | 20 | ||||
-rw-r--r-- | plugins/CoreHome/templates/datatable_rowactions.js | 6 | ||||
-rw-r--r-- | plugins/Overlay/API.php | 2 | ||||
-rw-r--r-- | plugins/Overlay/templates/helper.js | 9 | ||||
-rw-r--r-- | plugins/Overlay/templates/index.js | 65 | ||||
-rw-r--r-- | plugins/Overlay/templates/index.tpl | 5 | ||||
-rw-r--r-- | plugins/Transitions/API.php | 12 | ||||
-rw-r--r-- | plugins/Transitions/templates/transitions.js | 5 |
8 files changed, 86 insertions, 38 deletions
diff --git a/plugins/CoreHome/templates/broadcast.js b/plugins/CoreHome/templates/broadcast.js index dfcaad53a4..f3efff7bf1 100644 --- a/plugins/CoreHome/templates/broadcast.js +++ b/plugins/CoreHome/templates/broadcast.js @@ -153,9 +153,10 @@ 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) + propagateAjax: function (ajaxUrl, disableHistory) { broadcast.init(); @@ -187,9 +188,18 @@ var broadcast = { currentHashStr = broadcast.updateParamValue('idDashboard=', currentHashStr); } - // Let history know about this new Hash and load it. - broadcast.forceReload = true; - $.history.load(currentHashStr); + if (disableHistory) + { + var newLocation = window.location.href.split('#')[0] + '#' + currentHashStr; + // window.location.replace changes the current url without pushing it on the browser's history stack + window.location.replace(newLocation); + } + else + { + // Let history know about this new Hash and load it. + broadcast.forceReload = true; + $.history.load(currentHashStr); + } }, /** @@ -334,6 +344,8 @@ var broadcast = { /** * Loads the given url with ajax and replaces the content + * + * Note: the method is replaced in Overlay/templates/index.js - keep this in mind when making changes. * * @param {string} urlAjax url to load * @return {Boolean} diff --git a/plugins/CoreHome/templates/datatable_rowactions.js b/plugins/CoreHome/templates/datatable_rowactions.js index cbdc9765db..c0105b1966 100644 --- a/plugins/CoreHome/templates/datatable_rowactions.js +++ b/plugins/CoreHome/templates/datatable_rowactions.js @@ -256,6 +256,12 @@ function DataTable_RowActions_RowEvolution(dataTable) { this.multiEvolutionRows = []; } +/** Static helper method to launch row evolution from anywhere */ +DataTable_RowActions_RowEvolution.launch = function(apiMethod, label) { + var param = 'RowEvolution:' + apiMethod + ':0:' + label; + broadcast.propagateNewPopoverParameter('RowAction', param); +}; + DataTable_RowActions_RowEvolution.prototype = new DataTable_RowAction; DataTable_RowActions_RowEvolution.prototype.performAction = function(label, tr, e) { diff --git a/plugins/Overlay/API.php b/plugins/Overlay/API.php index 4108a0addf..17197edbe9 100644 --- a/plugins/Overlay/API.php +++ b/plugins/Overlay/API.php @@ -77,7 +77,7 @@ class Piwik_Overlay_API $this->authenticate($idSite); $url = Piwik_Tracker_Action::excludeQueryParametersFromUrl($url, $idSite); - $url = Piwik_Common::unsanitizeInputValue($url); + // we don't unsanitize $url here. it will be done in the Transitions plugin. $resultDataTable = new Piwik_DataTable; diff --git a/plugins/Overlay/templates/helper.js b/plugins/Overlay/templates/helper.js index de98b26851..ee62cd60aa 100644 --- a/plugins/Overlay/templates/helper.js +++ b/plugins/Overlay/templates/helper.js @@ -9,20 +9,21 @@ 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') + // url encode + replace % with $ to make sure that browsers don't break the encoding + return encodeURIComponent(url).replace(/%/g, '$') }, /** Decode the url after reading it from the hash */ decodeFrameUrl: function(url) { - return url.replace(/%23/g, '#'); + // reverse encodeFrameUrl() + return decodeURIComponent(url.replace(/\$/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); + url += '#l=' + Overlay_Helper.encodeFrameUrl(link); } return url; } diff --git a/plugins/Overlay/templates/index.js b/plugins/Overlay/templates/index.js index 42116e62e6..807eb6b565 100644 --- a/plugins/Overlay/templates/index.js +++ b/plugins/Overlay/templates/index.js @@ -106,19 +106,28 @@ var Piwik_Overlay = (function() { } /** $.history callback for hash change */ - function hashChangeCallback(currentUrl) { + function hashChangeCallback(urlHash) { + var location = broadcast.getParamValue('l', urlHash); + location = Overlay_Helper.decodeFrameUrl(location); + if (!updateComesFromInsideFrame) { var iframeUrl = iframeSrcBase; - if (currentUrl) { - iframeUrl += '#' + Overlay_Helper.decodeFrameUrl(currentUrl); + if (location) { + iframeUrl += '#' + location; } $iframe.attr('src', iframeUrl); showLoading(); } else { - loadSidebar(currentUrl); + loadSidebar(location); } updateComesFromInsideFrame = false; + + // handle window resize + // this needs to be bound here because broadcast unbinds it after every hash change + $(window).resize(function() { + adjustDimensions(); + }); } return { @@ -146,18 +155,20 @@ var Piwik_Overlay = (function() { showLoading(); + // apply initial dimensions window.setTimeout(function() { - // sometimes the frame is too high at first adjustDimensions(); }, 50); - // handle window resize - $(window).resize(function() { - adjustDimensions(); - }); - // handle hash change - $.history.init(hashChangeCallback, {unescape: true}); + broadcast.loadAjaxContent = hashChangeCallback; + broadcast.init(); + + if (window.location.href.split('#').length == 1) { + // if there's no hash, broadcast won't trigger the callback - we have to do it here + hashChangeCallback(''); + } + // handle date selection var $select = $('select#Overlay_DateRangeSelect').change(function() { @@ -183,15 +194,13 @@ var Piwik_Overlay = (function() { // handle transitions link $transitionsLink.click(function() { - var transitions = new Piwik_Transitions('url', iframeCurrentPageNormalized, null); - transitions.showPopover(); + DataTable_RowActions_Transitions.launchForUrl(iframeCurrentPageNormalized); return false; }); // handle row evolution link $rowEvolutionLink.click(function() { - var rowEvolution = new DataTable_RowActions_RowEvolution(null); - rowEvolution.showRowEvolution('Actions.getPageUrls', iframeCurrentActionLabel, '0'); + DataTable_RowActions_RowEvolution.launch('Actions.getPageUrls', iframeCurrentActionLabel); return false; }); @@ -210,20 +219,24 @@ var Piwik_Overlay = (function() { setCurrentUrl: function(currentUrl) { showLoading(); - // put the current iframe url in the main url to enable refresh and deep linking. - var location = window.location.href; - var newLocation = location.split('#')[0] + '#' + Overlay_Helper.encodeFrameUrl(currentUrl); + var locationParts = location.href.split('#'); + var currentLocation = ''; + if (locationParts.length > 1) { + currentLocation = broadcast.getParamValue('l', locationParts[1]); + } + + var newLocation = Overlay_Helper.encodeFrameUrl(currentUrl); - // 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) { + if (newLocation != currentLocation) { updateComesFromInsideFrame = true; - window.location.replace(newLocation); + // put the current iframe url in the main url to enable refresh and deep linking. + // use disableHistory=true to make sure that the back and forward buttons can be + // used on the iframe (which in turn notifies the parent about the location change) + broadcast.propagateAjax('l=' + newLocation, true); + } else { + // happens when the url is changed by hand or when the l parameter is there on page load + loadSidebar(currentUrl); } - - // load the sidebar for the current url - loadSidebar(currentUrl); } }; diff --git a/plugins/Overlay/templates/index.tpl b/plugins/Overlay/templates/index.tpl index cd03e8d018..2499b1662e 100644 --- a/plugins/Overlay/templates/index.tpl +++ b/plugins/Overlay/templates/index.tpl @@ -36,9 +36,10 @@ <a id="Overlay_RowEvolution">{'CoreHome_RowEvolutionRowActionTooltipTitle_js'|translate|escape:'html'}</a> <a id="Overlay_Transitions">{'CoreHome_TransitionsRowActionTooltipTitle_js'|translate|escape:'html'}</a> -<a id="Overlay_FullScreen" href="#"> +<!-- TODO: rethink the way the sidebar works --> +<!-- <a id="Overlay_FullScreen" href="#"> {'Overlay_OpenFullScreen'|translate|escape:'html'} -</a> +</a> --> <div id="Overlay_Main"> diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php index 4d1a0aea8b..5b25514edf 100644 --- a/plugins/Transitions/API.php +++ b/plugins/Transitions/API.php @@ -143,8 +143,18 @@ class Piwik_Transitions_API switch ($actionType) { case 'url': + $originalActionName = $actionName; $actionName = Piwik_Common::unsanitizeInputValue($actionName); - return $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url'); + $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url'); + + if ($id < 0) + { + // an example where this is needed is urls containing < or > + $actionName = $originalActionName; + $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url'); + } + + return $id; case 'title': $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_name'); diff --git a/plugins/Transitions/templates/transitions.js b/plugins/Transitions/templates/transitions.js index 2dec90d31e..dfc4d32114 100644 --- a/plugins/Transitions/templates/transitions.js +++ b/plugins/Transitions/templates/transitions.js @@ -17,6 +17,11 @@ function DataTable_RowActions_Transitions(dataTable) { DataTable_RowActions_Transitions.prototype = new DataTable_RowAction; +/** Static helper method to launch transitions from anywhere */ +DataTable_RowActions_Transitions.launchForUrl = function(url) { + broadcast.propagateNewPopoverParameter('RowAction', 'Transitions:url:' + url); +}; + DataTable_RowActions_Transitions.isPageUrlReport = function(module, action) { return module == 'Actions' && (action == 'getPageUrls' || action == 'getEntryPageUrls' || action == 'getExitPageUrls' || action == 'getPageUrlsFollowingSiteSearch'); |