How to detect keyboard events in Gmail

I am writing a browser extension that needs to bind handlers to events with the keyboard and keydown on all pages. I can make it work very well with the following script code.

document.addEventListener("keydown",keyDown, true); document.addEventListener("keyup", keyUp, true); 

I can't get this to work in Gmail. In particular, I cannot get it to work when creating the body of a new letter. It will work wherever I tested. I think the problem is that Gmail calls stopPropagation on all keyboard events, but it's hard to debug their minimized code. I thought setting the third parameter to true would cause the event to be committed during CAPTURE_PHASE , but this does not work.

How can I capture keyup and keydown when creating a new organ in Gmail with Google Chrome script content?

Edit:

I made sure that my content scripts are injected into all iframes of the DOM by adding "all_frames": true, to my manifest. I even tried using the following code:

 document.addEventListener("DOMNodeInserted", function (event) { if(event.type === "DOMNodeInserted") { if(event.srcElement.nodeName === "IFRAME") { console.log(event.srcElement.nodeName + " iframe detected"); event.srcElement.addEventListener("keydown", function(kevent) { document.dispatchEvent(kevent); }, true); event.srcElement.addEventListener("keyup", function(kevent) { document.dispatchEvent(kevent); }, true); } } },true); 

This does not fix the problem with Gmail yet.

+3
source share
1 answer

Your code does not work because event.srcElement refers to the <iframe> element, not its contents. To access your content document, you need to wait for the frame to load ( onload or polling), then use frame.contentDocument to access the frame.

Starting with Chrome 37.0.1995.0, you can also use match_about_blank (with all_frames ) to insert the contents of the script into the about:blank frame, which captures the event and sends it to the parent content of the script.

Here is an example of implementing the original idea (using a survey):

Relevant parts of manifest.json :

  "content_scripts": [{ "matches": ["*://mail.google.com/*"], "js": ["contentscript.js"], "run_at": "document_end" }], 

contentscript.js

 function keyDown(e) {console.log(e.which);}; // Test function keyUp(e) {console.log(e.keyCode);}; // Test (function checkForNewIframe(doc) { if (!doc) return; // document does not exist. Cya // Note: It is important to use "true", to bind events to the capturing // phase. If omitted or set to false, the event listener will be bound // to the bubbling phase, where the event is not visible any more when // Gmail calls event.stopPropagation(). // Calling addEventListener with the same arguments multiple times bind // the listener only once, so we don't have to set a guard for that. doc.addEventListener('keydown', keyDown, true); doc.addEventListener('keyup', keyUp, true); doc.hasSeenDocument = true; for (var i = 0, contentDocument; i<frames.length; i++) { try { contentDocument = iframes[i].document; } catch (e) { continue; // Same-origin policy violation? } if (contentDocument && !contentDocument.hasSeenDocument) { // Add poller to the new iframe checkForNewIframe(iframes[i].contentDocument); } } setTimeout(checkForNewIframe, 250, doc; // <-- delay of 1/4 second })(document); // Initiate recursive function for the document. 

Note that I used polling instead of DOM mutation events, because the latter significantly reduces performance .

+6
source

All Articles