- // ==UserScript==
- // @name toMorse
- // @description Plays selected text as morse code.
- // @namespace https://greasyfork.org/en/users/11891-qon
- // @author Qon
- // @include *
- // @compatible firefox
- // @compatible chrome
- // @grant GM_getValue
- // @grant GM_setValue
- // @license Simple Public License 2.0 (SimPL) https://tldrlegal.com/license/simple-public-license-2.0-%28simpl%29
- // @version 0.0.1.20150723034148
- // ==/UserScript==
-
- /*
- TODO
- Split text into smaller parts and play and request one after another.
- */
-
- var settSc = {}
- settSc['tm-refresh'] = 0
- settSc['tm-stop'] = 0
- settSc['tm-key'] = 'm1000'
-
- var settCw = {}
- settCw['cwpm'] = {def: 20, val: 20, min: 1, max: 100, label: 'Letter WPM', description: 'cwpm'}
- settCw['ewpm'] = {def: 20, val: 20, min: 1, max: 100, label: 'Effective WPM', description: 'ewpm'}
- settCw['tone'] = {def: 800, val: 800, min: 200, max: 3200, label: 'Tone frequency', description: 'tone'}
- settCw['vol'] = {def: 100, val: 100, min: 0, max: 100, label: 'Volume', description: 'volume'}
-
- var currentAudio = null
-
- function refresh() {
- var old = settSc['tm-refresh']['val']
- var nuw = GM_getValue('tm-refresh', 1)
- if (old != nuw) {
- settSc['tm-refresh'] = nuw
- settSc['tm-stop'] = GM_getValue('tm-stop', settSc['tm-stop'])
- settSc['tm-key'] = GM_getValue('tm-key', settSc['tm-key'])
- for (var key in settCw) {
- if(settCw.hasOwnProperty(key)) {
- settCw[key]['val'] = GM_getValue(key, settCw[key]['val'])
- }
- }
- }
- }
- refresh()
-
- function signalNeedRefresh() {
- var o = GM_getValue('tm-refresh', 1)
- GM_setValue('tm-refresh', o+1)
- }
-
- function evToKeystoreformat(ev) {
- return ev.key.toLowerCase()+(ev.ctrlKey+1-1)+(ev.shiftKey+1-1)+(ev.altKey+1-1)+(ev.metaKey+1-1)
- }
-
- function dotdashToAbc(s) {
- var r = ''
- var atd = {}
- // atd['prosign_error']="........";
- atd[' ']="/";
- atd['a']=".-"; atd['b']="-..."; atd['c']="-.-."; atd['d']="-.."; atd['e']="."; atd['f']="..-."; atd['g']="--."; atd['h']="...."; atd['i']=".."; atd['j']=".---"; atd['k']="-.-"; atd['l']=".-.."; atd['m']="--"; atd['n']="-."; atd['o']="---"; atd['p']=".--."; atd['q']="--.-"; atd['r']=".-."; atd['s']="..."; atd['t']="-"; atd['u']="..-"; atd['v']="...-"; atd['w']=".--"; atd['x']="-..-"; atd['y']="-.--"; atd['z']="--..";
- atd['1']=".----"; atd['2']="..---"; atd['3']="...--"; atd['4']="....-"; atd['5']="....."; atd['6']="-...."; atd['7']="--..."; atd['8']="---.."; atd['9']="----."; atd['0']="-----"; atd['.']=".-.-.-";
- atd[',']="--..--"; atd['?']="..--.."; atd['!']="-.-.--"; atd[':']="---..."; atd['=']="-...-"; atd['+']=".-.-."; atd['-']="-....-";
- var dta = {}
- for(var key in atd) {
- if (atd.hasOwnProperty(key)) {
- // console.log(key, atd[key])
- dta[atd[key]] = key[key.length-1] // just /*= key*/ doesn't work becuse for some reason "." becomes "." (invisible character and a dot). Same for several special chars.
- }
- }
-
- var a = s.split(' ')
- for(q of a) {
- if (q=='') continue;
- var c = dta[q]
- if(c) {
- r += c
- } else {
- r = prosign_error
- }
- }
- console.log(r)
- return r
- }
-
- function keypress (ev) {
- if (!ev) ev = window.event;
- if(!ev.key) {ev.key = String.fromCharCode(ev.which)}
- refresh()
- var s = evToKeystoreformat(ev)
- var k = settSc['tm-key']
- if (k == s) {
- var text = window.getSelection().toString()
- if(/[\s\.\-\/]+/.exec(text)==text){
- text = dotdashToAbc(text)
- }
- playTextLCWO(settCw['cwpm']['val'], settCw['ewpm']['val'], settCw['tone']['val'], settCw['vol']['val'], text)
- }
- }
- window.addEventListener("keydown", keypress);
-
- function playTextLCWO(charWpm, effectiveWpm, tone, volume, str) {
- // var prevAudio = document.getElementById('audioLCWO')
- if(currentAudio) {
- currentAudio.pause()
- currentAudio = null
- // currentAudio.remove()
- }
- if(str=='') {
- return
- }
- var audio = document.createElement('audio')
- audio.id = 'audioLCWO'
- audio.class = ''+settSc['tm-stop']
- audio.src = 'http://cgi2.lcwo.net/cgi-bin/cw.ogg?s='+charWpm+'&e='+effectiveWpm+'&f='+tone+'&t='+str
- audio.addEventListener('ended', function(){/*document.getElementById('audioLCWO').remove()*/currentAudio=null});
- // document.body.appendChild(audio)
- currentAudio = audio
- audio.volume = volume/100
- audio.play()
- function checkStop() {
- refresh()
- // var el = document.getElementById('audioLCWO')
- if(currentAudio) {
- if(currentAudio.class != ''+settSc['tm-stop']) {
- currentAudio.pause()
- currentAudio = null
- // currentAudio.remove()
- } else {
- currentAudio.volume = settCw['vol']['val']/100
- setTimeout(checkStop, 300)
- }
- }
- }
- setTimeout(checkStop, 300)
- }
-
- /*
- * The settings form.
- * Only loads on the scripts home page on greasyfork.
- */
- if (document.location == 'https://greasyfork.org/en/scripts/11117-tomorse') {
- var settingsdiv = document.createElement('div');
- settingsdiv.id = 'tomorse-settings'
- var h3 = document.createElement('h3')
- h3.innerHTML = 'Script Settings'
- h3.style.marginBottom = '0'
- h3.style.paddingBottom = '0'
- settingsdiv.appendChild(h3)
- var qontdiv = document.createElement('div');
- qontdiv.style.padding = '1em'
- qontdiv.style.margin = '0'
- qontdiv.style.background = '#E6FFE6'
- var setform = document.createElement('form');
-
- function setting(name, variable, decription) {
- var span = document.createElement('span')
- span.innerHTML = name+': '
- var inpN = document.createElement('input')
- inpN.id = 'input-'+variable
- inpN.name = variable
- inpN.type = 'number'
- inpN.value = settCw[variable]['val']
- var inpRange = document.createElement('input')
- inpRange.id = 'input-range-'+variable
- inpRange.name = variable
- inpRange.type = 'range'
- inpRange.min = settCw[variable]['min']
- inpRange.max = settCw[variable]['max']
- inpRange.value = settCw[variable]['val']
- f = function(ev){
- var el = ev.target
- var inte = parseInt(el.value)
- GM_setValue(el.name, inte)
- settCw[el.name]['val'] = inte
- document.getElementById('input-range-'+el.name).value = inte
- document.getElementById('input-'+el.name).value = inte
- if(el.name == 'cwpm' && document.getElementById('wpm-link').checked) {
- document.getElementById('input-range-'+'ewpm').value = inte
- document.getElementById('input-'+'ewpm').value = inte
- GM_setValue('ewpm', inte)
- settCw['ewpm']['val'] = inte
- }
- signalNeedRefresh()
- }
- inpN.addEventListener('input', f)
- inpRange.addEventListener('input', f)
- setform.appendChild(span)
- setform.appendChild(inpN)
- setform.appendChild(inpRange)
- setform.appendChild(document.createElement('br'))
- }
-
- for(var key in settCw) {
- if(settCw.hasOwnProperty(key)) {
- setting(settCw[key]['label'], key, settCw[key]['description'])
- }
- }
- var box = document.createElement('input')
- box.id = 'wpm-link'
- box.checked = true
- box.type = 'checkbox'
- var linkSpan = document.createElement('span')
- linkSpan.innerHTML = 'Copy value to "Effective WPM"'
- linkSpan.style.fontSize = '75%'
- linkSpan.style.marginLeft = '100px'
- setform.insertBefore(linkSpan, setform.getElementsByTagName('br')[0])
- setform.insertBefore(box, setform.getElementsByTagName('br')[0])
- // var reset = document.createElement('input')
- // reset.type = 'reset'
- // setform.appendChild(reset)
- var span = document.createElement('span')
- span.innerHTML = 'Hotkey: '
- var key = document.createElement('input')
- key.type = 'text'
- // key.readonly = true // doesn't work :/
- key.id = 'tm-key-field'
- function keystoreformatToString(s) {
- var l = s.length
- var r = (s[l-4]=='1'?'ctrl+':'')+(s[l-3]=='1'?'shift+':'')+(s[l-2]=='1'?'alt+':'')+(s[l-1]=='1'?'meta+':'')
- var e = s.slice(0, -4)
- if(e == 'control' || e == 'shift' || e == 'alt' || e == 'meta') {
- return r.slice(0,-1)
- }
- return r+e
- }
- function evToString(ev) {
- var r = (ev.ctrlKey?'ctrl+':'')+(ev.shiftKey?'shift+':'')+(ev.altKey?'alt+':'')+(ev.metaKey?'meta+':'')
- if (/[a-zA-Z\d]/.exec(ev.key)==ev.key) {
- if(r!='shift+' && r!='') {
- r += ev.key
- }
- } else if (ev.key.length==1 && !ev.ctrlKey && ev.which!=16) {
- r = ''
- } else if (ev.key.toLowerCase()=='backspace' && !ev.ctrlKey) {
- r += 'backspace '
- } else if (ev.key=='Control' || ev.key=='Shift' || ev.key == 'Alt' || ev.which==16 || ev.which==17 || ev.which==18) {
- r = r.slice(0, -1)
- } else {
- r += ev.key.toLowerCase()
- }
- return r
- }
- key.value = keystoreformatToString(settSc['tm-key'], false)
- key.addEventListener('keydown', function(ev){
- if (!ev) ev = window.event;
- if(!ev.key) {ev.key = String.fromCharCode(ev.which)}
- var el = ev.target
- GM_setValue('tm-key', evToKeystoreformat(ev))
- el.value = evToString(ev)
- signalNeedRefresh()
- })
- key.addEventListener('keyup', function (ev) {
- if(!(ev.key=='Control' || ev.key=='Shift' || ev.key == 'Alt')) {
- ev.target.blur()
- }
- })
- setform.appendChild(span)
- setform.appendChild(key)
- var stopSpan = document.createElement('span')
- stopSpan.innerHTML = 'Stop playing morse audio in all tabs: '
- var stop = document.createElement('input')
- stop.type = 'button'
- stop.value = 'Stop!'
- stop.addEventListener('click', function (ev) {
- GM_setValue('tm-stop', 1-GM_getValue('tm-stop', 0))
- signalNeedRefresh()
- })
- setform.appendChild(document.createElement('br'))
- setform.appendChild(stopSpan)
- setform.appendChild(stop)
- // var stopSpan = document.createElement('span')
- // stopSpan.innerHTML = ' (in case you can\'t find the right one because you have too many tabs!)'
- // stopSpan.style.fontSize = '75%'
- // setform.appendChild(stopSpan)
-
- document.getElementById('script-content').insertBefore(settingsdiv, document.getElementById('share'))
- qontdiv.appendChild(setform)
- settingsdiv.appendChild(qontdiv)
- }