rmo.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * Get rid of full-page overlays.
  3. *
  4. * @title rm overlays
  5. */
  6. (function rmo() {
  7. function getFirstZIndexedElement(elements) {
  8. if (!Array.isArray(elements)) {
  9. elements = Array.from(elements);
  10. }
  11. for (let i = 0; i < elements.length; i++) {
  12. if (!isNaN(getComputedStyle(elements[i]).zIndex)) {
  13. return elements[i];
  14. }
  15. }
  16. return null;
  17. }
  18. /* Recursively execute the logic on the document and its sub-documents. */
  19. function execute(document) {
  20. /* Look for absolutely positioned (well, Z-indexed) elements that
  21. * cover the entire width of the page. Look for them in the vertical
  22. * center, to avoid cookie/GDPR/… banners that are typically at the
  23. * top or bottom of the window, and slightly away from the edges, to
  24. * avoid scrollbars/social sharing toolbars/… */
  25. let leftX = 64;
  26. let leftY = document.defaultView.innerHeight / 2;
  27. let leftOverlay = getFirstZIndexedElement(document.elementsFromPoint(leftX, leftY));
  28. if (!leftOverlay)
  29. return;
  30. let rightX = document.defaultView.innerWidth - 64;
  31. let rightY = document.defaultView.innerHeight / 2;
  32. let rightOverlay = getFirstZIndexedElement(document.elementsFromPoint(rightX, rightY));
  33. if (!rightOverlay)
  34. return;
  35. if (leftOverlay !== rightOverlay)
  36. return;
  37. let centerX = document.defaultView.innerWidth / 2;
  38. let centerY = document.defaultView.innerHeight / 2;
  39. let centerElements = document.elementsFromPoint(centerX, centerY);
  40. if (!centerElements.indexOf(leftOverlay) === -1)
  41. return;//leftOverlay not in center
  42. /* Hide the overlay and its “visual descendants” (i.e., the elements
  43. * on top of the overlay). */
  44. for (let i = 0; i < centerElements.length; i++) {
  45. centerElements[i].style.display = 'none';
  46. if (centerElements[i] === leftOverlay) {
  47. break;
  48. }
  49. }
  50. /* Re-enable scrolling on the BODY element. */
  51. let currentBodyStyle = document.body.hasAttribute('style')
  52. ? document.body.getAttribute('style')
  53. : '';
  54. let newBodyStyle = currentBodyStyle +
  55. '; overflow: auto !important' +
  56. '; position: static !important';
  57. document.body.setAttribute('style', newBodyStyle);
  58. /* Re-enable scrolling on Quora.com. */
  59. document.body.classList.remove('login_no_scroll');
  60. /* Re-enable scrolling disabled by inline styles. */
  61. [].forEach.call(
  62. document.querySelectorAll('[style*="overflow"][style*="hidden"]'),
  63. function (elem) {
  64. elem.setAttribute('style', elem.getAttribute('style').replace(/overflow\s*:\s*hidden\s*;?/, ''));
  65. }
  66. );
  67. /* Recurse for frames and IFRAMEs. */
  68. try {
  69. Array.from(
  70. document.querySelectorAll('frame, iframe, object[type^="text/html"], object[type^="application/xhtml+xml"]')
  71. ).forEach(
  72. elem => execute(elem.contentDocument)
  73. );
  74. } catch (e) {
  75. /* Catch and ignore exceptions for out-of-domain access. */
  76. }
  77. }
  78. execute(document);
  79. })();