1

I am writing a Chrome extension which needs to be able to trigger keydown events at the document level of the target page. The target page has an event listener which uses javascript like:

document.addEventListener("keydown", function (event) {…});

My manifest.json is as follows:

{
    "manifest_version": 2,
    "name": "Title",
    "version": "1.0",

    "description": "Testing",
    "icons": {
        "default_icon": "icon.png"
    },

    "browser_action": {
        "default_title": "Title"
    },

    "author": "James McLaughlin",
    "background": {
        "scripts": ["jquery.js", "event.js"],
        "persistent": false
    },
    "permissions": ["<all_urls>"]
}

And my event.js:

function injectedMethod (tab, method, callback) {
    chrome.tabs.executeScript(tab.id, {file: 'jquery.js'}, function() {});
    chrome.tabs.executeScript(tab.id, {file: 'inject.js'}, function() {
        chrome.tabs.sendMessage(tab.id, {method: method}, callback);
    });
}

function run (tab) {
    injectedMethod(tab, 'run', function (response) {
        return true;
    });
}

chrome.browserAction.onClicked.addListener(run);

And my inject.js (I used one of the methods of JS injection available here because it seemed applicable:

var injected = injected || (function(){

    var methods = {};

    methods.run = function () {
    injectScript(function () {
        var e = jQuery.Event("keydown");
        e.which = 40;
        $(document).trigger(e);
    });
    }

    function injectScript(func) {
        var actualCode = '(' + func + ')();';
        var script = document.createElement('script');
        script.textContent = actualCode;
        (document.body||document.documentElement).appendChild(script);
        //script.parentNode.removeChild(script);
    }

    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
        $('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>').appendTo('head');
        var data = {};

        if (methods.hasOwnProperty(request.method))
        data = methods[request.method]();

        sendResponse({data:data});
        return true;
    });

    return true;
})();

However, when I push the chrome extension, the target page does not respond to the keydown event. This got me thinking that perhaps a jQuery-generated event cannot trigger a pure JS listener. To test this theory, I put the following in an HTML file and ran it:

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>

<body>
<script>
    //listener one
    document.addEventListener("keydown", function (event) {
        alert(event.which);
    });

    //listener two
    $(document).on('keydown', function (event) {
        alert(event.which);
    });

    $(document).ready(function(e) {
        var e = jQuery.Event("keydown");
        e.which = 40;
        $(document).trigger(e);
    });
</script>
</body>
</html>

When I ran the above html file, only the jQuery event listener was fired. When I commented out the jQuery listener, nothing happened. Furthermore, when I commented out the JS listener and uncommented the JS listener, the jQuery event listener fired without problem.

Since the jQuery keydown did not appear to fire the pure JS listener in either case, I tried to trigger the keydown with pure JS:

    var pressEvent = document.createEvent ('KeyboardEvent');
    pressEvent.initKeyEvent ('keydown', true, true, window, true, false, false, false, 65, 0);
    document.dispatchEvent (pressEvent);

However, that generates an "undefined is not a function" on the "initKeyEvent".

I also tried the suggestion available here, here (but that one did not specify a which or keyCode, here (but again no keyCode or which),

How can I trigger a pure JS keydown listener from a Chrome extension?

Thank you

Community
  • 1
  • 1
cryptopi
  • 303
  • 9
  • 19
  • Does pieces work as general document ? i.e.g., If try `event` pieces as `js` without implementing within `extension`, does `keydown` `event` work ? Thanks – guest271314 Apr 13 '14 at 15:50
  • @guest271314 I'm sorry; what is it exactly you want me to try? I am not quite sure what that means. – cryptopi Apr 13 '14 at 16:22
  • Do the pieces work at general web page (`document`) ? Without trying to incorporate with an `extension` ? Does the piece as whole work at general `html` document, with `jquery` loaded at document ? – guest271314 Apr 13 '14 at 16:24
  • @guest271314 Ah. Now I think I understand. I think I may have already addressed that (please see the HTML document above right after I said "I put the following in an HTML file and ran it:". Basically, the jQuery-generated keydown triggered only the jQuery-based keydown listener and not the actual JS listener. Does that answer your question? – cryptopi Apr 13 '14 at 16:42

1 Answers1

2

Try this (pattern)

manifest.json

  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }

js (modified jquery-1.10-2.min-chromium-ext.js)

// if `jquery` not in `window`, utilize `jquery-1.10-2.min-chromium-ext.js`
if (!window.jQuery) {
// `jquery-1.10.2.min.js`
};
// _eof_

js (background.js)

chrome.browserAction.onClicked.addListener(function(tab) {   
  chrome.tabs.executeScript(null, {file: "jquery-1.10.2.min-chromium-ext.js"}, function() {
    chrome.tabs.executeScript(null, {file: "chromium-extension.js"})
  });   
});

js (chromium-extension.js)

    $(function() {        
      if (window.jQuery) {          
        $(document).on("keydown", function(e) {
          alert(e.which)
        })       
      };        
    });

Resources https://developer.chrome.com/extensions/samples

https://developer.chrome.com/extensions/getstarted#unpacked

guest271314
  • 1
  • 15
  • 104
  • 177
  • Please edit your answer. No need for all the licenses in the code here (you linked to the full one) and your list is barely readable. – Xan Apr 13 '14 at 20:48
  • @Xan Removed license. Not certain about list ? Need to adjust formatting ? Thanks – guest271314 Apr 13 '14 at 21:07
  • Are you sure you really need to write it out step by step? URL to the zip, saying to load it as unpacked extension with a link to https://developer.chrome.com/extensions/getstarted#unpacked should be much more readable. The person asking the question seems reasonable – Xan Apr 13 '14 at 21:10
  • Much better, upvoted, now question is whether it will help @cryptopi – Xan Apr 13 '14 at 22:43