How to use DOMParser in PhantomJS?

2.2k views Asked by At

The following snippet works correctly and returns a Document node in Firefox, Chrome and Safari web consoles. However, it returns null in PhantomJS 1.9.8.

(new DOMParser()).parseFromString("<div></div>", "text/html");

Any idea why this is returning null?

3

There are 3 answers

2
Artjom B. On BEST ANSWER

As you may have noticed parseFromString() takes a second argument which denotes the expected type. HTML is simply not supported in PhantomJS (currently version 2.0.0):

enter image description here

As this page notes, PhantomJS 2 is based on WebKit 538.1 (October/November 2013) and the above table shows that HTML support was added into Chrome with version 30 which came out on 1. Oktober 2013 which was already Blink (yes, the german WikiPedia page is better than the english one). It came probably in a later WebKit version depending on development cycles.

Other ways

  • PhantomJS can create a DOCUMENT from "text/xml". So if you have xhtml, you can parse it like this.

  • You can also look into other ways of parsing HTML. This MDN article is extensive in that regard: HTML to DOM.

  • If that's fruitless, you can try to see if some node.js module can parse HTML sufficiently. PhantomJS and node.js have different execution environments, but modules that have almost no dependencies tend to work in both.

0
schpet On

you can use a polyfill like this one:
https://gist.github.com/eligrey/1129031

if you copy that into vendor/assets/javascripts, you can have it load only in tests:

# config/initializers/assets.rb
Rails.application.config.assets.precompile += %w(html-domparser.js)

# app/views/layouts/application.html.erb
<%= javascript_include_tag 'html-domparser' if Rails.env.test? =>

alternatively if you are interested in supporting older browsers, you can load it in all environments like any other js.

0
user2031423 On

Building off of what @schpet wrote.

If you feel strange about the if Rails.env.test? in your application.html.erb.

This worked for me: in rails_helper.rb:

Capybara.register_driver :poltergeist do |app|
  options = {
    phantomjs: "/usr/local/bin/phantomjs",
    extensions: [
      Rails.root.join("vendor", "assets", "javascripts", "html-domparser.js"),
    ],
  }
  Capybara::Poltergeist::Driver.new(app, options)
end