S
Seni Seven
Suppose I have HTML markup with a SCRIPT element as shown below:
<script type="text/javascript">
function multiply(a, b) {
return a * b;
}
var i = multiply(2, 5);
document.write("The value of <i>i</i> is " + i);
</script>
All of this markup and contained script code is retrieved as a string using
Ajax.
I have an HTML parser with support for parsing the string containing the
script code.
In parsing the contained code (using JavaScript, of course), how would you
convert the contained script code from string into source?
What I have found so far (using Firebug in Firefox for development) is this:
1) Isolating the string "function multiply(a, b) { return a * b; }" and then
passing that string as an argument to eval() does not cause the definition
of the function named "multiply," it seems.
2) I can parse the function definition in a way to create the string:
"var multiply = new Function (\"a\", \"b\", \"{ return a * b; }\");"
and then use eval() on it (without error). And then when I eval() the
global level code in a debugger (Firebug in FireFox), as so
eval("var i = multiply(2, 5); document.write(\"The value " +
"of <i>i</i> is \" + i);"); // parsed code as string on one line
the value of identifier 'i' is immediately set to 10 in the debugger, but
the debugger exits with error 'multiply is not defined', which indicates
multiple levels of execution contexts, I suppose. In fact, if I just do an
eval() on the "multiply" assignment of the Function constructor, the
identifier 'multiply' is still not defined.
QUESTION: What's the solution to the goal I want to achieve?
[don't worry about the 'document.write()' call for the moment: that string
pattern gets replaced eventually with a function that injects DOM nodes into
the tree in the same way document.write() would on document loading]
For those who are curious as to why I would want to do this, there is a
basis for this. See BACKGROUND below.
BACKGROUND
I have a modular interactive chemistry calculator running entirely on the
client side.
The "modularity" is such that a main HTML document provides a base interface
and I extend functionality by reading in one JS file which specifies a
document in HTML markup--the markup is valid, but not the document--which is
read in using Ajax. The JS file also contains all the code for doing the
chemistry calculations specific for that module.
The string representing the markup obtained by Ajax retrieval is then passed
to a parsing function which is supposed to do it all: parses the HTML
markup using DOM methods to insert the DocumentFragment into the main
document tree. It also parses CSS (stylesheets and style attributes), as
well as any Javascript contained inside SCRIPT elements. Everything becomes
part of the interactive document by using DOM method calls, HTML --> element
nodes with attributes; CSS --> as stylesheets in LINK element nodes for
external stylesheets, as style property changes to DOM element nodes where
style attributes are identified; JavaScript --> converting strings into
executable source, parsing named functions from global level source (which
might be wrapped in anonymous functions and called).
So far there has been no problem with the HTML and CSS. It's the Javascript
that remains a barrier now.
Security considerations: all the module HTML documents and JS files are
delivered from the same server, the one from which the main document was
loaded. Inherent Javascript security features against accessing the file
system without user permissions are always in play.
<script type="text/javascript">
function multiply(a, b) {
return a * b;
}
var i = multiply(2, 5);
document.write("The value of <i>i</i> is " + i);
</script>
All of this markup and contained script code is retrieved as a string using
Ajax.
I have an HTML parser with support for parsing the string containing the
script code.
In parsing the contained code (using JavaScript, of course), how would you
convert the contained script code from string into source?
What I have found so far (using Firebug in Firefox for development) is this:
1) Isolating the string "function multiply(a, b) { return a * b; }" and then
passing that string as an argument to eval() does not cause the definition
of the function named "multiply," it seems.
2) I can parse the function definition in a way to create the string:
"var multiply = new Function (\"a\", \"b\", \"{ return a * b; }\");"
and then use eval() on it (without error). And then when I eval() the
global level code in a debugger (Firebug in FireFox), as so
eval("var i = multiply(2, 5); document.write(\"The value " +
"of <i>i</i> is \" + i);"); // parsed code as string on one line
the value of identifier 'i' is immediately set to 10 in the debugger, but
the debugger exits with error 'multiply is not defined', which indicates
multiple levels of execution contexts, I suppose. In fact, if I just do an
eval() on the "multiply" assignment of the Function constructor, the
identifier 'multiply' is still not defined.
QUESTION: What's the solution to the goal I want to achieve?
[don't worry about the 'document.write()' call for the moment: that string
pattern gets replaced eventually with a function that injects DOM nodes into
the tree in the same way document.write() would on document loading]
For those who are curious as to why I would want to do this, there is a
basis for this. See BACKGROUND below.
BACKGROUND
I have a modular interactive chemistry calculator running entirely on the
client side.
The "modularity" is such that a main HTML document provides a base interface
and I extend functionality by reading in one JS file which specifies a
document in HTML markup--the markup is valid, but not the document--which is
read in using Ajax. The JS file also contains all the code for doing the
chemistry calculations specific for that module.
The string representing the markup obtained by Ajax retrieval is then passed
to a parsing function which is supposed to do it all: parses the HTML
markup using DOM methods to insert the DocumentFragment into the main
document tree. It also parses CSS (stylesheets and style attributes), as
well as any Javascript contained inside SCRIPT elements. Everything becomes
part of the interactive document by using DOM method calls, HTML --> element
nodes with attributes; CSS --> as stylesheets in LINK element nodes for
external stylesheets, as style property changes to DOM element nodes where
style attributes are identified; JavaScript --> converting strings into
executable source, parsing named functions from global level source (which
might be wrapped in anonymous functions and called).
So far there has been no problem with the HTML and CSS. It's the Javascript
that remains a barrier now.
Security considerations: all the module HTML documents and JS files are
delivered from the same server, the one from which the main document was
loaded. Inherent Javascript security features against accessing the file
system without user permissions are always in play.