18ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen/*
28ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen * Background page for Chrome Sounds extension.
38ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen * This tracks various events from Chrome and plays sounds.
48ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen */
58ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
68ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of hostname suffixes or URLs without query params to sounds.
78ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Yeah OK, some of these are a little cliche...
88ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar urlSounds = {
98ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.google.ca/": "canadian-hello.mp3",
108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "about:histograms": "time-passing.mp3",
118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "about:memory": "transform!.mp3",
128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "about:crash": "sadtrombone.mp3",
138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "chrome://extensions/": "beepboop.mp3",
148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.google.com.au/": "didgeridoo.mp3",
158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.google.com.my/": "my_subway.mp3",
168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.google.com/appserve/fiberrfi/": "dialup.mp3",
178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "lively.com": "cricket.mp3",
188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.google.co.uk/": "mind_the_gap.mp3",
198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://news.google.com/": "news.mp3",
208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "http://www.bing.com/": "sonar.mp3",
218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of query parameter words to sounds.
248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// More easy cliches...
258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar searchSounds = {
268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "scotland": "bagpipe.mp3",
278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "seattle": "rain.mp3",
288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of tab numbers to notes on a scale.
318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar tabNoteSounds = {
328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab0": "mando-1.mp3",
338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab1": "mando-2.mp3",
348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab2": "mando-3.mp3",
358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab3": "mando-4.mp3",
368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab4": "mando-5.mp3",
378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab5": "mando-6.mp3",
388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tab6": "mando-7.mp3",
398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of sounds that play in a continuous loop while an event is happening
428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// in the content area (e.g. "keypress" while start and keep looping while
438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// the user keeps typing).
448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar contentSounds = {
458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "keypress": "typewriter-1.mp3",
468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "resize": "harp-transition-2.mp3",
478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "scroll": "shepard.mp3"
488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of events to their default sounds
518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar eventSounds = {
528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabCreated": "conga1.mp3",
538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabMoved": "bell-transition.mp3",
548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabRemoved": "smash-glass-1.mp3",
558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabSelectionChanged": "click.mp3",
568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabAttached": "whoosh-15.mp3",
578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabDetached": "sword-shrill.mp3",
588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabNavigated": "click.mp3",
598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowCreated": "bell-small.mp3",
608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowFocusChanged": "click.mp3",
618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkCreated": "bubble-drop.mp3",
628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkMoved": "thud.mp3",
638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkRemoved": "explosion-6.mp3",
648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowCreatedIncognito": "weird-wind1.mp3",
658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "startup": "whoosh-19.mp3"
668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar soundLists = [urlSounds, searchSounds, eventSounds, tabNoteSounds,
698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    contentSounds];
708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar sounds = {};
728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of event names to extension events.
748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Events intentionally skipped:
758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// chrome.windows.onRemoved - can't suppress the tab removed that comes first
768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar events = {
778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabCreated": chrome.tabs.onCreated,
788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabMoved": chrome.tabs.onMoved,
798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabRemoved": chrome.tabs.onRemoved,
808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabSelectionChanged": chrome.tabs.onSelectionChanged,
818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabAttached": chrome.tabs.onAttached,
828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabDetached": chrome.tabs.onDetached,
838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabNavigated": chrome.tabs.onUpdated,
848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowCreated": chrome.windows.onCreated,
858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowFocusChanged": chrome.windows.onFocusChanged,
868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkCreated": chrome.bookmarks.onCreated,
878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkMoved": chrome.bookmarks.onMoved,
888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "bookmarkRemoved": chrome.bookmarks.onRemoved
898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Map of event name to a validation function that is should return true if
928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// the default sound should be played for this event.
938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar eventValidator = {
948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabCreated": tabCreated,
958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabNavigated": tabNavigated,
968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabRemoved": tabRemoved,
978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "tabSelectionChanged": tabSelectionChanged,
988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowCreated": windowCreated,
998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  "windowFocusChanged": windowFocusChanged,
1008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen};
1018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar started = false;
1038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction shouldPlay(id) {
1058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // Ignore all events until the startup sound has finished.
1068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (id != "startup" && !started)
1078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
1088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var val = localStorage.getItem(id);
1098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (val && val != "enabled") {
1108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    console.log(id + " disabled");
1118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
1128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
1138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
1148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction didPlay(id) {
1178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (!localStorage.getItem(id))
1188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    localStorage.setItem(id, "enabled");
1198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction playSound(id, loop) {
1228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (!shouldPlay(id))
1238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return;
1248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var sound = sounds[id];
1268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("playsound: " + id);
1278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (sound && sound.src) {
1288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (!sound.paused) {
1298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      if (sound.currentTime < 0.2) {
1308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        console.log("ignoring fast replay: " + id + "/" + sound.currentTime);
1318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        return;
1328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      }
1338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      sound.pause();
1348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      sound.currentTime = 0;
1358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
1368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (loop)
1378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      sound.loop = loop;
1388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    // Sometimes, when playing multiple times, readyState is HAVE_METADATA.
1408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (sound.readyState == 0) {  // HAVE_NOTHING
1418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      console.log("bad ready state: " + sound.readyState);
1428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    } else if (sound.error) {
1438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      console.log("media error: " + sound.error);
1448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    } else {
1458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      didPlay(id);
1468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      sound.play();
1478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
1488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  } else {
1498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    console.log("bad playSound: " + id);
1508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
1518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction stopSound(id) {
1548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("stopSound: " + id);
1558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var sound = sounds[id];
1568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (sound && sound.src && !sound.paused) {
1578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    sound.pause();
1588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    sound.currentTime = 0;
1598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
1608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar base_url = "http://dl.google.com/dl/chrome/extensions/audio/";
1638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction soundLoadError(audio, id) {
1658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("failed to load sound: " + id + "-" + audio.src);
1668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.src = "";
1678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (id == "startup")
1688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    started = true;
1698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction soundLoaded(audio, id) {
1728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("loaded sound: " + id);
1738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  sounds[id] = audio;
1748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (id == "startup")
1758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    playSound(id);
1768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Hack to keep a reference to the objects while we're waiting for them to load.
1798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar notYetLoaded = {};
1808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction loadSound(file, id) {
1828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (!file.length) {
1838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    console.log("no sound for " + id);
1848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return;
1858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
1868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var audio = new Audio();
1878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.id = id;
1888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.onerror = function() { soundLoadError(audio, id); };
1898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.addEventListener("canplaythrough",
1908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      function() { soundLoaded(audio, id); }, false);
1918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (id == "startup") {
1928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    audio.addEventListener("ended", function() { started = true; });
1938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
1948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.src = base_url + file;
1958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  audio.load();
1968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  notYetLoaded[id] = audio;
1978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
1988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Remember the last event so that we can avoid multiple events firing
2008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// unnecessarily (e.g. selection changed due to close).
2018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar eventsToEat = 0;
2028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction eatEvent(name) {
2048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eventsToEat > 0) {
2058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    console.log("ate event: " + name);
2068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    eventsToEat--;
2078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return true;
2088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
2098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return false;
2108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
2118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction soundEvent(event, name) {
2138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (event) {
2148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    var validator = eventValidator[name];
2158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (validator) {
2168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      event.addListener(function() {
2178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        console.log("handling custom event: " + name);
2188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // Check this first since the validator may bump the count for future
2208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // events.
2218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        var canPlay = (eventsToEat == 0);
2228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (validator.apply(this, arguments)) {
2238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          if (!canPlay) {
2248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            console.log("ate event: " + name);
2258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            eventsToEat--;
2268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return;
2278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          }
2288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          playSound(name);
2298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        }
2308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      });
2318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    } else {
2328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      event.addListener(function() {
2338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        console.log("handling event: " + name);
2348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (eatEvent(name)) {
2358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          return;
2368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        }
2378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        playSound(name);
2388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      });
2398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
2408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  } else {
2418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    console.log("no event for " + name);
2428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
2438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
2448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar navSound;
2468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction stopNavSound() {
2488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (navSound) {
2498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    stopSound(navSound);
2508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    navSound = null;
2518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
2528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
2538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction playNavSound(id) {
2558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  stopNavSound();
2568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  navSound = id;
2578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  playSound(id);
2588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
2598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction tabNavigated(tabId, changeInfo, tab) {
2618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // Quick fix to catch the case where the content script doesn't have a chance
2628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // to stop itself.
2638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  stopSound("keypress");
2648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  //console.log(JSON.stringify(changeInfo) + JSON.stringify(tab));
2668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (changeInfo.status != "complete") {
2678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
2688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
2698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("tabNavigated")) {
2708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
2718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
2728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log(JSON.stringify(tab));
2748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (navSound)
2768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    stopSound(navSound);
2778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var re = /https?:\/\/([^\/:]*)[^\?]*\??(.*)/i;
2798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  match = re.exec(tab.url);
2808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (match) {
2818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (match.length == 3) {
2828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      var query = match[2];
2838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      var parts = query.split("&");
2848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      for (var i in parts) {
2858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (parts[i].indexOf("q=") == 0) {
2868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          var q = decodeURIComponent(parts[i].substring(2));
2878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          q = q.replace("+", " ");
2888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          console.log("query == " + q);
2898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          var words = q.split(" ");
2908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          for (j in words) {
2918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (searchSounds[words[j]]) {
2928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen              console.log("searchSound: " + words[j]);
2938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen              playNavSound(words[j]);
2948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen              return false;
2958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
2968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          }
2978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          break;
2988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        }
2998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      }
3008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
3018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (match.length >= 2) {
3028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      var hostname = match[1];
3038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      if (hostname) {
3048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        var parts = hostname.split(".");
3058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (parts.length > 1) {
3068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          var tld2 = parts.slice(-2).join(".");
3078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          var tld3 = parts.slice(-3).join(".");
3088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          var sound = urlSounds[tld2];
3098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          if (sound) {
3108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            playNavSound(tld2);
3118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return false;
3128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          }
3138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          sound = urlSounds[tld3];
3148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          if (sound) {
3158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            playNavSound(tld3);
3168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return false;
3178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen          }
3188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        }
3198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      }
3208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
3218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // Now try a direct URL match (without query string).
3248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var url = tab.url;
3258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var query = url.indexOf("?");
3268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (query > 0) {
3278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    url = tab.url.substring(0, query);
3288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log(tab.url);
3308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var sound = urlSounds[url];
3318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (sound) {
3328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    playNavSound(url);
3338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
3378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar selectedTabId = -1;
3408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction tabSelectionChanged(tabId) {
3428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  selectedTabId = tabId;
3438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("tabSelectionChanged"))
3448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var count = 7;
3478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  chrome.tabs.get(tabId, function(tab) {
3488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    var index = tab.index % count;
3498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    playSound("tab" + index);
3508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  });
3518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return false;
3528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction tabCreated(tab) {
3558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("tabCreated")) {
3568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  eventsToEat++;  // tabNavigated or tabSelectionChanged
3598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // TODO - unfortunately, we can't detect whether this tab will get focus, so
3608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // we can't decide whether or not to eat a second event.
3618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
3628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction tabRemoved(tabId) {
3658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("tabRemoved")) {
3668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (tabId == selectedTabId) {
3698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    eventsToEat++;  // tabSelectionChanged
3708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    stopNavSound();
3718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
3738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction windowCreated(window) {
3768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("windowCreated")) {
3778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  eventsToEat += 3;  // tabNavigated, tabSelectionChanged, windowFocusChanged
3808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (window.incognito) {
3818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    playSound("windowCreatedIncognito");
3828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
3858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar selectedWindowId = -1;
3888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction windowFocusChanged(windowId) {
3908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (windowId == selectedWindowId) {
3918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  selectedWindowId = windowId;
3948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eatEvent("windowFocusChanged")) {
3958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
3968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
3978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return true;
3988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
3998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction contentScriptHandler(request) {
4018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (contentSounds[request.eventName]) {
4028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (request.eventValue == "started") {
4038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      playSound(request.eventName, true);
4048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    } else if (request.eventValue == "stopped") {
4058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      stopSound(request.eventName);
4068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    } else {
4078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      playSound(request.eventName);
4088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
4098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
4108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("got message: " + JSON.stringify(request));
4118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
4128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen//////////////////////////////////////////////////////
4158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Listen for messages from content scripts.
4178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenchrome.extension.onRequest.addListener(contentScriptHandler);
4188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Load the sounds and register event listeners.
4208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfor (var list in soundLists) {
4218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  for (var id in soundLists[list]) {
4228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    loadSound(soundLists[list][id], id);
4238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
4248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
4258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfor (var name in events) {
4268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  soundEvent(events[name], name);
4278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
428