From 369e39382b7f830ee6ccdfc889f4a7c854e69e03 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 16 Nov 2017 18:34:32 +0100 Subject: [PATCH] Remove all kinds of flickering refs #72 --- application/controllers/GraphController.php | 2 +- library/Graphite/Graphing/Chart.php | 3 ++ library/Graphite/Web/Widget/Graphs.php | 9 ++-- public/js/module.js | 57 +++++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/application/controllers/GraphController.php b/application/controllers/GraphController.php index 3585455..5dc16e9 100644 --- a/application/controllers/GraphController.php +++ b/application/controllers/GraphController.php @@ -19,7 +19,7 @@ class GraphController extends MonitoringAwareController * * @var string[] */ - protected $graphParamsNames = ['start', 'end', 'width', 'height', 'legend', 'template']; + protected $graphParamsNames = ['start', 'end', 'width', 'height', 'legend', 'template', 'cachebuster']; /** * The URL parameters for metrics filtering diff --git a/library/Graphite/Graphing/Chart.php b/library/Graphite/Graphing/Chart.php index a3897f6..b630eb9 100644 --- a/library/Graphite/Graphing/Chart.php +++ b/library/Graphite/Graphing/Chart.php @@ -158,6 +158,9 @@ class Chart $response ->setHeader('Content-Type', 'image/png', true) ->setHeader('Content-Disposition', 'inline; filename="graph.png"', true) + ->setHeader('Cache-Control', null, true) + ->setHeader('Expires', null, true) + ->setHeader('Pragma', null, true) ->setBody($image) ->sendResponse(); diff --git a/library/Graphite/Web/Widget/Graphs.php b/library/Graphite/Web/Widget/Graphs.php index 5fd9236..122e6c2 100644 --- a/library/Graphite/Web/Widget/Graphs.php +++ b/library/Graphite/Web/Widget/Graphs.php @@ -210,14 +210,17 @@ abstract class Graphs extends AbstractWidget ->setParam('start', $this->start) ->setParam('end', $this->end) ->setParam('width', $this->width) - ->setParam('height', $this->height); + ->setParam('height', $this->height) + ->setParam('cachebuster', time() * 65536 + mt_rand(0, 65535)); if (! $this->compact) { $imageUrl->setParam('legend', 1); } - $result[] = 'without('cachebuster')); + $result[] = '" src="'; $result[] = (string) $imageUrl; - $result[] = '" class="graphiteImg" alt="" width="'; + $result[] = '" class="detach graphiteImg" alt="" width="'; $result[] = $this->width; $result[] = '" height="'; $result[] = $this->height; diff --git a/public/js/module.js b/public/js/module.js index 08087fd..d116a77 100644 --- a/public/js/module.js +++ b/public/js/module.js @@ -103,6 +103,63 @@ }(Icinga)); +(function(Icinga, $) { + 'use strict'; + + var extractUrlParams = /^([^?]*)\?(.+)$/; + var parseUrlParam = /^([^=]+)=(.*)$/; + + function GraphiteCachebusterUpdater(icinga) { + Icinga.EventListener.call(this, icinga); + + this.on('rendered', this.onRendered, this); + } + + GraphiteCachebusterUpdater.prototype = new Icinga.EventListener(); + + GraphiteCachebusterUpdater.prototype.onRendered = function(event) { + $(event.target).find('img.graphiteImg').each(function() { + var e = $(this); + var src = e.attr('src'); + + if (typeof(src) !== 'undefined') { + var matchParams = extractUrlParams.exec(src); + + if (matchParams !== null) { + var urlParams = Object.create(null); + + matchParams[2].split('&').forEach(function(urlParam) { + var matchParam = parseUrlParam.exec(urlParam); + if (matchParam !== null) { + urlParams[matchParam[1]] = matchParam[2]; + } + }); + + if (typeof(urlParams.cachebuster) !== 'undefined') { + var cachebuster = parseInt(urlParams.cachebuster); + + if (cachebuster === cachebuster) { + urlParams.cachebuster = (cachebuster + 1).toString(); + + var renderedUrlParams = []; + + for (var urlParam in urlParams) { + renderedUrlParams.push(urlParam + '=' + urlParams[urlParam]); + } + + e.attr('src', matchParams[1] + '?' + renderedUrlParams.join('&')); + } + } + } + } + }); + }; + + Icinga.Behaviors = Icinga.Behaviors || {}; + + Icinga.Behaviors.GraphiteCachebusterUpdater = GraphiteCachebusterUpdater; +}(Icinga, jQuery)); + (function(Icinga, $) { 'use strict';