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