Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It seems like when a script has already been injected it is not injected again.<br> So, the way to go would be to initiate your action by passing a message to the content script. (Of course, if the content script has not been injected yet, you need to inject it first.)</p> <p>One solution I came up with (and after testing confirmed it works fine) is the following:</p> <ol> <li><p>On <code>pageAction.onClicked</code> send a message from the background page to the content script, asking it to do something (e.g. post the grades). Also, request a response to be sent back to the background page.<br> [See, also, <strong><a href="http://developer.chrome.com/extensions/tabs.html#method-sendMessage" rel="nofollow">chrome.tabs.sendMessage(...)</a></strong>.]</p></li> <li><p>If the content script has already been injected, have it receive the message, send a confirmation back to the background page and proceed doing something (e.g. posting the grades). This process can take place as many times as you want.<br> [See, also, <strong><a href="http://developer.chrome.com/extensions/runtime.html#event-onMessage" rel="nofollow">chrome.runtime.onMessage</a></strong>.]</p></li> <li><p>The first time that the <code>pageAction.onClicked</code> is fired, there will be no content script listening for messages. In that case, there will be no message confirmation. Instead <strong><a href="http://developer.chrome.com/extensions/runtime.html#property-lastError" rel="nofollow">chrome.runtime.lastError</a></strong> will be set. In that case, the background page will have to inject the content script first and then send the message again.<br> [See, also, <strong><a href="http://developer.chrome.com/extensions/runtime.html#property-lastError" rel="nofollow">chrome.runtime.lastError</a></strong>.]</p></li> </ol> <hr> <p>Theoreticaly speaking, that should do it !<br> Practicaly, this is the sample code that worked for me:</p> <p><strong>manifest.json</strong>: (Note: If you have more specific requirements regarding the pages you need to access, you could incorporate them into the manifest and get rid of some of the permissions.)</p> <pre><code>{ ... "background": { "persistent": false, "scripts": ["background.js"] }, "page_action": { "default_title": "Test Extension" }, "permissions": [ "tabs", "http://*/*", "https://*/*" ] ... } </code></pre> <p><strong>background.js:</strong></p> <pre><code>function checkForValidURL(tabId, info, tab) { var idx = tab.url.indexOf("tiger.armstrong"); if (idx &gt; 0) { chrome.pageAction.show(tabId); } else { chrome.pageAction.hide(tabId); } } chrome.tabs.onUpdated.addListener(checkForValidURL); function onPageActionClicked(tab) { // Send message to content script, asking to post grades alert("Calling content_script..."); chrome.tabs.sendMessage(tab.id, { action: "postGrades" }, function() { if (chrome.runtime.lastError) { // The error indicates that the content script // has not been injected yet. Inject it and... chrome.tabs.executeScript(tab.id, { file: "content.js" }, function() { if (!chrome.runtime.lastError) { // ...if injected successfully, send the message anew onPageActionClicked(tab); } }); } else { // The content script called our response callback, // confirming that it is there and got our message alert("Message got through !"); } }); }; chrome.pageAction.onClicked.addListener(onPageActionClicked); </code></pre> <p><strong>content.js:</strong></p> <pre><code>var livelabtools = { /** * This function is like window.open, but it can POST (rather than GET) from * JS source: http://canop.org/blog/?p=426 */ canop_open: function (method, url, data, target) { var form = document.createElement("form"); form.action = url; form.method = method; form.target = target || "_self"; // 'data' is an object with key-value pairs // of fields to be sent if (data) { for (var key in data) { var input = document.createElement("input"); input.name = key; input.value = (typeof(data[key]) === "object") ? JSON.stringify(data[key]) : data[key]; form.appendChild(input); } } form.submit(); form.remove(); }, post_grades: function () { console.log("Posting some grades..."); livelabtools.canop_open("POST", "http://aspen2.cscofc.info/jsontocsv.php", "{}"); console.log("Grades sent !"); } } // Listen for messages from the background page // (It actually listens for messages from anyone in the context, // but the background page is the one that interrests us) chrome.runtime.onMessage.addListener(function(msg, sender, response) { // If we've been asked to post grades... if (msg.action &amp;&amp; (msg.action == "postGrades")) { // ...confirm we got the message and... response(); // ...do what we do best: post grades ! livelabtools.post_grades(); } }); </code></pre> <hr> <p>Let's hope this covers it :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload