Permalink
Browse files

Browser is now an EventEmitter, you can listen to drain (event queue

empty), error (loading page) and loaded (what is says).
  • Loading branch information...
1 parent 2e14582 commit 8473a74ebc4fa9769032f118c65dc5a973c14e50 @assaf committed Dec 22, 2010
Showing with 53 additions and 5 deletions.
  1. +3 −0 CHANGELOG.md
  2. +13 −0 README.md
  3. +23 −0 spec/browser-spec.coffee
  4. +1 −1 spec/helpers.coffee
  5. +4 −2 src/zombie/browser.coffee
  6. +2 −0 src/zombie/eventloop.coffee
  7. +7 −2 src/zombie/history.coffee
View
3 CHANGELOG.md
@@ -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
View
13 README.md
@@ -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
View
23 spec/browser-spec.coffee
@@ -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":
View
2 spec/helpers.coffee
@@ -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
View
6 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)
@@ -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?)
View
2 src/zombie/eventloop.coffee
@@ -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.
View
9 src/zombie/history.coffee
@@ -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

0 comments on commit 8473a74

Please sign in to comment.