jejacks0n / teaspoon

Teaspoon: Javascript test runner for Rails. Use Selenium, BrowserStack, or PhantomJS.
1.43k stars 243 forks source link

Don't use innerHTML for fixtures! #387

Closed mcasimir closed 9 years ago

mcasimir commented 9 years ago

Hi guys.

using innerHTML in fixture load/add will cause IE8 and below to completely remove <script> tags and any other browser to ignore them (wont run as expected).

You have basically 2 workaround to make it behave correctly:

1- Get rid of innerHTML and use a Cross Browser DOM parser:

onLoadComplete: (content) ->
   fragment = parseFragment(content);
   target.appendChild(fragment);

2- A working but risky hack on html:

onLoadComplete: (content) ->
  content = content.replace(/<script/g, '<div data-was-script="1"').replace(/script>/g, 'div>');

  # Use this in place of innerHTML cause it has better support:
  target.insertAdjacentHTML('afterbegin', content);

  traverse target, child ->
    if elem.getAttribute('data-was-script')
            src = child.getAttribute('src');
            runningScript = if src then createScriptWithSrc(src) else createScriptWithContent(child.innerHTML);
            insertAfter(child, runningScript);
            child.parentNode.removeChild(child);
mcasimir commented 9 years ago

Update

Since IE8 support is a must for our project i patched teaspoon fixture to use jquery.parseHTML, it worked perfectly. You can provide a similar solution. Sorry for vanilla js:

  addContent = function(content) {
    if (!window.fixture.el) {
      create();
    }
    var parsed = $($.parseHTML(content, document, true));
    for (var i = 0; i < parsed.length; i++) {
      window.fixture.el.appendChild(parsed[i]);
    }
  };

  putContent = function(content) {
    cleanup();
    addContent(content);
  };

Notice the 3rd parameter that specifies wether you want to run scripts or just append to the dom.

mikepack commented 9 years ago

I've opened #389 to fix this, but it will only work if the host project uses jQuery. Teaspoon does not ship with jQuery and therefor cannot rely on it. Thank you for the succinct solution!