This is a user script for Chrome. It provides hotkeys for two modes of dictation (replacement and insertion).
The included shell script was used when I was looking at doing this with a bookmarklet.
This is a user script for Chrome. It provides hotkeys for two modes of dictation (replacement and insertion).
The included shell script was used when I was looking at doing this with a bookmarklet.
#!/bin/bash | |
nodejs <<- EOF | |
var compressor = require('node-minify'); | |
// Using Google Closure Compiler | |
compressor.minify({ | |
compressor: 'gcc', | |
input: 'voice.js', | |
output: 'out.js', | |
callback: function (err, min) { | |
// console.log(min); | |
console.log(err); | |
} | |
}); | |
EOF | |
echo 'javascript:' | cat - out.js | tr -d '\n' | xsel -ib | |
echo 'javascript:' | cat - out.js | tr -d '\n' |
(function(){ | |
function buildRecognition() { | |
var recognition = new webkitSpeechRecognition(); | |
recognition.isOn = false; | |
recognition.continuous = false; | |
recognition.interimResults = false; | |
return recognition; | |
} | |
var recognition = buildRecognition(); | |
function extractTranscript(event) { | |
var transcript = ''; | |
for (var i = event.resultIndex; i < event.results.length; ++i) { | |
transcript += event.results[i][0].transcript; | |
} | |
return transcript || ''; | |
} | |
function dictate(input, onresult) { | |
if (recognition.isOn) { | |
recognition.stop(); | |
} | |
else { | |
recognition.onresult = onresult; | |
recognition.onstart = function onstart(event) { | |
input.style.background = '#dfd'; | |
recognition.isOn = true; | |
}; | |
recognition.onend = function onend(event) { | |
input.style.background = input.origBg || ''; | |
recognition.isOn = false; | |
}; | |
recognition.start(); | |
} | |
} | |
function replaceText(input) { | |
dictate(input, function(event) { | |
input.value = extractTranscript(event); | |
}); | |
} | |
function replaceTextFocused() { | |
replaceText(document.activeElement); | |
} | |
function insertText(input) { | |
dictate(input, function(event) { | |
var t = input.value || ''; | |
var d = extractTranscript(event); | |
var i = input.selectionStart; | |
input.value = t.slice(0, i) + d + t.slice(i); | |
input.selectionStart = i + d.length; | |
input.selectionEnd = i + d.length; | |
}); | |
} | |
var textareas = Array.prototype.slice.call(document.getElementsByTagName('textarea')); | |
var textinputs = Array.prototype.slice.call(document.getElementsByTagName('input')).filter(function (o) { | |
return o.type == 'text' || !o.type; | |
}); | |
var els = textinputs.concat(textareas); | |
for (var i in els) { | |
var e = els[i]; | |
if (!e.style) continue; | |
e.onkeypress = function(evt) { | |
if (evt.ctrlKey && evt.which == 14) | |
replaceText(this); | |
else if (evt.ctrlKey && evt.which == 12) | |
insertText(this); | |
else | |
console.log('key', evt.which); | |
}; | |
console.log(e); | |
e.origBg = e.style.background; | |
} | |
// Add access to fns from global namespace | |
var script = document.createElement('script'); | |
script.appendChild(document.createTextNode('(function(){' | |
+ 'var buildRecognition = ' + buildRecognition + ';' | |
+ 'var recognition = buildRecognition();' | |
+ 'var extractTranscript = ' + extractTranscript + ';' | |
+ 'var dictate = ' + dictate + ';' | |
+ 'var replaceText = ' + replaceText + ';' | |
+ 'window.replaceTextFocused = ' + replaceTextFocused + ';' | |
+ 'var insertText = ' + insertText + ';' | |
+ '})();')); | |
(document.body || document.head || document.documentElement).appendChild(script); | |
console.log('userscript loaded 10'); | |
})(); |