Coder Social home page Coder Social logo

cloudbrowser-jsdom's Introduction

jsdom

A JavaScript implementation of the W3C DOM.

Install

$ npm install jsdom

Human contact

see: mailing list

Easymode

Bootstrapping a DOM is generally a difficult process involving many error prone steps. We didn't want jsdom to fall into the same trap and that is why a new method, jsdom.env(), has been added in jsdom 0.2.0 which should make everyone's lives easier.

with URL

// Count all of the links from the nodejs build page
var jsdom = require("jsdom");

jsdom.env(
  "http://nodejs.org/dist/",
  ["http://code.jquery.com/jquery.js"],
  function (errors, window) {
    console.log("there have been", window.$("a").length, "nodejs releases!");
  }
);

or with raw HTML

// Run some jQuery on a html fragment
var jsdom = require("jsdom");

jsdom.env(
  '<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom\'s Homepage</a></p>',
  ["http://code.jquery.com/jquery.js"],
  function(errors, window) {
    console.log("contents of a.the-link:", window.$("a.the-link").text());
  }
);

or with a configuration object

// Print all of the news items on hackernews
var jsdom = require("jsdom");

jsdom.env({
  html: "http://news.ycombinator.com/",
  scripts: ["http://code.jquery.com/jquery.js"],
  done: function (errors, window) {
    var $ = window.$;
    console.log("HN Links");
    $("td.title:not(:last) a").each(function() {
      console.log(" -", $(this).text());
    });
  }
});

or with raw JavaScript source

// Print all of the news items on hackernews
var jsdom = require("jsdom");
var fs = require("fs");
var jquery = fs.readFileSync("./jquery.js").toString();

jsdom.env({
  html: "http://news.ycombinator.com/",
  src: [jquery],
  done: function (errors, window) {
    var $ = window.$;
    console.log("HN Links");
    $("td.title:not(:last) a").each(function() {
      console.log(" -", $(this).text());
    });
  }
});

How it works

jsdom.env is built for ease of use, which is rare in the world of the DOM! Since the web has some absolutely horrible JavaScript on it, as of jsdom 0.2.0 jsdom.env will not process external resources (scripts, images, etc). If you want to process the JavaScript use one of the methods below (jsdom.jsdom or jsdom.jQueryify)

jsdom.env(html, [scripts], [config], callback);
  • html (required): may be a URL, HTML fragment, or file.
  • scripts (optional): may contain files or URLs.
  • config (optional): see below.
  • callback (required): takes two arguments:
    • errors: an array of errors
    • window: a brand new window

example:

jsdom.env(html, function (errors, window) {
  // free memory associated with the window
  window.close();
});

If you would like to specify a configuration object only:

jsdom.env(config);
  • config.html: see html above.
  • config.scripts: see scripts above.
  • config.src: an array of JavaScript strings that will be evaluated against the resulting document. Similar to scripts, but it accepts JavaScript instead of paths/URLs.
  • config.done: see callback above.
  • config.document:
    • referer: the new document will have this referer
    • cookie: manually set a cookie value, e.g. 'key=value; expires=Wed, Sep 21 2011 12:00:00 GMT; path=/'
  • config.features : see Flexibility section below. Note: the default feature set for jsdom.env does not include fetching remote JavaScript and executing it. This is something that you will need to carefully enable yourself.

For the hardcore

If you want to spawn a document/window and specify all sorts of options this is the section for you. This section covers the jsdom.jsdom method:

var jsdom = require("jsdom").jsdom;
var doc = jsdom(markup, level, options);
var window = doc.createWindow();
  • markup is an HTML/XML document to be parsed. You can also pass null or an undefined value to get a basic document with empty <head> and <body> tags. Document fragments are also supported (including ""), and will behave as sanely as possible (e.g. the resulting document will lack the head, body and documentElement properties if the corresponding elements aren't included).

  • level is null (which means level3) by default, but you can pass another level if you'd like.

    var jsdom = require("jsdom");
    var doc = jsdom.jsdom("<html><body></body></html>", jsdom.level(1, "core"));
  • options see the Flexibility section below.

Flexibility

One of the goals of jsdom is to be as minimal and light as possible. This section details how someone can change the behavior of Documents on the fly. These features are baked into the DOMImplementation that every Document has, and may be tweaked in two ways:

  1. When you create a new Document using the jsdom builder (require("jsdom").jsdom())
var jsdom = require("jsdom").jsdom;
var doc = jsdom("<html><body></body></html>", null, {
  features: {
    FetchExternalResources : ["img"]
  }
});

Do note, that this will only affect the document that is currently being created. All other documents will use the defaults specified below (see: Default Features).

  1. Before creating any documents, you can modify the defaults for all future documents:
require("jsdom").defaultDocumentFeatures = {
  FetchExternalResources: ["script"],
  ProcessExternalResources: false,
  MutationEvents: false,
  QuerySelector: false
};

Default Features

Default features are extremely important for jsdom as they lower the configuration requirement and present developers a set of consistent default behaviors. The following sections detail the available features, their defaults, and the values that jsdom uses.

FetchExternalResources

  • Default: ["script"]
  • Allowed: ["script", "img", "css", "frame", "iframe", "link"] or false

Enables/disables fetching files over the file system/HTTP.

ProcessExternalResources

  • Default: ["script"]
  • Allowed: ["script"] or false

Disabling this will disable script execution (currently only JavaScript).

MutationEvents

  • Default: "2.0"
  • Allowed : "2.0" or false

Initially enabled to be up to spec. Disable this if you do not need mutation events and want jsdom to be a bit more efficient.

Note: ProcessExternalResources requires this to be enabled.

QuerySelector

  • Default : false
  • Allowed : true

This feature is backed by sizzle but currently causes problems with some libraries. Enable this if you want document.querySelector and friends, but be aware that many libraries feature detect for this, and it may cause you a bit of trouble.

Canvas

jsdom includes support for using the canvas package to extend any <canvas> elements with the canvas API. To make this work, you need to include canvas as a dependency in your project, as a peer of jsdom. If jsdom can find the canvas package, it will use it, but if it's not present, then <canvas> elements will behave like <div>s.

More Examples

Creating a document-less window

var jsdom = require("jsdom");
var window = jsdom.createWindow();

console.log(window.document); // output: undefined

Creating a document

var jsdom = require("jsdom");
var doc = new (jsdom.level(1, "core").Document)();

console.log(doc.nodeName); // outputs: #document

Creating a browser-like BOM/DOM/Window

var jsdom = require("jsdom").jsdom;
var document = jsdom("<html><head></head><body>hello world</body></html>");
var window = document.createWindow();

console.log(window.document.innerHTML);
// output: "<html><head></head><body>hello world</body></html>"

console.log(window.innerWidth);
// output: 1024

console.log(typeof window.document.getElementsByClassName);
// outputs: function

jQueryify

var jsdom = require("jsdom");
var window = jsdom.jsdom().createWindow();

jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
  window.$("body").append('<div class="testing">Hello World, It works</div>');

  console.log(window.$(".testing").text());
});

Passing objects to scripts inside the page

var jsdom = require("jsdom").jsdom;
var window = jsdom().createWindow();

window.__myObject = { foo: "bar" };

var scriptEl = window.document.createElement("script");
scriptEl.src = "anotherScript.js";
window.document.body.appendChild(scriptEl);

// anotherScript.js will have the ability to read `window.__myObject`, even
// though it originated in Node!

Test Compliance:

 level1/core                        532/532      100%
 level1/html                        238/238      100%
 level1/svg                         527/527      100%
 level2/core                        283/283      100%
 level2/html                        694/694      100%
 level2/style                           5/5      100%
 level2/extra                           4/4      100%
 level2/events                        24/24      100%
 level3/xpath                         93/93      100%
 window/index                           5/5      100%
 window/script                        10/10      100%
 window/frame                         14/14      100%
 sizzle/index                         12/15       80%
 jsdom/index                          80/80      100%
 jsonp/jsonp                            1/1      100%
 browser/contextifyReplacement          4/4      100%
 browser/index                        22/22      100%
------------------------------------------------------
TOTALS: 3/2551 failed; 99% success

Running the tests

First you'll want to npm install. To run all the tests, use npm test, which just calls node test/runner.

Using test/runner directly, you can slice and dice which tests your want to run from different levels. Usage is as follows:

test/runner --help
Run the jsdom test suite

Options:
-s, --suites     suites that you want to run. ie: -s level1/core,1/html,html [string]
-f, --fail-fast  stop on the first failed test
-h, --help       show the help
-t, --tests      choose the test cases to run. ie: -t jquery

cloudbrowser-jsdom's People

Contributors

tmpvar avatar waslogic avatar davglass avatar fgnass avatar djcsdy avatar domenic avatar brianmcd avatar swizec avatar aredridel avatar karunasagark avatar papandreou avatar yonran avatar ejones avatar jasondavies avatar godmar avatar aflatter avatar josh avatar indexzero avatar deitch avatar liucougar avatar trodrigues avatar oelmekki avatar jsievert avatar joshmarshall avatar iizukanao avatar sinegar avatar lbdremy avatar d-ash avatar fbzhong avatar rubys avatar

Watchers

JT5D avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.