18ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen/*
28ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen * Content script for Chrome Sounds.
38ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen * Tracks in-page events and notifies the background page.
48ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen */
58ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
68ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction sendEvent(event, value) {
78ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  console.log("sendEvent: " + event + "," + value);
88ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  chrome.extension.sendRequest({eventName: event, eventValue: value});
98ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Timers to trigger "stopEvent" for coalescing events.
128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar timers = {};
138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction stopEvent(type) {
158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  timers[type] = 0;
168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  sendEvent(type, "stopped");
178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Automatically coalesces repeating events into a start and a stop event.
208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// |validator| is a function which should return true if the event is
218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// considered to be a valid event of this type.
228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction handleEvent(event, type, validator) {
238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (validator) {
248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    if (!validator(event)) {
258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen      return;
268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    }
278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var timerId = timers[type];
298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  var eventInProgress = (timerId > 0);
308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (eventInProgress) {
318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    clearTimeout(timerId);
328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    timers[type] = 0;
338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  } else {
348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    sendEvent(type, "started");
358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }
368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  timers[type] = setTimeout(stopEvent, 300, type);
378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenfunction listenAndCoalesce(target, type, validator) {
408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  target.addEventListener(type, function(event) {
418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    handleEvent(event, type, validator);
428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  }, true);
438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
458ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenlistenAndCoalesce(document, "scroll");
468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// For some reason, "resize" doesn't seem to work with addEventListener.
488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenif ((window == window.top) && document.body && !document.body.onresize) {
498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  document.body.onresize = function(event) {
508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    sendEvent("resize", "");
518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  };
528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
548ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenlistenAndCoalesce(document, "keypress", function(event) {
558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  if (event.charCode == 13)
568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return false;
578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  // TODO(erikkay) This doesn't work in gmail's rich text compose window.
598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  return event.target.tagName == "TEXTAREA" ||
608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         event.target.tagName == "INPUT" ||
618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         event.target.isContentEditable;
628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen});
63