1

I have a backbone.js CMS of sorts, that accepts html and then renders it in the browser. The following is the template file (in .hamlc) that renders the backbone page object.

%h1.text= @page.get('title')
.text.page-content!= @page.get('content')

This works fine, until I have a <script> tag. I have a script tag for a widget (below)

<script src='http://www.opentable.com/frontdoor/default.aspx?rid=52900&restref=52900&bgcolor=8AA86B&titlecolor=0F0F0F&subtitlecolor=0F0F0F&btnbgimage=http://www.opentable.com/frontdoor/img/ot_btn_black.png&otlink=FFFFFF&icon=light&mode=short&hover=1'></script>

This widget uses document.write (which you can see if you look at the source). First, when I load the page it doesn't show anything (I've tested the widget in an html file by itself and it displays their normal god-awful ). When I inspect the element, it looks like the script tag was removed.

However, when I test with the following:

<script type="text/javascript">
    alert(0);
</script>

It runs. Still nothing in the inspector though.

Finally, testing with the following:

<script type="text/javascript">
    document.write('test');
</script>

It also runs. However, it completely destroys the page content and just shows 'test'.

According to this article about using document.write for widgets, it says it can't be run after the page load. I'm assuming that's what's happening here is that document.write is being run after page load and destroying all the content, given that's the technique backbone.js uses (appending/replacing elements in the DOM once the page is loaded).

How can I make my Backbone.js CMS accept script tags with document.write widgets without either not showing anything or destroying the entire page?

jake
  • 1,635
  • 2
  • 20
  • 30
  • Can you expand this question some more? Based on the sample code you provided, it's unclear where/how Backbone.js even fits into this equation. Can you give some more supporting code samples? – cpjolicoeur Jun 27 '13 at 14:19
  • I didn't give more code samples (let me know if something else might be helpful), but re-asked without all of the update nonsense. Hopefully it's a little clearer. – jake Jun 27 '13 at 14:59

3 Answers3

2

I cannot reproduce it, the template renders as it should:

$ coffee
coffee> hc = require './src/hamlc'
{ compile: [Function],
  template: [Function],
  __express: [Function] }
coffee> template = hc.compile ".text.page-content!= @content"
[Function]
coffee> template(content: 'Hello <script>Script</script>')
'<div class=\'page-content text\'>Hello <script>Script</script></div>'

and the script tag is persisted. Do you have the latest version installed?

Netzpirat
  • 5,481
  • 1
  • 22
  • 21
  • I'm using haml_coffee_assets 1.12.0 – jake Jun 18 '13 at 14:03
  • If I put comments around it, then it persists. If I don't, when I inspect element in chrome, it's not there... Also, it leaves the script tag in if I use "=" instead of "!=". Not sure if this is a backbone thing? – jake Jun 18 '13 at 14:34
1

If I understand correctly, you're trying to include the script tag for the widget inside a template, which means it's being inserted after the initial DOM is ready. That won't work for the reasons you mentioned; when the script executes, it will replace everything in the DOM.

You need to load the script before the initial DOM is complete, that is either in <head> or at the beginning of <body>. That in turn means that you have to include the script tag in your initial HTML as delivered by the server rather than trying to dynamically generate it client-side.

ebohlman
  • 14,795
  • 5
  • 33
  • 35
  • Right, but isn't this impossible with Backbone.js? It's a client-side framework. – jake Jul 01 '13 at 13:19
  • The script tag simply becomes part of the initial HTML payload the server delivers, the same payload that invokes the application's scripts. – ebohlman Jul 01 '13 at 22:25
1

You're calling document.write after the page has been loaded, so it'll overwrite the whole page. You could try putting the script tag in an iframe, or monkey patch document.write to behave differently after the page has been loaded. See the top answer on this question:

Dynamically added JavaScript overwrite the html page view (not the code)

Community
  • 1
  • 1
wkf
  • 842
  • 9
  • 17