Makes Code Window be Floatable - PythonTutor

PythonTutor is sick, but its interface is sucks. What a shame!

  1. // ==UserScript==
  2. // @name Makes Code Window be Floatable - PythonTutor
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description PythonTutor is sick, but its interface is sucks. What a shame!
  6. // @author You
  7. // @match https://pythontutor.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=pythontutor.com
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. var styleSheet =
  17. `
  18. #codAndNav{
  19. padding: 20px;
  20. padding-top: 0;
  21. right: 10px;
  22. background-color: white;
  23. z-index: 9999999;
  24. border: 1px grey solid;
  25. }
  26.  
  27. #qtip-pyCodeOutputDiv, #footer, iframe{
  28. display: none;
  29. }
  30.  
  31. #dragBar{
  32. background-color: #F5F5F5;
  33. text-align: center;
  34. padding: 10px 0;
  35. border-radius: 0 0 100px 100px;
  36. cursor: move;
  37. }
  38.  
  39. `
  40.  
  41. var sty = document.createElement("style")
  42. sty.innerHTML = styleSheet
  43. document.body.appendChild(sty)
  44.  
  45.  
  46. var intv = setInterval(()=>{
  47. var codePanel = document.getElementById("codAndNav")
  48. if(codePanel){
  49. clearInterval(intv)
  50. createDragBar(codePanel)
  51. }
  52. },1000)
  53.  
  54. function createDragBar(panel){
  55. var drag = document.createElement("div")
  56. drag.innerHTML = "Draggable"
  57. drag.id = "dragBar"
  58. panel.prepend(drag)
  59. floatElement(panel, drag, true);
  60. }
  61.  
  62. function floatElement(eleToBeFloat, dragArea, allowDragOutOfBorder){
  63. //PENDING(B2) 讀取LocalStorage,把top, left, width, height應用到邊框上
  64. allowDragOutOfBorder = allowDragOutOfBorder == void 0?false:allowDragOutOfBorder
  65. eleToBeFloat.style.position = "absolute"
  66.  
  67. dragArea.onmousedown = function(e){
  68. e = e || window.event
  69. var MouseX = e.clientX, MouseY = e.clientY //瀏覽器左上到鼠標位置的坐標
  70. //鼠標相對於eleToBeFloat的偏移量
  71. var relativeMouseX = MouseX - eleToBeFloat.offsetLeft
  72. var relativeMouseY = MouseY - eleToBeFloat.offsetTop
  73.  
  74. const mouseMoveFunc = function(){
  75. var e = e || window.event
  76. //窗口相對於瀏覽器左上的偏移量
  77. var offsetX = (e.clientX - relativeMouseX)
  78. var offsetY = (e.clientY - relativeMouseY)
  79.  
  80. if(e.clientX < 0 || e.clientY < 0) return false
  81. if(!allowDragOutOfBorder&&isEdgeReached(offsetX, offsetY)) return false
  82. eleToBeFloat.style.left = offsetX + "px"
  83. eleToBeFloat.style.top = offsetY + "px"
  84. }
  85. const mouseUpFunc = function(){
  86. document.removeEventListener('mousemove', mouseMoveFunc)
  87. document.removeEventListener('mouseup', mouseUpFunc)
  88. // PENDING(B2) 用LocalStorage把top, left, width, height存起來,準備下次調用
  89. }
  90.  
  91. document.addEventListener('mousemove', mouseMoveFunc)
  92. document.addEventListener('mouseup', mouseUpFunc)
  93.  
  94. function isEdgeReached(offsetX, offsetY){
  95. var floatingWindowLeft = offsetX
  96. var floatingWindowTop = offsetY
  97. var floatingWindowRight = offsetX + eleToBeFloat.clientWidth
  98. var floatingWindowBottom = offsetY + eleToBeFloat.clientHeight
  99.  
  100. if(floatingWindowTop <= 0 || floatingWindowLeft <= 0) return true
  101. else if(floatingWindowRight >= document.body.scrollWidth || floatingWindowBottom >= document.body.scrollHeight) return true
  102. else return false
  103. //PENDING(A1) 判斷是哪一條邊超過了邊界 找到它 然後把相應的Left/top設置成貼近那條邊的地方
  104. }
  105.  
  106. return false
  107. }
  108. }
  109.  
  110. // Your code here...
  111. })();