ABP Digest: Open in pop-in

Opens reports in pop-in window.

  1. // ==UserScript==
  2. // @name ABP Digest: Open in pop-in
  3. // @namespace lainscripts_abp_digest_popin
  4. // @description Opens reports in pop-in window.
  5. // @include *://reports.adblockplus.org/*
  6. // @version 0.1
  7. // @grant none
  8. // @run-at document-start
  9. // ==/UserScript==
  10. /* jshint esnext: true */
  11. (()=>{
  12. 'use strict';
  13.  
  14. var inIframe = (function(){ try { return window.self !== window.top; } catch (ignore) { return true; } })();
  15. // attach styles before document displayed
  16. (function(style) {
  17. style.id = 'popinStyles';
  18. style.type = 'text/css';
  19. document.head.appendChild(style);
  20.  
  21. style.sheet.insertRule('@keyframes spinnerFrames {0% {transform:rotate(0deg)} 100% {transform:rotate(-360deg)}}',0);
  22. style.sheet.insertRule('#popinSpinner svg {'+
  23. ['animation: spinnerFrames linear 1s',
  24. 'animation-iteration-count: infinite',
  25. 'transform-origin: 50% 50%'].join(';')+'}', 0);
  26. style.sheet.insertRule('#popinBackground {'+
  27. ['box-sizing: border-box',
  28. 'position: fixed',
  29. 'top: 0',
  30. 'left: 0',
  31. 'padding: 35px 40px',
  32. 'width: 100%',
  33. 'height: 100%',
  34. 'background-color: rgba(0,0,0,0.85)',
  35. 'z-index: 1000000',
  36. 'display: none'].join(';')+'}', 0);
  37. style.sheet.insertRule('#popinFrame {'+
  38. ['position: relative',
  39. 'width: 100%',
  40. 'height: 100%',
  41. 'border: #aaa 2px solid',
  42. 'border-radius: 3px',
  43. 'background-color: rgba(0,0,0,0.33)',
  44. 'z-index: 1'].join(';')+'}', 0);
  45. style.sheet.insertRule('#popinSpinner {'+
  46. ['position: fixed',
  47. 'top: 50%',
  48. 'left: 50%',
  49. 'margin-top: -50px',
  50. 'margin-left: -50px',
  51. 'width: 100px',
  52. 'height: 100px',
  53. 'z-index: 2'].join(';')+'}', 0);
  54.  
  55.  
  56. // modify navigation elements when various pages are loaded in the pop-in
  57. if (inIframe) {
  58. // make page cover the entire window height and reset padding with margin if someone changed them
  59. style.sheet.insertRule('html, body {'+['height: 100%',
  60. 'padding: 0!important',
  61. 'margin: 0!important'].join(';')+'}', 0);
  62. // let that status block at the top grow
  63. style.sheet.insertRule('#overview th, #overview td { max-width: none !important }', 0);
  64. }
  65.  
  66. })(document.createElement('style'));
  67.  
  68. function createSVGSpinner(out_radius, in_radius, width, number_of_lines, period, direction) {
  69. var num = number_of_lines, shift = out_radius + width / 2, step = 0;
  70. var nameSpace = 'http://www.w3.org/2000/svg';
  71.  
  72. var svg = document.createElementNS(nameSpace, 'svg');
  73. svg.setAttribute('version', '1.1');
  74. svg.setAttribute('x', '0px');
  75. svg.setAttribute('y', '0px');
  76. svg.setAttribute('width', (2 * shift) + 'px');
  77. svg.setAttribute('height', (2 * shift) + 'px');
  78. svg.setAttribute('style', ['stroke: #fff',
  79. 'stroke-width: ' + width + 'px',
  80. 'stroke-linecap: round'].join(';'));
  81.  
  82. var g = document.createElementNS(nameSpace, 'g');
  83. svg.appendChild(g);
  84.  
  85. var line;
  86. while (num--) {
  87. if (direction >= 0) step = num; else step = number_of_lines - num;
  88. line = document.createElementNS(nameSpace, 'line');
  89. line.setAttribute('x1', shift + Math.cos(2 * Math.PI / number_of_lines * num) * in_radius);
  90. line.setAttribute('y1', shift + Math.sin(2 * Math.PI / number_of_lines * num) * in_radius);
  91. line.setAttribute('x2', shift + Math.cos(2 * Math.PI / number_of_lines * num) * out_radius);
  92. line.setAttribute('y2', shift + Math.sin(2 * Math.PI / number_of_lines * num) * out_radius);
  93. line.setAttribute('stroke-opacity', 1 / (num + 1));
  94. g.appendChild(line);
  95. }
  96. return svg;
  97. }
  98.  
  99. function popinObj() {
  100. /* jshint validthis: true */
  101. var _self = this;
  102. _self.childPopin = null;
  103.  
  104. var spinner = document.createElement('div');
  105. spinner.appendChild(createSVGSpinner(45, 25, 10, 10, 1.8, -1));
  106. spinner.id = 'popinSpinner';
  107.  
  108. var popin = document.createElement('div');
  109. popin.id = 'popinBackground';
  110.  
  111. var ifrm = null;
  112. var openFrame = function (a) {
  113. var url = a.href;
  114. var ifr = document.createElement('iframe');
  115. ifr.id = 'popinFrame';
  116. ifr.onload = function() { spinner.style.zIndex = 0; };
  117.  
  118. // Hide spinner if page keeps loading after a 5 seconds
  119. setTimeout(function() {
  120. if (popin.style.display === 'block')
  121. spinner.style.zIndex = 0;
  122. }, 5000);
  123.  
  124. ifr.src = url;
  125. return ifr;
  126. };
  127.  
  128. popin.appendChild(spinner);
  129. document.body.appendChild(popin);
  130.  
  131. _self.show = function (a) {
  132. document.body.style.overflowY = 'hidden';
  133. ifrm = openFrame(a);
  134. popin.appendChild(ifrm);
  135. popin.style.display = 'block';
  136. };
  137.  
  138. _self.hide = function () {
  139. document.body.style.overflowY = 'auto';
  140. popin.removeAttribute('style');
  141. spinner.removeAttribute('style');
  142. ifrm.parentNode.removeChild(ifrm);
  143. ifrm = null;
  144. };
  145.  
  146. popin.onclick = _self.hide;
  147. }
  148.  
  149. document.addEventListener ("DOMContentLoaded", function() {
  150. document.popin = new popinObj();
  151.  
  152. document.body.addEventListener('click', function(e) {
  153. var t = e.target;
  154.  
  155. // handle only LMB clicks
  156. if (e.which !== 1)
  157. return;
  158.  
  159. // try to drill up to an A element if present
  160. while (t.parentNode && !t.href)
  161. t = t.parentNode;
  162.  
  163. // if user clicked a link - try to handle it properly
  164. if (t.href) {
  165. if (!inIframe && t.hostname === document.location.hostname) {
  166. document.popin.show(t);
  167. e.preventDefault();
  168. } else {
  169. t.target = '_blank';
  170. }
  171. }
  172. });
  173. });
  174. })();