Skip to content
Closed
86 changes: 54 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ If this gives you trouble with errors about installing Contextify, especially on

see: [mailing list](http://groups.google.com/group/jsdom)

## Easymode
## Easymode: `jsdom.env`

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.
`jsdom.env` is an API that allows you to throw a bunch of stuff at it, and it will generally do the right thing.

You can use it with a URL

Expand Down Expand Up @@ -51,7 +51,7 @@ jsdom.env(
or with a configuration object

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

jsdom.env({
Expand All @@ -70,7 +70,7 @@ jsdom.env({
or with raw JavaScript source

```js
// Print all of the news items on hackernews
// Print all of the news items on Hacker News
var jsdom = require("jsdom");
var fs = require("fs");
var jquery = fs.readFileSync("./jquery.js", "utf-8");
Expand All @@ -89,6 +89,7 @@ jsdom.env({
```

### 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`)

```js
Expand All @@ -101,8 +102,8 @@ The arguments are:
- `scripts`: a string or array of strings, containing file names or URLs that will be inserted as `<script>` tags
- `config`: see below
- `callback`: takes two arguments
- `error`: either an `Error` object if something failed initializing the window, or an array of error messages from the DOM if there were script errors
- `window`: a brand new `window`
- `errors`: either `null`, if nothing goes wrong, or an array of errors
- `window`: a brand new `window`, if there were no loading errors

_Example:_

Expand All @@ -125,33 +126,63 @@ jsdom.env(config);
- `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.jar`: a custom cookie jar, if desired; see [mikeal/request](https://github.com/mikeal/request) documentation.
- `config.done`: see `callback` above.
- `config.level`: either `1`, `2`, `3`, or `'living'`, to restrict yourselves to features in certain DOM specifications. The default is `'living'`.
- `config.document`:
- `referrer`: the new document will have this referrer.
- `cookie`: manually set a cookie value, e.g. `'key=value; expires=Wed, Sep 21 2011 12:00:00 GMT; path=/'`.
- `cookieDomain`: a cookie domain for the manually set cookie; defaults to `127.0.0.1`.
- `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.
- `config.features`: see `Flexibility` section below. **Note**: the default feature set for `jsdom.env` will fetch and execute remote JavaScript, which may be dangerous. Be careful!
- `config.done`, `config.loaded`, `config.created`: see below.

Note that at least one of the callbacks (`done`, `loaded`, or `created`) is required, as is one of `html`, `file`, or `url`.

### Initialization lifecycle

If you just want to load the document and execute it, the `done` callback shown above is the simplest. If anything goes wrong, either while loading the document and creating the window, or while executing any `<script>`s, the problem will show up in the `errors` array passed as the first argument.

However, if you want more control over or insight into the initialization lifecycle, you'll want to use the `created` and/or `loaded` callbacks:

#### `created(error, window)`

The `created` callback is called as soon as the window is created, or if that process fails. You may access all `window` properties here; however, `window.document` is not ready for use yet, as the HTML has not been parsed.

The primary use-case for `created` is to modify the window object (e.g. add new functions on built-in prototypes) before any scripts execute.

You can also set an event handler for `'load'` or other events on the window if you wish. But the `loaded` callback, below, can be more useful, since it includes script errors.

If the `error` argument is non-`null`, it will contain whatever loading error caused the window creation to fail; in that case `window` will not be passed.

#### `loaded(errors, window)`

The `loaded` callback is called along with the window's `'load'` event. This means it will only be called if creation succeeds without error. Note that by the time it has called, any external resources will have been downloaded, and any `<script>`s will have finished executing.

If `errors` is non-`null`, it will contain an array of all JavaScript errors that occured during script execution. `window` will still be passed, however.

#### `done(errors, window)`

Note that `config.done` is required, as is one of `config.html`, `config.file`, or `config.url`.
Now that you know about `created` and `loaded`, you can see that `done` is essentially both of them smashed together:

## For the hardcore
- If window creation succeeds and no `<script>`s cause errors, then `errors` will be null, and `window` will be usable.
- If window creation succeeds but there are script errors, then `errors` will be an array containing those errors, but `window` will still be usable.
- If window creation fails, then `errors` will be an array containing the creation error, and `window` will not be passed.

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:
#### Migrating from before v1.0.0

If you used jsdom before v1.0.0, it only had a `done` callback, and it was kind of buggy, sometimes behaving one way, and sometimes another. Due to some excellent work by [@Sebmaster](https://github.com/Sebmaster) in [#792](https://github.com/tmpvar/jsdom/pull/792), we fixed it up into the above lifecycle. For more information on the migration, see [the wiki](https://github.com/tmpvar/jsdom/wiki/PR-792).

## For the hardcore: `jsdom.jsdom`

The `jsdom.jsdom` method does less things automatically; it takes in only HTML source, and does not let you to separately supply script that it will inject and execute. It just gives you back a `document` object, with usable `document.parentWindow`, and starts asynchronously executing any `<script>`s included in the HTML source. You can listen for the `'load'` event to wait until scripts are done loading and executing, just like you would in a normal HTML page.

Usage of the API generally looks like this:

```js
var jsdom = require("jsdom").jsdom;
var doc = jsdom(markup, level, options);
var doc = jsdom(markup, options);
var window = doc.parentWindow;
```

- `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.

```js
var jsdom = require("jsdom");
var doc = jsdom.jsdom("<html><body></body></html>", jsdom.level(1, "core"));
```
- `markup` is an HTML/XML document to be parsed. You can also pass `undefined` to get the basic document, equivalent to what a browser will give if you open up an empty `.html` file. Our parser currently doesn't do that well with missing `<html>`, `<head>`, and `<body>` tags, but we're working to fix that.

- `options` See the explanation of the `config` object above.

Expand All @@ -163,7 +194,7 @@ One of the goals of jsdom is to be as minimal and light as possible. This sectio

```js
var jsdom = require("jsdom").jsdom;
var doc = jsdom("<html><body></body></html>", null, {
var doc = jsdom("<html><body></body></html>", {
features: {
FetchExternalResources : ["img"]
}
Expand Down Expand Up @@ -214,16 +245,7 @@ jsdom includes support for using the [canvas](https://npmjs.org/package/canvas)

## More Examples

### Creating a document

```js
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
### Creating a browser-like Window

```js
var jsdom = require("jsdom").jsdom;
Expand Down Expand Up @@ -273,7 +295,7 @@ window.document.body.appendChild(scriptEl);

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:
Using `test/runner` directly, you can slice and dice which tests your want to run. Usage is as follows:

```
test/runner --help
Expand Down
Loading