瀏覽代碼

CSS is now all namespaced.

Added classes throughout and changed all CSS selectors to be namespaced under the body's classname, and then additionally use all class names where appropriate.  This should mean less interference with embedding the script in other pages/sites, and hopefully resolve #47.
Andrew Collington 5 年之前
父節點
當前提交
9166a8761e
共有 2 個文件被更改,包括 133 次插入142 次删除
  1. 104 111
      index.php
  2. 29 31
      src/status.jsx

+ 104 - 111
index.php

@@ -8,7 +8,7 @@ namespace OpcacheGui;
  * A simple but effective single-file GUI for the OPcache PHP extension.
  * A simple but effective single-file GUI for the OPcache PHP extension.
  *
  *
  * @author Andrew Collington, andy@amnuts.com
  * @author Andrew Collington, andy@amnuts.com
- * @version 2.5.2
+ * @version 2.6.0
  * @link https://github.com/amnuts/opcache-gui
  * @link https://github.com/amnuts/opcache-gui
  * @license MIT, http://acollington.mit-license.org/
  * @license MIT, http://acollington.mit-license.org/
  */
  */
@@ -23,7 +23,7 @@ $options = [
     'allow_reset'      => true,          // give option to reset the whole cache
     'allow_reset'      => true,          // give option to reset the whole cache
     'allow_realtime'   => true,          // give option to enable/disable real-time updates
     'allow_realtime'   => true,          // give option to enable/disable real-time updates
     'refresh_time'     => 5,             // how often the data will refresh, in seconds
     'refresh_time'     => 5,             // how often the data will refresh, in seconds
-    'size_precision'   => 2,             // Digits after decimal point
+    'size_precision'   => 0,             // Digits after decimal point
     'size_space'       => false,         // have '1MB' or '1 MB' when showing sizes
     'size_space'       => false,         // have '1MB' or '1 MB' when showing sizes
     'charts'           => true,          // show gauge chart or just big numbers
     'charts'           => true,          // show gauge chart or just big numbers
     'debounce_rate'    => 250,           // milliseconds after key press to send keyup event when filtering
     'debounce_rate'    => 250,           // milliseconds after key press to send keyup event when filtering
@@ -54,7 +54,7 @@ header('Pragma: no-cache');
 
 
 class OpCacheService
 class OpCacheService
 {
 {
-    const VERSION = '2.5.2';
+    const VERSION = '2.6.0';
 
 
     protected $data;
     protected $data;
     protected $options;
     protected $options;
@@ -311,68 +311,66 @@ $opcache = OpCacheService::init($options);
     <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
     <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
     <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
     <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
     <style type="text/css">
     <style type="text/css">
-        body { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
-        nav { padding-top: 20px; }
-        nav > ul { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
-        nav > ul > li { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
-        nav > ul > li > a { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
-        nav > ul > li > a:hover { background-color: #f4f4f4; text-decoration: underline; }
-        nav > ul > li > a.active:hover { background-color: initial; }
-        nav > ul > li > a[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
-        table { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
-        table caption { text-align: left; font-size: 1.5em; }
-        table tr { background-color: #99D0DF; border-color: #fff; }
-        table th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
-        table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
-        table tr:nth-child(odd) { background-color: #EFFEFF; }
-        table tr:nth-child(even) { background-color: #E0ECEF; }
-        #filelist table tr { background-color: #EFFEFF; }
-        #filelist table tr.alternate { background-color: #E0ECEF; }
-        td.pathname { width: 70%; }
-        footer { border-top: 1px solid #ccc; padding: 1em 2em; }
-        footer a { padding: 2em; text-decoration: none; opacity: 0.7; }
-        footer a:hover { opacity: 1; }
-        canvas { display: block; max-width: 100%; height: auto; margin: 0 auto; }
-        #tabs { padding: 2em; }
-        #tabs > div { display: none; }
-        #tabs > div#overview { display:block; }
-        #resetCache, #toggleRealtime, footer > a { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
-        footer > a { background-position: 0 50%; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
-        #resetCache { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
-        #toggleRealtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
-        #counts { width: 270px; float: right; }
-        #counts > div > div { background-color: #ededed; margin-bottom: 10px; }
-        #counts > div > div > h3 { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
-        #counts > div > div > p { margin: 0; text-align: center; }
-        #counts > div > div > p span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
-        #counts > div > div > p span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
-        #info { margin-right: 280px; }
-        #frmFilter { width: 520px; }
-        #fileCacheOnly { margin-top: 0; }
-        .moreinfo > div { padding: 10px; }
-        .moreinfo > div > p { margin: 0; line-height: 1.75em; }
-        .metainfo { font-size: 80%; }
-        .hide { display: none; }
-        #toggleRealtime.pulse::before {
+        .opcache-gui { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
+        .opcache-gui .hide { display: none; }
+        .opcache-gui .main-nav { padding-top: 20px; }
+        .opcache-gui .nav-tab-list { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
+        .opcache-gui .nav-tab { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
+        .opcache-gui .nav-tab-link { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
+        .opcache-gui .nav-tab-link:hover { background-color: #f4f4f4; text-decoration: underline; }
+        .opcache-gui .nav-tab-link.active:hover { background-color: initial; }
+        .opcache-gui .nav-tab-link[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
+        .opcache-gui .nav-tab-link-reset { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
+        .opcache-gui .nav-tab-link-realtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
+        .opcache-gui .nav-tab-link-realtime.pulse::before {
             content: ""; position: absolute;
             content: ""; position: absolute;
             top: 13px; left: 3px; width: 18px; height: 18px;
             top: 13px; left: 3px; width: 18px; height: 18px;
             z-index: 10; opacity: 0; background-color: transparent;
             z-index: 10; opacity: 0; background-color: transparent;
             border: 2px solid rgb(255, 116, 0); border-radius: 100%;
             border: 2px solid rgb(255, 116, 0); border-radius: 100%;
-            -webkit-animation: pulse 1s linear 2;
-            -moz-animation: pulse 1s linear 2;
             animation: pulse 1s linear 2;
             animation: pulse 1s linear 2;
         }
         }
+        .opcache-gui .tab-content-container { padding: 2em; }
+        .opcache-gui .tab-content { display: none; }
+        .opcache-gui .tab-content-overview { display:block; }
+        .opcache-gui .tab-content-overview-counts { width: 270px; float: right; }
+        .opcache-gui .tab-content-overview-info { margin-right: 280px; }
+        .opcache-gui .graph-widget { display: block; max-width: 100%; height: auto; margin: 0 auto; }
+        .opcache-gui .widget-panel { background-color: #ededed; margin-bottom: 10px; }
+        .opcache-gui .widget-header { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
+        .opcache-gui .widget-value { margin: 0; text-align: center; }
+        .opcache-gui .widget-value span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
+        .opcache-gui .widget-value span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
+        .opcache-gui .widget-info { margin: 0; padding: 10px; }
+        .opcache-gui .widget-info * { margin: 0; line-height: 1.75em; text-align: left; }
+        .opcache-gui .tables { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
+        .opcache-gui .tables tr { background-color: #99D0DF; border-color: #fff; }
+        .opcache-gui .tables th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
+        .opcache-gui .tables td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
+        .opcache-gui .tables tr:nth-child(odd) { background-color: #EFFEFF; }
+        .opcache-gui .tables tr:nth-child(even) { background-color: #E0ECEF; }
+        .opcache-gui .tables.file-list-table tr { background-color: #EFFEFF; }
+        .opcache-gui .tables.file-list-table tr.alternate { background-color: #E0ECEF; }
+        .opcache-gui .file-filter { width: 520px; }
+        .opcache-gui .file-metainfo { font-size: 80%; }
+        .opcache-gui .file-pathname { width: 70%; display: block; }
+        .opcache-gui .nav-tab-link-reset,
+        .opcache-gui .nav-tab-link-realtime,
+        .opcache-gui .github-link { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
+        .opcache-gui .main-footer { border-top: 1px solid #ccc; padding: 1em 2em; }
+        .opcache-gui .github-link { background-position: 0 50%; padding: 2em; text-decoration: none; opacity: 0.7; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
+        .opcache-gui .github-link:hover { opacity: 1; }
+        .opcache-gui .file-cache-only { margin-top: 0; }
         @media screen and (max-width: 750px) {
         @media screen and (max-width: 750px) {
-            #info { margin-right:auto; clear:both; }
-            nav > ul { border-bottom: 0; }
-            nav > ul > li { display: block; margin: 0; }
-            nav > ul > li > a { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
-            nav > ul > li > a[data-for].active { border-bottom-color: #ccc; }
-            #counts { position:relative; display:block; width:100%; }
-            #toggleRealtime.pulse::before { top: 8px; }
+            .opcache-gui .nav-tab-list { border-bottom: 0; }
+            .opcache-gui .nav-tab { display: block; margin: 0; }
+            .opcache-gui .nav-tab-link { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
+            .opcache-gui .nav-tab-link[data-for].active { border-bottom-color: #ccc; }
+            .opcache-gui .tab-content-overview-info { margin-right:auto; clear:both; }
+            .opcache-gui .tab-content-overview-counts { position:relative; display:block; width:100%; }
+            .opcache-gui .nav-tab-link-realtime.pulse::before { top: 8px; }
         }
         }
         @media screen and (max-width: 550px) {
         @media screen and (max-width: 550px) {
-            #frmFilter { width: 100%; }
+            .opcache-gui .file-filter { width: 100%; }
         }
         }
         @keyframes pulse {
         @keyframes pulse {
             0% {transform: scale(1); opacity: 0;}
             0% {transform: scale(1); opacity: 0;}
@@ -392,34 +390,34 @@ $opcache = OpCacheService::init($options);
     </style>
     </style>
 </head>
 </head>
 
 
-<body>
+<body class="opcache-gui">
 
 
 <header>
 <header>
-    <nav>
-        <ul>
-            <li><a data-for="overview" href="#overview" class="active">Overview</a></li>
+    <nav class="main-nav">
+        <ul class="nav-tab-list">
+            <li class="nav-tab"><a data-for="overview" href="#overview" class="active nav-tab-link">Overview</a></li>
             <?php if ($opcache->getOption('allow_filelist')): ?>
             <?php if ($opcache->getOption('allow_filelist')): ?>
-            <li><a data-for="files" href="#files">File usage</a></li>
+            <li class="nav-tab"><a data-for="files" href="#files" class="nav-tab-link">File usage</a></li>
             <?php endif; ?>
             <?php endif; ?>
             <?php if ($opcache->getOption('allow_reset')): ?>
             <?php if ($opcache->getOption('allow_reset')): ?>
-            <li><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');">Reset cache</a></li>
+            <li class="nav-tab"><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');" class="nav-tab-link nav-tab-link-reset">Reset cache</a></li>
             <?php endif; ?>
             <?php endif; ?>
             <?php if ($opcache->getOption('allow_realtime')): ?>
             <?php if ($opcache->getOption('allow_realtime')): ?>
-            <li><a href="#" id="toggleRealtime">Enable real-time update</a></li>
+            <li class="nav-tab"><a href="#" id="toggleRealtime" class="nav-tab-link nav-tab-link-realtime">Enable real-time update</a></li>
             <?php endif; ?>
             <?php endif; ?>
         </ul>
         </ul>
     </nav>
     </nav>
 </header>
 </header>
 
 
-<div id="tabs">
-    <div id="overview">
-        <div class="container">
-            <div id="counts"></div>
-            <div id="info">
+<div id="tabs" class="tab-content-container">
+    <div id="overview" class="tab-content tab-content-overview">
+        <div>
+            <div id="counts" class="tab-content-overview-counts"></div>
+            <div id="info" class="tab-content-overview-info">
                 <div id="generalInfo"></div>
                 <div id="generalInfo"></div>
                 <div id="directives"></div>
                 <div id="directives"></div>
                 <div id="functions">
                 <div id="functions">
-                    <table>
+                    <table class="tables">
                         <thead>
                         <thead>
                             <tr><th>Available functions</th></tr>
                             <tr><th>Available functions</th></tr>
                         </thead>
                         </thead>
@@ -434,19 +432,19 @@ $opcache = OpCacheService::init($options);
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
-    <div id="files">
+    <div id="files" class="tab-content tab-content-files">
         <?php if ($opcache->getOption('allow_filelist')): ?>
         <?php if ($opcache->getOption('allow_filelist')): ?>
         <form action="#">
         <form action="#">
             <label for="frmFilter">Start typing to filter on script path</label><br>
             <label for="frmFilter">Start typing to filter on script path</label><br>
-            <input type="text" name="filter" id="frmFilter">
+            <input type="text" name="filter" id="frmFilter" class="file-filter">
         </form>
         </form>
         <?php endif; ?>
         <?php endif; ?>
-        <div class="container" id="filelist"></div>
+        <div id="filelist"></div>
     </div>
     </div>
 </div>
 </div>
 
 
-<footer>
-    <a href="https://github.com/amnuts/opcache-gui" target="_blank" title="opcache-gui (currently version <?php echo OpCacheService::VERSION; ?>) on GitHub">https://github.com/amnuts/opcache-gui - version <?php echo OpCacheService::VERSION; ?></a>
+<footer class="main-footer">
+    <a class="github-link" href="https://github.com/amnuts/opcache-gui" target="_blank" title="opcache-gui (currently version <?php echo OpCacheService::VERSION; ?>) on GitHub">https://github.com/amnuts/opcache-gui - version <?php echo OpCacheService::VERSION; ?></a>
 </footer>
 </footer>
 
 
 <script type="text/javascript">
 <script type="text/javascript">
@@ -634,7 +632,7 @@ $opcache = OpCacheService::init($options);
         },
         },
         render: function () {
         render: function () {
             if (this.props.chart == true) {
             if (this.props.chart == true) {
-                return React.createElement("canvas", { id: this.props.gaugeId, width: "250", height: "250", "data-value": this.props.value });
+                return React.createElement("canvas", { id: this.props.gaugeId, className: "graph-widget", width: "250", height: "250", "data-value": this.props.value });
             }
             }
             return React.createElement(
             return React.createElement(
                 "p",
                 "p",
@@ -657,15 +655,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "memory usage"
                     "memory usage"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -722,15 +720,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "opcache statistics"
                     "opcache statistics"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -806,15 +804,15 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "div",
                 "div",
-                { className: "moreinfo" },
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "interned strings usage"
                     "interned strings usage"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "div",
                     "div",
-                    null,
+                    { className: "widget-value widget-info" },
                     React.createElement(
                     React.createElement(
                         "p",
                         "p",
                         null,
                         null,
@@ -876,7 +874,7 @@ $opcache = OpCacheService::init($options);
             if (this.state.data == false) {
             if (this.state.data == false) {
                 return React.createElement(
                 return React.createElement(
                     "p",
                     "p",
-                    { id: "fileCacheOnly" },
+                    { "class": "file-cache-only" },
                     "You have ",
                     "You have ",
                     React.createElement(
                     React.createElement(
                         "i",
                         "i",
@@ -901,45 +899,45 @@ $opcache = OpCacheService::init($options);
 
 
             var memoryHighlight = this.state.highlight.memory ? React.createElement(
             var memoryHighlight = this.state.highlight.memory ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "memory"
                     "memory"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage, gaugeId: "memoryUsageCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage, gaugeId: "memoryUsageCanvas" })
                 )
                 )
             ) : null;
             ) : null;
 
 
             var hitsHighlight = this.state.highlight.hits ? React.createElement(
             var hitsHighlight = this.state.highlight.hits ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "hit rate"
                     "hit rate"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage, gaugeId: "hitRateCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage, gaugeId: "hitRateCanvas" })
                 )
                 )
             ) : null;
             ) : null;
 
 
             var keysHighlight = this.state.highlight.keys ? React.createElement(
             var keysHighlight = this.state.highlight.keys ? React.createElement(
                 "div",
                 "div",
-                null,
+                { className: "widget-panel" },
                 React.createElement(
                 React.createElement(
                     "h3",
                     "h3",
-                    null,
+                    { className: "widget-header" },
                     "keys"
                     "keys"
                 ),
                 ),
                 React.createElement(
                 React.createElement(
                     "p",
                     "p",
-                    null,
+                    { className: "widget-value" },
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_key_percentage, gaugeId: "keyUsageCanvas" })
                     React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_key_percentage, gaugeId: "keyUsageCanvas" })
                 )
                 )
             ) : null;
             ) : null;
@@ -1009,7 +1007,7 @@ $opcache = OpCacheService::init($options);
             ) : '';
             ) : '';
             return React.createElement(
             return React.createElement(
                 "table",
                 "table",
-                null,
+                { className: "tables general-info-table" },
                 React.createElement(
                 React.createElement(
                     "thead",
                     "thead",
                     null,
                     null,
@@ -1139,7 +1137,7 @@ $opcache = OpCacheService::init($options);
             });
             });
             return React.createElement(
             return React.createElement(
                 "table",
                 "table",
-                null,
+                { className: "tables directives-table" },
                 React.createElement(
                 React.createElement(
                     "thead",
                     "thead",
                     null,
                     null,
@@ -1202,7 +1200,7 @@ $opcache = OpCacheService::init($options);
                             ",\xA0",
                             ",\xA0",
                             React.createElement(
                             React.createElement(
                                 "a",
                                 "a",
-                                { className: "metainfo", href: '?invalidate=' + file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate },
+                                { className: "file-metainfo", href: '?invalidate=' + file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate },
                                 "force file invalidation"
                                 "force file invalidation"
                             )
                             )
                         );
                         );
@@ -1214,18 +1212,13 @@ $opcache = OpCacheService::init($options);
                             "td",
                             "td",
                             null,
                             null,
                             React.createElement(
                             React.createElement(
-                                "div",
-                                null,
-                                React.createElement(
-                                    "span",
-                                    { className: "pathname" },
-                                    file.full_path
-                                ),
-                                React.createElement("br", null),
-                                React.createElement(FilesMeta, { data: [file.readable.hits, file.readable.memory_consumption, file.last_used] }),
-                                invalidate,
-                                invalidated
-                            )
+                                "span",
+                                { className: "file-pathname" },
+                                file.full_path
+                            ),
+                            React.createElement(FilesMeta, { data: [file.readable.hits, file.readable.memory_consumption, file.last_used] }),
+                            invalidate,
+                            invalidated
                         )
                         )
                     );
                     );
                 }.bind(this));
                 }.bind(this));
@@ -1235,7 +1228,7 @@ $opcache = OpCacheService::init($options);
                     React.createElement(FilesListed, { showing: this.state.showing }),
                     React.createElement(FilesListed, { showing: this.state.showing }),
                     React.createElement(
                     React.createElement(
                         "table",
                         "table",
-                        null,
+                        { className: "tables file-list-table" },
                         React.createElement(
                         React.createElement(
                             "thead",
                             "thead",
                             null,
                             null,
@@ -1266,7 +1259,7 @@ $opcache = OpCacheService::init($options);
         render: function () {
         render: function () {
             return React.createElement(
             return React.createElement(
                 "span",
                 "span",
-                { className: "metainfo" },
+                { className: "file-metainfo" },
                 React.createElement(
                 React.createElement(
                     "b",
                     "b",
                     null,
                     null,

+ 29 - 31
src/status.jsx

@@ -17,7 +17,7 @@ var UsageGraph = React.createClass({
     },
     },
     render: function() {
     render: function() {
         if (this.props.chart == true) {
         if (this.props.chart == true) {
-            return(<canvas id={this.props.gaugeId} width="250" height="250" data-value={this.props.value} />);
+            return(<canvas id={this.props.gaugeId} className="graph-widget" width="250" height="250" data-value={this.props.value} />);
         }
         }
         return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
         return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
     }
     }
@@ -26,9 +26,9 @@ var UsageGraph = React.createClass({
 var MemoryUsagePanel = React.createClass({
 var MemoryUsagePanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>memory usage</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">memory usage</h3>
+                <div className="widget-value widget-info">
                     <p><b>total memory:</b> {this.props.total}</p>
                     <p><b>total memory:</b> {this.props.total}</p>
                     <p><b>used memory:</b> {this.props.used}</p>
                     <p><b>used memory:</b> {this.props.used}</p>
                     <p><b>free memory:</b> {this.props.free}</p>
                     <p><b>free memory:</b> {this.props.free}</p>
@@ -42,9 +42,9 @@ var MemoryUsagePanel = React.createClass({
 var StatisticsPanel = React.createClass({
 var StatisticsPanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>opcache statistics</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">opcache statistics</h3>
+                <div className="widget-value widget-info">
                     <p><b>number of cached files:</b> {this.props.num_cached_scripts}</p>
                     <p><b>number of cached files:</b> {this.props.num_cached_scripts}</p>
                     <p><b>number of hits:</b> {this.props.hits}</p>
                     <p><b>number of hits:</b> {this.props.hits}</p>
                     <p><b>number of misses:</b> {this.props.misses}</p>
                     <p><b>number of misses:</b> {this.props.misses}</p>
@@ -60,9 +60,9 @@ var StatisticsPanel = React.createClass({
 var InternedStringsPanel = React.createClass({
 var InternedStringsPanel = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <div className="moreinfo">
-                <h3>interned strings usage</h3>
-                <div>
+            <div className="widget-panel">
+                <h3 className="widget-header">interned strings usage</h3>
+                <div className="widget-value widget-info">
                     <p><b>buffer size:</b> {this.props.buffer_size}</p>
                     <p><b>buffer size:</b> {this.props.buffer_size}</p>
                     <p><b>used memory:</b> {this.props.strings_used_memory}</p>
                     <p><b>used memory:</b> {this.props.strings_used_memory}</p>
                     <p><b>free memory:</b> {this.props.strings_free_memory}</p>
                     <p><b>free memory:</b> {this.props.strings_free_memory}</p>
@@ -84,7 +84,7 @@ var OverviewCounts = React.createClass({
     render: function() {
     render: function() {
         if (this.state.data == false) {
         if (this.state.data == false) {
             return (
             return (
-                <p id="fileCacheOnly">
+                <p class="file-cache-only">
                     You have <i>opcache.file_cache_only</i> turned on.  As a result, the memory information is not available.  Statistics and file list may also not be returned by <i>opcache_get_statistics()</i>.
                     You have <i>opcache.file_cache_only</i> turned on.  As a result, the memory information is not available.  Statistics and file list may also not be returned by <i>opcache_get_statistics()</i>.
                 </p>
                 </p>
             );
             );
@@ -100,23 +100,23 @@ var OverviewCounts = React.createClass({
         );
         );
 
 
         var memoryHighlight = this.state.highlight.memory ? (
         var memoryHighlight = this.state.highlight.memory ? (
-                <div>
-                    <h3>memory</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} gaugeId="memoryUsageCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">memory</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} gaugeId="memoryUsageCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
         var hitsHighlight = this.state.highlight.hits ? (
         var hitsHighlight = this.state.highlight.hits ? (
-                <div>
-                    <h3>hit rate</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} gaugeId="hitRateCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">hit rate</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} gaugeId="hitRateCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
         var keysHighlight = this.state.highlight.keys ? (
         var keysHighlight = this.state.highlight.keys ? (
-                <div>
-                    <h3>keys</h3>
-                    <p><UsageGraph chart={this.state.chart} value={this.state.data.used_key_percentage} gaugeId="keyUsageCanvas"/></p>
+                <div className="widget-panel">
+                    <h3 className="widget-header">keys</h3>
+                    <p className="widget-value"><UsageGraph chart={this.state.chart} value={this.state.data.used_key_percentage} gaugeId="keyUsageCanvas"/></p>
                 </div>
                 </div>
             ) : null;
             ) : null;
 
 
@@ -163,7 +163,7 @@ var GeneralInfo = React.createClass({
             ? <tr><td>Last reset</td><td>{this.state.reset}</td></tr>
             ? <tr><td>Last reset</td><td>{this.state.reset}</td></tr>
             : '';
             : '';
         return (
         return (
-            <table>
+            <table className="tables general-info-table">
                 <thead>
                 <thead>
                     <tr><th colSpan="2">General info</th></tr>
                     <tr><th colSpan="2">General info</th></tr>
                 </thead>
                 </thead>
@@ -213,7 +213,7 @@ var Directives = React.createClass({
             );
             );
         });
         });
         return (
         return (
-            <table>
+            <table className="tables directives-table">
                 <thead>
                 <thead>
                     <tr><th colSpan="2">Directives</th></tr>
                     <tr><th colSpan="2">Directives</th></tr>
                 </thead>
                 </thead>
@@ -249,18 +249,16 @@ var Files = React.createClass({
                     invalidated = <span><i className="invalid metainfo"> - has been invalidated</i></span>;
                     invalidated = <span><i className="invalid metainfo"> - has been invalidated</i></span>;
                 }
                 }
                 if (canInvalidate) {
                 if (canInvalidate) {
-                    invalidate = <span>,&nbsp;<a className="metainfo" href={'?invalidate='
+                    invalidate = <span>,&nbsp;<a className="file-metainfo" href={'?invalidate='
                         + file.full_path} data-file={file.full_path} onClick={this.handleInvalidate}>force file invalidation</a></span>;
                         + file.full_path} data-file={file.full_path} onClick={this.handleInvalidate}>force file invalidation</a></span>;
                 }
                 }
                 return (
                 return (
                     <tr key={file.full_path} data-path={file.full_path.toLowerCase()} className={i%2?'alternate':''}>
                     <tr key={file.full_path} data-path={file.full_path.toLowerCase()} className={i%2?'alternate':''}>
                         <td>
                         <td>
-                            <div>
-                                <span className="pathname">{file.full_path}</span><br/>
-                                <FilesMeta data={[file.readable.hits, file.readable.memory_consumption, file.last_used]} />
-                                {invalidate}
-                                {invalidated}
-                            </div>
+                            <span className="file-pathname">{file.full_path}</span>
+                            <FilesMeta data={[file.readable.hits, file.readable.memory_consumption, file.last_used]} />
+                            {invalidate}
+                            {invalidated}
                         </td>
                         </td>
                     </tr>
                     </tr>
                 );
                 );
@@ -268,7 +266,7 @@ var Files = React.createClass({
             return (
             return (
                 <div>
                 <div>
                     <FilesListed showing={this.state.showing}/>
                     <FilesListed showing={this.state.showing}/>
-                    <table>
+                    <table className="tables file-list-table">
                         <thead>
                         <thead>
                         <tr>
                         <tr>
                             <th>Script</th>
                             <th>Script</th>
@@ -287,7 +285,7 @@ var Files = React.createClass({
 var FilesMeta = React.createClass({
 var FilesMeta = React.createClass({
     render: function() {
     render: function() {
         return (
         return (
-            <span className="metainfo">
+            <span className="file-metainfo">
                 <b>hits: </b><span>{this.props.data[0]}, </span>
                 <b>hits: </b><span>{this.props.data[0]}, </span>
                 <b>memory: </b><span>{this.props.data[1]}, </span>
                 <b>memory: </b><span>{this.props.data[1]}, </span>
                 <b>last used: </b><span>{this.props.data[2]}</span>
                 <b>last used: </b><span>{this.props.data[2]}</span>