FloatingWindow

Adds FloatingWindow

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/477480/1270124/FloatingWindow.js

  1. // ==UserScript==
  2. // @name FloatingWindow
  3. // @version 1.2
  4. // @grant GM_addStyle
  5. // @grant GM_getValue
  6. // @grant GM_setValue
  7. // @description Adds FloatingWindow
  8. // ==/UserScript==
  9.  
  10. GM_addStyle(`
  11. .floatingWindowContainer {
  12. width:200px;
  13. position:fixed;
  14. opacity:0.5;
  15. z-index: 9999;
  16. }
  17. .floatingWindowTitleBar {
  18. background-color:#fff;
  19. font-weight:bold;
  20. text-align:center;
  21. cursor:pointer;
  22. }
  23. .floatingWindowContainer.active {
  24. opacity:1;
  25. z-index: 10000;
  26. }
  27. .floatingWindowBody{
  28. flex-wrap:wrap;
  29. }
  30.  
  31. `);
  32.  
  33. class FloatingWindow {
  34. constructor(title,settings = {}) {
  35. this.settings = {
  36. position:settings?.position || {x:window.innerWidth*0.8,y:100},
  37. open: settings.hasOwnProperty("open") ? settings.open : true,
  38. bodyDisplay:settings?.bodyDisplay || "block"
  39. }
  40. this.container = document.createElement("div");
  41. this.container.className = "floatingWindowContainer";
  42. this.container.id = title.toLowerCase().replaceAll(/\W+/g,"_");
  43. this.windowPosition = GM_getValue(`${this.container.id}_position`,this.settings.position);
  44. this.container.style.left = `${this.windowPosition.x}px`;
  45. this.container.style.top = `${this.windowPosition.y}px`;
  46. this.titleBar = document.createElement("div");
  47. this.titleBar.className = "floatingWindowTitleBar";
  48. this.titleBar.appendChild(document.createTextNode(title));
  49. this.titleBar.addEventListener("pointerdown",(e)=>{this.pointerDownHandler(e);});
  50. document.addEventListener("pointermove",(e)=>{this.pointerMoveHandler(e);});
  51. document.addEventListener("pointerup",(e)=>{this.pointerUpHandler(e);});
  52. this.container.appendChild(this.titleBar);
  53. this.body = document.createElement("div");
  54. this.body.className = "floatingWindowBody";
  55. this.windowOpen = GM_getValue(`${this.container.id}_open`,this.settings.open);
  56. if (this.windowOpen) this.container.classList.add("active");
  57. this.body.style.display = this.windowOpen ? this.settings.bodyDisplay : "none";
  58. this.container.appendChild(this.body);
  59. document.body.appendChild(this.container);
  60. this.pointerValues = {
  61. newPosition:null,
  62. positionOffset:null,
  63. dragging:false
  64. };
  65. }
  66. toggleWindow() {
  67. this.windowOpen = !this.windowOpen;
  68. this.container.classList.toggle("active");
  69. GM_setValue(`${this.container.id}_open`,this.windowOpen);
  70. this.body.style.display = this.windowOpen ? this.settings.bodyDisplay : "none";
  71. }
  72. pointerDownHandler(e) {
  73. this.pointerValues.positionOffset = {
  74. x:e.clientX - this.windowPosition.x,
  75. y:e.clientY - this.windowPosition.y
  76. };
  77. }
  78. pointerMoveHandler(e) {
  79. if (this.pointerValues.positionOffset) {
  80. e.preventDefault()
  81. this.pointerValues.newPosition = {
  82. x:e.clientX - this.pointerValues.positionOffset.x,
  83. y:e.clientY - this.pointerValues.positionOffset.y
  84. };
  85. if (!this.pointerValues.dragging) {
  86. if (
  87. Math.abs(e.clientX - this.windowPosition.x) > 10 ||
  88. Math.abs(e.clientY - this.windowPosition.y) > 10
  89. ) this.pointerValues.dragging = true;
  90. } else {
  91. this.container.style.left = `${this.pointerValues.newPosition.x}px`;
  92. this.container.style.top = `${this.pointerValues.newPosition.y}px`;
  93. }
  94. }
  95. }
  96. pointerUpHandler(e) {
  97. if (this.pointerValues.positionOffset) {
  98. if (this.pointerValues.dragging) {
  99. this.pointerValues.newPosition = {
  100. x:e.clientX - this.pointerValues.positionOffset.x,
  101. y:e.clientY - this.pointerValues.positionOffset.y
  102. };
  103. this.container.style.left = `${this.pointerValues.newPosition.x}px`;
  104. this.container.style.top = `${this.pointerValues.newPosition.y}px`;
  105. this.windowPosition = this.pointerValues.newPosition;
  106. GM_setValue(`${this.container.id}_position`,this.windowPosition);
  107. } else {
  108. this.toggleWindow();
  109. }
  110. this.pointerValues.dragging = false;
  111. this.pointerValues.newPosition = this.pointerValues.positionOffset = null;
  112. }
  113.  
  114. }
  115. }