0

I am making a live editor for my website. I have the CSS and HTML parts down, only issue is the JS part now. Here is a snippet of the code

var frame = $('#preview_content'),
           contents = frame.contents(),
           body = contents.find('body');
           csstag = contents.find('head').append('<style></style>').children('style');
           java = contents.find('head').append('<script><\/script>').children('script');//Issues here
       $('.area_content_box').focus(function() {
       var $this = $(this);
       var check = $this.attr('id');
        $this.keyup(function() {

        if (check === "html_process"){
        body.html($this.val());
        } else if(check === "css_process") {
        csstag.text($this.val());
        } else if (check === "java_process"){
        java.text( $this.val() );
        }

        });
      });

Problem is it is not injecting script tags in the iframes body nor the head when ever I try this. I've read up on injecting and some issues containing the ending script tag. I need to figure out how to inject script tags, really want them in the head but if it is easier in the body that is fine.

jfriend00 - I will be focusing on making this vanilla, if you think I should honestly.

So any words of advice on how to go about making my editor work correctly with the injecting JS?

EasyBB
  • 6,176
  • 9
  • 47
  • 77
  • Have you thought about using contenteditable attribute instead of an iframe? Even IE supports it going way back. – Jodes Mar 12 '13 at 04:25
  • Is contenteditable able to show like an iframe? If you understand what I mean? – EasyBB Mar 12 '13 at 04:28
  • It's different, but the same effect can be achieved. You only really want to use an iframe these days in a limited range of scenarios where you're embedding something from another website. – Jodes Mar 12 '13 at 04:36
  • Well I do plan on using some other sites of mine that are hosted some where else to be a guide for my users to find and see the ID/ Class name. Do so do you know if there is any way for the iframe injection? If not how would a contenteditable go about this – EasyBB Mar 12 '13 at 04:42
  • have you found a solution to this ? Secondly, in my case the iframe comes from different domain. Is injecting java-script still possible ? – coding_idiot Sep 28 '13 at 08:37

1 Answers1

4

These two lines of code look like they could have problems:

csstag = contents.find('head').append('<style></style>').children('style');
java = contents.find('head').append('<script><\/script>').children('script');//Issues here

It seems like it would be much better to create the style tag and remember that DOM element.

var iframe = document.getElementById("preview_content");
var iframewindow = iframe.contentWindow || iframe.contentDocument.defaultView;
var doc = iframewindow.document;
var csstag = doc.createElement("style");
var scripttag = doc.createElement("script");
var head = doc.getElementsByTagName("head")[0];
head.appendChild.cssTag;
head.appendChild.scriptTag;

$('.area_content_box').focus(function() {
    var $this = $(this);
    var check = this.id;
    $this.keyup(function() {
        if (check === "html_process") {\
            // I would expect this to work
            doc.body.html($this.val());
        } else if(check === "css_process") {
            // I don't know if you can just replace CSS text like this 
            // or if you have to physically remove the previous style tag
            // and then insert a new one
            csstag.text($this.val());
        } else if (check === "java_process"){
            // this is unlikely to work
            // you probably have to create and insert a new script tag each time
            java.text( $this.val() );
        }
    });
});

This should work for the body HTML and it may work for the CSS text into the style tag.

I do not believe it will work for the javascript as you can't change a script by assigning text to the tag the way you are. Once a script has been parsed, it's in the javascript namespace.

There is no public API I'm aware of for removing previously defined and interpreted scripts. You can redefine global symbols with subsequent scripts, but not remove previous scripts or their effects.

If this were my code, I'd remove the previous style tag, create a new one, set the text on it before it was inserted in the DOM and then insert it in the DOM.

If you're not going to do it that way, then you'll have to test to see if this concept of setting .text() on an already inserted (and parsed) style tag works or not in all relevant browsers.

For the script tag, I'm pretty sure you'll have to create a new script tag and reinsert it, but there's no way to get rid of older code that has already been parsed other than redefining global symbols. If you really wanted to start fresh on the code, you'd have to create a new iframe object from scratch.


There are other issues with this too. You're installing a .keyup() event handler every time the .area_content_box gets focus which could easily end up with many of the event handlers installed, all getting called and all trying to do the same work.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Hmmm I'll take a look over this tomorrow as I am headed to bed. I know the CSS works. This is just a Live Editor. There are no styles in the elements. The person clicks the HTML textarea and writes HTML. Then they click the CSS box and style those elements. Then the javascript would be the same way just inside the script tags lol. Its sort of like JSBin, but I am making it specifically for my site and adding some features that work with the hosting company. Still up voted for you actually coming and reading this. Thank you – EasyBB Mar 12 '13 at 06:21
  • In my case the iframe comes from different domain, is injecting java-script still possible ? – coding_idiot Sep 28 '13 at 08:37
  • 1
    @coding_idiot - For security reasons, you cannot modify an iframe from a different domain. See same origin policy [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript). – jfriend00 Sep 28 '13 at 18:44
  • There must be some way. I'm thinking about applet & flash. Do you think it's possible that way ?! – coding_idiot Sep 28 '13 at 22:01
  • @coding_idiot - did you read the reference on same-origin security restrictions I cited? Unless you can change the code in the iframe on the other domain to cooperate via something like `window.postMessage()`, then you can't modify a frame on another domain. – jfriend00 Sep 28 '13 at 22:07
  • yeah, I did read that. Sorry to write a confusing reply. Actually the main goal is to send http-requests to different domain from users' browser using browser cookies for that domain. I believe this can be attained by applet. – coding_idiot Sep 28 '13 at 23:59
  • @coding_idiot - I'd suggest you post your own question with your own specifics because your request seems to have little to do with this question/answer. You may want to look into [JSONP](http://en.wikipedia.org/wiki/JSONP). – jfriend00 Sep 29 '13 at 00:27