How to pass jQuery to eval'd code? - javascript

First, check out my fiddle fiddle
jsFiddle is nice, but sometimes it runs a bit slow, so I made this simple pure JS fiddle (can be ran locally)
Working great so far, but I want to be able to use jQuery in my fiddle. Type alert(typeof $); in the bottom left box and press "Run" to see what I mean (says undefined).
So how do I pass jQuery off to the iframe and give it the correct context? I suspect I could set doc.contentWindow.$=$ or something like that, but I still need to give the correct context so it knows where to find the elements. How would I do that?
iframe.contentWindow.$ = $.proxy($,iframe.contentWindow);
That didn't work either. Gives me access to jQuery, but the context is still wrong.
iframe.contentWindow.$ = function(s){return $(s,doc);};
That sort of works... but it's a bit of a hack.

Why not do as jsfiddle itself does? It simply includes a script tag for jQuery (or whatever framework you asked for) in the head of the iframe.
If you look in head of the... uh "outer" iframe (the one jsfiddle created), you'll see they just threw this in there:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.js"></script>
Same thing applies to the "on ready" and "on load" options, jsfiddle just wraps the appropriate call around your javascript before injecting it into the iframe.
Modifying your code a little, you can create a script element:
var doc = iframe.contentWindow.document;
var jqueryTag = doc.createElement('script');
jqueryTag.type = 'text/javascript';
jqueryTag.src = 'http://code.jquery.com/jquery-1.6.4.js';
and then append that element to the head.

I tweaked your fiddle fiddle a little: http://jsfiddle.net/gilly3/XcSYz/3/
First, you can't write a doctype to the body's innerHTML and expect it to do anything for you. Same with a charset meta tag. I moved all of that to a document.write call.
You were evaluating script tags oninput of the editors. First this throws errors like crazy if you are editing a script tag in the html frame. Second, if you put an alert("hello") in a script tag in the HTML pane, then with every keypress, you get an alert. Third, you were evaluating the scripts in the context of the parent window. I changed html script tags to be evaluated when run is clicked and with the correct context.
Since you don't want to re-write the document every time (you can't, eg doctype), I modified it slightly to do some dom manipulation instead. It removes and replaces the style tag and writes only the HTML pane contents to the body's innerHTML.
This is a fun little project you are trying. jsFiddle is buggy and needs some updates. I don't know how viable your pure client-side fiddle is - jsFiddle is quite robust (despite its bugs), but it is a nice exercise to give your approach a try.
Edit: One more change included in this version: I modified your textareas to use width: 50%; height: 50%; instead of setting right and bottom. Those weren't working properly in IE or FF.

Related

Run Javascript/jQuery inside iframe

I'm currently working on a web editor where you can enter your HTML, CSS and JavaScript code and see the result in real time. Something similar to JSBin or JSFiddle. (I'm doing that to get an offline editor)
I've already been through many problems especially when it comes to CSS but I solved them by using an iframe and injecting all my code into it. And that works amazingly well until you type some JavaScript.
I'm sending the code between <script></script> but unlike CSS it won't run. What's very weird is that when I enter something like $('button').css('color', 'red');, the buttons of the editor effectively get affected but not those of my iframe. Exactly the opposite of what I expected. I've tried many things, looked at many topics on the forum, but nothing works. I also tried to load a blank page in my iframe. In that case, JavaScript runs but it becomes impossible to edit the code in the iframe! What's going on? Where am I going wrong? Thank you in advance for your help!
Here's my editor : https://jsbin.com/tuqite/edit?html,js,output/
Try updating the content of the iframe like this.
// this string contains both html and script
var html_string= "content";
document.getElementById('childFrame').src = "data:text/html;charset=utf-8," + escape(html_string);
By directly updating the iframe DOM like the way you are doing may not be the right way .

Necessity of <!-- code here //--> block in old jsp file

I am working on some pretty old code and in every jsp file where there is a javaScript block I see some bizarre Syntax. It goes like :
<script language="JavaScript">
<!--
here is the main code (mixed jsp and javaScript)
//-->
</script>
neccesity <!-- code here //-->
I don't find any necessity for <!-- //--> this syntax. But to remove these from the whole project I really have to be sure why these syntax was used.
Does those had any significance previously, I mean for browser issue or something?
Or,
Just a simple mistake which were carried on.?
HTML style comments in javascript date back to a time when not all browsers supported javascript, so would render the code as text. The <script> tag was just assumed to be just like any other unknown tag, so the tag itself was not rendered, but the contents were
I don't think any current browser would have a problem with it, but I would recommend getting rid of it, because who knows what the future will bring
Does those had any significance previously, I mean for browser issue or something?
Yes, it used to. Remember that a script tag embeds non-HTML inside an HTML document, in this case JavaScript code. Since the content of the script tag isn't HTML, but is being parsed by an HTML parser (while it looks for the ending tag), the idea was to use an HTML comment (<!-- ... -->) to contain the JavaScript code, so the HTML parser wouldn't get confused by HTML-like things within the JavaScript code, and so really old browsers that didn't understand script tags at all wouldn't show the "text" inside them.
The one you've quoted is one of many variations.
There's no need, at all, to do this in an HTML document, with modern browsers — or even with really old browsers, at this point.
In an XHTML document, you do need to do something, but what's shown there is likely to be insufficient; you'd need a CDATA section instead.
Assuming you're writing HTML5 documents (<!doctype html>), you can remove those comments from the JSPs.
As stated here: http://www.w3schools.com/tags/tag_comment.asp
You can also use the comment tag to "hide" scripts from browsers without support for scripts (so they don't show them as plain text)
Nowadays not really an issue I suppose. But may not be the best idea to get rid of them.
Those are comments, just removed if no documentation comments are there
Back in the days there were all sorts of tricks used to make sure that the content looked decent even if the user had javascript or cookies disabled.
This looks like it was meant for hiding the javascript, if the browser didn't understand Javascript.

Content Scripts: Page-worker - <body> element with 0 width

I want to automatically open a website and reveal details about the rendered DOM. For that purpose I use a page-worker (https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/page-worker). When in the content script I execute something like the following:
var body = document.getElementsByTagName("body")[0];
console.log(getComputedStyle(body).width);
console.log(body.getBoundingClientRect().width);
The output is "0" for both of the width values. The same also applies to other elements. Should I conclude that DOM elements are not rendered properly when using a page-worker? Is there a way to gain authentic data from that? Or is there any other proper way to get details about the rendered DOM that behave exactly like the website was opened in a web browser by hand? Because if I open the same website manually and execute the same commands, it reveals (correctly) the width of the window (1440), of course.
edit
I probably should have said that before, but:
It's not that gaining the values does not work at all. If I go deeper in the DOM structure, I get correct values. I only have problems with the root body element, I think. Weirdly enough if I execute the exact same commands on the firefox console, the return values are perfectly correct.
It's very interesting the way you do it.
You don't have to do getElementsByTagName to get the body element, its a property of the document object var body = document.body;
getComputedStyle is a function of the window object so that's why it works without you putting window. in front of it but still just want to let you know.
You dont do a getPropertyValue which is required for getComputedStyle, I just tried it without it and it worked but i never saw it used like that before so maybe that has something to do with it:
So doing this from bootstrap or from scratchpad window: gBrowser.contentWindow.getComputedStyle(gBrowser.contentDocument.body).getPropertyValue('width')
works for me.
From your content-script scope do:
window.getComputedStyle(document.body).getPropertyValue('width')
If it still doesn't work I would thinky maybe myabe maybe, thers a chance you might be executing the code to early.
Let me know how that works.

How to dynamically add a Javascript function (and invoke)

Based on a click event on the page, via ajax I fetch a block of html and script, I am able to take the script element and append it to the head element, however WebKit based browsers are not treating it as script (ie. I cannot invoke a function declared in the appended script).
Using the Chrome Developer Tools I can see that my script node is indeed there, but it shows up differently then a script block that is not added dynamically, a non-dynamic script has a text child element and I cannot figure out a way to duplicate this for the dynamic script.
Any ideas or better ways to be doing this? The driving force is there is potentially a lot of html and script that would never be needed unless a user clicks on a particular tab, in which case the relevant content (and script) would be loaded. Thanks!
You could try using jQuery... it provides a method called .getScript that will load the JavaScript dynamically in the proper way. And it works fine in all well known browsers.
How about calling eval() on the content you receive from the server? Of course, you have to cut off the <script> and </script> parts.
If you're using a library like jQuery just use the built-in methods for doing this.
Otherwise you'd need to append it to the document rather than the head like this:
document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></scr" + "ipt>");
In all honesty, I have no idea why the script tag is cut like that, but a lot of examples do that so there's probably a good reason.
You'll also need to account for the fact that loading the script might take quite a while, so after you've appended this to the body you should set up a timer that checks if the script is loaded. This can be achieved with a simple typeof check on any global variable the script exports.
Or you could just do an eval() on the actual javascript body, but there might be some caveats.
Generally speaking though, I'd leave this kind of thing up to the browser cache and just load the javascript on the page that your tabs are on. Just try not to use any onload events, but rather call whatever initializers you need when the tab is displayed.

editing the <head> section with javascript

I would like to clear the entire head section once the page loads... actually, my goal would be to delete all JavaScript code held in the head section.
Is there some way to do something like this:
document.head.innerHTML = "";
Explanation:
I am using a Python script that uses Qt and webkit to take screenshots of websits.
It works on most sties, but there is one that it fails on. That site has a bunch of JavaScript code that it runs on timeouts. The WebKit webpage object allows me to execute JavaScript on the page. If there is some way to have the JavaScript remove all of the code form the head section I'd like to be able to try that for testing purposes to see if it resolves my screenshot script issue.
You can remove elements from the head, but it wont matter. The scripts have already run and removing the elements wont unload them or anything.
document.getElementsByTagName("head")[0].innerHTML = "";
// IE
var htmlEl = document.getElementsByTagName("html")[0];
htmlEl.removeChild(document.getElementsByTagName("head")[0])
var el = document.createElement("head");
htmlEl.appendChild(el);
To stop JavaScript scripts running by setTimeout, you should use clearTimeout, but for this case you should have a handler... But you're lucky, if they are defined as global variables.
Try using:
document.getElementsByTagName('head').innerHTML = "";
to clear the head. document.head does not exist so this may not work.
But you may want to try to disable the JavaScript using JavaScript like suggested by noah.
See http://www.manticmoo.com/articles/jeff/programming/javascript/removing-javascript-with-javascript.php for directions. It sounds crazy but evidently it works.
As noah said, simply removing the code from the head tag won't accomplish anything. You have to actually undo what the code is doing. For example, if it's using setTimeout() to set up the timeout code you're complaining about, you need to use clearTimeout() to disable it.
$('#id').empty();
Worked very well.

Categories

Resources