On Fri, Jul 31, 2009 at 5:57 PM, Aaron Boodman<[email protected]> wrote:
>
> On Fri, Jul 31, 2009 at 5:14 PM, Daniel Wagner-Hall<[email protected]> wrote:
>> I suppose only allowing contentWindow.eval and not any other interaction
>> with the page's JS would significantly restrict the ability to take over
>> the extension (notably where that ability was only there through
>> laziness/oversight), and hopefully ensure that extension writers
>> properly thought about the consequences of direct page interaction when
>> they wrote it.  While it would leave a hole open, it is a much lesser
>> hole, and I believe a significantly useful one.
>
> You can probably setup two-way communication between the content
> script and the js context of the page by using DOM events as a side
> channel. This is something I've heard of people doing in Firefox.
>
> We'll keep thinking about ways to make a (small) first-class hole
> between content scripts and the page, but I think it is a minority use
> case.

I would like to propose a modification to the API such that there is
an additional method available to content scripts,
executeScriptInPageContext(script[, timeout][, args]).  |script| is
the script to be executed as a string. |timeout| is an optional number
of milliseconds after which to give up on the script.  |args| is an
optional JSON representation of an array of any args to be passed to
the script.  We could make do without the args entirely.  I've hacked
together a way of doing this by script tag injection on the DOM (see
below).

I think it would be *much* nicer if we provided this functionality
directly, rather than expecting extension developers to do it manually
themselves, and this would make it clear that only things wrapped up
in text can be put to the page, or gotten from the page (i.e. objects
cannot be shared).  This could be very easily implemented as a
callback-style function (like all the tab and window functions),
though if it could be its own function which simply returns a value,
that would be nicer... I'm not sure how this would be directly
implemented in Chrome, but the javascript is easy enough...

Currently, my executeScriptInPageContext(script) method looks roughly like:
var scriptTag = document.createElement('script');
//The below may be lacking some required escaping
scriptTag.innerText = 'var e = document.createEvent("MutationEvent");' +
                        'var args = "' + args + '";' +
                        'var val = eval(' + script + ').apply(window,
JSON.parse(args));' +
                        'if (typeof(val) == "string") { val = \'"\' +
val + \'"\'; }' +
                        'e.initMutationEvent("DOMAttrModified", true,
false, THIS_ELEMENT, null, "function() { return " + val + "}", null,
0);' +
                        'THIS_ELEMENT.dispatchEvent(e);';
scriptTag.addEventListener('DOMAttrModified',
returnFromJavascriptInPage, false);
document.getElementsByTagName("body")[0].appendChild(scriptTag);

I'm getting THIS_ELEMENT by attaching a UUID as the ID of the script
tag and getting element by that, but I'm sure there is a way to do it
without needing an ID...

 My returnFromJavascriptInPage(e) function basically reduces to:
//[Remove the element from the DOM (I'm doing this by ID, but could
use a reference to the element from the event]
return eval(e.newValue)();

I also have a timeout function (which is called if the script takes
more than timeout ms), which is quite wooly at the moment, but removes
the element from the DOM (which may be entirely ineffectual, as the
DOM may be blocked on the script?) and returns an error code.

Adding our own kind of DOM event rather than piggybacking on/abusing
the DOMAttrModified event could also be quite nice...

Thoughts?

--~--~---------~--~----~------------~-------~--~----~
Chromium Developers mailing list: [email protected] 
View archives, change email options, or unsubscribe: 
    http://groups.google.com/group/chromium-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to