Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Minor touches on annotated source code documentation.

Added navigation links to documentation.
  • Loading branch information...
commit 9a63fa0cdc707ccc7fd3a325f72fef6c9c490b9e 1 parent 2d55b46
@assaf authored
View
2  Cakefile
@@ -97,7 +97,7 @@ documentPages = (callback)->
documentSource = (callback)->
log "Documenting source files ...", green
- exec "docco src/**/*.coffee", (err)->
+ exec "docco src/*.coffee src/**/*.coffee", (err)->
onerror err
log "Copying to html/source ...", green
exec "mkdir -p html && cp -rf docs/ html/source && rm -rf docs", callback
View
18 doc/_layout.html
@@ -5,8 +5,20 @@
<link href="screen.css" media="screen,projection" rel="stylesheet" type="text/css">
</head>
<body>
- <div class="title"><a href="/">Zombie.js</a></div>
- <h1>{{title}}</h1>
- <div id="content">{{body}}</div>
+ <div id="header">
+ <div class="title"><a href="/">Zombie.js</a></div>
+ <ul class="navigation">
+ <li><a href="/">Documentation</a></li>
+ <li><a href="/changelog.html">Changelog</a></li>
+ <li><a href="/todo.html">Todo</a></li>
+ <li><a href="/source/">Annotated</a></li>
+ <li><a href="https://github.com/assaf/zombie/issues">Issues</a></li>
+ <li><a href="https://github.com/assaf/zombie">Fork Me</a></li>
+ </ul>
+ </div>
+ <div id="content">
+ <h1>{{title}}</h1>
+ {{body}}
+ </div>
</body>
</html>
View
23 doc/screen.css
@@ -5,7 +5,7 @@ body {
margin: 1em auto;
color: #222;
}
-h1, h2, h3, h4 {
+h1, h2, h3, h4, #header {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
color: #660000;
}
@@ -23,16 +23,29 @@ pre, code {
color: #060;
}
-.title {
+#header .title {
text-align: right;
- font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-weight: bolder;
- font-size: 24pt;
+ font-size: 28pt;
}
.title a {
text-decoration: none;
- color: #660000;
+ color: #600;
+}
+#header .navigation {
+ display: inline;
+ padding: 0;
+}
+#header .navigation li {
+ font-weight: bolder;
+ display: inline;
+ margin-right: 0.6em;
+}
+#header .navigation a {
+ text-decoration: none;
+ color: #22c;
}
#content {
+ margin-top: 2em;
}
View
22 src/index.coffee
@@ -2,24 +2,24 @@
exports.Browser = require("./zombie/browser").Browser
-# ### visit url, callback
+# ### zombie.visit(url, callback)
#
# Creates a new Browser, opens window to the URL and calls the callback when
# done processing all events.
#
# For example:
-# zombie = require("zombie")
+# zombie = require("zombie")
#
-# vows.describe("Brains").addBatch(
-# "seek":
-# topic: ->
-# zombie.browse "http://localhost:3000/brains", @callback
-# "should find": (browser)->
-# assert.ok browser.html("#brains")[0]
-# ).export(module);
+# vows.describe("Brains").addBatch(
+# "seek":
+# topic: ->
+# zombie.browse "http://localhost:3000/brains", @callback
+# "should find": (browser)->
+# assert.ok browser.html("#brains")[0]
+# ).export(module);
#
-# url -- URL of page to open
-# callback -- Called with error, browser
+# * url -- URL of page to open
+# * callback -- Called with error, browser
exports.visit = (url, callback)->
browser = new exports.Browser
browser.visit url, callback
View
56 src/zombie/browser.coffee
@@ -50,9 +50,10 @@ class Browser extends require("events").EventEmitter
# With one argument, that argument is the callback. With two arguments, the
# first argument is a terminator and the last argument is the callback. The
# terminator is one of:
- # - null -- process all events
- # - number -- process that number of events
- # - function -- called after each event, stop processing when function
+ #
+ # * null -- process all events
+ # * number -- process that number of events
+ # * function -- called after each event, stop processing when function
# returns false
#
# Events include timeout, interval and XHR `onreadystatechange`. DOM events
@@ -71,9 +72,9 @@ class Browser extends require("events").EventEmitter
# link. These events will bubble up and can be cancelled. With a callback, this
# function will call `wait`.
#
- # name -- Even name (e.g `click`)
- # target -- Target element (e.g a link)
- # callback -- Wait for events to be processed, then call me (optional)
+ # * name -- Even name (e.g `click`)
+ # * target -- Target element (e.g a link)
+ # * callback -- Wait for events to be processed, then call me (optional)
this.fire = (name, target, callback)->
event = window.document.createEvent("HTMLEvents")
event.initEvent name, true, true
@@ -102,7 +103,8 @@ class Browser extends require("events").EventEmitter
#
# Select a single element (first match) and return it.
#
- # selector -- CSS selector
+ # * selector -- CSS selector
+ #
# Returns an Element or null
this.querySelector = (selector)-> window.document?.querySelector(selector)
@@ -110,7 +112,8 @@ class Browser extends require("events").EventEmitter
#
# Select multiple elements and return a static node list.
#
- # selector -- CSS selector
+ # * selector -- CSS selector
+ #
# Returns a NodeList or null
this.querySelectorAll = (selector)-> window.document?.querySelectorAll(selector)
@@ -118,8 +121,9 @@ class Browser extends require("events").EventEmitter
#
# Returns the text contents of the selected elements.
#
- # selector -- CSS selector (if missing, entire document)
- # context -- Context element (if missing, uses document)
+ # * selector -- CSS selector (if missing, entire document)
+ # * context -- Context element (if missing, uses document)
+ #
# Returns a string
this.text = (selector, context)->
elements = if selector then (context || @document).querySelectorAll(selector).toArray() else [@document]
@@ -129,8 +133,9 @@ class Browser extends require("events").EventEmitter
#
# Returns the HTML contents of the selected elements.
#
- # selector -- CSS selector (if missing, entire document)
- # context -- Context element (if missing, uses document)
+ # * selector -- CSS selector (if missing, entire document)
+ # * context -- Context element (if missing, uses document)
+ #
# Returns a string
this.html = (selector, context)->
elements = if selector then (context || @document).querySelectorAll(selector).toArray() else [@document]
@@ -186,8 +191,8 @@ class Browser extends require("events").EventEmitter
# page, etc: use a callback to be notified of completion. Finds link by
# text content or selector.
#
- # selector -- CSS selector or link text
- # callback -- Called with two arguments: error and browser
+ # * selector -- CSS selector or link text
+ # * callback -- Called with two arguments: error and browser
this.clickLink = (selector, callback)->
if link = @querySelector(selector)
@fire "click", link, callback if link
@@ -226,8 +231,9 @@ class Browser extends require("events").EventEmitter
#
# Fill in a field: input field or text area.
#
- # field -- CSS selector, field name or text of the field label
- # value -- Field value
+ # * field -- CSS selector, field name or text of the field label
+ # * value -- Field value
+ #
# Returns this
this.fill = (field, value)->
match = (elem)-> elem.nodeName == "TEXTAREA" || textTypes.indexOf(elem.type?.toLowerCase()) >= 0
@@ -255,7 +261,8 @@ class Browser extends require("events").EventEmitter
#
# Checks a checkbox.
#
- # field -- CSS selector, field name or text of the field label
+ # * field -- CSS selector, field name or text of the field label
+ #
# Returns this
this.check = (field)-> setCheckbox field, true
@@ -263,7 +270,8 @@ class Browser extends require("events").EventEmitter
#
# Unchecks a checkbox.
#
- # field -- CSS selector, field name or text of the field label
+ # * field -- CSS selector, field name or text of the field label
+ #
# Returns this
this.uncheck = (field)-> setCheckbox field, false
@@ -271,7 +279,8 @@ class Browser extends require("events").EventEmitter
#
# Selects a radio box option.
#
- # field -- CSS selector, field value or text of the field label
+ # * field -- CSS selector, field value or text of the field label
+ #
# Returns this
this.choose = (field)->
match = (elem)-> elem.nodeName == "INPUT" && elem.type?.toLowerCase() == "radio"
@@ -293,8 +302,9 @@ class Browser extends require("events").EventEmitter
#
# Selects an option.
#
- # field -- CSS selector, field name or text of the field label
- # value -- Value (or label) or option to select
+ # * field -- CSS selector, field name or text of the field label
+ # * value -- Value (or label) or option to select
+ #
# Returns this
this.select = (field, value)->
match = (elem)-> elem.nodeName == "SELECT"
@@ -320,8 +330,8 @@ class Browser extends require("events").EventEmitter
# this will submit the form. Use the callback to wait for the from
# submission, page to load and all events run their course.
#
- # name -- CSS selector, button name or text of BUTTON element
- # callback -- Called with two arguments: error and browser
+ # * name -- CSS selector, button name or text of BUTTON element
+ # * callback -- Called with two arguments: error and browser
this.pressButton = (name, callback)->
if button = @querySelector(name)
button.click()
View
43 src/zombie/cookies.coffee
@@ -1,13 +1,11 @@
-# Cookies.
+# See [RFC 2109](http://tools.ietf.org/html/rfc2109.html) and
+# [document.cookie](http://developer.mozilla.org/en/document.cookie)
URL = require("url")
core = require("jsdom").dom.level3.core
# Maintains cookies for a Browser instance. This is actually a domain/path
# specific scope around the global cookies collection.
-#
-# See [RFC 2109](http://tools.ietf.org/html/rfc2109.html) and
-# [document.cookie](http://developer.mozilla.org/en/document.cookie)
class Cookies
constructor: (browser, cookies, hostname, pathname)->
pathname = "/" if !pathname || pathname == ""
@@ -48,23 +46,23 @@ class Cookies
str = str + "; secure" if cookie.secure
str
- #### cookies(host, path).get name => String
+ #### cookies(host, path).get(name) => String
#
# Returns the value of a cookie.
#
- # name -- Cookie name
- # Returns cookie value if known
+ # * name -- Cookie name
+ # * Returns cookie value if known
this.get = (name)->
for match in selected()
return match[3].value if match[2] == name
- #### cookies(host, path).set name, value, options?
+ #### cookies(host, path).set(name, value, options?)
#
# Sets a cookie (deletes if expires/max-age is in the past).
#
- # name -- Cookie name
- # value -- Cookie value
- # options -- Options max-age, expires, secure
+ # * name -- Cookie name
+ # * value -- Cookie value
+ # * options -- Options max-age, expires, secure
this.set = (name, value, options = {})->
name = name.toLowerCase()
state = { value: value.toString() }
@@ -83,20 +81,22 @@ class Cookies
in_path = in_domain[pathname] ||= {}
in_path[name] = state
- #### cookies(host, path).remove name
+ #### cookies(host, path).remove(name)
#
# Deletes a cookie.
#
- # name -- Cookie name
+ # * name -- Cookie name
this.remove = (name, options = {})->
if in_domain = cookies[hostname]
if in_path = in_domain[pathname]
delete in_path[name.toLowerCase()]
+ #### cookies(host, path).update(serialized)
+ #
# Update cookies from serialized form. This method works equally well for
# the Set-Cookie header and value passed to document.cookie setter.
#
- # serialized -- Serialized form
+ # * serialized -- Serialized form
this.update = (serialized)->
return unless serialized
for cookie in serialized.split(/,(?=[^;,]*=)|,$/)
@@ -126,23 +126,32 @@ class Cookies
in_path = in_domain[path || pathname] ||= {}
in_path[name] = options
+ #### cookies(host, path).addHeader(headers)
+ #
# Adds Cookie header suitable for sending to the server.
this.addHeader = (headers)->
header = ("#{match[2]}=\"#{match[3].value}\";$Path=\"#{match[1]}\"" for match in selected()).join("; ")
if header.length > 0
headers.cookie = "$Version=\"1\"; #{header}"
+ #### cookies(host, path).pairs => String
+ #
# Returns key/value pairs of all cookies in this domain/path.
@__defineGetter__ "pairs", ->
("#{match[2]}=#{match[3].value}" for match in selected()).join("; ")
- this.dump = ->
- (serialize.apply this, match for match in selected()).join("\n")
+ #### cookies(host, path).dump(separator?) => String
+ #
+ # The default separator is a line break, useful to output when
+ # debugging. If you need to save/load, use comma as the line
+ # separator and then call `cookies.update`.
+ this.dump(separator = "\n") = ->
+ (serialize.apply this, match for match in selected()).join(separator)
# ### document.cookie => String
#
-# Returns name=value; pairs
+# Returns name=value pairs
core.HTMLDocument.prototype.__defineGetter__ "cookie", -> @parentWindow.cookies.pairs
# ### document.cookie = String
#
View
19 src/zombie/eventloop.coffee
@@ -7,7 +7,7 @@ class EventLoop
timers = {}
lastHandle = 0
- # ### window.setTimeout fn, delay
+ # ### window.setTimeout(fn, delay) => Number
#
# Implements window.setTimeout using event queue
this.setTimeout = (fn, delay)->
@@ -26,7 +26,7 @@ class EventLoop
timers[handle] = timer
handle
- # ### window.setInterval fn, delay
+ # ### window.setInterval(fn, delay) => Number
#
# Implements window.setInterval using event queue
this.setInterval = (fn, delay)->
@@ -45,11 +45,11 @@ class EventLoop
timers[handle] = timer
handle
- # ### window.clearTimeout timeout
+ # ### window.clearTimeout(timeout)
#
# Implements window.clearTimeout using event queue
this.clearTimeout = (handle)-> delete timers[handle] if timers[handle]?.timeout
- # ### window.clearInterval interval
+ # ### window.clearInterval(interval)
#
# Implements window.clearInterval using event queue
this.clearInterval = (handle)-> delete timers[handle] if timers[handle]?.interval
@@ -60,6 +60,8 @@ class EventLoop
# Queue of events.
queue = []
+ # ### queue(event)
+ #
# Queue an event to be processed by wait(). Event is a function call in the
# context of the window.
this.queue = (event)->
@@ -67,6 +69,8 @@ class EventLoop
wait() for wait in waiting
waiting = []
+ # ### wait(window, terminate, callback, intervals)
+ #
# Process all events from the queue. This method returns immediately, events
# are processed in the background. When all events are exhausted, it calls
# the callback with null, window; if any event fails, it calls the callback
@@ -75,9 +79,10 @@ class EventLoop
# With one argument, that argument is the callback. With two arguments, the
# first argument is a terminator and the last argument is the callback. The
# terminator is one of:
- # - null -- process all events
- # - number -- process that number of events
- # - function -- called after each event, stop processing when function
+ #
+ # * null -- process all events
+ # * number -- process that number of events
+ # * function -- called after each event, stop processing when function
# returns false
#
# Events include timeout, interval and XHR onreadystatechange. DOM events
View
29 src/zombie/history.coffee
@@ -12,11 +12,11 @@ class History
stack = []
index = -1
history = @
- # ### history.forward amount
+ # ### history.forward()
@forward = -> @go(1)
- # ### history.back amount
+ # ### history.back()
@back = -> @go(-1)
- # ### history.go amount
+ # ### history.go(amount)
@go = (amount)->
new_index = index + amount
new_index = 0 if new_index < 0
@@ -36,17 +36,19 @@ class History
else
pageChanged old
return
+ # ### history.length => Number
+ #
# Number of states/URLs in the history.
@__defineGetter__ "length", -> stack.length
- # ### history.pushState state, title, url
+ # ### history.pushState(state, title, url)
#
# Push new state to the stack, do not reload
@pushState = (state, title, url)->
entry = stack[index] if index >= 0
url = URL.resolve(entry, url) if entry
stack[++index] = { state: state, title: title, url: URL.parse(url.toString()), pop: true }
- # ### history.replaceState state, title, url
+ # ### history.replaceState(state, title, url)
#
# Replace existing state in the stack, do not reload
@replaceState = (state, title, url)->
@@ -79,10 +81,10 @@ class History
resource @_location
# Form submission. Makes request and loads response in the background.
#
- # url -- Same as form action, can be relative to current document
- # method -- Method to use, defaults to GET
- # data -- Form valuesa
- # enctype -- Encoding type, or use default
+ # * url -- Same as form action, can be relative to current document
+ # * method -- Method to use, defaults to GET
+ # * data -- Form valuesa
+ # * enctype -- Encoding type, or use default
@_submit = (url, method, data, enctype)->
url = URL.resolve(URL.format(@_location), url)
url = URL.parse(url)
@@ -191,11 +193,11 @@ class History
# Represents window.location and document.location.
class Location
constructor: (history, @_url)->
- # ### location.assign url
+ # ### location.assign(url)
@assign = (url)-> history._assign url
- # ### location.replace url
+ # ### location.replace(url)
@replace = (url)-> history._replace url
- # ### location.reload force?
+ # ### location.reload(force?)
@reload = (force)-> history._loadPage(force)
# ### location.toString() => String
@toString = -> URL.format(@_url)
@@ -211,7 +213,8 @@ class Location
new_url[prop] = value
history._assign URL.format(new_url)
-# ## document.location
+# ## document.location => Location
+#
# document.location is same as window.location
jsdom.dom.level3.core.HTMLDocument.prototype.__defineGetter__ "location", -> @parentWindow.location
View
21 src/zombie/storage.coffee
@@ -1,4 +1,4 @@
-# Web Storage, see http://dev.w3.org/html5/webstorage/
+# See [Web Storage](http://dev.w3.org/html5/webstorage/)
core = require("jsdom").dom.level3.core
events = require("jsdom").dom.level3.events
@@ -62,12 +62,31 @@ class StorageArea
class Storage
constructor: (area, window)->
area.associate this, window if window
+ # ### storage.length => Number
+ #
+ # Returns the number of key/value pairs in this storage.
@__defineGetter__ "length", -> area.length
+ # ### storage.key(index) => String
+ #
+ # Returns the key at this position.
this.key = (index)-> area.key(index)
+ # ### storage.getItem(key) => Object
+ #
+ # Returns item by key.
this.getItem = (key)-> area.get(key.toString())
+ # ### storage.setItem(key, Object)
+ #
+ # Add item or change value of existing item.
this.setItem = (key, value)-> area.set this, key.toString(), value
+ # ### storage.removeItem(key)
+ #
+ # Remove item.
this.removeItem = (key)-> area.remove this, key.toString()
+ # ### storage.clear()
+ #
+ # Remove all items.
this.clear = -> area.clear this
+ # Dump to a string, useful for debugging.
this.dump = -> area.dump()
Please sign in to comment.
Something went wrong with that request. Please try again.