1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5var timeoutId; 6var ttsId = -1; 7var ttsWindow; 8var milliseconds; 9var curOptions; 10 11function areNewOptions(options) { 12 var properties = ['voiceName', 'lang', 'gender', 'rate', 'pitch', 'volume']; 13 14 for (var i = 0; i < properties.length; ++i) { 15 if (options[properties[i]] != curOptions[properties[i]]) { 16 return true; 17 } 18 } 19 20 return false; 21} 22 23function getTtsElement(element) { 24 return ttsWindow.document.getElementById(element); 25} 26 27function appendText(text) { 28 getTtsElement("text").innerHTML += text; 29} 30 31function logOptions() { 32 getTtsElement("voiceName").innerHTML = curOptions.voiceName; 33 getTtsElement("lang").innerHTML = curOptions.lang; 34 getTtsElement("gender").innerHTML = curOptions.gender; 35 getTtsElement("rate").innerHTML = curOptions.rate; 36 getTtsElement("pitch").innerHTML = curOptions.pitch; 37 getTtsElement("volume").innerHTML = curOptions.volume; 38} 39 40function logUtterance(utterance, index, sendTtsEvent) { 41 if (index == utterance.length) { 42 sendTtsEvent({'type': 'end', 'charIndex': utterance.length}); 43 return; 44 } 45 46 appendText(utterance[index]); 47 48 if (utterance[index] == ' ') { 49 sendTtsEvent({'type': 'word', 'charIndex': index}); 50 } 51 else if (utterance[index] == '.' || 52 utterance[index] == '?' || 53 utterance[index] == '!') { 54 sendTtsEvent({'type': 'sentence', 'charIndex': index}); 55 } 56 57 timeoutId = setTimeout(function() { 58 logUtterance(utterance, ++index, sendTtsEvent) 59 }, milliseconds); 60} 61 62var speakListener = function(utterance, options, sendTtsEvent) { 63 clearTimeout(timeoutId); 64 65 sendTtsEvent({'type': 'start', 'charIndex': 0}); 66 67 if (ttsId == -1) { 68 // Create a new window that overlaps the bottom 40% of the current window 69 chrome.windows.getCurrent(function(curWindow) { 70 chrome.windows.create( 71 {"url": "console_tts_engine.html", 72 "focused": false, 73 "top": Math.round(curWindow.top + 6/10 * curWindow.height), 74 "left": curWindow.left, 75 "width": curWindow.width, 76 "height": Math.round(4/10 * curWindow.height)}, 77 function(newWindow) { 78 ttsId = newWindow.id; 79 ttsWindow = chrome.extension.getViews({"windowId": ttsId})[0]; 80 81 curOptions = options; 82 logOptions(); 83 84 // Fastest timeout == 1 ms (@ options.rate = 10.0) 85 milliseconds = 10 / curOptions.rate; 86 logUtterance(utterance, 0, sendTtsEvent); 87 } 88 ); 89 }); 90 } else { 91 if (areNewOptions(options)) { 92 curOptions = options; 93 logOptions(); 94 95 milliseconds = 10 / curOptions.rate; 96 } 97 98 logUtterance(utterance, 0, sendTtsEvent); 99 } 100 101}; 102 103var stopListener = function() { 104 clearTimeout(timeoutId); 105}; 106 107var removedListener = function(windowId, removeInfo) { 108 if (ttsId == windowId) { 109 ttsId = -1; 110 } 111} 112 113chrome.ttsEngine.onSpeak.addListener(speakListener); 114chrome.ttsEngine.onStop.addListener(stopListener); 115chrome.windows.onRemoved.addListener(removedListener); 116