├── LICENSE ├── README.org ├── Remove sticky and add red scrolling-indicator.js ├── Remove sticky.js ├── YT - Streamchat improver.js ├── YT - speed - default.js ├── YT - speed - faster.js ├── YT - speed - slower.js ├── install.gif ├── space-scroll.gif ├── speedread.gif ├── speedread.js └── yt-chat.gif /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Philipp Uhl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | 2 | * TODO Bookmarklets 3 | 4 | A bookmarklet is like a tiny Add-on for your browser. You drag it into 5 | your bookmark-bar and when you click it, it does something. 6 | 7 | [[file:install.gif]] 8 | 9 | If you are using Firefox and a script-blocking Add-on (NoScript, 10 | uMatrix, ...) you will notice that bookmarklets do not work if scripts 11 | are disabled for the domain the website is on. This is a bug in 12 | Firefox but there is an Add-on to work arround this issue: 13 | [[https://addons.mozilla.org/en-US/firefox/addon/bookmarklets-context-menu/][Bookmarklets context menu]]. 14 | 15 | This Add-on requiers your bookmarklets to be HTML-URL-decodable. If 16 | you are writing bookmarklets for your self, be aware that 17 | copy-n-pasting your code into a new cookie does not fully URL-encode 18 | your code. The =%=-sign for example stays unencoded and has to be 19 | replaced manually by =%25=. 20 | 21 | ** Remove Sticky 22 | 23 | Removes all sticky elements from the page. 24 | 25 | *Bookmarklet:* [[javascript:(function()%257B%2520let%2520i%252C%2520elements%2520%253D%2520document.querySelectorAll('body%2520*')%253B%2520for%2520(i%2520%253D%25200%253B%2520i%2520%253C%2520elements.length%253B%2520i%252B%252B)%2520%257B%2520if(getComputedStyle(elements%255Bi%255D).position%2520%253D%253D%253D%2520'fixed'%2520%257C%257C%2520getComputedStyle(elements%255Bi%255D).position%2520%253D%253D%253D%2520'sticky')%257B%2520elements%255Bi%255D.parentNode.removeChild(elements%255Bi%255D)%253B%2520%257D%2520%257D%2520%257D)()][Remove sticky (drag me into the bookmark bar)]] 26 | 27 | #+BEGIN_SRC javascript 28 | javascript:(function(){ 29 | let i, elements = document.querySelectorAll('body *'); 30 | for (i = 0; i < elements.length; i++) { 31 | if(getComputedStyle(elements[i]).position === 'fixed' 32 | || getComputedStyle(elements[i]).position === 'sticky'){ 33 | elements[i].parentNode.removeChild(elements[i]); 34 | } 35 | } 36 | })() 37 | #+END_SRC 38 | 39 | ** Scroll Better with the Space-Bar 40 | 41 | When scrolling with the space-bar sticky headers can be annoying as 42 | they cover up text that scrolles underneath them. 43 | 44 | This bookmarklet removes sticky content and adds a red indicator-line 45 | that shows, where the bottom of the page was, when you pressed space 46 | to scroll. 47 | 48 | [[file:space-scroll.gif]] 49 | 50 | *Bookmarklet:* [[javascript:(function()%257B%2520let%2520i%252C%2520elements%253Ddocument.querySelectorAll('body%2520*')%253Bfor%2520(i%253D0%253Bi%2520%253C%2520elements.length%253Bi%252B%252B)%2520%257B%2520if%2520(getComputedStyle(elements%255Bi%255D).position%2520%253D%253D%253D%2520'fixed'%2520%257C%257C%2520getComputedStyle(elements%255Bi%255D).position%2520%253D%253D%253D%2520'sticky')%2520%257B%2520elements%255Bi%255D.parentNode.removeChild(elements%255Bi%255D)%253B%257D%257Dlet%2520elem%253DArray.from(document.getElementsByTagName(%2522body%2522))%255B0%255D.appendChild(document.createElement('div'))%253Belem.style.width%253D%2522100%2525%2522%253Belem.style.borderTop%253D%25221px%2520solid%2520red%2522%253Belem.style.position%253D%2522absolute%2522%253Belem.style.top%253D%25220px%2522%253Belem.style.opacity%253D%25220%2522%253Belem.style.transition%253D%2522opacity%25201000ms%2522%253Bwindow.addEventListener('keydown'%252C%2520e%2520%253D%253E%2520%257B%2520if(e.code%2520%253D%253D%253D%2520%2522Space%2522)%257B%2520elem.style.transition%253D%2522%2522%253Belem.style.top%253D(window.innerHeight%2520%252B%2520window.scrollY)%2520%252B%2520%2522px%2522%253Belem.style.opacity%253D%25221%2522%253BsetTimeout(function()%257B%2520elem.style.transition%253D%2522opacity%25201000ms%2522%253Belem.style.opacity%253D%25220%2522%253B%257D%252C%2520200)%253B%257D%257D)%253B%257D())][Space-scroll (drag me into the bookmark bar)]] 51 | 52 | [[file:Remove%20sticky%20and%20add%20red%20scrolling-indicator.js][Source]] 53 | 54 | ** Youtube - Better Livestream-Chat in Cinema-mode 55 | 56 | Arranges the video and the chat side by side. Currently only working 57 | with screensizes arround 1920x1080. 58 | 59 | [[file:yt-chat.gif]] 60 | 61 | *Bookmarklet:* [[javascript:(function()%257B%2520let%2520video%253DArray.from(document.getElementsByClassName(%2522video-stream%2520html5-main-video%2522))%255B0%255D%253Blet%2520chat%253Ddocument.getElementById(%2522chat%2522)%253Bchat.style.position%253D'fixed'%253Bchat.style.top%253D'60px'%253Bchat.style.right%253D'5px'%253Bchat.style.height%253D'754.1px'%253Bvideo.style.left%253D'57.889px'%253B%257D)()][Better YT-Chat (drag me into the bookmark bar)]] 62 | 63 | #+BEGIN_SRC javascript 64 | javascript:(function(){ 65 | let video = Array.from(document.getElementsByClassName("video-stream html5-main-video"))[0]; 66 | let chat = document.getElementById("chat"); 67 | chat.style.position = 'fixed'; 68 | chat.style.top = '60px'; 69 | chat.style.right = '5px'; 70 | chat.style.height = '754.1px'; 71 | video.style.left = '57.889px'; 72 | })() 73 | #+END_SRC 74 | 75 | ** HTML5-Speed 76 | 77 | Regulates the playback-speed of the video. Works on all HTML5-Videos 78 | (e.g. Youtube). 79 | 80 | *** Faster 81 | 82 | *Bookmarklet:* [[javascript:(function()%257BArray.from(document.getElementsByTagName('video')).forEach(vid%2520%253D%253E%2520vid.playbackRate%2520*%253D%25201.25)%253B%257D())][+ (drag me into the bookmark bar)]] 83 | 84 | #+BEGIN_SRC javascript 85 | javascript:(function(){ 86 | Array.from(document.getElementsByTagName('video')) 87 | .forEach(vid => vid.playbackRate *= 1.25); 88 | }()) 89 | #+END_SRC 90 | 91 | *** Slower 92 | 93 | *Bookmarklet:* [[javascript:(function()%257BArray.from(document.getElementsByTagName('video')).forEach(vid%2520%253D%253E%2520vid.playbackRate%2520*%253D0.8)%253B%257D())][- (drag me into the bookmark bar)]] 94 | 95 | #+BEGIN_SRC javascript 96 | javascript:(function(){ 97 | Array.from(document.getElementsByTagName('video')) 98 | .forEach(vid => vid.playbackRate *= 0.8); 99 | }()) 100 | #+END_SRC 101 | 102 | *** Reset 103 | 104 | *Bookmarklet:* [[javascript:(function()%257BArray.from(document.getElementsByTagName('video')).forEach(vid%2520%253D%253E%2520vid.playbackRate%2520%253D0)%253B%257D())][0 (drag me into the bookmark bar)]] 105 | #+html: 0 106 | #+BEGIN_SRC javascript 107 | javascript:(function(){ 108 | Array.from(document.getElementsByTagName('video')) 109 | .forEach(vid => vid.playbackRate = 0); 110 | }()) 111 | #+END_SRC 112 | 113 | ** Speedread 114 | 115 | After activating the bookmarklet one can select text on the page and 116 | it will be displayed word by word (roughly). The bookmarklet uses the 117 | "Optimal Recognition Point" for displaying the words at the right 118 | position. 119 | 120 | [[file:./speedread.gif]] 121 | 122 | *Bookmarklet:* [[javascript:(function()%257B%2520wpm%2520%253D%2520localStorage.getItem('___aotavnkoyayovfuy_WPM')%2520%257C%257C%2520250%253B%2520let%2520gtimeout%2520%253D%25200%253B%2520let%2520inner%253B%2520let%2520outer%253B%2520let%2520wpmCounter%253B%2520let%2520setWpm%2520%253D%2520(dif)%2520%253D%253E%2520%257B%2520wpm%2520%252B%253D%2520dif%253B%2520wpmCounter.innerHTML%2520%253D%2520wpm%253B%2520localStorage.setItem('___aotavnkoyayovfuy_WPM'%252C%2520wpm)%253B%2520%257D%253B%2520document.addEventListener('selectionchange'%252C%2520()%2520%253D%253E%2520%257B%2520let%2520term%2520%253D%2520window.getSelection().toString()%253B%2520stop()%253B%2520if(term.length%2520%253C%252010)%257B%2520return%253B%2520%257D%2520if(!outer)%257B%2520outer%2520%253D%2520Array.from(document.getElementsByTagName('body'))%255B0%255D.appendChild(document.createElement('div'))%253B%2520inner%2520%253D%2520outer.appendChild(document.createElement('div'))%253B%2520outer.style.position%2520%253D%2520'fixed'%253B%2520outer.style.top%2520%253D%2520'calc(50%2525%2520-%252050px)'%253B%2520outer.style.margin%2520%253D%2520'auto'%253B%2520outer.style.height%2520%253D%2520'100px'%253B%2520outer.style.minWidth%2520%253D%2520'800px'%253B%2520outer.style.background%2520%253D%2520'%2523f5f5f5'%253B%2520outer.style.left%2520%253D%2520'calc(50%2525%2520-%2520400px)'%253B%2520outer.style.fontSize%2520%253D%2520'70px'%253B%2520outer.style.textAlign%2520%253D%2520'center'%253B%2520outer.style.lineHeight%2520%253D%2520'100px'%253B%2520outer.style.flexDirection%2520%253D%2520'row'%253B%2520outer.style.justifyContent%2520%253D%2520'center'%253B%2520outer.style.alignItems%2520%253D%2520'center'%253B%2520outer.style.display%2520%253D%2520'flex'%253B%2520outer.style.borderTop%2520%253D%2520'3px%2520solid'%253B%2520outer.style.borderBottom%2520%253D%2520'3px%2520solid'%253B%2520outer.style.opacity%2520%253D%2520'0.97'%253B%2520let%2520temp%2520%253D%2520outer.appendChild(document.createElement('div'))%253B%2520temp.style.width%2520%253D%2520'3px'%253B%2520temp.style.background%2520%253D%2520'black'%253B%2520temp.style.height%2520%253D%2520'7px'%253B%2520temp.style.position%2520%253D%2520'absolute'%253B%2520temp.style.top%2520%253D%2520'0px'%253B%2520temp.style.left%2520%253D%2520'50%2525'%253B%2520temp%2520%253D%2520outer.appendChild(document.createElement('div'))%253B%2520temp.style.width%2520%253D%2520'3px'%253B%2520temp.style.background%2520%253D%2520'black'%253B%2520temp.style.height%2520%253D%2520'7px'%253B%2520temp.style.position%2520%253D%2520'absolute'%253B%2520temp.style.bottom%2520%253D%2520'0px'%253B%2520temp.style.left%2520%253D%2520'50%2525'%253B%2520let%2520temp1%2520%253D%2520outer.appendChild(document.createElement('div'))%253B%2520temp1.style.position%2520%253D%2520'absolute'%253B%2520temp1.style.left%2520%253D%2520'10px'%253B%2520temp1.style.flexDirection%2520%253D%2520'row'%253B%2520temp1.style.display%2520%253D%2520'flex'%253B%2520temp1.style.alignItems%2520%253D%2520'center'%253B%2520temp1.style.top%2520%253D%2520'5px'%253B%2520temp%2520%253D%2520temp1.appendChild(document.createElement('button'))%253B%2520temp.style.background%2520%253D%2520'%2523eee'%253B%2520temp.style.color%2520%253D%2520'black'%253B%2520temp.style.border%2520%253D%2520'none'%253B%2520temp.style.fontSize%2520%253D%2520'10px'%253B%2520temp.innerHTML%2520%253D%2520'-'%253B%2520temp.addEventListener('click'%252C%2520()%2520%253D%253E%2520setWpm(-10))%253B%2520wpmCounter%2520%253D%2520temp1.appendChild(document.createElement('div'))%253B%2520wpmCounter.style.fontSize%2520%253D%2520'10px'%253B%2520wpmCounter.style.lineHeight%2520%253D%2520'10px'%253B%2520wpmCounter.style.height%2520%253D%2520'10px'%253B%2520wpmCounter.style.margin%2520%253D%2520'10px'%253B%2520wpmCounter.innerHTML%2520%253D%2520wpm%253B%2520temp%2520%253D%2520temp1.appendChild(document.createElement('button'))%253B%2520temp.style.background%2520%253D%2520'%2523eee'%253B%2520temp.style.color%2520%253D%2520'black'%253B%2520temp.style.border%2520%253D%2520'none'%253B%2520temp.style.fontSize%2520%253D%2520'10px'%253B%2520temp.innerHTML%2520%253D%2520'%252B'%253B%2520temp.addEventListener('click'%252C%2520()%2520%253D%253E%2520setWpm(10))%253B%2520inner.style.display%2520%253D%2520'inline-block'%253B%2520inner.style.transform%2520%253D%2520'translate(8%2525)'%253B%2520inner.innerHTML%2520%253D%2520'3'%253B%2520%257D%2520setTimeout(()%2520%253D%253E%2520inner.innerHTML%2520%253D%2520'2'%252C%2520200)%253B%2520setTimeout(()%2520%253D%253E%2520inner.innerHTML%2520%253D%2520'1'%252C%2520400)%253B%2520gtimeout%2520%253D%2520setTimeout(()%2520%253D%253E%2520nextWord(term.split('%2520').reverse())%252C%2520600)%253B%2520%257D)%253B%2520let%2520nextWord%2520%253D%2520(words)%2520%253D%253E%2520%257B%2520let%2520next%2520%253D%2520words.pop()%253B%2520if(next.length%2520%253C%25203%2520%2526%2526%2520words.length%2520%2526%2526%2520words%255Bwords.length%2520-%25201%255D.length%2520%253C%25206)%257B%2520next%2520%252B%253D%2520'%2520'%2520%252B%2520words.pop()%253B%2520%257D%2520inner.innerHTML%2520%253D%2520next%253B%2520let%2520duration%2520%253D%2520(1000%2520%252F%2520(wpm%2520%252F%252060))%2520*%2520((next.length%2520%252F%25205%2520-%25201)%2520*%25200.5%2520%252B%25201)%253B%2520let%2520timeout%2520%253D%2520setTimeout(()%2520%253D%253E%2520%257B%2520if(words.length)%257B%2520if(timeout%2520!%253D%253D%2520gtimeout)%257B%2520return%253B%2520%257D%2520nextWord(words)%253B%2520%257D%2520else%2520%257B%2520stop()%253B%2520%257D%2520%257D%252C%2520duration)%253B%2520gtimeout%2520%253D%2520timeout%253B%2520%257D%253B%2520stop%2520%253D%2520()%2520%253D%253E%2520%257B%2520clearTimeout(gtimeout)%253B%2520gtimeout%2520%253D%25200%253B%2520if(outer)%257B%2520try%257B%2520Array.from(document.getElementsByTagName('body'))%255B0%255D.removeChild(outer)%253B%2520%257D%2520catch(e)%257B%257D%2520outer%2520%253D%2520inner%2520%253D%2520undefined%253B%2520%257D%2520%257D%253B%257D)()%253B][speedread (drag me into the bookmark bar)]] 123 | 124 | [[file:speedread.js][Source]] 125 | -------------------------------------------------------------------------------- /Remove sticky and add red scrolling-indicator.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){ 2 | let i, elements = document.querySelectorAll('body *'); 3 | for (i = 0; i < elements.length; i++) { 4 | if (getComputedStyle(elements[i]).position === 'fixed' || 5 | getComputedStyle(elements[i]).position === 'sticky') { 6 | elements[i].parentNode.removeChild(elements[i]); 7 | } 8 | } 9 | 10 | let elem = Array.from(document.getElementsByTagName("body"))[0].appendChild(document.createElement('div')); 11 | elem.style.width = "100%"; 12 | elem.style.borderTop = "1px solid red"; 13 | elem.style.position = "absolute"; 14 | elem.style.top = "0px"; 15 | elem.style.opacity = "0"; 16 | elem.style.transition = "opacity 1000ms"; 17 | window.addEventListener('keydown', e => { 18 | if(e.code === "Space"){ 19 | elem.style.transition = ""; 20 | elem.style.top = 21 | (window.innerHeight + window.scrollY) + "px"; 22 | elem.style.opacity = "1"; 23 | setTimeout(function(){ 24 | elem.style.transition = "opacity 1000ms"; 25 | elem.style.opacity = "0"; 26 | }, 200); 27 | } 28 | }); 29 | }()) 30 | -------------------------------------------------------------------------------- /Remove sticky.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){ 2 | (function() { 3 | var i, elements = document.querySelectorAll('body *'); 4 | for (i = 0; i < elements.length; i++) { 5 | if (getComputedStyle(elements[i]).position === 'fixed' || getComputedStyle(elements[i]).position === 'sticky') { 6 | elements[i].parentNode.removeChild(elements[i]); 7 | } 8 | } 9 | })() 10 | })() -------------------------------------------------------------------------------- /YT - Streamchat improver.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){ 2 | let video = Array.from(document.getElementsByClassName("video-stream html5-main-video"))[0]; 3 | let chat = document.getElementById("chat"); 4 | 5 | chat.style.position = 'fixed'; 6 | chat.style.top = '60px'; 7 | chat.style.right = '5px'; 8 | chat.style.height = '754.1px'; 9 | 10 | video.style.left = '57.889px'; 11 | })() 12 | -------------------------------------------------------------------------------- /YT - speed - default.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){Array.from(document.getElementsByTagName('video')).forEach(vid => vid.playbackRate =0);}()) 2 | -------------------------------------------------------------------------------- /YT - speed - faster.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){Array.from(document.getElementsByTagName('video')).forEach(vid => vid.playbackRate *=1.25);}()) 2 | -------------------------------------------------------------------------------- /YT - speed - slower.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){Array.from(document.getElementsByTagName('video')).forEach(vid => vid.playbackRate *=0.8);}()) 2 | -------------------------------------------------------------------------------- /install.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuhl/bookmarklets/9754cd0c7d0cbe6b20b2a69577277da4f0a0ed6a/install.gif -------------------------------------------------------------------------------- /space-scroll.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuhl/bookmarklets/9754cd0c7d0cbe6b20b2a69577277da4f0a0ed6a/space-scroll.gif -------------------------------------------------------------------------------- /speedread.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuhl/bookmarklets/9754cd0c7d0cbe6b20b2a69577277da4f0a0ed6a/speedread.gif -------------------------------------------------------------------------------- /speedread.js: -------------------------------------------------------------------------------- 1 | javascript:(function(){ 2 | wpm = localStorage.getItem('___aotavnkoyayovfuy_WPM') || 250; 3 | 4 | let gtimeout = 0; 5 | let inner; 6 | let outer; 7 | let wpmCounter; 8 | 9 | let setWpm = (dif) => { 10 | wpm += dif; 11 | wpmCounter.innerHTML = wpm; 12 | localStorage.setItem('___aotavnkoyayovfuy_WPM', wpm); 13 | }; 14 | 15 | document.addEventListener('selectionchange', () => { 16 | let term = window.getSelection().toString(); 17 | stop(); 18 | if(term.length < 10){ 19 | return; 20 | } 21 | if(!outer){ 22 | outer = Array.from(document.getElementsByTagName('body'))[0].appendChild(document.createElement('div')); 23 | inner = outer.appendChild(document.createElement('div')); 24 | outer.style.position = 'fixed'; 25 | outer.style.top = 'calc(50% - 50px)'; 26 | outer.style.margin = 'auto'; 27 | outer.style.height = '100px'; 28 | outer.style.minWidth = '800px'; 29 | outer.style.background = '#f5f5f5'; 30 | outer.style.left = 'calc(50% - 400px)'; 31 | outer.style.fontSize = '70px'; 32 | outer.style.textAlign = 'center'; 33 | outer.style.lineHeight = '100px'; 34 | outer.style.flexDirection = 'row'; 35 | outer.style.justifyContent = 'center'; 36 | outer.style.alignItems = 'center'; 37 | outer.style.display = 'flex'; 38 | outer.style.borderTop = '3px solid'; 39 | outer.style.borderBottom = '3px solid'; 40 | outer.style.opacity = '0.97'; 41 | 42 | let temp = outer.appendChild(document.createElement('div')); 43 | temp.style.width = '3px'; 44 | temp.style.background = 'black'; 45 | temp.style.height = '7px'; 46 | temp.style.position = 'absolute'; 47 | temp.style.top = '0px'; 48 | temp.style.left = '50%'; 49 | 50 | temp = outer.appendChild(document.createElement('div')); 51 | temp.style.width = '3px'; 52 | temp.style.background = 'black'; 53 | temp.style.height = '7px'; 54 | temp.style.position = 'absolute'; 55 | temp.style.bottom = '0px'; 56 | temp.style.left = '50%'; 57 | 58 | let temp1 = outer.appendChild(document.createElement('div')); 59 | temp1.style.position = 'absolute'; 60 | temp1.style.left = '10px'; 61 | temp1.style.flexDirection = 'row'; 62 | temp1.style.display = 'flex'; 63 | temp1.style.alignItems = 'center'; 64 | temp1.style.top = '5px'; 65 | 66 | temp = temp1.appendChild(document.createElement('button')); 67 | temp.style.background = '#eee'; 68 | temp.style.color = 'black'; 69 | temp.style.border = 'none'; 70 | temp.style.fontSize = '10px'; 71 | temp.innerHTML = '-'; 72 | temp.addEventListener('click', () => setWpm(-10)); 73 | 74 | wpmCounter = temp1.appendChild(document.createElement('div')); 75 | wpmCounter.style.fontSize = '10px'; 76 | wpmCounter.style.lineHeight = '10px'; 77 | wpmCounter.style.height = '10px'; 78 | wpmCounter.style.margin = '10px'; 79 | wpmCounter.innerHTML = wpm; 80 | 81 | temp = temp1.appendChild(document.createElement('button')); 82 | temp.style.background = '#eee'; 83 | temp.style.color = 'black'; 84 | temp.style.border = 'none'; 85 | temp.style.fontSize = '10px'; 86 | temp.innerHTML = '+'; 87 | temp.addEventListener('click', () => setWpm(10)); 88 | 89 | inner.style.display = 'inline-block'; 90 | inner.style.transform = 'translate(8%)'; 91 | 92 | inner.innerHTML = '3'; 93 | } 94 | setTimeout(() => inner.innerHTML = '2', 200); 95 | setTimeout(() => inner.innerHTML = '1', 400); 96 | gtimeout = setTimeout(() => nextWord(term.split(' ').reverse()), 600); 97 | }); 98 | 99 | let nextWord = (words) => { 100 | let next = words.pop(); 101 | if(next.length < 3 && words.length && words[words.length - 1].length < 6){ 102 | next += ' ' + words.pop(); 103 | } 104 | inner.innerHTML = next; 105 | let duration = (1000 / (wpm / 60)) * ((next.length / 5 - 1) * 0.5 + 1); 106 | let timeout = setTimeout(() => { 107 | if(words.length){ 108 | if(timeout !== gtimeout){ 109 | return; 110 | } 111 | nextWord(words); 112 | } else { 113 | stop(); 114 | } 115 | }, duration); 116 | gtimeout = timeout; 117 | }; 118 | 119 | stop = () => { 120 | clearTimeout(gtimeout); 121 | gtimeout = 0; 122 | if(outer){ 123 | try{ 124 | Array.from(document.getElementsByTagName('body'))[0].removeChild(outer); 125 | } catch(e){} 126 | outer = inner = undefined; 127 | } 128 | }; 129 | })(); 130 | -------------------------------------------------------------------------------- /yt-chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuhl/bookmarklets/9754cd0c7d0cbe6b20b2a69577277da4f0a0ed6a/yt-chat.gif --------------------------------------------------------------------------------