Setting up script communication between the web page and content script

1,067 views
Skip to first unread message

Tom Lee

unread,
Jan 23, 2012, 1:08:42 PM1/23/12
to Chromium-extensions
Hello, I am trying to find the correct way to establish a link between
the web document script and my content script. The scenario is that if
I navaigate to a page of my web site I want the extension to
communicate with my web page.

So I have provided a simple example of what I am trying to do.It seems
as though executeScript is not going to work with a standard callback.

Is there anyway to set this up to work with my Chrome Extension.


///////////////// CONTENT SCRIPT
var extensionName = 'helloWorldExtension';

function eventObject()
{
}

eventObject.prototype.GetExtensionName() = function()
{
if(hs == hash)
return true;

return extensionName;
}

// Trying to find the correct way to call the web doc script???? This
does not work
chrome.tabs.executeScript(tabId, { code: function(){SetContentHook(new
eventObject)} });


function DocumentComplete(tabId, tab)
{
InitDocumentFunctionality(tabId, tab, document);
}


chrome.tabs.onUpdated.addListener(
function(tabId, changeInfo, tab)
{
if(changeInfo.status == "complete")
{
document.addEventListener ("DOMContentLoaded",
DocumentComplete(tabId, tab));

}
);


////////////// WEB PAGE
<html>
<head>
</head>
<body>

<script type="text/javascript">
var contentVar = null;


function SetContentHook(itemVar)
{
contentVar = itemVar;
}

function GetNameInfo()
{
var extName = contentVar.GetExtensionName();
alert('Extension name: ' + extName);
}



var pageLink = document.createElement('a');
pageLink.href = "javascript:onclick=GetNameInfo();";
pageLink.innerHTML = "Get Extension Name";

</script>

</body>
<html>

Devin

unread,
Jan 24, 2012, 6:53:42 PM1/24/12
to Chromium-extensions
First thing that caught me eye:

eventObject.prototype.GetExtensionName() = function()
{
if(hs == hash)
return true;
return extensionName;
}

You are confused about function objects here. Here's a good tidbit:

var eventObject = function() {};
is the same as
function eventObject() {}

BOTH of these are called in the exact same way: eventObject();

that is, functionVar() triggers the code of said functionVar. So in
assigning the function code to GetExtensionName, you do NOT put parens
before the assignment

//Next
executeScript "Injects JavaScript code into a page" what Google
actually means by this is that the javascript code is injected into an
*isolated world* of the page. In isolated worlds, you have a separate
javascript context from the javascript of the webpage, but can access
a copy of the DOM. With this, you cannot interact with any webpage
javascript from your content_script, or via executeScript. Btw,
executeScript and content_scripts are 100% identical in nature, except
executeScript can be triggered from the extension background page.

//Next.5

executeScript takes in a string of javascript code, unfortunately it
cannot take a function object because the background page sends this
js to a totally different and foreign javascript context

//Aside: To actually interact with webpage javascript:
You need to inject a <script> into the DOM of the page. Then this
javascript is in the context of the webpage, and outside of Chrome's
isolated world.

This is done like so:

var sc = document.createElement('script');
sc.innerText = 'PageFunction(); window.extensionInstalled = true;'; //
perhaps your page wants to know if an extension is running on it.

//Aside 2: For page js to interact with your content_script in
Chrome's isolated world:
You might have guessed it, your content script needs to detect
something in the dom. An efficient way:

var forContentScipts = document.createElement('span');
forContentScripts.id = 'forContentScripts';


//Aside 3: Don't count on anything for detecting if the DOM is ready.
Nothing from Chrome (this include tab.status === 'complete') or any
DOM event in content_script code

I've found you simply can't depend on these. The best and fastest way
is to poll if the object is truthy like so

function htmlElement() {
if (document.getElementsByTagName('html')[0]) {
//html element is ready, run free!

//After you add anything you need to the html element, proceed to
the body element.
bodyElement();
} else {
setTimeout(htmlElement, 5);
}
}

function bodyElement() {
if (document.getElementsByTagName('body')[0]) {
//body element is ready
} else {
setTimeout(bodyElement, 5);
}
}
htmlElement();

Lastly, I've found the html element of document.documentElement are
the fastest to become available to a content_script isolated world.

-DevinRhode2 — Feel free to email me directly at devinrhode2 [at]
gmail — let me know if you get it worked out

ViKi

unread,
May 28, 2019, 5:46:07 AM5/28/19
to Chromium Extensions, devin...@gmail.com
While searching for a solution to this issue, I ended up here. Hence, I thought it is good to keep this post updated so it might save someone else's time.

It is now recommended to use
postMessage
 for this communication. For more info, please take a look at the official docs
Reply all
Reply to author
Forward
0 new messages