Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Handle DOMParser exception #175

Merged
merged 2 commits into from

3 participants

@reed
Collaborator
  • Fixes #168
  • Alternative to #174
  • Implemented without overloading DOMParser
  • Tested on:
    • Firefox 9
    • Firefox 18.0.1
    • Opera 12.12
    • Chrome 24.0.1312.56
    • Safari 6.0
@dhh
Owner

Looking good but let's get some comments in there for the various tests explaining what they're intended for.

@reed
Collaborator

Updated with comments.

@dhh dhh merged commit 16d3c85 into rails:master
@cmer

Not sure if this helps, but here's the workaround we've been using to fix the DOMParser in Opera (sorry for pure JS):

// Fix DOMParser (used in Turbolink) under Opera.
// Source: http://stackoverflow.com/questions/9500318/troubles-trying-to-parse-an-html-string-with-domparser
if (typeof(DOMParser) !== "undefined") {
    (function(DOMParser) {  
        "use strict";  
        var DOMParser_proto = DOMParser.prototype  
          , real_parseFromString = DOMParser_proto.parseFromString;

        // Test if parsing will throw an error. If so, it's DAMN broken!
        var broken = false;
        try {  
            (new DOMParser).parseFromString("", "text/html");
        } catch (ex) {
            broken = true;
        }

        if (broken) {
            // Patching DOMParser

            DOMParser_proto.parseFromString = function(markup, type) {  
                if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {  
                    var doc = document.implementation.createHTMLDocument("")
                      , doc_elt = doc.documentElement
                      , first_elt;

                    doc_elt.innerHTML = markup;
                    first_elt = doc_elt.firstElementChild;

                    if (doc_elt.childElementCount === 1
                        && first_elt.localName.toLowerCase() === "html") {  
                        doc.replaceChild(first_elt, doc_elt);  
                    }  

                    return doc;  
                } else {  
                    return real_parseFromString.apply(this, arguments);  
                }  
            };  
        }
    }(DOMParser));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 28, 2013
  1. @reed

    Handle DOMParser exception

    reed authored
Commits on Jan 29, 2013
  1. @reed
This page is out of date. Refresh to see the latest.
Showing with 25 additions and 7 deletions.
  1. +25 −7 lib/assets/javascripts/turbolinks.js.coffee
View
32 lib/assets/javascripts/turbolinks.js.coffee
@@ -155,6 +155,11 @@ browserCompatibleDocumentParser = ->
createDocumentUsingParser = (html) ->
(new DOMParser).parseFromString html, 'text/html'
+ createDocumentUsingDOM = (html) ->
+ doc = document.implementation.createHTMLDocument ''
+ doc.documentElement.innerHTML = html
+ doc
+
createDocumentUsingWrite = (html) ->
doc = document.implementation.createHTMLDocument ''
doc.open 'replace'
@@ -162,13 +167,26 @@ browserCompatibleDocumentParser = ->
doc.close()
doc
- if window.DOMParser
- testDoc = createDocumentUsingParser '<html><body><p>test'
-
- if testDoc?.body?.childNodes.length is 1
- createDocumentUsingParser
- else
- createDocumentUsingWrite
+ # Use createDocumentUsingParser if DOMParser is defined and natively
+ # supports 'text/html' parsing (Firefox 12+, IE 10)
+ #
+ # Use createDocumentUsingDOM if createDocumentUsingParser throws an exception
+ # due to unsupported type 'text/html' (Firefox < 12, Opera)
+ #
+ # Use createDocumentUsingWrite if:
+ # - DOMParser isn't defined
+ # - createDocumentUsingParser returns null due to unsupported type 'text/html' (Chrome, Safari)
+ # - createDocumentUsingDOM doesn't create a valid HTML document (safeguarding against potential edge cases)
+ try
+ if window.DOMParser
+ testDoc = createDocumentUsingParser '<html><body><p>test'
+ createDocumentUsingParser
+ catch e
+ testDoc = createDocumentUsingDOM '<html><body><p>test'
+ createDocumentUsingDOM
+ finally
+ unless testDoc?.body?.childNodes.length is 1
+ return createDocumentUsingWrite
installClickHandlerLast = (event) ->
Something went wrong with that request. Please try again.