| <!DOCTYPE html> |
| <!-- |
| | Test the SpeechSynthesis interface. |
| --> |
| <html> |
| <head> |
| <style> |
| body { |
| background-color: #FFFFFF; |
| } |
| </style> |
| <script> |
| var on_voices_changed_event_count = 0; |
| function log_info(message) { |
| console.log(message); |
| document.getElementById('info').innerHTML += message + '.\n'; |
| } |
| function log_error(message) { |
| console.log(message); |
| document.getElementById('error').innerHTML += message + '.\n'; |
| } |
| function assert(condition, message) { |
| if (!condition) { log_error('ASSERT: ' + message + '.'); } |
| } |
| function SaySomething(voice) { |
| var unheard_utterance_text = 'You Should Not Hear This.'; |
| var utterance_text = 'Cobalt can talk.'; |
| var final_utterance_text = 'It really can!'; |
| |
| var utterance = new SpeechSynthesisUtterance(unheard_utterance_text); |
| assert(utterance, 'new SpeechSynthesisUtterance failed'); |
| assert(typeof utterance != undefined, |
| 'new SpeechSynthesisUtterance undefined'); |
| assert(utterance.text === unheard_utterance_text, |
| 'SpeechSynthesisUtterance doesn\'t get text from constructor'); |
| |
| assert(utterance.onstart !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define start event handler'); |
| assert(utterance.onend !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define end event handler'); |
| assert(utterance.onpause !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define pause event handler'); |
| assert(utterance.onresume !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define resume event handler'); |
| assert(utterance.onmark !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define mark event handler'); |
| utterance.onmark = function(e) { log_info('SpeechSynthesisUtterance onmark called for: ' + e.utterance.text); } |
| assert(utterance.onboundary !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define boundary event handler'); |
| utterance.onboundary = function(e) { log_info('SpeechSynthesisUtterance onboundary called for: ' + e.utterance.text); } |
| |
| assert(utterance.voice !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define voice attribute'); |
| assert(typeof utterance.voice !== 'SpeechSynthesisVoice', |
| 'SpeechSynthesisUtterance voice isn\'t of type SpeechSynthesisVoice'); |
| utterance.voice = voice; |
| |
| assert(utterance.volume !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define volume attribute'); |
| utterance.volume = 1.0; |
| |
| assert(utterance.rate !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define rate attribute'); |
| utterance.rate = 1.0; |
| |
| assert(utterance.pitch !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define pitch attribute'); |
| utterance.pitch = 1.0; |
| |
| assert(utterance.onerror !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define error event handler'); |
| utterance.onerror = function(e) { log_info('SpeechSynthesisUtterance onerror called as expected with: ' + e.error); } |
| |
| assert(utterance.lang !== undefined, |
| 'SpeechSynthesisUtterance doesn\'t define lang attribute'); |
| utterance.lang = "Martian is not a language"; |
| |
| utterance.onstart = function(e) { log_error('SpeechSynthesisUtterance onstart called for: ' + e.utterance.text); } |
| utterance.onend = function(e) { log_error('SpeechSynthesisUtterance onend called for: ' + e.utterance.text); } |
| utterance.onpause = function(e) { log_error('SpeechSynthesisUtterance onpause called for: ' + e.utterance.text); } |
| utterance.onresume = function(e) { log_error('SpeechSynthesisUtterance onresume called for: ' + e.utterance.text); } |
| |
| assert(speechSynthesis.speak !== undefined, |
| 'SpeechSynthesis doesn\'t define speak'); |
| speechSynthesis.speak(utterance); |
| |
| utterance.lang = voice.lang; |
| |
| assert(speechSynthesis.pause !== undefined, |
| 'SpeechSynthesis doesn\'t define pause'); |
| speechSynthesis.pause(); |
| |
| // These will be canceled below. They will not be heard. |
| speechSynthesis.speak(utterance); |
| speechSynthesis.speak(utterance); |
| speechSynthesis.speak(utterance); |
| |
| utterance.onerror = function(e) { log_error('SpeechSynthesisUtterance onerror called as with: ' + e.error); } |
| |
| assert(speechSynthesis.cancel !== undefined, |
| 'SpeechSynthesis doesn\'t define cancel'); |
| speechSynthesis.cancel(); |
| assert(speechSynthesis.resume !== undefined, |
| 'SpeechSynthesis doesn\'t define resume'); |
| speechSynthesis.resume(); |
| speechSynthesis.pause(); |
| |
| utterance.text = utterance_text; |
| utterance.onstart = function(e) { log_info('SpeechSynthesisUtterance onstart called for: ' + e.utterance.text); } |
| utterance.onend = function(e) { log_info('SpeechSynthesisUtterance onend called for: ' + e.utterance.text); } |
| |
| assert(utterance.text === utterance_text, |
| 'SpeechSynthesisUtterance text doesn\'t get text updated'); |
| speechSynthesis.speak(utterance); |
| |
| utterance.text = final_utterance_text; |
| utterance.onstart = function(e) { log_info('SpeechSynthesisUtterance onstart called again for: ' + e.utterance.text); } |
| utterance.onend = function(e) { log_info('SpeechSynthesisUtterance onend called again for: ' + e.utterance.text); } |
| |
| speechSynthesis.resume(); |
| log_info('You should hear \"' + utterance_text + '\" being spoken (once), with onstart and onend calls'); |
| |
| speechSynthesis.speak(utterance); |
| log_info('You should hear \"' + final_utterance_text + '\" being spoken (once), with onstart and onend calls'); |
| } |
| function onVoicesChanged() { |
| if (on_voices_changed_event_count) { |
| console.log('Note: onVoicesChanged called more than once.'); |
| return; |
| } |
| ++on_voices_changed_event_count; |
| |
| assert(speechSynthesis.getVoices !== undefined, |
| 'SpeechSynthesis doesn\'t define getVoices'); |
| |
| var voices = speechSynthesis.getVoices(); |
| assert(voices, 'SpeechSynthesis.getVoices() returned nothing'); |
| assert(typeof voices !== undefined, |
| 'SpeechSynthesis.getVoices() returned undefined type'); |
| |
| document.getElementById('voice_count').innerHTML = voices.length; |
| assert(voices.length > 0, |
| 'SpeechSynthesis.getVoices() returned no voices'); |
| |
| var voice = voices[0]; |
| assert(voice, 'First voice element is nothing'); |
| assert(typeof voice !== undefined, |
| 'First voice element is of undefined type'); |
| |
| assert(voice.name !== undefined, 'Voice does not have a name attribute'); |
| assert(voice.lang !== undefined, |
| 'Voice does not have a language attribute'); |
| assert(voice.lang.length > 0, |
| 'Voice has an empty language attribute string'); |
| assert(voice.voiceURI !== undefined, |
| 'Voice does not have a URI attribute'); |
| assert(voice.localService !== undefined, |
| 'Voice does not have a localservice attribute'); |
| assert(voice.default !== undefined, |
| 'Voice does not have a default attribute'); |
| var voice_data = 'name=\'' + voice.name + '\' ' + |
| 'lang=\'' + voice.lang + '\' ' + |
| 'URI=\'' + voice.voiceURI + '\' ' + |
| 'local=' + voice.localService + ' ' + |
| 'default=' + voice.default; |
| |
| document.getElementById('voice_data').innerHTML = voice_data; |
| SaySomething(voice); |
| } |
| window.onload = function() { |
| |
| document.getElementById('lang').innerHTML = navigator.language; |
| |
| assert(window.speechSynthesis !== undefined, |
| 'window.SpeechSynthesis doesn\'t exist'); |
| assert(speechSynthesis, 'SpeechSynthesis doesn\'t exist'); |
| assert(typeof speechSynthesis !== undefined, |
| 'SpeechSynthesis is of undefined type'); |
| assert(speechSynthesis === window.speechSynthesis, |
| 'SpeechSynthesis doesn\'t match window.SpeechSynthesis'); |
| |
| assert(speechSynthesis.onvoiceschanged !== undefined, |
| 'SpeechSynthesis doesn\'t define voiceschanged event handler'); |
| speechSynthesis.onvoiceschanged = onVoicesChanged; |
| |
| assert(speechSynthesis.pending !== undefined, |
| 'SpeechSynthesis does not define pending attribute'); |
| assert(speechSynthesis.speaking !== undefined, |
| 'SpeechSynthesis does not define speaking attribute'); |
| assert(speechSynthesis.paused !== undefined, |
| 'SpeechSynthesis does not define paused attribute'); |
| |
| window.setTimeout(function() { |
| if (!on_voices_changed_event_count) { |
| log_error('ERROR: onVoicesChanged never called!'); |
| } |
| }, 333); |
| } |
| </script> |
| </head> |
| <body> |
| <div>Speech Synthesis Test |
| <div>Document Language: <span id='lang'>-</div> |
| <div>Voice Count: <span id='voice_count'>-</div> |
| <div>Voice Data: <span id='voice_data'>-</div> |
| <span id='error' style='white-space: pre; color:#FFFFFF; background-color:#FF0000'></span> |
| <span id='info' style='white-space: pre; background-color:#00FF00'></span> |
| <div> |
| </div> |
| </body> |
| </html> |