HighDots Forums  

Re: How to make injected js execute?

Javascript JavaScript language (comp.lang.javascript)


Discuss Re: How to make injected js execute? in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #61  
Old   
ajile@iskitz.com
 
Posts: n/a

Default Re: How to make injected js execute? - 09-18-2007 , 04:15 AM






Randy,
First let me say I'm not sure of the right or wrong way to quote and
maintain context in these newsgroups so please bear with me. I'm only
here because I noticed this topic and thought the discussion was
interesting and felt I had something of value to add. That said,
please forgive any newbie posting errors and read on.

You've had some pretty passionate discussions in this group regarding
injected js so I'd guess you're still interested in finding an
acceptable solution. You might be interested to try Ajile (http://
ajile.iskitz.com/). It's a JavaScript namespace and dynamic loading
library I've created that imo addresses the cross-browser dynamic
script loading issue quite well. I haven't as yet finalized NN4
support, but Ajile functions perfectly (as designed) in modern and
early version browsers like IE 4, Opera 7 and Netscape 6. NN4 does
actually work as far as namespacing and dynamic loading go, but the
browser dies after completing loading for an as yet undetermined
reason (I'm still partially troubleshooting that one).

I'm very interested in your assessment of Ajile as you seem to be
fairly focused on finding a solution to the problem and are aware of
some of the more challenging aspects of that search. Ajile is the end
product of now nearly four years on and off effort to refine and
expand a concept I originally implemented back in 2003 as JSPackaging.
Although your reason for seeking a solution was slightly different
than my motivation to create it, I believe Ajile solves a good part,
if not all of both our problems.

Below I'll try to respond to some of the points you've raised in your
conversations with Andrea, in relation to Ajile:

On Aug 30, 10:07 pm, Randy Webb <HikksNotAtH... (AT) aol (DOT) com> wrote:

Quote:
How do you debug code that doesn't exist anymore? There are more reasons
to leave it than there are to remove it. It is a choice. I choose to
leave mine.

Ajile also removes script tags, though not immediately and provides
multiple ways to enable/disable that feature (cloaking). I've found
controlling cloaking to be very useful when debugging. In my testing
and use I haven't encountered any garbage collection problems around
script tag removal, maybe you can offer an effective way to verify
this. I don't believe the removal of script tags affects the
availability of code that has already been processed. I *have* found
that the timing for when you choose to remove script tags is important
as removing one while it's being processed can crash IE.

Quote:
Run it in a Mac browser and
your success ratio (across browsers) will drop to around 50% or so as
there are at least 7 (probably more) that don't support setting the
.text property on a script element and 6 (that I know of) that do
support setting it. I say 50% simply because I am pretty sure the
statistics there are skewed as I don't have a mac to investigate with.

You can view the listings here:

URL:http://members.aol.com/_ht_a/hikksnotathome/loadJSFile/

Scroll down to the MAC OS'es and look at the column under the "Change
.text" button.

Ajile implements multiple dynamic script loading strategies and should
work for most if not all the browsers you've listed on your test page.
I'd be interested to see what you find if you're able to test it in
the listed environments.

Quote:
The only browser, that I know of, that doesn't support createElement on
a SCRIPT element is IE and that is what has led to a lot of this coding
is an effort to cope with IE not implementing createElement on a script
element. If it did, you would code it like this:

var newScript = document.createElement('script');
newScript.type = "text/javascript";
newScriptText = "alert('createTextNode worked')";
var s = document.createTextNode(newScriptText);
newScript.appendChild(s);
It's a simple proposal enanchment, however I tested my proposal with
every used IE (5,5.5,6,7) and it seems to work perfectly. Maybe You're
talking about Mac IE 5.X .... this death browser?

No, I am referring to the fact that if IE supported - properly -
createTextNode on a SCRIPT element then the entire thing would be
trivial. It isn't because of IE.

A subtle point easily missed by those who haven't taken the time to
investigate the root cause.

Quote:
Do You write code for IE4 too? In this case, good luck for your
solution!!!

Can I inject scripts in IE4? Who cares? No, I don't develop for IE4 but
I do develop with a mindset of at least having it fail gracefully
instead of puking errors all over the user.

Since you mention IE4 though, I *can* inject scripts in NN4.

I completely agree with you on graceful failure, imo anything less
shows at least one of the following: ignorance, lack of skill, poor
quality, or total disregard for the varied potential user base. I
believe as developers we should always seek to provide the highest
quality to as wide a user base as possible especially when within our
capabilities, but that's just me.

Quote:
how many days did You spend to perform this research?

My research as far as script injection is concerned has been going on
for over 7 years now and I would not even be able to come close to
guessing how much time I have spent on it. Can I do it? Absolutely. Can
Imakeit work in any browser that can handle Dynamic Script Insertion?
Yes I can. Does your code do that? Not even close.

I applaud your 7 year effort, it's definitely not been an easy task,
and it really requires a clear understanding of the JavaScript
language and the various browser environments.

Quote:
Your script does not work with NS6.0 Windows.
Your script does not work with NS6.1 Windows.
Your script does not work with iCab 3.0.3 Mac.
Your script does not work with IE5.2 Mac.
Your script does not work with Shiira 1.2.2 Mac.
Your script does not work with Sunrise 0.89 Mac.

The only browser listed that your script doesn't work in that I can't
inject script into is NS6.0/6.1. The rest of them? Absolutely.

Ajile doesn't currently work with iCab and I don't have IE 5.2 Mac to
test, but it works flawlessly with the Shiira, Sunrise, and NS
browsers you've listed. I'll be looking into iCab compatibility, not
quite sure what the issue is there...

If you plan to respond, please respond to the group as this email is
rarely checked.



Reply With Quote
  #62  
Old   
Randy Webb
 
Posts: n/a

Default Re: How to make injected js execute? - 09-23-2007 , 01:51 AM






ajile (AT) iskitz (DOT) com said the following on 9/18/2007 4:15 AM:
Quote:
Randy,
First let me say I'm not sure of the right or wrong way to quote and
maintain context in these newsgroups so please bear with me. I'm only
here because I noticed this topic and thought the discussion was
interesting and felt I had something of value to add. That said,
please forgive any newbie posting errors and read on.
The group FAQ is a place to start. It has a section on posting and
quoting. And, reading the old posts can give some hints about posting
styles preferred in this group.

Quote:
You've had some pretty passionate discussions in this group regarding
injected js so I'd guess you're still interested in finding an
acceptable solution. You might be interested to try Ajile (http://
ajile.iskitz.com/). It's a JavaScript namespace and dynamic loading
library I've created that imo addresses the cross-browser dynamic
script loading issue quite well. I haven't as yet finalized NN4
support, but Ajile functions perfectly (as designed) in modern and
early version browsers like IE 4, Opera 7 and Netscape 6. NN4 does
actually work as far as namespacing and dynamic loading go, but the
browser dies after completing loading for an as yet undetermined
reason (I'm still partially troubleshooting that one).
From what little I have read in the last few minutes, it appears the
library is designed to handle loading files as the page loads. What I
"specialize" in (if you want to call it that) is loading script files or
text after the page has finished loading. And, getting the execution
context correct.

FYI, in the Load section:
<quote>
Until that time, none of the variables or functions in the loaded module
will be accessible.
</quote>

Is not true in IE7. The only one that I am aware of that I would be full
confident enough to say, without a doubt, that it is true would be in
Firefox (where I know it is true). There may be others but FF is the
only one I know of.

Simple test code:

<script id="myScriptTag" src="blank.js"></script>

myVar = "old value";
function insertScriptTest(){
alert(myVar)
document.getElementById('myScriptTag').src= 'blank.js';
alert(myVar)
}

Where blank.js has a single line in it:

myVar = "new value";

From what your page is saying, I should get "old value" from both
alerts but I don't in IE. I get "old value" and then "new value".

Quote:
I'm very interested in your assessment of Ajile as you seem to be
fairly focused on finding a solution to the problem and are aware of
some of the more challenging aspects of that search. Ajile is the end
product of now nearly four years on and off effort to refine and
expand a concept I originally implemented back in 2003 as JSPackaging.
Although your reason for seeking a solution was slightly different
than my motivation to create it, I believe Ajile solves a good part,
if not all of both our problems.
I think it is trying to solve a different problem which has a different
solution. Netscape4 would be a simple proof of that. If you are trying
to "dynamically" load .js files in the sense that your file names are
not hard coded in the HTML, then you can simply document.write the
script elements in Netscape4 and all is fine. Trying to do it after the
page has loaded is a little different whereby you simply open a layer,
write to that layer, and then close the layer. (Closing the layer may be
the source of your NN4 problems).

Quote:
Below I'll try to respond to some of the points you've raised in your
conversations with Andrea, in relation to Ajile:

On Aug 30, 10:07 pm, Randy Webb <HikksNotAtH... (AT) aol (DOT) com> wrote:

How do you debug code that doesn't exist anymore? There are more reasons
to leave it than there are to remove it. It is a choice. I choose to
leave mine.


Ajile also removes script tags, though not immediately and provides
multiple ways to enable/disable that feature (cloaking). I've found
controlling cloaking to be very useful when debugging. In my testing
and use I haven't encountered any garbage collection problems around
script tag removal, maybe you can offer an effective way to verify
this. I don't believe the removal of script tags affects the
availability of code that has already been processed. I *have* found
that the timing for when you choose to remove script tags is important
as removing one while it's being processed can crash IE.
I will look at your site again later today. It is now 0200 and I have
been up since 0500 yesterday and drove 10 hours to get home so I am too
tired to look through it right now.

Quote:
Run it in a Mac browser and
your success ratio (across browsers) will drop to around 50% or so as
there are at least 7 (probably more) that don't support setting the
.text property on a script element and 6 (that I know of) that do
support setting it. I say 50% simply because I am pretty sure the
statistics there are skewed as I don't have a mac to investigate with.
You can view the listings here:

URL:http://members.aol.com/_ht_a/hikksnotathome/loadJSFile/

Scroll down to the MAC OS'es and look at the column under the "Change
.text" button.


Ajile implements multiple dynamic script loading strategies and should
work for most if not all the browsers you've listed on your test page.
I'd be interested to see what you find if you're able to test it in
the listed environments.
That depends, directly, on whether my assessment was correct about
*when* you are loading files. From what I saw, you are loading prior to
window.onload firing and I am loading them after it fires.

Quote:
The only browser, that I know of, that doesn't support createElement on
a SCRIPT element is IE and that is what has led to a lot of this coding
is an effort to cope with IE not implementing createElement on a script
element. If it did, you would code it like this:
var newScript = document.createElement('script');
newScript.type = "text/javascript";
newScriptText = "alert('createTextNode worked')";
var s = document.createTextNode(newScriptText);
newScript.appendChild(s);
It's a simple proposal enanchment, however I tested my proposal with
every used IE (5,5.5,6,7) and it seems to work perfectly. Maybe You're
talking about Mac IE 5.X .... this death browser?
No, I am referring to the fact that if IE supported - properly -
createTextNode on a SCRIPT element then the entire thing would be
trivial. It isn't because of IE.


A subtle point easily missed by those who haven't taken the time to
investigate the root cause.
And a point that I have yet to find a solid feature detection solution to.

Quote:
how many days did You spend to perform this research?
My research as far as script injection is concerned has been going on
for over 7 years now and I would not even be able to come close to
guessing how much time I have spent on it. Can I do it? Absolutely. Can
Imakeit work in any browser that can handle Dynamic Script Insertion?
Yes I can. Does your code do that? Not even close.


I applaud your 7 year effort, it's definitely not been an easy task,
and it really requires a clear understanding of the JavaScript
language and the various browser environments.
It has actually been closer to 9 years or so. The 7 years was from the
earliest post I could find in the archives about it even though I was
doing it before then.

Quote:
Your script does not work with NS6.0 Windows.
Your script does not work with NS6.1 Windows.
Your script does not work with iCab 3.0.3 Mac.
Your script does not work with IE5.2 Mac.
Your script does not work with Shiira 1.2.2 Mac.
Your script does not work with Sunrise 0.89 Mac.

The only browser listed that your script doesn't work in that I can't
inject script into is NS6.0/6.1. The rest of them? Absolutely.


Ajile doesn't currently work with iCab and I don't have IE 5.2 Mac to
test, but it works flawlessly with the Shiira, Sunrise, and NS
browsers you've listed. I'll be looking into iCab compatibility, not
quite sure what the issue is there...
If you are loading as the page loads, I can't answer you. If you are
loading after the page loads, I can tell you how to do that in iCab.

Quote:
If you plan to respond, please respond to the group as this email is
rarely checked.
I bet you check your email more often than I email replies to Usenet
postings

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/


Reply With Quote
  #63  
Old   
Stevo
 
Posts: n/a

Default Re: How to make injected js execute? - 09-23-2007 , 02:53 AM



Randy Webb wrote:
Quote:
What I "specialize" in (if you want to call it that) is loading
script files or text after the page has finished loading. And,
getting the execution context correct.
Do you have a link to your latest function that does the script loading?

I have a script-injecting problem on Firefox under certain conditions
and I'd like to see if your script solves my issue (before I post a code
example).

I'm using the dynamic script loading technique, but doing it before the
page has finished loading. On Firefox in a simple test page it works
just fine, perhaps because the page has already finished loading.

On some larger pages it can also work just fine, even where the page
definitely has not finished loading.

On some rarer pages though, it fails. The variables that should have
been defined by the script inject, although they exist, they give back
JS errors along the lines of "has no properties". Two seconds later if I
re-try the same operation on that variable, it succeeds. So clearly the
variables were created properly, they just weren't usable yet.


Reply With Quote
  #64  
Old   
Randy Webb
 
Posts: n/a

Default Re: How to make injected js execute? - 09-23-2007 , 06:58 PM



Stevo said the following on 9/23/2007 2:53 AM:
Quote:
Randy Webb wrote:
What I "specialize" in (if you want to call it that) is loading
script files or text after the page has finished loading. And,
getting the execution context correct.

Do you have a link to your latest function that does the script loading?
Not on a web-page. The closest would be the last one I wrote and posted
to Usenet but it won't solve the issue you are having.

<URL:
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/7fa64dffc0c5297e/7ef0d3199b27b32a?lnk=gst&q=loadhtmlfragment&rnum=1 #7ef0d3199b27b32a>

Not completed yet but it will work in Firefox.

Quote:
I have a script-injecting problem on Firefox under certain conditions
and I'd like to see if your script solves my issue (before I post a code
example).
It won't.

Quote:
I'm using the dynamic script loading technique, but doing it before the
page has finished loading. On Firefox in a simple test page it works
just fine, perhaps because the page has already finished loading.
Which "dynamic script loading technique"? Mine (which I now refer to as
HikkScript) or the Ajile approach? One is prior to page loading, one is
after the page has loaded.

Quote:
On some larger pages it can also work just fine, even where the page
definitely has not finished loading.
That is because external files are loaded before script processing
continues:

<script type="text/javascript" src="external.js">
<script type="text/javascript">
alert('You wont see this until external.js has loaded')
</script>

Quote:
On some rarer pages though, it fails. The variables that should have
been defined by the script inject, although they exist, they give back
JS errors along the lines of "has no properties".
There are two causes for that. One is execution context, the other is
timing issues where you are trying to access it before the file has
finished loading.

Quote:
Two seconds later if I re-try the same operation on that variable,
it succeeds.
That could be either scenario. If you take the code I posted in my last
reply and take out the IE'ism and make it work in Firefox:

Where external.js contains a single statement:

myVar = "new value";

And this script/html in the page:

myVar = "old value";

function testIt(){
var s = document.createElement('script');
s.src = 'external.js';
document.getElementById('scriptDiv').appendChild(s );
alert(myVar)
}

<button onclick="testIt()">Test It</button>
<div id="scriptDiv"></div>


IE7: alerts "new value"
FF1.5: alerts "old value"
FF2.0: alerts "old value"

If you change the functions to something like this:

function testIt(){
var s = document.createElement('script');
s.src = 'external.js';
document.getElementById('scriptDiv').appendChild(s );
}

function doSomethingWithIt(){
alert(myVar)
}

Where you will end up is asking yourself "How do I know when external.js
has finished loading?" (That question is in the archives somewhere). The
simple solution is to move the function call to the end of external.js
and then it can only get called when the file has loaded.

external.js:

//lots of stuff here
someFunctionToCall()


Quote:
So clearly the variables were created properly, they just weren't usable yet.
Or, they weren't loaded yet before you tried to access them because of
file load time.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/


Reply With Quote
  #65  
Old   
Stevo
 
Posts: n/a

Default Re: How to make injected js execute? - 09-25-2007 , 05:49 PM



Randy Webb wrote:
Quote:
Stevo said the following on 9/23/2007 2:53 AM:
Do you have a link to your latest function that does the script loading?

Not on a web-page. The closest would be the last one I wrote and posted
to Usenet but it won't solve the issue you are having.
URL:
http://groups.google.com/group/comp....f0d3199b27b32a
Not completed yet but it will work in Firefox.
What I'm having a problem with isn't actually script loading, it's
script "creating" from a string. This following code is running in an
iframe and trying to inject a function into the parent page (in the same
domain).

try
{
//next 3 lines are normally one line. broken up
//just so the line lengths aren't too long here
var pd=parent.document;
var b=pd.getElementsByTagName('iframe').item(0);
var bn=b.parentNode;

var s=document.createElement('SCRIPT');
s.text="function test(){return 2;}";

if(bn)
bn.insertBefore(s,bn.firstChild);

//try and call the function we injected
//this often fails with a message about
//test not being a function, but the call
//in the setTimeout works just fine.

if(parent.test()==2)
alert("success");
else
alert("failed - wrong return value");
}
catch(e){alert("exception "+e.name+":"+e.message);}

setTimeout("try{alert(parent.test());}catch(e){ale rt('bad')}",5000);


The call inside the try block fails when the page is cached, but the
second call (from the setTimeout) works just fine. Both are run from the
same context (inside the iframe). It's as if there's a timing issue.
Calling a function created from a createElement like this can't be
called too quickly. Give it a second or two though, and the test object
magically transforms into being a function, and is callable.

I've tried various combinations of injecting the code (appendChild,
insertAfter, etc) but all seem to have this problem.

One other thing I've noticed, is that if the parent page is a really
simple test page, then I never get this problem. If it's a big old
monster of a page, then I do get this problem, but, only if the page is
cached.

Tearing my hair out. Right now I have to completely block Firefox
because I can't solve this issue. I'm not expecting a pre-built
solution, but if anyone has any ideas of something to try then I'd be
thankful

btw, if anyone copies this code and puts it in an iframe on a simple
test page and says "works for me", remember, it works for me on a simple
test page too. It's only on heavy parent pages, and not even ALL of
them. That's not too helpful though, I have no influence on those pages.
I have to work around whatever challenges they're presenting me.


Reply With Quote
  #66  
Old   
Randy Webb
 
Posts: n/a

Default Re: How to make injected js execute? - 09-25-2007 , 06:36 PM



Stevo said the following on 9/25/2007 5:49 PM:
Quote:
Randy Webb wrote:
Stevo said the following on 9/23/2007 2:53 AM:
Do you have a link to your latest function that does the script loading?

Not on a web-page. The closest would be the last one I wrote and
posted to Usenet but it won't solve the issue you are having.
URL:
http://groups.google.com/group/comp....f0d3199b27b32a
Not completed yet but it will work in Firefox.

What I'm having a problem with isn't actually script loading, it's
script "creating" from a string. This following code is running in an
iframe and trying to inject a function into the parent page (in the same
domain).
It is a timing issue where Firefox isn't updating everything until the
current execution exits. And even then it gets really weird with the way
it does or doesn't update.



Quote:
try
{
//next 3 lines are normally one line. broken up
//just so the line lengths aren't too long here
var pd=parent.document;
var b=pd.getElementsByTagName('iframe').item(0);
var bn=b.parentNode;

var s=document.createElement('SCRIPT');
s.text="function test(){return 2;}";

if(bn)
bn.insertBefore(s,bn.firstChild);
Is there any particular reason you used insertBefore rather than a
simple appendChild?

Quote:
//try and call the function we injected
//this often fails with a message about
//test not being a function, but the call
//in the setTimeout works just fine.
That is because setTimeout causes the current execution to end and start
another execution thread. After the current one ends, Firefox updates
and all is fine. And, it is the only reliable way to get Firefox to
update dynamic scripts.

Quote:
The call inside the try block fails when the page is cached, but the
second call (from the setTimeout) works just fine. Both are run from the
same context (inside the iframe). It's as if there's a timing issue.
It isn't so much a timing issue as an execution context issue.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/


Reply With Quote
  #67  
Old   
Stevo
 
Posts: n/a

Default Re: How to make injected js execute? - 09-25-2007 , 06:59 PM



Randy Webb wrote:
Quote:
What I'm having a problem with isn't actually script loading, it's
script "creating" from a string. This following code is running in an
iframe and trying to inject a function into the parent page (in the
same domain) (and failing).

It is a timing issue where Firefox isn't updating everything until the
current execution exits. And even then it gets really weird with the way
it does or doesn't update.

That is because setTimeout causes the current execution to end and start
another execution thread. After the current one ends, Firefox updates
and all is fine. And, it is the only reliable way to get Firefox to
update dynamic scripts.

It isn't so much a timing issue as an execution context issue.
Thanks Randy. That makes perfect sense. It's somewhat unfortunate for
the way my code is currently structured, but that's something I'll have
to deal with


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.