Why is CDATA needed and not working everywhere the same way?
- by baptx
In Firefox's and Chrome's consoles, this works (alerts script content):
var script = document.createElement("script");
script.textContent = (
function test() {
var a = 1;
}
);
document.getElementsByTagName("head")[0].appendChild(script);
alert(document.getElementsByTagName("head")[0].lastChild.textContent);
Using this code as a Greasemonkey script for Firefox works too.
Now, if want to add a "private method" do() to test() It is not working anymore, in neither Firefox/Chrome console nor in a Greasemonkey script:
var script = document.createElement("script");
script.textContent = (
function test() {
var a = 1;
var do = function () {
var b = 2;
};
}
);
document.getElementsByTagName("head")[0].appendChild(script);
alert(document.getElementsByTagName("head")[0].lastChild.textContent);
To make this work in a Greasemonkey script, I have to put all the code in a CDATA tag block:
var script = document.createElement("script");
script.textContent = (<![CDATA[
function test() {
var a = 1;
var do = function() {
var b = 2;
};
}
]]>);
document.getElementsByTagName("head")[0].appendChild(script);
alert(document.getElementsByTagName("head")[0].lastChild.textContent);
This is only works in a Greasemonkey script; it throws an error from the Firefox/Chrome console. I don't understand why I should use a CDATA tag, I have no XML rules to respect here because I'm not using XHTML.
To make it work in Firefox console (or Firebug), I need to do put CDATA into tags like <> and </>:
var script = document.createElement("script");
script.textContent = (<><![CDATA[
function test() {
var a = 1;
var do = function() {
var b = 2;
};
}
]]></>);
document.getElementsByTagName("head")[0].appendChild(script);
alert(document.getElementsByTagName("head")[0].lastChild.textContent);
This doesn't working from the Chrome console. I've tried adding .toString() at the end like many people are doing (]]></>).toString();), but it's useless.
I tried to replace <> and </> with a tag name <foo> </foo> but that didn't work either.
Why doesn't my first code snippet work if I define var do = function(){} inside another function?
Why should I use CDATA as a workaround even if I'm not using XHTML?
And why should I add <> </> for Firefox console if it's working without in a Greasemonkey script?
Finally, what is the solution for Chrome and other browsers?
EDIT:
My bad, I've never used do-while in JS and I've created this example in a simple text editor, so I didn't see "do" was a reserved keyword :p
But problem is still here, I've not initialized the Javascript class in my examples.
With this new example, CDATA is needed for Greasemonkey, Firefox need CDATA between E4X <> </> and Chrome fails:
var script = document.createElement("script");
script.textContent = (
<><![CDATA[var aClass = new aClass();
function aClass() {
var a = 1;
var aPrivateMethod = function() {
var b = 2;
alert(b);
};
this.aPublicMethod = function() {
var c = 3;
alert(c);
};
}
aClass.aPublicMethod();]]></>
);
document.getElementsByTagName("head")[0].appendChild(script);
Question: why?