Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Commit

Permalink
Browser is now an EventEmitter, you can listen to drain (event queue
Browse files Browse the repository at this point in the history
empty), error (loading page) and loaded (what is says).
  • Loading branch information
assaf committed Dec 22, 2010
1 parent 2e14582 commit 8473a74
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,9 @@ Added `querySelector` and `querySelectorAll` based on the [DOM Selector
API](http://www.w3.org/TR/selectors-api/). Use this instead of `find`
method.

Browser is now an EventEmitter, you can listen to drain (event queue
empty), error (loading page) and loaded (what is says).

184 tests
2.0 sec to complete

Expand Down
13 changes: 13 additions & 0 deletions README.md
Expand Up @@ -201,6 +201,19 @@ The terminator is optional and can be one of:

Returns the main window.

#### Event: "drain"

Emitted whenever the event queue goes back to empty.

#### Event: "loaded"

Emitted whenever new page loaded. This event is emitted before `DOMContentLoaded`.

#### Event: "error"

Emitted if an error occurred loading a page or submitting a form.




## Guts
Expand Down
23 changes: 23 additions & 0 deletions spec/browser-spec.coffee
Expand Up @@ -85,6 +85,29 @@ vows.describe("Browser").addBatch(
"should execute route": (browser)-> assert.equal browser.text("#main"), "The Living Dead"
"should change location": (browser)-> assert.equal browser.location, "http://localhost:3003/living#/dead"

"event emitter":
"successful":
topic: ->
browser = new zombie.Browser
browser.on "loaded", (browser)=> @callback null, browser
browser.wants "http://localhost:3003/"
"should fire load event": (browser)-> assert.ok browser.visit
"error":
topic: ->
browser = new zombie.Browser
browser.on "error", (err)=> @callback null, err
browser.wants "http://localhost:3003/deadend"
"should fire onerror event": (err)->
assert.ok err.message && err.stack
assert.equal err.message, "Could not load document at http://localhost:3003/deadend, got 404"
"wait over":
topic: ->
browser = new zombie.Browser
browser.on "drain", (browser)=> @callback null, browser
browser.wants "http://localhost:3003/"
"should fire done event": (browser)-> assert.ok browser.visit


"content selection":
zombie.wants "http://localhost:3003/living"
"query text":
Expand Down
2 changes: 1 addition & 1 deletion spec/helpers.coffee
Expand Up @@ -77,7 +77,7 @@ zombie.wants = (url, context)->
zombie.Browser.prototype.wants = (url, callback)->
brains.ready =>
@visit url, (err, browser)=>
callback err, this
callback err, this if callback
return


Expand Down
6 changes: 4 additions & 2 deletions src/zombie/browser.coffee
@@ -1,12 +1,13 @@
jsdom = require("jsdom")

require "./jsdom_patches"
require "./sizzle"
require "./forms"

# Use the browser to open up new windows and load documents.
#
# The browser maintains state for cookies and localStorage.
class Browser
class Browser extends require("events").EventEmitter
constructor: ->
cookies = require("./cookies").use(this)
storage = require("./storage").use(this)
Expand Down Expand Up @@ -60,7 +61,8 @@ class Browser
if !callback
callback = terminate
terminate = null
eventloop.wait window, terminate, (err) => callback err, this
eventloop.wait window, terminate, (error) =>
callback error, this if callback
return

# ### browser.fire(name, target, calback?)
Expand Down
2 changes: 2 additions & 0 deletions src/zombie/eventloop.coffee
Expand Up @@ -114,10 +114,12 @@ class EventLoop
return
@wait window, terminate, callback, intervals
catch err
browser.emit "error", err
callback err, window
else if requests > 0
waiting.push => @wait window, terminate, callback, intervals
else
browser.emit "drain", browser
callback null, window

# Counts outstanding requests.
Expand Down
9 changes: 7 additions & 2 deletions src/zombie/history.coffee
Expand Up @@ -137,27 +137,32 @@ class History
document.open()
document.write body
document.close()
error = "Could not parse document at #{URL.format(url)}" unless document.documentElement
if document.documentElement
browser.emit "loaded", browser
else
error = "Could not parse document at #{URL.format(url)}"
when 301, 302, 303, 307
redirect = URL.parse(URL.resolve(url, response.headers["location"]))
stack[index] = { url: redirect }
browser.emit "redirected", redirect
process.nextTick ->
makeRequest redirect, "GET"
else
error = "Could not load document at #{URL.format(url)}, got #{response.statusCode}"
# onerror is the only reliable way we have to notify the
# application.
if error
console.error "Error requesting #{URL.format(url)}", error
event = document.createEvent("HTMLEvents")
event.initEvent "error", true, false
document.dispatchEvent event
browser.emit "error", new Error(error)

client.on "error", (error)->
console.error "Error requesting #{URL.format(url)}", error
event = document.createEvent("HTMLEvents")
event.initEvent "error", true, false
document.dispatchEvent event
browser.emit "error", new Error(error)
done error
request.end data, "utf8"
makeRequest url, method, data
Expand Down

0 comments on commit 8473a74

Please sign in to comment.