| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Browser, Path, Util, contextify, listen, visit; |
| 3 | ||
| 4 | 1 | Browser = require("./browser"); |
| 5 | ||
| 6 | 1 | Path = require("path"); |
| 7 | ||
| 8 | 1 | Util = require("util"); |
| 9 | ||
| 10 | 1 | try { |
| 11 | 1 | contextify = Path.resolve(require.resolve("jsdom"), "../../node_modules/contextify"); |
| 12 | 1 | require(contextify); |
| 13 | } catch (ex) { | |
| 14 | 0 | throw new Error("Zombie will not run correctly without the Contextify module"); |
| 15 | } | |
| 16 | ||
| 17 | 1 | visit = function(url, options, callback) { |
| 18 | 18 | return new Browser(options).visit(url, options, callback); |
| 19 | }; | |
| 20 | ||
| 21 | 1 | listen = function(port, callback) { |
| 22 | 0 | return require("./zombie/protocol").listen(port, callback); |
| 23 | }; | |
| 24 | ||
| 25 | 1 | console.depth = 0; |
| 26 | ||
| 27 | 1 | console.showHidden = false; |
| 28 | ||
| 29 | 1 | console.log = function() { |
| 30 | 0 | var arg, formatted; |
| 31 | 0 | formatted = (function() { |
| 32 | 0 | var _i, _len, _results; |
| 33 | 0 | _results = []; |
| 34 | 0 | for (_i = 0, _len = arguments.length; _i < _len; _i++) { |
| 35 | 0 | arg = arguments[_i]; |
| 36 | 0 | _results.push(typeof arg === "string" ? arg : Util.inspect(arg, console.showHidden, console.depth)); |
| 37 | } | |
| 38 | 0 | return _results; |
| 39 | }).apply(this, arguments); | |
| 40 | 0 | if (typeof Util.format === 'function') { |
| 41 | 0 | return process.stdout.write(Util.format.apply(this, formatted) + "\n"); |
| 42 | } else { | |
| 43 | 0 | return process.stdout.write(formatted.join(" ") + "\n"); |
| 44 | } | |
| 45 | }; | |
| 46 | ||
| 47 | 1 | Browser.listen = listen; |
| 48 | ||
| 49 | 1 | Browser.visit = visit; |
| 50 | ||
| 51 | 1 | Browser.debug = !!process.env.DEBUG; |
| 52 | ||
| 53 | 1 | Browser.Browser = Browser; |
| 54 | ||
| 55 | 1 | module.exports = Browser; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var BROWSER_OPTIONS, Browser, Cache, Cookies, Credentials, EventEmitter, EventLoop, FS, GLOBAL_OPTIONS, HTML, HTML5, Interact, JSDOM, MOUSE_EVENT_NAMES, Mime, PACKAGE, Path, Q, Resources, Storages, URL, VERSION, Windows, XHR, deprecated, |
| 3 | __hasProp = {}.hasOwnProperty, | |
| 4 | 7 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, |
| 5 | 0 | __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; |
| 6 | ||
| 7 | 1 | require("./jsdom_patches"); |
| 8 | ||
| 9 | 1 | require("./forms"); |
| 10 | ||
| 11 | 1 | require("./xpath"); |
| 12 | ||
| 13 | 1 | deprecated = require("./helpers").deprecated; |
| 14 | ||
| 15 | 1 | Cache = require("./cache"); |
| 16 | ||
| 17 | 1 | Cookies = require("./cookies"); |
| 18 | ||
| 19 | 1 | EventEmitter = require("events").EventEmitter; |
| 20 | ||
| 21 | 1 | EventLoop = require("./eventloop"); |
| 22 | ||
| 23 | 1 | FS = require("fs"); |
| 24 | ||
| 25 | 1 | HTML5 = require("html5").HTML5; |
| 26 | ||
| 27 | 1 | Interact = require("./interact"); |
| 28 | ||
| 29 | 1 | JSDOM = require("jsdom"); |
| 30 | ||
| 31 | 1 | Mime = require("mime"); |
| 32 | ||
| 33 | 1 | Q = require("q"); |
| 34 | ||
| 35 | 1 | Path = require("path"); |
| 36 | ||
| 37 | 1 | Resources = require("./resources"); |
| 38 | ||
| 39 | 1 | Storages = require("./storage"); |
| 40 | ||
| 41 | 1 | URL = require("url"); |
| 42 | ||
| 43 | 1 | Windows = require("./windows"); |
| 44 | ||
| 45 | 1 | XHR = require("./xhr"); |
| 46 | ||
| 47 | 1 | BROWSER_OPTIONS = ["debug", "headers", "htmlParser", "loadCSS", "maxWait", "proxy", "referer", "runScripts", "silent", "site", "userAgent", "waitFor", "name"]; |
| 48 | ||
| 49 | 1 | GLOBAL_OPTIONS = ["debug", "headers", "htmlParser", "loadCSS", "maxWait", "proxy", "runScripts", "silent", "site", "userAgent", "waitFor"]; |
| 50 | ||
| 51 | 1 | PACKAGE = JSON.parse(require("fs").readFileSync(__dirname + "/../../package.json")); |
| 52 | ||
| 53 | 1 | VERSION = PACKAGE.version; |
| 54 | ||
| 55 | 1 | HTML = JSDOM.dom.level3.html; |
| 56 | ||
| 57 | 1 | MOUSE_EVENT_NAMES = ["mousedown", "mousemove", "mouseup"]; |
| 58 | ||
| 59 | 1 | Browser = (function(_super) { |
| 60 | ||
| 61 | 1 | __extends(Browser, _super); |
| 62 | ||
| 63 | 1 | function Browser(options) { |
| 64 | 195 | var name, _i, _len, |
| 65 | _this = this; | |
| 66 | 195 | if (options == null) { |
| 67 | 175 | options = {}; |
| 68 | } | |
| 69 | 195 | this._cache = new Cache(); |
| 70 | 195 | this._cookies = new Cookies(); |
| 71 | 195 | this._eventloop = new EventLoop(this); |
| 72 | 195 | this._storages = new Storages(); |
| 73 | 195 | this._interact = Interact.use(this); |
| 74 | 195 | this._xhr = XHR.use(this._cache); |
| 75 | 195 | this.on("error", function(error) { |
| 76 | 15 | _this.errors.push(error); |
| 77 | 15 | return _this.log(error.message, error.stack); |
| 78 | }); | |
| 79 | 195 | this.referer = void 0; |
| 80 | 195 | this.name = "nodejs"; |
| 81 | 195 | for (_i = 0, _len = BROWSER_OPTIONS.length; _i < _len; _i++) { |
| 82 | 2535 | name = BROWSER_OPTIONS[_i]; |
| 83 | 2535 | if (options.hasOwnProperty(name)) { |
| 84 | 20 | this[name] = options[name]; |
| 85 | 2515 | } else if (~GLOBAL_OPTIONS.indexOf(name)) { |
| 86 | 2144 | this[name] = Browser[name]; |
| 87 | } | |
| 88 | } | |
| 89 | 195 | this._setCredentials(options.credentials || Browser.credentials); |
| 90 | 195 | this.errors = []; |
| 91 | 195 | this.resources = new Resources(this); |
| 92 | 195 | this.windows = new Windows(this); |
| 93 | } | |
| 94 | ||
| 95 | 1 | Browser.debug = false; |
| 96 | ||
| 97 | 1 | Browser.htmlParser = HTML5; |
| 98 | ||
| 99 | 1 | Browser.loadCSS = true; |
| 100 | ||
| 101 | 1 | Browser.maxWait = "5s"; |
| 102 | ||
| 103 | 1 | Browser.proxy = null; |
| 104 | ||
| 105 | 1 | Browser.runScripts = true; |
| 106 | ||
| 107 | 1 | Browser.silent = false; |
| 108 | ||
| 109 | 1 | Browser.userAgent = "Mozilla/5.0 Chrome/10.0.613.0 Safari/534.15 Zombie.js/" + VERSION; |
| 110 | ||
| 111 | 1 | Browser.site = void 0; |
| 112 | ||
| 113 | 1 | Browser.waitFor = "0.5s"; |
| 114 | ||
| 115 | 1 | Browser.headers = {}; |
| 116 | ||
| 117 | 1 | Browser.prototype.withOptions = function(options, fn) { |
| 118 | 191 | var k, restore, v, _ref, |
| 119 | _this = this; | |
| 120 | 191 | if (options) { |
| 121 | 4 | restore = {}; |
| 122 | 4 | for (k in options) { |
| 123 | 4 | v = options[k]; |
| 124 | 4 | if (~BROWSER_OPTIONS.indexOf(k)) { |
| 125 | 3 | _ref = [this[k], v], restore[k] = _ref[0], this[k] = _ref[1]; |
| 126 | } | |
| 127 | } | |
| 128 | 4 | this._setCredentials(options.credentials); |
| 129 | 4 | return function() { |
| 130 | 4 | var _results; |
| 131 | 4 | _results = []; |
| 132 | 4 | for (k in restore) { |
| 133 | 3 | v = restore[k]; |
| 134 | 3 | _results.push(_this[k] = v); |
| 135 | } | |
| 136 | 4 | return _results; |
| 137 | }; | |
| 138 | } else { | |
| 139 | 187 | return function() {}; |
| 140 | } | |
| 141 | }; | |
| 142 | ||
| 143 | 1 | Browser.prototype.fork = function() { |
| 144 | 1 | var forked, name, _i, _len; |
| 145 | 1 | forked = new Browser(); |
| 146 | 1 | forked.loadCookies(this.saveCookies()); |
| 147 | 1 | forked.loadStorage(this.saveStorage()); |
| 148 | 1 | forked.loadHistory(this.saveHistory()); |
| 149 | 1 | forked.location = this.location; |
| 150 | 1 | for (_i = 0, _len = BROWSER_OPTIONS.length; _i < _len; _i++) { |
| 151 | 13 | name = BROWSER_OPTIONS[_i]; |
| 152 | 13 | forked[name] = this[name]; |
| 153 | } | |
| 154 | 1 | return forked; |
| 155 | }; | |
| 156 | ||
| 157 | 1 | Browser.prototype.__defineGetter__("window", function() { |
| 158 | 1572 | return this.windows.current; |
| 159 | }); | |
| 160 | ||
| 161 | 1 | Browser.prototype.open = function(options) { |
| 162 | 24 | this._eventloop.reset(); |
| 163 | 24 | this.errors = []; |
| 164 | 24 | this.resources.clear(); |
| 165 | 24 | return this.windows.open(options || {}); |
| 166 | }; | |
| 167 | ||
| 168 | 1 | Browser.prototype.__defineGetter__("error", function() { |
| 169 | 2 | return this.errors[this.errors.length - 1]; |
| 170 | }); | |
| 171 | ||
| 172 | 1 | Browser.prototype.wait = function(duration, callback) { |
| 173 | 329 | var deferred, last, _ref, |
| 174 | _this = this; | |
| 175 | 329 | if (arguments.length < 2 && typeof duration === "function") { |
| 176 | 37 | _ref = [duration, null], callback = _ref[0], duration = _ref[1]; |
| 177 | } | |
| 178 | 329 | deferred = Q.defer(); |
| 179 | 329 | last = this.errors[this.errors.length - 1]; |
| 180 | 329 | this._eventloop.wait(this.window, duration, function(error) { |
| 181 | 329 | var newest; |
| 182 | 329 | newest = _this.errors[_this.errors.length - 1]; |
| 183 | 329 | if (!(error || last === newest)) { |
| 184 | 14 | error = newest; |
| 185 | } | |
| 186 | 329 | if (error) { |
| 187 | 14 | deferred.reject(error); |
| 188 | } else { | |
| 189 | 315 | deferred.resolve(); |
| 190 | } | |
| 191 | 329 | if (callback) { |
| 192 | 231 | return callback(error); |
| 193 | } | |
| 194 | }); | |
| 195 | 329 | if (!callback) { |
| 196 | 98 | return deferred.promise; |
| 197 | } | |
| 198 | }; | |
| 199 | ||
| 200 | 1 | Browser.prototype.fire = function(name, target, callback) { |
| 201 | 105 | var event, type; |
| 202 | 105 | type = __indexOf.call(MOUSE_EVENT_NAMES, name) >= 0 ? "MouseEvents" : "HTMLEvents"; |
| 203 | 105 | event = this.window.document.createEvent(type); |
| 204 | 105 | event.initEvent(name, true, true); |
| 205 | 105 | this.dispatchEvent(target, event); |
| 206 | 105 | return this.wait(callback); |
| 207 | }; | |
| 208 | ||
| 209 | 1 | Browser.prototype.dispatchEvent = function(target, event) { |
| 210 | 226 | return this._eventloop.dispatch(target, event); |
| 211 | }; | |
| 212 | ||
| 213 | 1 | Browser.prototype.queryAll = function(selector, context) { |
| 214 | 97 | var ret; |
| 215 | 97 | if (selector) { |
| 216 | 88 | context || (context = this.document); |
| 217 | 88 | ret = context.querySelectorAll(selector); |
| 218 | 88 | return Array.prototype.slice.call(ret, 0); |
| 219 | } else { | |
| 220 | 9 | context || (context = this.document.documentElement); |
| 221 | 9 | return [context]; |
| 222 | } | |
| 223 | }; | |
| 224 | ||
| 225 | 1 | Browser.prototype.query = function(selector, context) { |
| 226 | 55 | context || (context = this.document); |
| 227 | 55 | if (selector) { |
| 228 | 55 | return context.querySelector(selector); |
| 229 | } else { | |
| 230 | 0 | return context; |
| 231 | } | |
| 232 | }; | |
| 233 | ||
| 234 | 1 | Browser.prototype.$$ = function(selector, context) { |
| 235 | 2 | return this.query(selector, context); |
| 236 | }; | |
| 237 | ||
| 238 | 1 | Browser.prototype.querySelector = function(selector) { |
| 239 | 263 | var _ref; |
| 240 | 263 | return (_ref = this.window.document) != null ? _ref.querySelector(selector) : void 0; |
| 241 | }; | |
| 242 | ||
| 243 | 1 | Browser.prototype.querySelectorAll = function(selector) { |
| 244 | 72 | var _ref; |
| 245 | 72 | return (_ref = this.window.document) != null ? _ref.querySelectorAll(selector) : void 0; |
| 246 | }; | |
| 247 | ||
| 248 | 1 | Browser.prototype.text = function(selector, context) { |
| 249 | 82 | if (this.document.documentElement) { |
| 250 | 82 | return this.queryAll(selector, context).map(function(e) { |
| 251 | 82 | return e.textContent; |
| 252 | }).join("").trim().replace(/\s+/g, " "); | |
| 253 | } | |
| 254 | 0 | return this.source; |
| 255 | }; | |
| 256 | ||
| 257 | 1 | Browser.prototype.html = function(selector, context) { |
| 258 | 14 | if (this.document.documentElement) { |
| 259 | 14 | return this.queryAll(selector, context).map(function(e) { |
| 260 | 14 | return e.outerHTML.trim(); |
| 261 | }).join(""); | |
| 262 | } | |
| 263 | 0 | return this.source; |
| 264 | }; | |
| 265 | ||
| 266 | 1 | Browser.prototype.css = function(selector, context) { |
| 267 | 0 | deprecated("Browser.css is deprecated, please use browser.query and browser.queryAll instead."); |
| 268 | 0 | return this.queryAll(selector, context); |
| 269 | }; | |
| 270 | ||
| 271 | 1 | Browser.prototype.xpath = function(expression, context) { |
| 272 | 30 | return this.document.evaluate(expression, context || this.document.documentElement); |
| 273 | }; | |
| 274 | ||
| 275 | 1 | Browser.prototype.__defineGetter__("document", function() { |
| 276 | 356 | var _ref; |
| 277 | 356 | return (_ref = this.window) != null ? _ref.document : void 0; |
| 278 | }); | |
| 279 | ||
| 280 | 1 | Browser.prototype.__defineGetter__("body", function() { |
| 281 | 2 | var _ref; |
| 282 | 2 | return (_ref = this.window.document) != null ? _ref.querySelector("body") : void 0; |
| 283 | }); | |
| 284 | ||
| 285 | 1 | Browser.prototype.__defineGetter__("statusCode", function() { |
| 286 | 145 | var _ref; |
| 287 | 145 | return (_ref = this.response) != null ? _ref[0] : void 0; |
| 288 | }); | |
| 289 | ||
| 290 | 1 | Browser.prototype.__defineGetter__("success", function() { |
| 291 | 6 | return this.statusCode >= 200 && this.statusCode < 300; |
| 292 | }); | |
| 293 | ||
| 294 | 1 | Browser.prototype.__defineGetter__("redirected", function() { |
| 295 | 3 | var _ref, _ref1; |
| 296 | 3 | return !!((_ref = this.resources.last) != null ? (_ref1 = _ref.response) != null ? _ref1.redirected : void 0 : void 0); |
| 297 | }); | |
| 298 | ||
| 299 | 1 | Browser.prototype.__defineGetter__("source", function() { |
| 300 | 2 | var _ref; |
| 301 | 2 | return (_ref = this.response) != null ? _ref[2] : void 0; |
| 302 | }); | |
| 303 | ||
| 304 | 1 | Browser.prototype.close = function() { |
| 305 | 1 | var _results; |
| 306 | 1 | _results = []; |
| 307 | 1 | while (this.windows.current) { |
| 308 | 1 | _results.push(this.windows.close()); |
| 309 | } | |
| 310 | 1 | return _results; |
| 311 | }; | |
| 312 | ||
| 313 | 1 | Browser.prototype.visit = function(url, options, callback) { |
| 314 | 191 | var deferred, duration, reset_options, site, _ref, _ref1, |
| 315 | _this = this; | |
| 316 | 191 | if (typeof options === "function" && !callback) { |
| 317 | 122 | _ref = [options, null], callback = _ref[0], options = _ref[1]; |
| 318 | } | |
| 319 | 191 | if (typeof options !== "object") { |
| 320 | 65 | _ref1 = [options, null], duration = _ref1[0], options = _ref1[1]; |
| 321 | } | |
| 322 | 191 | deferred = Q.defer(); |
| 323 | 191 | reset_options = this.withOptions(options); |
| 324 | 191 | if (site = this.site) { |
| 325 | 191 | if (!/^(https?:|file:)/i.test(site)) { |
| 326 | 191 | site = "http://" + site; |
| 327 | } | |
| 328 | 191 | url = URL.resolve(site, URL.parse(URL.format(url))); |
| 329 | } | |
| 330 | 191 | this.window.history._assign(url); |
| 331 | 191 | this.wait(duration, function(error) { |
| 332 | 191 | reset_options(); |
| 333 | 191 | if (error) { |
| 334 | 11 | deferred.reject(error); |
| 335 | } else { | |
| 336 | 180 | deferred.resolve(); |
| 337 | } | |
| 338 | 191 | if (callback) { |
| 339 | 126 | return callback(error, _this, _this.statusCode, _this.errors); |
| 340 | } | |
| 341 | }); | |
| 342 | 191 | if (!callback) { |
| 343 | 65 | return deferred.promise; |
| 344 | } | |
| 345 | }; | |
| 346 | ||
| 347 | 1 | Browser.prototype.load = function(html, callback) { |
| 348 | 1 | var deferred, first; |
| 349 | 1 | try { |
| 350 | 1 | this.errors = []; |
| 351 | 1 | this.document.open(); |
| 352 | 1 | this.document.write(html); |
| 353 | 1 | this.document.close(); |
| 354 | } catch (error) { | |
| 355 | 0 | this.emit("error", error); |
| 356 | } | |
| 357 | 1 | first = this.errors[0]; |
| 358 | 1 | if (first) { |
| 359 | 0 | if (callback) { |
| 360 | 0 | process.nextTick(function() { |
| 361 | 0 | return callback(first); |
| 362 | }); | |
| 363 | } else { | |
| 364 | 0 | deferred = Q.defer(); |
| 365 | 0 | deferred.reject(first); |
| 366 | 0 | return deferred.promise; |
| 367 | } | |
| 368 | } else { | |
| 369 | 1 | return this.wait(callback); |
| 370 | } | |
| 371 | }; | |
| 372 | ||
| 373 | 1 | Browser.prototype.__defineGetter__("location", function() { |
| 374 | 70 | return this.window.location; |
| 375 | }); | |
| 376 | ||
| 377 | 1 | Browser.prototype.__defineSetter__("location", function(url) { |
| 378 | 1 | return this.window.location = url; |
| 379 | }); | |
| 380 | ||
| 381 | 1 | Browser.prototype.link = function(selector) { |
| 382 | 15 | var link, _i, _len, _ref; |
| 383 | 15 | if (selector instanceof HTML.Element) { |
| 384 | 1 | return selector; |
| 385 | } | |
| 386 | 14 | if (link = this.querySelector(selector)) { |
| 387 | 1 | if (link.tagName === "A") { |
| 388 | 1 | return link; |
| 389 | } | |
| 390 | } | |
| 391 | 13 | _ref = this.querySelectorAll("body a"); |
| 392 | 13 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 393 | 21 | link = _ref[_i]; |
| 394 | 21 | if (link.textContent.trim() === selector) { |
| 395 | 13 | return link; |
| 396 | } | |
| 397 | } | |
| 398 | }; | |
| 399 | ||
| 400 | 1 | Browser.prototype.clickLink = function(selector, callback) { |
| 401 | 14 | var link; |
| 402 | 14 | if (!(link = this.link(selector))) { |
| 403 | 0 | throw new Error("No link matching '" + selector + "'"); |
| 404 | } | |
| 405 | 14 | return this.fire("click", link, callback); |
| 406 | }; | |
| 407 | ||
| 408 | 1 | Browser.prototype.__defineGetter__("history", function() { |
| 409 | 19 | return this.window.history; |
| 410 | }); | |
| 411 | ||
| 412 | 1 | Browser.prototype.back = function(callback) { |
| 413 | 1 | this.window.history.back(); |
| 414 | 1 | return this.wait(callback); |
| 415 | }; | |
| 416 | ||
| 417 | 1 | Browser.prototype.reload = function(callback) { |
| 418 | 1 | this.window.location.reload(); |
| 419 | 1 | return this.wait(callback); |
| 420 | }; | |
| 421 | ||
| 422 | 1 | Browser.prototype.authenticate = function(host, create) { |
| 423 | 696 | var credentials, _ref; |
| 424 | 696 | if (create == null) { |
| 425 | 348 | create = true; |
| 426 | } | |
| 427 | 696 | host || (host = "*"); |
| 428 | 696 | credentials = (_ref = this._credentials) != null ? _ref[host] : void 0; |
| 429 | 696 | if (!credentials) { |
| 430 | 521 | if (create) { |
| 431 | 179 | credentials = new Credentials(); |
| 432 | 179 | this._credentials || (this._credentials = {}); |
| 433 | 179 | this._credentials[host] = credentials; |
| 434 | } else { | |
| 435 | 342 | credentials = this.authenticate(); |
| 436 | } | |
| 437 | } | |
| 438 | 696 | return credentials; |
| 439 | }; | |
| 440 | ||
| 441 | 1 | Browser.prototype._setCredentials = function(credentials) { |
| 442 | 199 | if (!credentials) { |
| 443 | 198 | return; |
| 444 | } | |
| 445 | 1 | deprecated("This credentials option is deprecated, please use browser.authenticate(host) instead."); |
| 446 | 1 | switch (credentials.scheme.toLowerCase()) { |
| 447 | case "basic": | |
| 448 | 1 | return this.authenticate().basic(credentials.user || credentials.username, credentials.password); |
| 449 | case "bearer": | |
| 450 | 0 | return this.authenticate().bearer(credentials.token); |
| 451 | case "oauth": | |
| 452 | 0 | return this.authenticate().oauth(credentials.token); |
| 453 | } | |
| 454 | }; | |
| 455 | ||
| 456 | 1 | Browser.prototype.saveHistory = function() { |
| 457 | 1 | return this.window.history.save(); |
| 458 | }; | |
| 459 | ||
| 460 | 1 | Browser.prototype.loadHistory = function(serialized) { |
| 461 | 1 | return this.window.history.load(serialized); |
| 462 | }; | |
| 463 | ||
| 464 | 1 | Browser.prototype.field = function(selector) { |
| 465 | 104 | var field, for_attr, label, _i, _len, _ref; |
| 466 | 104 | if (selector instanceof HTML.Element) { |
| 467 | 24 | return selector; |
| 468 | } | |
| 469 | 80 | if (field = this.querySelector(selector)) { |
| 470 | 25 | if (field.tagName === "INPUT" || field.tagName === "TEXTAREA" || field.tagName === "SELECT") { |
| 471 | 25 | return field; |
| 472 | } | |
| 473 | } | |
| 474 | 55 | if (field = this.querySelector(":input[name='" + selector + "']")) { |
| 475 | 25 | return field; |
| 476 | } | |
| 477 | 30 | _ref = this.querySelectorAll("label"); |
| 478 | 30 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 479 | 186 | label = _ref[_i]; |
| 480 | 186 | if (label.textContent.trim() === selector) { |
| 481 | 29 | if (for_attr = label.getAttribute("for")) { |
| 482 | 6 | return this.document.getElementById(for_attr); |
| 483 | } else { | |
| 484 | 23 | return label.querySelector(":input"); |
| 485 | } | |
| 486 | } | |
| 487 | } | |
| 488 | }; | |
| 489 | ||
| 490 | 1 | Browser.prototype.fill = function(selector, value, callback) { |
| 491 | 40 | var field; |
| 492 | 40 | field = this.field(selector); |
| 493 | 40 | if (!(field && (field.tagName === "TEXTAREA" || (field.tagName === "INPUT")))) { |
| 494 | 0 | throw new Error("No INPUT matching '" + selector + "'"); |
| 495 | } | |
| 496 | 40 | if (field.getAttribute("disabled")) { |
| 497 | 0 | throw new Error("This INPUT field is disabled"); |
| 498 | } | |
| 499 | 40 | if (field.getAttribute("readonly")) { |
| 500 | 0 | throw new Error("This INPUT field is readonly"); |
| 501 | } | |
| 502 | 40 | field.focus(); |
| 503 | 40 | field.value = value; |
| 504 | 40 | this.fire("change", field, callback); |
| 505 | 40 | return this; |
| 506 | }; | |
| 507 | ||
| 508 | 1 | Browser.prototype._setCheckbox = function(selector, value, callback) { |
| 509 | 21 | var field; |
| 510 | 21 | field = this.field(selector); |
| 511 | 21 | if (!(field && field.tagName === "INPUT" && field.type === "checkbox")) { |
| 512 | 0 | throw new Error("No checkbox INPUT matching '" + selector + "'"); |
| 513 | } | |
| 514 | 21 | if (field.getAttribute("disabled")) { |
| 515 | 0 | throw new Error("This INPUT field is disabled"); |
| 516 | } | |
| 517 | 21 | if (field.getAttribute("readonly")) { |
| 518 | 0 | throw new Error("This INPUT field is readonly"); |
| 519 | } | |
| 520 | 21 | if (field.checked ^ value) { |
| 521 | 19 | field.click(); |
| 522 | } | |
| 523 | 21 | if (callback) { |
| 524 | 4 | this.wait(callback); |
| 525 | } | |
| 526 | 21 | return this; |
| 527 | }; | |
| 528 | ||
| 529 | 1 | Browser.prototype.check = function(selector, callback) { |
| 530 | 16 | return this._setCheckbox(selector, true, callback); |
| 531 | }; | |
| 532 | ||
| 533 | 1 | Browser.prototype.uncheck = function(selector, callback) { |
| 534 | 5 | return this._setCheckbox(selector, false, callback); |
| 535 | }; | |
| 536 | ||
| 537 | 1 | Browser.prototype.choose = function(selector, callback) { |
| 538 | 11 | var field; |
| 539 | 11 | field = this.field(selector) || this.field("input[type=radio][value=\"" + (escape(selector)) + "\"]"); |
| 540 | 11 | if (!(field && field.tagName === "INPUT" && field.type === "radio")) { |
| 541 | 0 | throw new Error("No radio INPUT matching '" + selector + "'"); |
| 542 | } | |
| 543 | 11 | field.click(); |
| 544 | 11 | if (callback) { |
| 545 | 2 | this.wait(callback); |
| 546 | } | |
| 547 | 11 | return this; |
| 548 | }; | |
| 549 | ||
| 550 | 1 | Browser.prototype._findOption = function(selector, value) { |
| 551 | 26 | var field, option, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; |
| 552 | 26 | field = this.field(selector); |
| 553 | 26 | if (!(field && field.tagName === "SELECT")) { |
| 554 | 0 | throw new Error("No SELECT matching '" + selector + "'"); |
| 555 | } | |
| 556 | 26 | if (field.getAttribute("disabled")) { |
| 557 | 0 | throw new Error("This SELECT field is disabled"); |
| 558 | } | |
| 559 | 26 | if (field.getAttribute("readonly")) { |
| 560 | 0 | throw new Error("This SELECT field is readonly"); |
| 561 | } | |
| 562 | 26 | _ref = field.options; |
| 563 | 26 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 564 | 54 | option = _ref[_i]; |
| 565 | 54 | if (option.value === value) { |
| 566 | 22 | return option; |
| 567 | } | |
| 568 | } | |
| 569 | 4 | _ref1 = field.options; |
| 570 | 4 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
| 571 | 10 | option = _ref1[_j]; |
| 572 | 10 | if (option.label === value) { |
| 573 | 3 | return option; |
| 574 | } | |
| 575 | } | |
| 576 | 1 | _ref2 = field.options; |
| 577 | 1 | for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { |
| 578 | 2 | option = _ref2[_k]; |
| 579 | 2 | if (option.textContent.trim() === value) { |
| 580 | 1 | return option; |
| 581 | } | |
| 582 | } | |
| 583 | 0 | throw new Error("No OPTION '" + value + "'"); |
| 584 | }; | |
| 585 | ||
| 586 | 1 | Browser.prototype.select = function(selector, value, callback) { |
| 587 | 23 | var option; |
| 588 | 23 | option = this._findOption(selector, value); |
| 589 | 23 | return this.selectOption(option, callback); |
| 590 | }; | |
| 591 | ||
| 592 | 1 | Browser.prototype.selectOption = function(option, callback) { |
| 593 | 25 | var select; |
| 594 | 25 | if (option && !option.getAttribute("selected")) { |
| 595 | 24 | select = this.xpath("./ancestor::select", option).value[0]; |
| 596 | 24 | option.setAttribute("selected", "selected"); |
| 597 | 24 | select.focus(); |
| 598 | 24 | this.fire("change", select, callback); |
| 599 | 1 | } else if (callback) { |
| 600 | 0 | process.nextTick(function() { |
| 601 | 0 | return callback(null, false); |
| 602 | }); | |
| 603 | } | |
| 604 | 25 | return this; |
| 605 | }; | |
| 606 | ||
| 607 | 1 | Browser.prototype.unselect = function(selector, value, callback) { |
| 608 | 3 | var option; |
| 609 | 3 | option = this._findOption(selector, value); |
| 610 | 3 | return this.unselectOption(option, callback); |
| 611 | }; | |
| 612 | ||
| 613 | 1 | Browser.prototype.unselectOption = function(option, callback) { |
| 614 | 3 | var select; |
| 615 | 3 | if (option && option.getAttribute("selected")) { |
| 616 | 1 | select = this.xpath("./ancestor::select", option).value[0]; |
| 617 | 1 | if (!select.multiple) { |
| 618 | 0 | throw new Error("Cannot unselect in single select"); |
| 619 | } | |
| 620 | 1 | option.removeAttribute("selected"); |
| 621 | 1 | select.focus(); |
| 622 | 1 | this.fire("change", select, callback); |
| 623 | 2 | } else if (callback) { |
| 624 | 0 | process.nextTick(function() { |
| 625 | 0 | return callback(null, false); |
| 626 | }); | |
| 627 | } | |
| 628 | 3 | return this; |
| 629 | }; | |
| 630 | ||
| 631 | 1 | Browser.prototype.attach = function(selector, filename, callback) { |
| 632 | 4 | var field, file, stat; |
| 633 | 4 | field = this.field(selector); |
| 634 | 4 | if (!(field && field.tagName === "INPUT" && field.type === "file")) { |
| 635 | 0 | throw new Error("No file INPUT matching '" + selector + "'"); |
| 636 | } | |
| 637 | 4 | if (filename) { |
| 638 | 3 | stat = FS.statSync(filename); |
| 639 | 3 | file = new this.window.File(); |
| 640 | 3 | file.name = Path.basename(filename); |
| 641 | 3 | file.type = Mime.lookup(filename); |
| 642 | 3 | file.size = stat.size; |
| 643 | 3 | field.files || (field.files = []); |
| 644 | 3 | field.files.push(file); |
| 645 | 3 | field.value = filename; |
| 646 | } | |
| 647 | 4 | field.focus(); |
| 648 | 4 | this.fire("change", field, callback); |
| 649 | 4 | return this; |
| 650 | }; | |
| 651 | ||
| 652 | 1 | Browser.prototype.button = function(selector) { |
| 653 | 24 | var button, input, inputs, _i, _j, _k, _len, _len1, _len2, _ref; |
| 654 | 24 | if (selector instanceof HTML.Element) { |
| 655 | 1 | return selector; |
| 656 | } | |
| 657 | 23 | if (button = this.querySelector(selector)) { |
| 658 | 1 | if (button.tagName === "BUTTON" || button.tagName === "INPUT") { |
| 659 | 1 | return button; |
| 660 | } | |
| 661 | } | |
| 662 | 22 | _ref = this.querySelectorAll("button"); |
| 663 | 22 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 664 | 17 | button = _ref[_i]; |
| 665 | 17 | if (button.textContent.trim() === selector) { |
| 666 | 16 | return button; |
| 667 | } | |
| 668 | } | |
| 669 | 6 | inputs = this.querySelectorAll(":submit, :reset, :button"); |
| 670 | 6 | for (_j = 0, _len1 = inputs.length; _j < _len1; _j++) { |
| 671 | 9 | input = inputs[_j]; |
| 672 | 9 | if (input.name === selector) { |
| 673 | 2 | return input; |
| 674 | } | |
| 675 | } | |
| 676 | 4 | for (_k = 0, _len2 = inputs.length; _k < _len2; _k++) { |
| 677 | 5 | input = inputs[_k]; |
| 678 | 5 | if (input.value === selector) { |
| 679 | 4 | return input; |
| 680 | } | |
| 681 | } | |
| 682 | }; | |
| 683 | ||
| 684 | 1 | Browser.prototype.pressButton = function(selector, callback) { |
| 685 | 22 | var button; |
| 686 | 22 | if (!(button = this.button(selector))) { |
| 687 | 0 | throw new Error("No BUTTON '" + selector + "'"); |
| 688 | } | |
| 689 | 22 | if (button.getAttribute("disabled")) { |
| 690 | 0 | throw new Error("This button is disabled"); |
| 691 | } | |
| 692 | 22 | button.focus(); |
| 693 | 22 | return this.fire("click", button, callback); |
| 694 | }; | |
| 695 | ||
| 696 | 1 | Browser.prototype.focused = function() { |
| 697 | 0 | return this.window._focused; |
| 698 | }; | |
| 699 | ||
| 700 | 1 | Browser.prototype.cookies = function(domain, path) { |
| 701 | 391 | return this._cookies.access(domain || this.location.hostname, path || this.location.pathname); |
| 702 | }; | |
| 703 | ||
| 704 | 1 | Browser.prototype.saveCookies = function() { |
| 705 | 1 | return this._cookies.save(); |
| 706 | }; | |
| 707 | ||
| 708 | 1 | Browser.prototype.loadCookies = function(serialized) { |
| 709 | 1 | return this._cookies.load(serialized); |
| 710 | }; | |
| 711 | ||
| 712 | 1 | Browser.prototype.localStorage = function(host) { |
| 713 | 4 | return this._storages.local(host); |
| 714 | }; | |
| 715 | ||
| 716 | 1 | Browser.prototype.sessionStorage = function(host) { |
| 717 | 4 | return this._storages.session(host); |
| 718 | }; | |
| 719 | ||
| 720 | 1 | Browser.prototype.saveStorage = function() { |
| 721 | 1 | return this._storages.save(); |
| 722 | }; | |
| 723 | ||
| 724 | 1 | Browser.prototype.loadStorage = function(serialized) { |
| 725 | 1 | return this._storages.load(serialized); |
| 726 | }; | |
| 727 | ||
| 728 | 1 | Browser.prototype.evaluate = function(code, filename) { |
| 729 | 14 | return this.window._evaluate(code, filename); |
| 730 | }; | |
| 731 | ||
| 732 | 1 | Browser.prototype.onalert = function(fn) { |
| 733 | 4 | return this._interact.onalert(fn); |
| 734 | }; | |
| 735 | ||
| 736 | 1 | Browser.prototype.onconfirm = function(question, response) { |
| 737 | 2 | return this._interact.onconfirm(question, response); |
| 738 | }; | |
| 739 | ||
| 740 | 1 | Browser.prototype.onprompt = function(message, response) { |
| 741 | 3 | return this._interact.onprompt(message, response); |
| 742 | }; | |
| 743 | ||
| 744 | 1 | Browser.prototype.prompted = function(message) { |
| 745 | 11 | return this._interact.prompted(message); |
| 746 | }; | |
| 747 | ||
| 748 | 1 | Browser.prototype.viewInBrowser = function(browser) { |
| 749 | 0 | return require("./bcat").bcat(this.html()); |
| 750 | }; | |
| 751 | ||
| 752 | 1 | Browser.prototype.__defineGetter__("lastRequest", function() { |
| 753 | 4 | var _ref; |
| 754 | 4 | return (_ref = this.resources.last) != null ? _ref.request : void 0; |
| 755 | }); | |
| 756 | ||
| 757 | 1 | Browser.prototype.__defineGetter__("lastResponse", function() { |
| 758 | 0 | var _ref; |
| 759 | 0 | return (_ref = this.resources.last) != null ? _ref.response : void 0; |
| 760 | }); | |
| 761 | ||
| 762 | 1 | Browser.prototype.__defineGetter__("lastError", function() { |
| 763 | 0 | var _ref; |
| 764 | 0 | return (_ref = this.resources.last) != null ? _ref.error : void 0; |
| 765 | }); | |
| 766 | ||
| 767 | 1 | Browser.prototype.log = function() { |
| 768 | 600 | var arg, values, _i, _len; |
| 769 | 600 | if (this.debug) { |
| 770 | 0 | values = ["Zombie:"]; |
| 771 | 0 | if (typeof arguments[0] === "function") { |
| 772 | 0 | try { |
| 773 | 0 | values.push(arguments[0]()); |
| 774 | } catch (ex) { | |
| 775 | 0 | values.push(ex); |
| 776 | } | |
| 777 | } else { | |
| 778 | 0 | for (_i = 0, _len = arguments.length; _i < _len; _i++) { |
| 779 | 0 | arg = arguments[_i]; |
| 780 | 0 | values.push(arg); |
| 781 | } | |
| 782 | } | |
| 783 | 0 | return console.log.apply(null, values); |
| 784 | } | |
| 785 | }; | |
| 786 | ||
| 787 | 1 | Browser.prototype.dump = function() { |
| 788 | 0 | var html, indent; |
| 789 | 0 | indent = function(lines) { |
| 790 | 0 | return lines.map(function(l) { |
| 791 | 0 | return " " + l + "\n"; |
| 792 | }).join(""); | |
| 793 | }; | |
| 794 | 0 | process.stdout.write("Zombie: " + VERSION + "\n\n"); |
| 795 | 0 | process.stdout.write("URL: " + this.window.location.href + "\n"); |
| 796 | 0 | process.stdout.write("History:\n" + (indent(this.window.history.dump())) + "\n"); |
| 797 | 0 | process.stdout.write("Cookies:\n" + (indent(this._cookies.dump())) + "\n"); |
| 798 | 0 | process.stdout.write("Storage:\n" + (indent(this._storages.dump())) + "\n"); |
| 799 | 0 | process.stdout.write("Eventloop:\n" + (indent(this._eventloop.dump())) + "\n"); |
| 800 | 0 | if (this.document) { |
| 801 | 0 | html = this.document.outerHTML; |
| 802 | 0 | if (html.length > 497) { |
| 803 | 0 | html = html.slice(0, 497) + "..."; |
| 804 | } | |
| 805 | 0 | return process.stdout.write("Document:\n" + (indent(html.split("\n"))) + "\n"); |
| 806 | } else { | |
| 807 | 0 | if (!this.document) { |
| 808 | 0 | return process.stdout.write("No document\n"); |
| 809 | } | |
| 810 | } | |
| 811 | }; | |
| 812 | ||
| 813 | 1 | return Browser; |
| 814 | ||
| 815 | })(EventEmitter); | |
| 816 | ||
| 817 | 1 | Credentials = (function() { |
| 818 | ||
| 819 | 1 | function Credentials() {} |
| 820 | ||
| 821 | 1 | Credentials.prototype.apply = function(headers) { |
| 822 | 348 | var base64; |
| 823 | 348 | switch (this.scheme) { |
| 824 | case "basic": | |
| 825 | 5 | base64 = new Buffer(this.user + ":" + this.password).toString("base64"); |
| 826 | 5 | return headers["authorization"] = "Basic " + base64; |
| 827 | case "bearer": | |
| 828 | 2 | return headers["authorization"] = "Bearer " + this.token; |
| 829 | case "oauth": | |
| 830 | 0 | return headers["authorization"] = "OAuth " + this.token; |
| 831 | } | |
| 832 | }; | |
| 833 | ||
| 834 | 1 | Credentials.prototype.basic = function(user, password) { |
| 835 | 4 | this.user = user; |
| 836 | 4 | this.password = password; |
| 837 | 4 | return this.scheme = "basic"; |
| 838 | }; | |
| 839 | ||
| 840 | 1 | Credentials.prototype.bearer = function(token) { |
| 841 | 2 | this.token = token; |
| 842 | 2 | return this.scheme = "bearer"; |
| 843 | }; | |
| 844 | ||
| 845 | 1 | Credentials.prototype.oauth = function(token) { |
| 846 | 0 | this.token = token; |
| 847 | 0 | return this.scheme = "oauth"; |
| 848 | }; | |
| 849 | ||
| 850 | 1 | Credentials.prototype.reset = function() { |
| 851 | 0 | delete this.scheme; |
| 852 | 0 | delete this.token; |
| 853 | 0 | delete this.user; |
| 854 | 0 | return delete this.password; |
| 855 | }; | |
| 856 | ||
| 857 | 1 | return Credentials; |
| 858 | ||
| 859 | })(); | |
| 860 | ||
| 861 | 1 | Browser.VERSION = VERSION; |
| 862 | ||
| 863 | 1 | module.exports = Browser; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var HTML, Path, URL, createSizzle, descendantOf, descendants, element, original, sizzle, _i, _j, _len, _len1, _ref, _ref1; |
| 3 | ||
| 4 | 1 | Path = require("path"); |
| 5 | ||
| 6 | 1 | sizzle = Path.resolve(require.resolve("jsdom"), "../jsdom/selectors/sizzle"); |
| 7 | ||
| 8 | 1 | createSizzle = require(sizzle); |
| 9 | ||
| 10 | 1 | HTML = require("jsdom").dom.level3.html; |
| 11 | ||
| 12 | 1 | URL = require("url"); |
| 13 | ||
| 14 | 1 | HTML.HTMLElement.prototype.__defineGetter__("offsetLeft", function() { |
| 15 | 2 | return 0; |
| 16 | }); | |
| 17 | ||
| 18 | 1 | HTML.HTMLElement.prototype.__defineGetter__("offsetTop", function() { |
| 19 | 131 | return 0; |
| 20 | }); | |
| 21 | ||
| 22 | 1 | original = HTML.Element.prototype.setAttribute; |
| 23 | ||
| 24 | 1 | HTML.Element.prototype.setAttribute = function(name, value) { |
| 25 | 7994 | var attr, wrapped; |
| 26 | 7994 | if (/^on.+/.test(name)) { |
| 27 | 14 | wrapped = "if ((function() { " + value + " }).call(this,event) === false) event.preventDefault();"; |
| 28 | 14 | this[name] = function(event) { |
| 29 | 4 | var window; |
| 30 | 4 | window = this.run ? this : this._ownerDocument.parentWindow; |
| 31 | 4 | try { |
| 32 | 4 | window.event = event; |
| 33 | 4 | return window.run(wrapped); |
| 34 | } finally { | |
| 35 | 4 | window.event = null; |
| 36 | } | |
| 37 | }; | |
| 38 | 14 | if (this._ownerDocument) { |
| 39 | 14 | attr = this._ownerDocument.createAttribute(name); |
| 40 | 14 | attr.value = value; |
| 41 | 14 | return this._attributes.setNamedItem(attr); |
| 42 | } | |
| 43 | } else { | |
| 44 | 7980 | return original.apply(this, arguments); |
| 45 | } | |
| 46 | }; | |
| 47 | ||
| 48 | 1 | HTML.Element.prototype.getAttribute = function(name) { |
| 49 | 47055 | var attribute; |
| 50 | 47055 | attribute = this._attributes.getNamedItem(name); |
| 51 | 47055 | return (attribute != null ? attribute.value : void 0) || null; |
| 52 | }; | |
| 53 | ||
| 54 | 1 | HTML.HTMLAnchorElement.prototype.__defineGetter__("href", function() { |
| 55 | 19 | return HTML.resourceLoader.resolve(this._ownerDocument, this.getAttribute('href') || ""); |
| 56 | }); | |
| 57 | ||
| 58 | 1 | HTML.HTMLLinkElement.prototype.__defineGetter__("href", function() { |
| 59 | 26 | return HTML.resourceLoader.resolve(this._ownerDocument, this.getAttribute('href') || ""); |
| 60 | }); | |
| 61 | ||
| 62 | 1 | HTML.HTMLElement.prototype.__defineGetter__("id", function() { |
| 63 | 8762 | return this.getAttribute("id") || ""; |
| 64 | }); | |
| 65 | ||
| 66 | 1 | _ref = [HTML.HTMLFormElement, HTML.HTMLMenuElement, HTML.HTMLSelectElement, HTML.HTMLInputElement, HTML.HTMLTextAreaElement, HTML.HTMLButtonElement, HTML.HTMLAnchorElement, HTML.HTMLImageElement, HTML.HTMLObjectElement, HTML.HTMLParamElement, HTML.HTMLAppletElement, HTML.HTMLMapElement, HTML.HTMLFrameElement, HTML.HTMLIFrameElement]; |
| 67 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 68 | 14 | element = _ref[_i]; |
| 69 | 14 | element.prototype.__defineGetter__("name", function() { |
| 70 | 27107 | return this.getAttribute("name") || ""; |
| 71 | }); | |
| 72 | } | |
| 73 | ||
| 74 | 1 | _ref1 = [HTML.HTMLInputElement, HTML.HTMLButtonElement, HTML.HTMLParamElement]; |
| 75 | 1 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
| 76 | 3 | element = _ref1[_j]; |
| 77 | 3 | element.prototype.__defineGetter__("value", function() { |
| 78 | 260 | return this.getAttribute("value") || ""; |
| 79 | }); | |
| 80 | } | |
| 81 | ||
| 82 | 1 | HTML.HTMLAnchorElement.prototype._eventDefaults = { |
| 83 | click: function(event) { | |
| 84 | 8 | var anchor, browser, window; |
| 85 | 8 | anchor = event.target; |
| 86 | 8 | if (!anchor.href) { |
| 87 | 0 | return; |
| 88 | } | |
| 89 | 8 | window = anchor.ownerDocument.parentWindow; |
| 90 | 8 | browser = window.browser; |
| 91 | 8 | switch (anchor.target || "_self") { |
| 92 | case "_self": | |
| 93 | 2 | window = window; |
| 94 | 2 | break; |
| 95 | case "_parent": | |
| 96 | 1 | window = window.parent; |
| 97 | 1 | break; |
| 98 | case "_top": | |
| 99 | 1 | window = window.top; |
| 100 | 1 | break; |
| 101 | default: | |
| 102 | 4 | window = browser.windows.get(anchor.target) || browser.open({ |
| 103 | name: anchor.target | |
| 104 | }); | |
| 105 | } | |
| 106 | 8 | browser.windows.select(window); |
| 107 | 8 | return window.location = anchor.href; |
| 108 | } | |
| 109 | }; | |
| 110 | ||
| 111 | 1 | HTML.resourceLoader.load = function(element, href, callback) { |
| 112 | 68 | var document, loaded, ownerImplementation, tagName, url, window; |
| 113 | 68 | document = element.ownerDocument; |
| 114 | 68 | window = document.parentWindow; |
| 115 | 68 | ownerImplementation = document.implementation; |
| 116 | 68 | tagName = element.tagName.toLowerCase(); |
| 117 | 68 | if (ownerImplementation.hasFeature('FetchExternalResources', tagName)) { |
| 118 | 55 | switch (tagName) { |
| 119 | case "iframe": | |
| 120 | 0 | if (/^javascript:/.test(href)) { |
| 121 | 0 | return url = URL.parse(href); |
| 122 | } else { | |
| 123 | 0 | window = element.contentWindow; |
| 124 | 0 | url = this.resolve(window.parent.location, href); |
| 125 | 0 | loaded = function(response, filename) { |
| 126 | 0 | return callback(response.body, URL.parse(response.url).pathname); |
| 127 | }; | |
| 128 | 0 | return window.browser.resources.get(url, this.enqueue(element, loaded, url.pathname)); |
| 129 | } | |
| 130 | 0 | break; |
| 131 | default: | |
| 132 | 55 | url = URL.parse(this.resolve(document, href)); |
| 133 | 55 | loaded = function(response, filename) { |
| 134 | 53 | return callback.call(this, response.body, URL.parse(response.url).pathname); |
| 135 | }; | |
| 136 | 55 | return window.browser.resources.get(url, this.enqueue(element, loaded, url.pathname)); |
| 137 | } | |
| 138 | } | |
| 139 | }; | |
| 140 | ||
| 141 | 1 | HTML.Document.prototype._elementBuilders["iframe"] = function(doc, tag) { |
| 142 | 19 | var iframe, parent, window; |
| 143 | 19 | parent = doc.window; |
| 144 | 19 | iframe = new HTML.HTMLIFrameElement(doc, tag); |
| 145 | 19 | window = null; |
| 146 | 19 | Object.defineProperty(iframe, "contentWindow", { |
| 147 | get: function() { | |
| 148 | 71 | if (!window) { |
| 149 | 19 | window = parent.browser.open({ |
| 150 | name: iframe.name, | |
| 151 | parent: parent | |
| 152 | }); | |
| 153 | } | |
| 154 | 71 | return window; |
| 155 | } | |
| 156 | }); | |
| 157 | 19 | Object.defineProperty(iframe, "contentDocument", { |
| 158 | get: function() { | |
| 159 | 20 | return window.document; |
| 160 | } | |
| 161 | }); | |
| 162 | 19 | iframe.setAttribute = function(name, value) { |
| 163 | 47 | if (name === "src" && value) { |
| 164 | 22 | iframe.contentWindow.location = URL.resolve(parent.location, value); |
| 165 | 22 | iframe.contentWindow.addEventListener("load", function(event) { |
| 166 | 21 | var onload; |
| 167 | 21 | onload = parent.document.createEvent("HTMLEvents"); |
| 168 | 21 | onload.initEvent("load", false, false); |
| 169 | 21 | return parent.browser._eventloop.dispatch(iframe, onload); |
| 170 | }); | |
| 171 | 22 | return HTML.HTMLElement.prototype.setAttribute.call(this, name, value); |
| 172 | } else { | |
| 173 | 25 | return HTML.HTMLFrameElement.prototype.setAttribute.call(this, name, value); |
| 174 | } | |
| 175 | }; | |
| 176 | 19 | return iframe; |
| 177 | }; | |
| 178 | ||
| 179 | 1 | Object.defineProperty(HTML.CSSStyleDeclaration.prototype, "opacity", { |
| 180 | get: function() { | |
| 181 | 241 | return this._opacity || ""; |
| 182 | }, | |
| 183 | set: function(opacity) { | |
| 184 | 65 | if (opacity) { |
| 185 | 63 | opacity = parseFloat(opacity); |
| 186 | 63 | if (!isNaN(opacity)) { |
| 187 | 62 | return this._opacity = opacity.toString(); |
| 188 | } | |
| 189 | } else { | |
| 190 | 2 | return delete this._opacity; |
| 191 | } | |
| 192 | } | |
| 193 | }); | |
| 194 | ||
| 195 | 1 | ["height", "width"].forEach(function(prop) { |
| 196 | 2 | var client, internal, offset; |
| 197 | 2 | internal = "_" + prop; |
| 198 | 2 | client = "client" + (prop[0].toUpperCase()) + (prop.slice(1)); |
| 199 | 2 | offset = "offset" + (prop[0].toUpperCase()) + (prop.slice(1)); |
| 200 | 2 | Object.defineProperty(HTML.CSSStyleDeclaration.prototype, prop, { |
| 201 | get: function() { | |
| 202 | 904 | return this[internal] || ""; |
| 203 | }, | |
| 204 | set: function(value) { | |
| 205 | 575 | if (/^\d+px$/.test(value)) { |
| 206 | 428 | return this[internal] = value; |
| 207 | 147 | } else if (!value) { |
| 208 | 55 | return delete this[internal]; |
| 209 | } | |
| 210 | } | |
| 211 | }); | |
| 212 | 2 | Object.defineProperty(HTML.HTMLElement.prototype, client, { |
| 213 | get: function() { | |
| 214 | 0 | return parseInt(this[internal] || 100); |
| 215 | } | |
| 216 | }); | |
| 217 | 2 | return Object.defineProperty(HTML.HTMLElement.prototype, offset, { |
| 218 | get: function() { | |
| 219 | 116 | return parseInt(this[internal] || 100); |
| 220 | } | |
| 221 | }); | |
| 222 | }); | |
| 223 | ||
| 224 | 1 | HTML.Node.prototype.__defineGetter__("textContent", function() { |
| 225 | 1303 | if (this.nodeType === HTML.Node.TEXT_NODE || this.nodeType === HTML.Node.COMMENT_NODE || this.nodeType === HTML.Node.ATTRIBUTE_NODE || this.nodeType === HTML.Node.CDATA_SECTION_NODE) { |
| 226 | 596 | return this.nodeValue; |
| 227 | 707 | } else if (this.nodeType === HTML.Node.ELEMENT_NODE || this.nodeType === HTML.Node.DOCUMENT_FRAGMENT_NODE) { |
| 228 | 707 | return this.childNodes.filter(function(node) { |
| 229 | 757 | return node.nodeType === HTML.Node.TEXT_NODE || node.nodeType === HTML.Node.ELEMENT_NODE || node.nodeType === HTML.Node.CDATA_SECTION_NODE; |
| 230 | }).map(function(node) { | |
| 231 | 756 | return node.textContent; |
| 232 | }).join(""); | |
| 233 | } else { | |
| 234 | 0 | return null; |
| 235 | } | |
| 236 | }); | |
| 237 | ||
| 238 | 1 | HTML.NodeList.prototype.update = function() { |
| 239 | 10097 | var i, name, node, nodes, _k, _l, _len2, _ref2, _ref3; |
| 240 | 10097 | if (this._element && this._version < this._element._version) { |
| 241 | 5948 | for (i = _k = 0, _ref2 = this._length; 0 <= _ref2 ? _k <= _ref2 : _k >= _ref2; i = 0 <= _ref2 ? ++_k : --_k) { |
| 242 | 5968 | delete this[i]; |
| 243 | } | |
| 244 | 5948 | if (this._names) { |
| 245 | 6 | _ref3 = this._names; |
| 246 | 6 | for (_l = 0, _len2 = _ref3.length; _l < _len2; _l++) { |
| 247 | 10 | name = _ref3[_l]; |
| 248 | 10 | delete this[name]; |
| 249 | } | |
| 250 | } | |
| 251 | 5948 | nodes = this._snapshot = this._query(); |
| 252 | 5948 | this._length = nodes.length; |
| 253 | 5948 | this._names = []; |
| 254 | 5948 | for (i in nodes) { |
| 255 | 19412 | node = nodes[i]; |
| 256 | 19412 | this[i] = node; |
| 257 | 19412 | if (name = node.name) { |
| 258 | 18160 | this._names.push(name); |
| 259 | 18160 | this[node.name] = node; |
| 260 | } | |
| 261 | } | |
| 262 | 5948 | this._version = this._element._version; |
| 263 | } | |
| 264 | 10097 | return this._snapshot; |
| 265 | }; | |
| 266 | ||
| 267 | 1 | HTML.Node.prototype.contains = function(otherNode) { |
| 268 | 4 | return !!(this.compareDocumentPosition(otherNode) & 16); |
| 269 | }; | |
| 270 | ||
| 271 | 1 | HTML.HTMLDocument.prototype.querySelector = function(selector) { |
| 272 | 323 | this._sizzle || (this._sizzle = createSizzle(this)); |
| 273 | 323 | return this._sizzle(selector, this)[0]; |
| 274 | }; | |
| 275 | ||
| 276 | 1 | HTML.HTMLDocument.prototype.querySelectorAll = function(selector) { |
| 277 | 202 | this._sizzle || (this._sizzle = createSizzle(this)); |
| 278 | 202 | return new HTML.NodeList(this._sizzle(selector, this)); |
| 279 | }; | |
| 280 | ||
| 281 | 1 | descendantOf = function(element, context) { |
| 282 | 3360 | var parent; |
| 283 | 3360 | parent = element.parentNode; |
| 284 | 3360 | if (parent) { |
| 285 | 2726 | return parent === context || descendantOf(parent, context); |
| 286 | } else { | |
| 287 | 634 | return false; |
| 288 | } | |
| 289 | }; | |
| 290 | ||
| 291 | 1 | descendants = function(element, selector) { |
| 292 | 96 | var document, parent; |
| 293 | 96 | document = element.ownerDocument; |
| 294 | 96 | document._sizzle || (document._sizzle = createSizzle(document)); |
| 295 | 96 | if (!element.parentNode) { |
| 296 | 30 | parent = element.ownerDocument.createElement("div"); |
| 297 | 30 | parent.appendChild(element); |
| 298 | 30 | element = parent; |
| 299 | } | |
| 300 | 96 | return document._sizzle(selector, element.parentNode || element).filter(function(node) { |
| 301 | 687 | return descendantOf(node, element); |
| 302 | }); | |
| 303 | }; | |
| 304 | ||
| 305 | 1 | HTML.Element.prototype.querySelector = function(selector) { |
| 306 | 23 | return descendants(this, selector)[0]; |
| 307 | }; | |
| 308 | ||
| 309 | 1 | HTML.Element.prototype.querySelectorAll = function(selector) { |
| 310 | 73 | return new HTML.NodeList(descendants(this, selector)); |
| 311 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var File, HTML, Mime, Path, UploadedFile, element, focus, _i, _len, _ref; |
| 3 | ||
| 4 | 1 | HTML = require("jsdom").dom.level3.html; |
| 5 | ||
| 6 | 1 | Path = require("path"); |
| 7 | ||
| 8 | 1 | File = require("fs"); |
| 9 | ||
| 10 | 1 | Mime = require("mime"); |
| 11 | ||
| 12 | 1 | UploadedFile = function(filename) { |
| 13 | 3 | var file; |
| 14 | 3 | file = new String(Path.basename(filename)); |
| 15 | 3 | file.filename = filename; |
| 16 | 3 | file.mime = Mime.lookup(filename); |
| 17 | 3 | file.read = function() { |
| 18 | 3 | return File.readFileSync(filename); |
| 19 | }; | |
| 20 | 3 | return file; |
| 21 | }; | |
| 22 | ||
| 23 | 1 | HTML.HTMLFormElement.prototype.submit = function(button) { |
| 24 | 18 | var document, params, process, |
| 25 | _this = this; | |
| 26 | 18 | document = this.ownerDocument; |
| 27 | 18 | params = []; |
| 28 | 18 | process = function(index) { |
| 29 | 295 | var field, history, name, option, selected, value, _i, _len, _ref, _ref1; |
| 30 | 295 | if (field = _this.elements.item(index)) { |
| 31 | 277 | value = null; |
| 32 | 277 | if (!field.getAttribute("disabled") && (name = field.getAttribute("name"))) { |
| 33 | 250 | if (field.nodeName === "SELECT") { |
| 34 | 37 | selected = []; |
| 35 | 37 | _ref = field.options; |
| 36 | 37 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 37 | 118 | option = _ref[_i]; |
| 38 | 118 | if (option.selected) { |
| 39 | 5 | selected.push(option.value); |
| 40 | } | |
| 41 | } | |
| 42 | 37 | if (field.multiple) { |
| 43 | 6 | params.push([name, selected]); |
| 44 | } else { | |
| 45 | 31 | if (selected.length > 0) { |
| 46 | 3 | value = selected[0]; |
| 47 | } else { | |
| 48 | 28 | value = (_ref1 = field.options[0]) != null ? _ref1.value : void 0; |
| 49 | } | |
| 50 | 31 | params.push([name, value]); |
| 51 | } | |
| 52 | 213 | } else if (field.nodeName === "INPUT" && (field.type === "checkbox" || field.type === "radio")) { |
| 53 | 55 | if (field.checked) { |
| 54 | 27 | params.push([name, field.value || "1"]); |
| 55 | } | |
| 56 | 158 | } else if (field.nodeName === "INPUT" && field.type === "file") { |
| 57 | 9 | if (field.value) { |
| 58 | 3 | params.push([name, UploadedFile(field.value)]); |
| 59 | } | |
| 60 | 149 | } else if (field.nodeName === "TEXTAREA" || field.nodeName === "INPUT") { |
| 61 | 143 | if (field.type !== "submit" && field.type !== "image") { |
| 62 | 127 | params.push([name, field.value || ""]); |
| 63 | } | |
| 64 | } | |
| 65 | } | |
| 66 | 277 | return process(index + 1); |
| 67 | } else { | |
| 68 | 18 | if (button && button.name) { |
| 69 | 8 | params.push([button.name, button.value]); |
| 70 | } | |
| 71 | 18 | history = document.parentWindow.history; |
| 72 | 18 | return history._submit(_this.getAttribute("action"), _this.getAttribute("method"), params, _this.getAttribute("enctype")); |
| 73 | } | |
| 74 | }; | |
| 75 | 18 | return process(0); |
| 76 | }; | |
| 77 | ||
| 78 | 1 | HTML.HTMLFormElement.prototype.reset = function() { |
| 79 | 3 | var field, option, _i, _len, _ref, _results; |
| 80 | 3 | _ref = this.elements; |
| 81 | 3 | _results = []; |
| 82 | 3 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 83 | 108 | field = _ref[_i]; |
| 84 | 108 | if (field.nodeName === "SELECT") { |
| 85 | 18 | _results.push((function() { |
| 86 | 18 | var _j, _len1, _ref1, _results1; |
| 87 | 18 | _ref1 = field.options; |
| 88 | 18 | _results1 = []; |
| 89 | 18 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
| 90 | 54 | option = _ref1[_j]; |
| 91 | 54 | _results1.push(option.selected = option._defaultSelected); |
| 92 | } | |
| 93 | 18 | return _results1; |
| 94 | })()); | |
| 95 | 90 | } else if (field.nodeName === "INPUT" && field.type === "check" || field.type === "radio") { |
| 96 | 9 | _results.push(field.checked = field._defaultChecked); |
| 97 | 81 | } else if (field.nodeName === "INPUT" || field.nodeName === "TEXTAREA") { |
| 98 | 78 | _results.push(field.value = field._defaultValue); |
| 99 | } else { | |
| 100 | 3 | _results.push(void 0); |
| 101 | } | |
| 102 | } | |
| 103 | 3 | return _results; |
| 104 | }; | |
| 105 | ||
| 106 | 1 | HTML.HTMLFormElement.prototype._dispatchSubmitEvent = function(button) { |
| 107 | 20 | var event; |
| 108 | 20 | event = this.ownerDocument.createEvent("HTMLEvents"); |
| 109 | 20 | event.initEvent("submit", true, true); |
| 110 | 20 | event._button = button; |
| 111 | 20 | return this.ownerDocument.parentWindow.browser.dispatchEvent(this, event); |
| 112 | }; | |
| 113 | ||
| 114 | 1 | HTML.HTMLFormElement.prototype._eventDefaults["submit"] = function(event) { |
| 115 | 17 | return event.target.submit(event._button); |
| 116 | }; | |
| 117 | ||
| 118 | 1 | HTML.HTMLInputElement.prototype._eventDefaults = { |
| 119 | click: function(event) { | |
| 120 | 37 | var change, form, input; |
| 121 | 37 | input = event.target; |
| 122 | 37 | change = function() { |
| 123 | 28 | event = input.ownerDocument.createEvent("HTMLEvents"); |
| 124 | 28 | event.initEvent("change", true, true); |
| 125 | 28 | return input.ownerDocument.parentWindow.browser.dispatchEvent(input, event); |
| 126 | }; | |
| 127 | 37 | switch (input.type) { |
| 128 | case "reset": | |
| 129 | 2 | if (form = input.form) { |
| 130 | 2 | return form.reset(); |
| 131 | } | |
| 132 | 0 | break; |
| 133 | case "submit": | |
| 134 | case "image": | |
| 135 | 7 | if (form = input.form) { |
| 136 | 7 | return form._dispatchSubmitEvent(input); |
| 137 | } | |
| 138 | 0 | break; |
| 139 | case "checkbox": | |
| 140 | 18 | return change(); |
| 141 | case "radio": | |
| 142 | 10 | if (!input.getAttribute("readonly")) { |
| 143 | 10 | input.checked = true; |
| 144 | 10 | return change(); |
| 145 | } | |
| 146 | } | |
| 147 | } | |
| 148 | }; | |
| 149 | ||
| 150 | 1 | HTML.HTMLInputElement.prototype.click = function() { |
| 151 | 33 | var change, checked, click, original, radio, radios, _i, _j, _len, _len1, |
| 152 | _this = this; | |
| 153 | 33 | focus(this.ownerDocument, this); |
| 154 | 33 | click = function() { |
| 155 | 33 | var cancelled, event; |
| 156 | 33 | event = _this.ownerDocument.createEvent("HTMLEvents"); |
| 157 | 33 | event.initEvent("click", true, true); |
| 158 | 33 | cancelled = _this.ownerDocument.parentWindow.browser.dispatchEvent(_this, event); |
| 159 | 33 | return !cancelled; |
| 160 | }; | |
| 161 | 33 | change = function() { |
| 162 | 27 | var event; |
| 163 | 27 | event = _this.ownerDocument.createEvent("HTMLEvents"); |
| 164 | 27 | event.initEvent("change", true, true); |
| 165 | 27 | return _this.ownerDocument.parentWindow.browser.dispatchEvent(_this, event); |
| 166 | }; | |
| 167 | 33 | switch (this.type) { |
| 168 | case "checkbox": | |
| 169 | 19 | if (!this.getAttribute("readonly")) { |
| 170 | 19 | original = this.checked; |
| 171 | 19 | this.checked = !this.checked; |
| 172 | 19 | if (click()) { |
| 173 | 18 | change(); |
| 174 | } else { | |
| 175 | 1 | this.checked = original; |
| 176 | } | |
| 177 | } | |
| 178 | 19 | break; |
| 179 | case "radio": | |
| 180 | 11 | if (!this.getAttribute("readonly")) { |
| 181 | 11 | if (this.checked) { |
| 182 | 1 | click(); |
| 183 | } else { | |
| 184 | 10 | radios = this.ownerDocument.querySelectorAll(":radio[name='" + (this.getAttribute("name")) + "']", this.form); |
| 185 | 10 | checked = null; |
| 186 | 10 | for (_i = 0, _len = radios.length; _i < _len; _i++) { |
| 187 | 18 | radio = radios[_i]; |
| 188 | 18 | if (radio.checked) { |
| 189 | 9 | checked = radio; |
| 190 | 9 | radio.checked = false; |
| 191 | } | |
| 192 | } | |
| 193 | 10 | this.checked = true; |
| 194 | 10 | if (click()) { |
| 195 | 9 | change(); |
| 196 | } else { | |
| 197 | 1 | this.checked = false; |
| 198 | 1 | for (_j = 0, _len1 = radios.length; _j < _len1; _j++) { |
| 199 | 0 | radio = radios[_j]; |
| 200 | 0 | radio.checked = radio === checked; |
| 201 | } | |
| 202 | } | |
| 203 | } | |
| 204 | } | |
| 205 | 11 | break; |
| 206 | default: | |
| 207 | 3 | click(); |
| 208 | } | |
| 209 | }; | |
| 210 | ||
| 211 | 1 | HTML.HTMLButtonElement.prototype._eventDefaults = { |
| 212 | click: function(event) { | |
| 213 | 13 | var button, form; |
| 214 | 13 | button = event.target; |
| 215 | 13 | if (button.getAttribute("disabled")) { |
| 216 | ||
| 217 | } else { | |
| 218 | 13 | form = button.form; |
| 219 | 13 | if (form) { |
| 220 | 13 | return form._dispatchSubmitEvent(button); |
| 221 | } | |
| 222 | } | |
| 223 | } | |
| 224 | }; | |
| 225 | ||
| 226 | 1 | HTML.Document.prototype._elementBuilders["button"] = function(doc, s) { |
| 227 | 51 | var button; |
| 228 | 51 | button = new HTML.HTMLButtonElement(doc, s); |
| 229 | 51 | button.type || (button.type = "submit"); |
| 230 | 51 | return button; |
| 231 | }; | |
| 232 | ||
| 233 | 1 | HTML.HTMLDocument.prototype.__defineGetter__("activeElement", function() { |
| 234 | 226 | return document._focused; |
| 235 | }); | |
| 236 | ||
| 237 | 1 | focus = function(document, element) { |
| 238 | 125 | var onblur, onfocus; |
| 239 | 125 | if (element !== document._focused) { |
| 240 | 117 | if (document._focused) { |
| 241 | 66 | onblur = document.createEvent("HTMLEvents"); |
| 242 | 66 | onblur.initEvent("blur", false, false); |
| 243 | 66 | document._focused.dispatchEvent(onblur); |
| 244 | } | |
| 245 | 117 | if (element) { |
| 246 | 117 | onfocus = document.createEvent("HTMLEvents"); |
| 247 | 117 | onfocus.initEvent("focus", false, false); |
| 248 | 117 | element.dispatchEvent(onfocus); |
| 249 | } | |
| 250 | 117 | return document._focused = element; |
| 251 | } | |
| 252 | }; | |
| 253 | ||
| 254 | 1 | _ref = [HTML.HTMLInputElement, HTML.HTMLSelectElement, HTML.HTMLTextAreaElement, HTML.HTMLButtonElement, HTML.HTMLAnchorElement]; |
| 255 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 256 | 5 | element = _ref[_i]; |
| 257 | 5 | element.prototype.focus = function() { |
| 258 | 92 | return focus(this.ownerDocument, this); |
| 259 | }; | |
| 260 | 5 | element.prototype.blur = function() { |
| 261 | 0 | return focus(this.ownerDocument, null); |
| 262 | }; | |
| 263 | } |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var engine, fs, html, vm, xpath; |
| 3 | ||
| 4 | 1 | vm = require("vm"); |
| 5 | ||
| 6 | 1 | fs = require("fs"); |
| 7 | ||
| 8 | 1 | html = require("jsdom").dom.level3.html; |
| 9 | ||
| 10 | 1 | engine = null; |
| 11 | ||
| 12 | 1 | xpath = function() { |
| 13 | 30 | if (!engine) { |
| 14 | 1 | engine = vm.Script.createContext(); |
| 15 | 1 | engine.navigator = { |
| 16 | appVersion: "Zombie.js" | |
| 17 | }; | |
| 18 | 1 | new vm.Script(fs.readFileSync(__dirname + "/../../xpath/util.js")).runInContext(engine); |
| 19 | 1 | new vm.Script(fs.readFileSync(__dirname + "/../../xpath/xmltoken.js")).runInContext(engine); |
| 20 | 1 | new vm.Script(fs.readFileSync(__dirname + "/../../xpath/xpath.js")).runInContext(engine); |
| 21 | } | |
| 22 | 30 | return engine; |
| 23 | }; | |
| 24 | ||
| 25 | 1 | html.HTMLDocument.prototype.evaluate = function(expr, node, nsResolver, type, result) { |
| 26 | 30 | var context; |
| 27 | 30 | engine = xpath(); |
| 28 | 30 | context = new engine.ExprContext(node || this); |
| 29 | 30 | context.setCaseInsensitive(true); |
| 30 | 30 | result = engine.xpathParse(expr).evaluate(context); |
| 31 | 30 | if (result.type === 'node-set') { |
| 32 | 27 | result.value = result.value.sort(function(a, b) { |
| 33 | 22 | var value; |
| 34 | 22 | value = a.compareDocumentPosition(b); |
| 35 | 22 | if (value === 2 || value === 8 || value === 10) { |
| 36 | 8 | return 1; |
| 37 | } else { | |
| 38 | 14 | return -1; |
| 39 | } | |
| 40 | }); | |
| 41 | } | |
| 42 | 30 | return result; |
| 43 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var deprecated; |
| 3 | ||
| 4 | 1 | deprecated = function(message) { |
| 5 | 1 | this.shown || (this.shown = {}); |
| 6 | 1 | if (!this.shown[message]) { |
| 7 | 1 | this.shown[message] = true; |
| 8 | 1 | return process.stderr.write(message); |
| 9 | } | |
| 10 | }; | |
| 11 | ||
| 12 | 1 | module.exports = { |
| 13 | deprecated: deprecated.bind(deprecated) | |
| 14 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Cache; |
| 3 | ||
| 4 | 1 | Cache = (function() { |
| 5 | ||
| 6 | 1 | function Cache() {} |
| 7 | ||
| 8 | 1 | return Cache; |
| 9 | ||
| 10 | })(); | |
| 11 | ||
| 12 | 1 | module.exports = Cache; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Access, Cookie, Cookies, HTML, Tough; |
| 3 | ||
| 4 | 1 | HTML = require("jsdom").dom.level3.html; |
| 5 | ||
| 6 | 1 | Tough = require("tough-cookie"); |
| 7 | ||
| 8 | 1 | Cookie = Tough.Cookie; |
| 9 | ||
| 10 | 1 | Access = (function() { |
| 11 | ||
| 12 | 1 | function Access(_cookies, domain, path) { |
| 13 | 391 | this._cookies = _cookies; |
| 14 | 391 | this.domain = Tough.canonicalDomain(domain); |
| 15 | 391 | this.path = path || "/"; |
| 16 | } | |
| 17 | ||
| 18 | 1 | Access.prototype.all = function() { |
| 19 | 383 | var _this = this; |
| 20 | 383 | return this._cookies.all().filter(function(cookie) { |
| 21 | 373 | return Tough.domainMatch(_this.domain, cookie.domain) && Tough.pathMatch(_this.path, cookie.path) && cookie.TTL() > 0; |
| 22 | }).sort(Tough.cookieCompare); | |
| 23 | }; | |
| 24 | ||
| 25 | 1 | Access.prototype.get = function(name) { |
| 26 | 24 | var cookie, sorted, _i, _len; |
| 27 | 24 | sorted = this.all(); |
| 28 | 24 | for (_i = 0, _len = sorted.length; _i < _len; _i++) { |
| 29 | 115 | cookie = sorted[_i]; |
| 30 | 115 | if (cookie.key === name) { |
| 31 | 17 | return cookie.value; |
| 32 | } | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | 1 | Access.prototype.set = function(name, value, options) { |
| 37 | 12 | var cookie, |
| 38 | _this = this; | |
| 39 | 12 | if (options == null) { |
| 40 | 7 | options = {}; |
| 41 | } | |
| 42 | 12 | cookie = new Cookie({ |
| 43 | key: name, | |
| 44 | value: value, | |
| 45 | domain: options.domain || this.domain, | |
| 46 | path: options.path || this.path | |
| 47 | }); | |
| 48 | 12 | if (options.expires) { |
| 49 | 0 | cookie.setExpires(options.expirs); |
| 50 | 12 | } else if (options.hasOwnProperty("max-age")) { |
| 51 | 2 | cookie.setMaxAge(options["max-age"]); |
| 52 | } | |
| 53 | 12 | cookie.secure = !!options.secure; |
| 54 | 12 | cookie.httpOnly = !!options.httpOnly; |
| 55 | 12 | this._cookies.filter(function(c) { |
| 56 | 57 | return !(cookie.key === c.key && cookie.domain === c.domain && cookie.path === c.path); |
| 57 | }); | |
| 58 | 12 | if (Tough.domainMatch(cookie.domain, this.domain) && Tough.pathMatch(cookie.path, this.path) && cookie.TTL() > 0) { |
| 59 | 11 | return this._cookies.push(cookie); |
| 60 | } | |
| 61 | }; | |
| 62 | ||
| 63 | 1 | Access.prototype.remove = function(name) { |
| 64 | 0 | var _this = this; |
| 65 | 0 | return this._cookies.filter(function(cookie) { |
| 66 | 0 | return !(cookie.key === name && cookie.domain === _this.domain && cookie.path === _this.path); |
| 67 | }); | |
| 68 | }; | |
| 69 | ||
| 70 | 1 | Access.prototype.clear = function() { |
| 71 | 0 | var _this = this; |
| 72 | 0 | return this._cookies.filter(function(cookie) { |
| 73 | 0 | return !(cookie.domain === _this.domain && cookie.path === _this.path); |
| 74 | }); | |
| 75 | }; | |
| 76 | ||
| 77 | 1 | Access.prototype.update = function(serialized) { |
| 78 | 113 | var cookie, _i, _len, _ref, _results; |
| 79 | 113 | if (!serialized) { |
| 80 | 0 | return; |
| 81 | } | |
| 82 | 113 | if (serialized.constructor === Array) { |
| 83 | 0 | serialized = serialized.join(","); |
| 84 | } | |
| 85 | 113 | _ref = serialized.split(/,(?=[^;,]*=)|,$/); |
| 86 | 113 | _results = []; |
| 87 | 113 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 88 | 113 | cookie = _ref[_i]; |
| 89 | 113 | cookie = Cookie.parse(cookie); |
| 90 | 113 | cookie.domain || (cookie.domain = this.domain); |
| 91 | 113 | cookie.path || (cookie.path = this.path); |
| 92 | 113 | this._cookies.filter(function(c) { |
| 93 | 630 | return !(cookie.key === c.key && cookie.domain === c.domain && cookie.path === c.path); |
| 94 | }); | |
| 95 | 113 | if (Tough.domainMatch(this.domain, cookie.domain) && Tough.pathMatch(this.path, cookie.path) && cookie.TTL() > 0) { |
| 96 | 76 | _results.push(this._cookies.push(cookie)); |
| 97 | } else { | |
| 98 | 37 | _results.push(void 0); |
| 99 | } | |
| 100 | } | |
| 101 | 113 | return _results; |
| 102 | }; | |
| 103 | ||
| 104 | 1 | Access.prototype.addHeader = function(headers) { |
| 105 | 349 | var cookie, header; |
| 106 | 349 | header = ((function() { |
| 107 | 349 | var _i, _len, _ref, _results; |
| 108 | 349 | _ref = this.all(); |
| 109 | 349 | _results = []; |
| 110 | 349 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 111 | 99 | cookie = _ref[_i]; |
| 112 | 99 | _results.push(cookie.cookieString()); |
| 113 | } | |
| 114 | 349 | return _results; |
| 115 | }).call(this)).join("; "); | |
| 116 | 349 | if (header.length > 0) { |
| 117 | 16 | return headers.cookie = header; |
| 118 | } | |
| 119 | }; | |
| 120 | ||
| 121 | 1 | Access.prototype.dump = function(separator) { |
| 122 | 0 | var cookie; |
| 123 | 0 | if (separator == null) { |
| 124 | 0 | separator = "\n"; |
| 125 | } | |
| 126 | 0 | return ((function() { |
| 127 | 0 | var _i, _len, _ref, _results; |
| 128 | 0 | _ref = this.all(); |
| 129 | 0 | _results = []; |
| 130 | 0 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 131 | 0 | cookie = _ref[_i]; |
| 132 | 0 | _results.push(cookie.toString()); |
| 133 | } | |
| 134 | 0 | return _results; |
| 135 | }).call(this)).join(separator); | |
| 136 | }; | |
| 137 | ||
| 138 | 1 | Access.prototype.toString = function() { |
| 139 | 0 | var cookie; |
| 140 | 0 | return ((function() { |
| 141 | 0 | var _i, _len, _ref, _results; |
| 142 | 0 | _ref = this.all(); |
| 143 | 0 | _results = []; |
| 144 | 0 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 145 | 0 | cookie = _ref[_i]; |
| 146 | 0 | _results.push(cookie.toString()); |
| 147 | } | |
| 148 | 0 | return _results; |
| 149 | }).call(this)).join("\n"); | |
| 150 | }; | |
| 151 | ||
| 152 | 1 | return Access; |
| 153 | ||
| 154 | })(); | |
| 155 | ||
| 156 | 1 | Cookies = (function() { |
| 157 | ||
| 158 | 1 | function Cookies() { |
| 159 | 195 | this._cookies = []; |
| 160 | } | |
| 161 | ||
| 162 | 1 | Cookies.prototype.access = function(hostname, pathname) { |
| 163 | 391 | return new Access(this, hostname, pathname); |
| 164 | }; | |
| 165 | ||
| 166 | 1 | Cookies.prototype.extend = function(window) { |
| 167 | 223 | return Object.defineProperty(window, "cookies", { |
| 168 | get: function() { | |
| 169 | 14 | return this.browser.cookies(this.location.hostname, this.location.pathname); |
| 170 | } | |
| 171 | }); | |
| 172 | }; | |
| 173 | ||
| 174 | 1 | Cookies.prototype.dump = function() { |
| 175 | 0 | var cookie, _i, _len, _ref, _results; |
| 176 | 0 | _ref = this._cookies.sort(Tough.cookieCompare); |
| 177 | 0 | _results = []; |
| 178 | 0 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 179 | 0 | cookie = _ref[_i]; |
| 180 | 0 | _results.push(process.stdout.write(cookie.toString() + "\n")); |
| 181 | } | |
| 182 | 0 | return _results; |
| 183 | }; | |
| 184 | ||
| 185 | 1 | Cookies.prototype.save = function() { |
| 186 | 1 | var cookie, serialized, _i, _len, _ref; |
| 187 | 1 | serialized = ["# Saved on " + (new Date().toISOString())]; |
| 188 | 1 | _ref = this._cookies.sort(Tough.cookieCompare); |
| 189 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 190 | 1 | cookie = _ref[_i]; |
| 191 | 1 | serialized.push(cookie.toString()); |
| 192 | } | |
| 193 | 1 | return serialized.join("\n") + "\n"; |
| 194 | }; | |
| 195 | ||
| 196 | 1 | Cookies.prototype.load = function(serialized) { |
| 197 | 1 | var line, _i, _len, _ref, _results; |
| 198 | 1 | _ref = serialized.split(/\n+/); |
| 199 | 1 | _results = []; |
| 200 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 201 | 3 | line = _ref[_i]; |
| 202 | 3 | line = line.trim(); |
| 203 | 3 | if (line[0] === "#" || line === "") { |
| 204 | 2 | continue; |
| 205 | } | |
| 206 | 1 | _results.push(this._cookies.push(Cookie.parse(line))); |
| 207 | } | |
| 208 | 1 | return _results; |
| 209 | }; | |
| 210 | ||
| 211 | 1 | Cookies.prototype.filter = function(fn) { |
| 212 | 125 | return this._cookies = this._cookies.filter(fn); |
| 213 | }; | |
| 214 | ||
| 215 | 1 | Cookies.prototype.push = function(cookie) { |
| 216 | 87 | return this._cookies.push(cookie); |
| 217 | }; | |
| 218 | ||
| 219 | 1 | Cookies.prototype.all = function() { |
| 220 | 383 | return this._cookies.slice(); |
| 221 | }; | |
| 222 | ||
| 223 | 1 | return Cookies; |
| 224 | ||
| 225 | })(); | |
| 226 | ||
| 227 | 1 | HTML.HTMLDocument.prototype.__defineGetter__("cookie", function() { |
| 228 | 9 | var cookie, cookies; |
| 229 | 9 | cookies = (function() { |
| 230 | 9 | var _i, _len, _ref, _results; |
| 231 | 9 | _ref = this.parentWindow.cookies.all(); |
| 232 | 9 | _results = []; |
| 233 | 9 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 234 | 30 | cookie = _ref[_i]; |
| 235 | 30 | if (!cookie.httpOnly) { |
| 236 | 26 | _results.push("" + cookie.key + "=" + cookie.value); |
| 237 | } | |
| 238 | } | |
| 239 | 9 | return _results; |
| 240 | }).call(this); | |
| 241 | 9 | return cookies.join("; "); |
| 242 | }); | |
| 243 | ||
| 244 | 1 | HTML.HTMLDocument.prototype.__defineSetter__("cookie", function(cookie) { |
| 245 | 5 | return this.parentWindow.cookies.update(cookie); |
| 246 | }); | |
| 247 | ||
| 248 | 1 | module.exports = Cookies; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var EventLoop, URL, ms, raise; |
| 3 | ||
| 4 | 1 | ms = require("ms"); |
| 5 | ||
| 6 | 1 | URL = require("url"); |
| 7 | ||
| 8 | 1 | raise = require("./scripts").raise; |
| 9 | ||
| 10 | 1 | EventLoop = (function() { |
| 11 | ||
| 12 | 1 | function EventLoop(_browser) { |
| 13 | 195 | this._browser = _browser; |
| 14 | 195 | this._processing = 0; |
| 15 | 195 | this._waiting = []; |
| 16 | 195 | this._timers = []; |
| 17 | } | |
| 18 | ||
| 19 | 1 | EventLoop.prototype.reset = function() { |
| 20 | 24 | var timer, _i, _len, _ref; |
| 21 | 24 | if (this._timers) { |
| 22 | 24 | _ref = this._timers; |
| 23 | 24 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 24 | 1 | timer = _ref[_i]; |
| 25 | 1 | global.clearTimeout(timer.handle); |
| 26 | } | |
| 27 | } | |
| 28 | 24 | return this._timers = []; |
| 29 | }; | |
| 30 | ||
| 31 | 1 | EventLoop.prototype.apply = function(window) { |
| 32 | 223 | var remove, |
| 33 | _this = this; | |
| 34 | 223 | remove = function(timer) { |
| 35 | 67 | var index; |
| 36 | 67 | index = _this._timers.indexOf(timer); |
| 37 | 67 | if (~index) { |
| 38 | 59 | return _this._timers.splice(index, 1); |
| 39 | } | |
| 40 | }; | |
| 41 | 223 | window.setTimeout = function(fn, delay) { |
| 42 | 80 | var timer; |
| 43 | 80 | if (!fn) { |
| 44 | 0 | return; |
| 45 | } | |
| 46 | 80 | timer = { |
| 47 | handle: null, | |
| 48 | timeout: true, | |
| 49 | resume: function() { | |
| 50 | 94 | if (timer.handle) { |
| 51 | 8 | return; |
| 52 | } | |
| 53 | 86 | timer.next = Date.now() + Math.max(delay || 0, 0); |
| 54 | 86 | if (delay <= 0) { |
| 55 | 24 | remove(timer); |
| 56 | 24 | return _this.perform(function(done) { |
| 57 | 24 | return process.nextTick(function() { |
| 58 | 24 | _this._browser.log("Firing timeout after " + delay + "ms delay"); |
| 59 | 24 | window._evaluate(fn); |
| 60 | 24 | return done(); |
| 61 | }); | |
| 62 | }); | |
| 63 | } else { | |
| 64 | 62 | return timer.handle = global.setTimeout(function() { |
| 65 | 31 | return _this.perform(function(done) { |
| 66 | 31 | remove(timer); |
| 67 | 31 | _this._browser.log("Firing timeout after " + delay + "ms delay"); |
| 68 | 31 | window._evaluate(fn); |
| 69 | 31 | return done(); |
| 70 | }); | |
| 71 | }, delay); | |
| 72 | } | |
| 73 | }, | |
| 74 | pause: function() { | |
| 75 | 28 | global.clearTimeout(timer.handle); |
| 76 | 28 | timer.handle = null; |
| 77 | 28 | return delay = timer.next - Date.now(); |
| 78 | }, | |
| 79 | stop: function() { | |
| 80 | 10 | global.clearTimeout(timer.handle); |
| 81 | 10 | return remove(timer); |
| 82 | } | |
| 83 | }; | |
| 84 | 80 | _this._timers.push(timer); |
| 85 | 80 | timer.resume(); |
| 86 | 80 | return timer; |
| 87 | }; | |
| 88 | 223 | window.setInterval = function(fn, interval) { |
| 89 | 12 | var timer; |
| 90 | 12 | if (interval == null) { |
| 91 | 0 | interval = 0; |
| 92 | } | |
| 93 | 12 | if (!fn) { |
| 94 | 0 | return; |
| 95 | } | |
| 96 | 12 | timer = { |
| 97 | handle: null, | |
| 98 | interval: true, | |
| 99 | resume: function() { | |
| 100 | 23 | if (timer.handle) { |
| 101 | 6 | return; |
| 102 | } | |
| 103 | 17 | timer.next = Date.now() + interval; |
| 104 | 17 | return timer.handle = global.setInterval(function() { |
| 105 | 178 | return _this.perform(function(done) { |
| 106 | 178 | timer.next = Date.now() + interval; |
| 107 | 178 | _this._browser.log("Firing interval every " + interval + "ms"); |
| 108 | 178 | window._evaluate(fn); |
| 109 | 178 | return done(); |
| 110 | }); | |
| 111 | }, interval); | |
| 112 | }, | |
| 113 | pause: function() { | |
| 114 | 16 | global.clearInterval(timer.handle); |
| 115 | 16 | return timer.handle = null; |
| 116 | }, | |
| 117 | stop: function() { | |
| 118 | 2 | global.clearInterval(timer.handle); |
| 119 | 2 | return remove(timer); |
| 120 | } | |
| 121 | }; | |
| 122 | 12 | _this._timers.push(timer); |
| 123 | 12 | timer.resume(); |
| 124 | 12 | return timer; |
| 125 | }; | |
| 126 | 223 | window.clearTimeout = function(timer) { |
| 127 | 11 | if (timer && timer.timeout && timer.stop) { |
| 128 | 10 | return timer.stop(); |
| 129 | } | |
| 130 | }; | |
| 131 | 223 | return window.clearInterval = function(timer) { |
| 132 | 3 | if (timer && timer.interval && timer.stop) { |
| 133 | 2 | return timer.stop(); |
| 134 | } | |
| 135 | }; | |
| 136 | }; | |
| 137 | ||
| 138 | 1 | EventLoop.prototype.perform = function(fn) { |
| 139 | 828 | var _this = this; |
| 140 | 828 | ++this._processing; |
| 141 | 828 | fn(function() { |
| 142 | 828 | --_this._processing; |
| 143 | 828 | if (_this._processing === 0) { |
| 144 | 682 | return _this._next(); |
| 145 | } | |
| 146 | }); | |
| 147 | }; | |
| 148 | ||
| 149 | 1 | EventLoop.prototype.dispatch = function(target, event) { |
| 150 | 254 | var preventDefault; |
| 151 | 254 | preventDefault = false; |
| 152 | 254 | this.perform(function(done) { |
| 153 | 254 | var window; |
| 154 | 254 | if (target._evaluate) { |
| 155 | 20 | window = target; |
| 156 | } else { | |
| 157 | 234 | window = (target.ownerDocument || target.document).window; |
| 158 | } | |
| 159 | 254 | window._evaluate(function() { |
| 160 | 254 | return preventDefault = target.dispatchEvent(event); |
| 161 | }); | |
| 162 | 254 | return done(); |
| 163 | }); | |
| 164 | 254 | return preventDefault; |
| 165 | }; | |
| 166 | ||
| 167 | 1 | EventLoop.prototype.wait = function(window, duration, callback) { |
| 168 | 329 | var done, done_at, is_done, terminate, waiting, |
| 169 | _this = this; | |
| 170 | 329 | if (typeof duration === "function") { |
| 171 | 2 | is_done = duration; |
| 172 | 2 | done_at = Infinity; |
| 173 | } else { | |
| 174 | 327 | if (!(duration && duration !== 0)) { |
| 175 | 317 | duration = this._browser.waitFor; |
| 176 | } | |
| 177 | 327 | done_at = Date.now() + ms(duration || 0); |
| 178 | } | |
| 179 | 329 | done = function(error) { |
| 180 | 329 | var fn; |
| 181 | 329 | done = null; |
| 182 | 329 | _this._waiting = (function() { |
| 183 | 329 | var _i, _len, _ref, _results; |
| 184 | 329 | _ref = this._waiting; |
| 185 | 329 | _results = []; |
| 186 | 329 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 187 | 419 | fn = _ref[_i]; |
| 188 | 419 | if (fn !== waiting) { |
| 189 | 90 | _results.push(fn); |
| 190 | } | |
| 191 | } | |
| 192 | 329 | return _results; |
| 193 | }).call(_this); | |
| 194 | 329 | if (_this._waiting.length === 0) { |
| 195 | 292 | _this._pause(); |
| 196 | } | |
| 197 | 329 | if (terminate) { |
| 198 | 329 | clearTimeout(terminate); |
| 199 | } | |
| 200 | 329 | if (callback) { |
| 201 | 329 | process.nextTick(function() { |
| 202 | 329 | return callback(error, window); |
| 203 | }); | |
| 204 | } | |
| 205 | 329 | if (error) { |
| 206 | 0 | return _this._browser.emit("error", error); |
| 207 | } else { | |
| 208 | 329 | return _this._browser.emit("done"); |
| 209 | } | |
| 210 | }; | |
| 211 | 329 | terminate = setTimeout(done, ms(this._browser.maxWait)); |
| 212 | 329 | waiting = function() { |
| 213 | 993 | var next, timer, timers; |
| 214 | 993 | if (!done) { |
| 215 | 45 | return; |
| 216 | } | |
| 217 | 948 | if (_this._processing > 0) { |
| 218 | 481 | return; |
| 219 | } | |
| 220 | 467 | try { |
| 221 | 467 | if (is_done && is_done(window)) { |
| 222 | 2 | done(); |
| 223 | 2 | return; |
| 224 | } | |
| 225 | } catch (error) { | |
| 226 | 0 | done(error); |
| 227 | 0 | return; |
| 228 | } | |
| 229 | 465 | timers = (function() { |
| 230 | 465 | var _i, _len, _ref, _results; |
| 231 | 465 | _ref = this._timers; |
| 232 | 465 | _results = []; |
| 233 | 465 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 234 | 253 | timer = _ref[_i]; |
| 235 | 253 | _results.push(timer.next); |
| 236 | } | |
| 237 | 465 | return _results; |
| 238 | }).call(_this); | |
| 239 | 465 | next = Math.min.apply(Math, timers); |
| 240 | 465 | if (next > done_at) { |
| 241 | 327 | return done(); |
| 242 | } | |
| 243 | }; | |
| 244 | 329 | if (this._waiting.length === 0) { |
| 245 | 292 | this._resume(); |
| 246 | } | |
| 247 | 329 | this._waiting.push(waiting); |
| 248 | 329 | this._next(); |
| 249 | }; | |
| 250 | ||
| 251 | 1 | EventLoop.prototype._next = function() { |
| 252 | 1011 | var waiting, _i, _len, _ref; |
| 253 | 1011 | _ref = this._waiting; |
| 254 | 1011 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 255 | 993 | waiting = _ref[_i]; |
| 256 | 993 | process.nextTick(waiting); |
| 257 | } | |
| 258 | }; | |
| 259 | ||
| 260 | 1 | EventLoop.prototype._pause = function() { |
| 261 | 292 | var timer, _i, _len, _ref; |
| 262 | 292 | _ref = this._timers; |
| 263 | 292 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 264 | 44 | timer = _ref[_i]; |
| 265 | 44 | timer.pause(); |
| 266 | } | |
| 267 | }; | |
| 268 | ||
| 269 | 1 | EventLoop.prototype._resume = function() { |
| 270 | 292 | var timer, _i, _len, _ref; |
| 271 | 292 | _ref = this._timers.slice(); |
| 272 | 292 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 273 | 25 | timer = _ref[_i]; |
| 274 | 25 | timer.resume(); |
| 275 | } | |
| 276 | }; | |
| 277 | ||
| 278 | 1 | EventLoop.prototype.dump = function() { |
| 279 | 0 | return ["The time: " + (new Date), "Timers: " + this._timers.length, "Processing: " + this._processing, "Waiting: " + this._waiting.length]; |
| 280 | }; | |
| 281 | ||
| 282 | 1 | return EventLoop; |
| 283 | ||
| 284 | })(); | |
| 285 | ||
| 286 | 1 | module.exports = EventLoop; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var CoffeeScript, HTML, addInlineScriptSupport, raise; |
| 3 | ||
| 4 | 1 | HTML = require("jsdom").dom.level3.html; |
| 5 | ||
| 6 | 1 | try { |
| 7 | 1 | CoffeeScript = require("coffee-script"); |
| 8 | 1 | HTML.languageProcessors.coffeescript = function(element, code, filename) { |
| 9 | 0 | return this.javascript(element, CoffeeScript.compile(code), filename); |
| 10 | }; | |
| 11 | } catch (ex) { | |
| 12 | ||
| 13 | } | |
| 14 | ||
| 15 | 1 | HTML.languageProcessors.javascript = function(element, code, filename) { |
| 16 | 234 | var cast, doc, window; |
| 17 | 234 | if (doc = element.ownerDocument) { |
| 18 | 234 | window = doc.parentWindow; |
| 19 | 234 | try { |
| 20 | 234 | return window._evaluate(code, filename); |
| 21 | } catch (error) { | |
| 22 | 5 | if (!(error instanceof Error)) { |
| 23 | 5 | cast = new Error(error.message); |
| 24 | 5 | cast.stack = error.stack; |
| 25 | 5 | error = cast; |
| 26 | } | |
| 27 | 5 | return raise({ |
| 28 | element: element, | |
| 29 | location: filename, | |
| 30 | from: __filename, | |
| 31 | error: error | |
| 32 | }); | |
| 33 | } | |
| 34 | } | |
| 35 | }; | |
| 36 | ||
| 37 | 1 | addInlineScriptSupport = function(document) { |
| 38 | 469 | return document.addEventListener("DOMNodeInserted", function(event) { |
| 39 | 10379 | var node; |
| 40 | 10379 | node = event.target; |
| 41 | 10379 | if (node.tagName !== "SCRIPT") { |
| 42 | 10228 | return; |
| 43 | } | |
| 44 | 151 | if (node.src) { |
| 45 | 55 | return; |
| 46 | } | |
| 47 | 96 | HTML.resourceLoader.enqueue(node, function() { |
| 48 | 96 | var code, language; |
| 49 | 96 | code = node.text; |
| 50 | 96 | language = HTML.languageProcessors[node.language]; |
| 51 | 96 | if (code && language) { |
| 52 | 90 | return language(this, code, document.location.href); |
| 53 | } | |
| 54 | })(); | |
| 55 | }); | |
| 56 | }; | |
| 57 | ||
| 58 | 1 | raise = function(_arg) { |
| 59 | 5 | var document, element, error, event, from, line, location, message, partial, scope, window, _i, _len, _ref; |
| 60 | 5 | element = _arg.element, location = _arg.location, from = _arg.from, scope = _arg.scope, error = _arg.error; |
| 61 | 5 | document = element.ownerDocument || element; |
| 62 | 5 | window = document.parentWindow; |
| 63 | 5 | message = scope ? "" + scope + ": " + error.message : error.message; |
| 64 | 5 | location || (location = document.location.href); |
| 65 | 5 | partial = []; |
| 66 | 5 | if (error.stack) { |
| 67 | 5 | _ref = error.stack.split("\n"); |
| 68 | 5 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 69 | 17 | line = _ref[_i]; |
| 70 | 17 | if (~line.indexOf("contextify/lib/contextify.js")) { |
| 71 | 5 | break; |
| 72 | } | |
| 73 | 12 | partial.push(line); |
| 74 | } | |
| 75 | } | |
| 76 | 5 | partial.push(" in " + location); |
| 77 | 5 | error.stack = partial.join("\n"); |
| 78 | 5 | event = document.createEvent("Event"); |
| 79 | 5 | event.initEvent("error", false, false); |
| 80 | 5 | event.message = error.message; |
| 81 | 5 | event.error = error; |
| 82 | 5 | window.dispatchEvent(event); |
| 83 | }; | |
| 84 | ||
| 85 | 1 | module.exports = { |
| 86 | raise: raise, | |
| 87 | addInlineScriptSupport: addInlineScriptSupport | |
| 88 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Interaction; |
| 3 | ||
| 4 | 1 | Interaction = (function() { |
| 5 | ||
| 6 | 1 | function Interaction(browser) { |
| 7 | 195 | var alertFns, confirmCanned, confirmFns, promptCanned, promptFns, prompts; |
| 8 | 195 | prompts = []; |
| 9 | 195 | alertFns = []; |
| 10 | 195 | this.onalert = function(fn) { |
| 11 | 4 | return alertFns.push(fn); |
| 12 | }; | |
| 13 | 195 | confirmFns = []; |
| 14 | 195 | confirmCanned = {}; |
| 15 | 195 | this.onconfirm = function(question, response) { |
| 16 | 2 | if (typeof question === "function") { |
| 17 | 1 | return confirmFns.push(question); |
| 18 | } else { | |
| 19 | 1 | return confirmCanned[question] = !!response; |
| 20 | } | |
| 21 | }; | |
| 22 | 195 | promptFns = []; |
| 23 | 195 | promptCanned = {}; |
| 24 | 195 | this.onprompt = function(message, response) { |
| 25 | 3 | if (typeof message === "function") { |
| 26 | 1 | return promptFns.push(message); |
| 27 | } else { | |
| 28 | 2 | return promptCanned[message] = response; |
| 29 | } | |
| 30 | }; | |
| 31 | 195 | this.prompted = function(message) { |
| 32 | 11 | return prompts.indexOf(message) >= 0; |
| 33 | }; | |
| 34 | 195 | this.extend = function(window) { |
| 35 | 223 | window.alert = function(message) { |
| 36 | 5 | var fn, _i, _len; |
| 37 | 5 | prompts.push(message); |
| 38 | 5 | for (_i = 0, _len = alertFns.length; _i < _len; _i++) { |
| 39 | 5 | fn = alertFns[_i]; |
| 40 | 5 | fn(message); |
| 41 | } | |
| 42 | }; | |
| 43 | 223 | window.confirm = function(question) { |
| 44 | 3 | var fn, response, _i, _len; |
| 45 | 3 | prompts.push(question); |
| 46 | 3 | response = confirmCanned[question]; |
| 47 | 3 | if (!(response || response === false)) { |
| 48 | 2 | for (_i = 0, _len = confirmFns.length; _i < _len; _i++) { |
| 49 | 2 | fn = confirmFns[_i]; |
| 50 | 2 | response = fn(question); |
| 51 | 2 | if (response || response === false) { |
| 52 | 2 | break; |
| 53 | } | |
| 54 | } | |
| 55 | } | |
| 56 | 3 | return !!response; |
| 57 | }; | |
| 58 | 223 | return window.prompt = function(message, def) { |
| 59 | 4 | var fn, response, _i, _len; |
| 60 | 4 | prompts.push(message); |
| 61 | 4 | response = promptCanned[message]; |
| 62 | 4 | if (!(response || response === false)) { |
| 63 | 2 | for (_i = 0, _len = promptFns.length; _i < _len; _i++) { |
| 64 | 2 | fn = promptFns[_i]; |
| 65 | 2 | response = fn(message, def); |
| 66 | 2 | if (response || response === false) { |
| 67 | 1 | break; |
| 68 | } | |
| 69 | } | |
| 70 | } | |
| 71 | 4 | if (response) { |
| 72 | 2 | return response.toString(); |
| 73 | } | |
| 74 | 2 | if (response === false) { |
| 75 | 1 | return null; |
| 76 | } | |
| 77 | 1 | return def || ""; |
| 78 | }; | |
| 79 | }; | |
| 80 | } | |
| 81 | ||
| 82 | 1 | return Interaction; |
| 83 | ||
| 84 | })(); | |
| 85 | ||
| 86 | 1 | exports.use = function(browser) { |
| 87 | 195 | return new Interaction(browser); |
| 88 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Cache, FS, HTTP, HTTPRequest, HTTPResponse, HTTPS, Path, QS, Request, Resource, Resources, STATUS, URL, indent, inspect, partial, |
| 3 | __hasProp = {}.hasOwnProperty, | |
| 4 | 7 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; |
| 5 | ||
| 6 | 1 | inspect = require("util").inspect; |
| 7 | ||
| 8 | 1 | HTTP = require("http"); |
| 9 | ||
| 10 | 1 | HTTPS = require("https"); |
| 11 | ||
| 12 | 1 | FS = require("fs"); |
| 13 | ||
| 14 | 1 | Path = require("path"); |
| 15 | ||
| 16 | 1 | QS = require("querystring"); |
| 17 | ||
| 18 | 1 | Request = require("request"); |
| 19 | ||
| 20 | 1 | URL = require("url"); |
| 21 | ||
| 22 | 1 | partial = function(text, length) { |
| 23 | 4 | if (length == null) { |
| 24 | 4 | length = 250; |
| 25 | } | |
| 26 | 4 | if (!text) { |
| 27 | 2 | return ""; |
| 28 | } | |
| 29 | 2 | if (text.length <= length) { |
| 30 | 0 | return text; |
| 31 | } | |
| 32 | 2 | return text.substring(0, length - 3) + "..."; |
| 33 | }; | |
| 34 | ||
| 35 | 1 | indent = function(text) { |
| 36 | 4 | return text.toString().split("\n").map(function(l) { |
| 37 | 43 | return " " + l; |
| 38 | }).join("\n"); | |
| 39 | }; | |
| 40 | ||
| 41 | 1 | Resource = (function() { |
| 42 | ||
| 43 | 1 | function Resource(request) { |
| 44 | 314 | this.request = request; |
| 45 | 314 | this.request.resource = this; |
| 46 | 314 | this.redirects = 0; |
| 47 | 314 | this.start = new Date().getTime(); |
| 48 | 314 | this.time = 0; |
| 49 | } | |
| 50 | ||
| 51 | 1 | Resource.prototype.__defineGetter__("size", function() { |
| 52 | 2 | var _ref; |
| 53 | 2 | return ((_ref = this.response) != null ? _ref.body.length : void 0) || 0; |
| 54 | }); | |
| 55 | ||
| 56 | 1 | Resource.prototype.__defineGetter__("url", function() { |
| 57 | 4 | var _ref; |
| 58 | 4 | return ((_ref = this.response) != null ? _ref.url : void 0) || this.request.url; |
| 59 | }); | |
| 60 | ||
| 61 | 1 | Resource.prototype.__defineGetter__("response", function() { |
| 62 | 323 | return this._response; |
| 63 | }); | |
| 64 | ||
| 65 | 1 | Resource.prototype.__defineSetter__("response", function(response) { |
| 66 | 312 | this.time = new Date().getTime() - this.start; |
| 67 | 312 | response.resource = this; |
| 68 | 312 | return this._response = response; |
| 69 | }); | |
| 70 | ||
| 71 | 1 | Resource.prototype.toString = function() { |
| 72 | 2 | return "URL: " + this.url + "\nTime: " + this.time + "ms\nSize: " + (this.size / 1024) + "kb\nRequest:\n" + (indent(this.request)) + "\nResponse:\n" + (indent(this.response)) + "\n"; |
| 73 | }; | |
| 74 | ||
| 75 | 1 | return Resource; |
| 76 | ||
| 77 | })(); | |
| 78 | ||
| 79 | 1 | HTTPRequest = (function() { |
| 80 | ||
| 81 | 1 | function HTTPRequest(method, url, headers, body) { |
| 82 | 314 | this.method = method; |
| 83 | 314 | this.headers = headers; |
| 84 | 314 | this.body = body; |
| 85 | 314 | this.url = URL.format(url); |
| 86 | } | |
| 87 | ||
| 88 | 1 | HTTPRequest.prototype.toString = function() { |
| 89 | 2 | return "" + (inspect(this.headers)) + "\n" + (partial(this.body)); |
| 90 | }; | |
| 91 | ||
| 92 | 1 | return HTTPRequest; |
| 93 | ||
| 94 | })(); | |
| 95 | ||
| 96 | 1 | HTTPResponse = (function() { |
| 97 | ||
| 98 | 1 | function HTTPResponse(url, statusCode, headers, body) { |
| 99 | 315 | this.statusCode = statusCode; |
| 100 | 315 | this.headers = headers; |
| 101 | 315 | this.body = body; |
| 102 | 315 | this.url = URL.format(url); |
| 103 | } | |
| 104 | ||
| 105 | 1 | HTTPResponse.prototype.__defineGetter__("statusText", function() { |
| 106 | 11 | return STATUS[this.statusCode]; |
| 107 | }); | |
| 108 | ||
| 109 | 1 | HTTPResponse.prototype.__defineGetter__("redirected", function() { |
| 110 | 3 | return !!this.resource.redirects; |
| 111 | }); | |
| 112 | ||
| 113 | 1 | HTTPResponse.prototype.toString = function() { |
| 114 | 2 | return "" + this.statusCode + " " + this.statusText + "\n" + (inspect(this.headers)) + "\n" + (partial(this.body)); |
| 115 | }; | |
| 116 | ||
| 117 | 1 | return HTTPResponse; |
| 118 | ||
| 119 | })(); | |
| 120 | ||
| 121 | 1 | Resources = (function(_super) { |
| 122 | 1 | var stringify, stringifyPrimitive, typeOf; |
| 123 | ||
| 124 | 1 | __extends(Resources, _super); |
| 125 | ||
| 126 | 1 | function Resources(_browser) { |
| 127 | 195 | this._browser = _browser; |
| 128 | } | |
| 129 | ||
| 130 | 1 | Resources.prototype.__defineGetter__("first", function() { |
| 131 | 0 | return this[0]; |
| 132 | }); | |
| 133 | ||
| 134 | 1 | Resources.prototype.__defineGetter__("last", function() { |
| 135 | 7 | return this[this.length - 1]; |
| 136 | }); | |
| 137 | ||
| 138 | 1 | Resources.prototype.get = function(url, callback) { |
| 139 | 55 | return this.request("GET", url, null, null, callback); |
| 140 | }; | |
| 141 | ||
| 142 | 1 | Resources.prototype.request = function(method, url, data, headers, callback) { |
| 143 | 317 | var _this = this; |
| 144 | 317 | return this._browser._eventloop.perform(function(done) { |
| 145 | 317 | return _this._makeRequest(method, url, data, headers, null, function(error, response) { |
| 146 | 317 | done(); |
| 147 | 317 | return callback(error, response); |
| 148 | }); | |
| 149 | }); | |
| 150 | }; | |
| 151 | ||
| 152 | 1 | Resources.prototype.clear = function() { |
| 153 | 24 | return this.length = 0; |
| 154 | }; | |
| 155 | ||
| 156 | 1 | Resources.prototype.dump = function() { |
| 157 | 0 | process.stdout.write(this.toString()); |
| 158 | 0 | return process.stdout.write("\n"); |
| 159 | }; | |
| 160 | ||
| 161 | 1 | Resources.prototype.toString = function() { |
| 162 | 1 | return this.map(function(resource) { |
| 163 | 2 | return resource.toString(); |
| 164 | }).join("\n"); | |
| 165 | }; | |
| 166 | ||
| 167 | 1 | Resources.prototype._makeRequest = function(method, url, data, headers, resource, callback) { |
| 168 | 351 | var binary, body, boundary, browser, content, cookies, credentials, disp, field, jar, multipart, name, params, value, _i, _len, _ref, |
| 169 | _this = this; | |
| 170 | 351 | browser = this._browser; |
| 171 | 351 | url = URL.parse(url); |
| 172 | 351 | method = (method || "GET").toUpperCase(); |
| 173 | 351 | if (url.protocol === "file:") { |
| 174 | 3 | browser.log(function() { |
| 175 | 0 | return "" + method + " " + url.pathname; |
| 176 | }); | |
| 177 | 3 | if (method === "GET") { |
| 178 | 3 | FS.readFile(Path.normalize(url.pathname), function(err, data) { |
| 179 | 3 | var response; |
| 180 | 3 | if (err) { |
| 181 | 0 | browser.log(function() { |
| 182 | 0 | return "Error loading " + (URL.format(url)) + ": " + err.message; |
| 183 | }); | |
| 184 | 0 | callback(err); |
| 185 | } | |
| 186 | 3 | response = new HTTPResponse(url, 200, {}, String(data)); |
| 187 | 3 | return callback(null, response); |
| 188 | }); | |
| 189 | } else { | |
| 190 | 0 | callback(new Error("Cannot " + method + " a file: URL")); |
| 191 | } | |
| 192 | 3 | return; |
| 193 | } | |
| 194 | 348 | headers = headers ? JSON.parse(JSON.stringify(headers)) : {}; |
| 195 | 348 | headers["User-Agent"] = browser.userAgent; |
| 196 | 348 | headers["Accept-Encoding"] = "identity"; |
| 197 | 348 | if (method === "GET" || method === "HEAD") { |
| 198 | 326 | if (data) { |
| 199 | 2 | url.search = "?" + stringify(data); |
| 200 | } | |
| 201 | } else { | |
| 202 | 22 | switch (headers["content-type"]) { |
| 203 | case "multipart/form-data": | |
| 204 | 5 | if (Object.keys(data).length > 0) { |
| 205 | 3 | boundary = "" + (new Date().getTime()) + (Math.random()); |
| 206 | 3 | headers["content-type"] += "; boundary=" + boundary; |
| 207 | } else { | |
| 208 | 2 | headers["content-type"] = "text/plain;charset=UTF-8"; |
| 209 | } | |
| 210 | 5 | break; |
| 211 | case "application/x-www-form-urlencoded": | |
| 212 | 15 | data = stringify(data); |
| 213 | 15 | if (!headers["transfer-encoding"]) { |
| 214 | 15 | headers["content-length"] || (headers["content-length"] = data.length); |
| 215 | } | |
| 216 | 15 | break; |
| 217 | default: | |
| 218 | 2 | headers["content-type"] || (headers["content-type"] = "text/plain;charset=UTF-8"); |
| 219 | } | |
| 220 | } | |
| 221 | 348 | headers["Host"] = url.host; |
| 222 | 348 | credentials = this._browser.authenticate(url.host, false); |
| 223 | 348 | if (credentials) { |
| 224 | 348 | credentials.apply(headers); |
| 225 | } | |
| 226 | 348 | if (!(url.pathname && url.pathname[0] === "/")) { |
| 227 | 0 | url.pathname = "/" + (url.pathname || ""); |
| 228 | } | |
| 229 | 348 | if (!resource) { |
| 230 | 314 | resource = new Resource(new HTTPRequest(method, url, headers, null)); |
| 231 | 314 | this.push(resource); |
| 232 | } | |
| 233 | 348 | if (method === "PUT" || method === "POST") { |
| 234 | 22 | switch (headers["content-type"].split(";")[0]) { |
| 235 | case "application/x-www-form-urlencoded": | |
| 236 | 16 | body = data; |
| 237 | 16 | break; |
| 238 | case "multipart/form-data": | |
| 239 | 3 | multipart = []; |
| 240 | 3 | for (_i = 0, _len = data.length; _i < _len; _i++) { |
| 241 | 4 | field = data[_i]; |
| 242 | 4 | name = field[0], content = field[1]; |
| 243 | 4 | disp = "form-data; name=\"" + name + "\""; |
| 244 | 4 | if (content.read) { |
| 245 | 3 | binary = content.read(); |
| 246 | 3 | multipart.push({ |
| 247 | "Content-Disposition": "" + disp + "; filename=\"" + content + "\"", | |
| 248 | "Content-Type": content.mime || "application/octet-stream", | |
| 249 | "Content-Length": binary.length, | |
| 250 | body: binary | |
| 251 | }); | |
| 252 | } else { | |
| 253 | 1 | multipart.push({ |
| 254 | "Content-Disposition": disp, | |
| 255 | "Content-Type": "text/plain", | |
| 256 | "Content-Transfer-Encoding": "utf8", | |
| 257 | "Content-Length": content.length, | |
| 258 | body: content | |
| 259 | }); | |
| 260 | } | |
| 261 | } | |
| 262 | 3 | break; |
| 263 | default: | |
| 264 | 3 | body = (data || "").toString(); |
| 265 | } | |
| 266 | } else { | |
| 267 | 326 | delete headers["content-type"]; |
| 268 | 326 | delete headers["content-length"]; |
| 269 | 326 | delete headers["content-transfer-encoding"]; |
| 270 | } | |
| 271 | 348 | cookies = browser.cookies(url.hostname, url.pathname); |
| 272 | 348 | cookies.addHeader(headers); |
| 273 | 348 | jar = Request.jar(); |
| 274 | 348 | if (browser.headers) { |
| 275 | 348 | _ref = browser.headers; |
| 276 | 348 | for (name in _ref) { |
| 277 | 1 | value = _ref[name]; |
| 278 | 1 | headers[name] = value; |
| 279 | } | |
| 280 | } | |
| 281 | 348 | params = { |
| 282 | method: method, | |
| 283 | url: url, | |
| 284 | headers: headers, | |
| 285 | body: body, | |
| 286 | multipart: multipart, | |
| 287 | proxy: browser.proxy, | |
| 288 | jar: jar, | |
| 289 | followRedirect: false | |
| 290 | }; | |
| 291 | 348 | return Request(params, function(error, response) { |
| 292 | 348 | var cookie, redirect, _j, _len1, _ref1; |
| 293 | 348 | if (error) { |
| 294 | 2 | browser.log(function() { |
| 295 | 0 | return "" + method + " " + (URL.format(url).slice("#")[0]) + " => " + error.message; |
| 296 | }); | |
| 297 | 2 | callback(error); |
| 298 | 2 | return; |
| 299 | } | |
| 300 | 346 | _ref1 = jar.cookies; |
| 301 | 346 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
| 302 | 104 | cookie = _ref1[_j]; |
| 303 | 104 | cookies.update(cookie.str); |
| 304 | } | |
| 305 | 346 | switch (response.statusCode) { |
| 306 | case 301: | |
| 307 | case 307: | |
| 308 | 0 | if (method === "GET" || method === "HEAD") { |
| 309 | 0 | redirect = URL.resolve(url, response.headers['location']); |
| 310 | } | |
| 311 | 0 | break; |
| 312 | case 302: | |
| 313 | case 303: | |
| 314 | 34 | redirect = URL.resolve(url, response.headers['location']); |
| 315 | 34 | if (!(method === "GET" || method === "HEAD")) { |
| 316 | 2 | method = "GET"; |
| 317 | } | |
| 318 | } | |
| 319 | 346 | if (redirect) { |
| 320 | 34 | ++resource.redirects; |
| 321 | 34 | if (resource.redirects > 5) { |
| 322 | 0 | callback(new Error("More than five redirects, giving up")); |
| 323 | 0 | return; |
| 324 | } | |
| 325 | 34 | headers['referer'] = URL.format(url); |
| 326 | 34 | browser.log(function() { |
| 327 | 0 | return "" + response.statusCode + " => " + redirect; |
| 328 | }); | |
| 329 | 34 | return _this._makeRequest(method, redirect, null, headers, resource, callback); |
| 330 | } else { | |
| 331 | 312 | resource.response = new HTTPResponse(url, response.statusCode, response.headers, response.body); |
| 332 | 312 | browser.log(function() { |
| 333 | 0 | return "" + method + " " + (URL.format(url)) + " => " + response.statusCode; |
| 334 | }); | |
| 335 | 312 | return callback(null, resource.response); |
| 336 | } | |
| 337 | }); | |
| 338 | }; | |
| 339 | ||
| 340 | 1 | typeOf = function(object) { |
| 341 | 388 | return Object.prototype.toString.call(object); |
| 342 | }; | |
| 343 | ||
| 344 | 1 | stringifyPrimitive = function(v) { |
| 345 | 388 | var _ref; |
| 346 | 388 | switch (typeOf(v)) { |
| 347 | case '[object Boolean]': | |
| 348 | 0 | return v != null ? v : { |
| 349 | 'true': 'false' | |
| 350 | }; | |
| 351 | case '[object Number]': | |
| 352 | 0 | return (_ref = isFinite(v)) != null ? _ref : { |
| 353 | v: '' | |
| 354 | }; | |
| 355 | case '[object String]': | |
| 356 | 381 | return v; |
| 357 | default: | |
| 358 | 7 | return ''; |
| 359 | } | |
| 360 | }; | |
| 361 | ||
| 362 | 1 | stringify = function(object) { |
| 363 | 17 | if (!object.map) { |
| 364 | 4 | return object.toString(); |
| 365 | } | |
| 366 | 13 | return object.map(function(k) { |
| 367 | 198 | if (Array.isArray(k[1])) { |
| 368 | 6 | return k[1].map(function(v) { |
| 369 | 2 | return QS.escape(stringifyPrimitive(k[0])) + "=" + QS.escape(stringifyPrimitive(v)); |
| 370 | }).join("&"); | |
| 371 | } else { | |
| 372 | 192 | return QS.escape(stringifyPrimitive(k[0])) + "=" + QS.escape(stringifyPrimitive(k[1])); |
| 373 | } | |
| 374 | }).join("&"); | |
| 375 | }; | |
| 376 | ||
| 377 | 1 | return Resources; |
| 378 | ||
| 379 | })(Array); | |
| 380 | ||
| 381 | 1 | Cache = (function() { |
| 382 | ||
| 383 | 1 | function Cache(browser) { |
| 384 | 0 | this.resources = browser.resources; |
| 385 | } | |
| 386 | ||
| 387 | 1 | Cache.prototype.get = function(url, callback) { |
| 388 | 0 | return this.request("GET", url, null, null, callback); |
| 389 | }; | |
| 390 | ||
| 391 | 1 | Cache.prototype.request = function(method, url, data, headers, callback) { |
| 392 | 0 | return this.resources.request(method, url, data, headers, callback); |
| 393 | }; | |
| 394 | ||
| 395 | 1 | return Cache; |
| 396 | ||
| 397 | })(); | |
| 398 | ||
| 399 | 1 | STATUS = { |
| 400 | 100: "Continue", | |
| 401 | 101: "Switching Protocols", | |
| 402 | 200: "OK", | |
| 403 | 201: "Created", | |
| 404 | 202: "Accepted", | |
| 405 | 203: "Non-Authoritative", | |
| 406 | 204: "No Content", | |
| 407 | 205: "Reset Content", | |
| 408 | 206: "Partial Content", | |
| 409 | 300: "Multiple Choices", | |
| 410 | 301: "Moved Permanently", | |
| 411 | 302: "Found", | |
| 412 | 303: "See Other", | |
| 413 | 304: "Not Modified", | |
| 414 | 305: "Use Proxy", | |
| 415 | 307: "Temporary Redirect", | |
| 416 | 400: "Bad Request", | |
| 417 | 401: "Unauthorized", | |
| 418 | 402: "Payment Required", | |
| 419 | 403: "Forbidden", | |
| 420 | 404: "Not Found", | |
| 421 | 405: "Method Not Allowed", | |
| 422 | 406: "Not Acceptable", | |
| 423 | 407: "Proxy Authentication Required", | |
| 424 | 408: "Request Timeout", | |
| 425 | 409: "Conflict", | |
| 426 | 410: "Gone", | |
| 427 | 411: "Length Required", | |
| 428 | 412: "Precondition Failed", | |
| 429 | 413: "Request Entity Too Large", | |
| 430 | 414: "Request-URI Too Long", | |
| 431 | 415: "Unsupported Media Type", | |
| 432 | 416: "Requested Range Not Satisfiable", | |
| 433 | 417: "Expectation Failed", | |
| 434 | 500: "Internal Server Error", | |
| 435 | 501: "Not Implemented", | |
| 436 | 502: "Bad Gateway", | |
| 437 | 503: "Service Unavailable", | |
| 438 | 504: "Gateway Timeout", | |
| 439 | 505: "HTTP Version Not Supported" | |
| 440 | }; | |
| 441 | ||
| 442 | 1 | module.exports = Resources; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Event, HTML, Storage, StorageArea, StorageEvent, Storages; |
| 3 | ||
| 4 | 1 | HTML = require("jsdom").dom.level3.html; |
| 5 | ||
| 6 | 1 | Event = require("jsdom").dom.level3.events.Event; |
| 7 | ||
| 8 | 1 | StorageArea = (function() { |
| 9 | ||
| 10 | 1 | function StorageArea() { |
| 11 | 16 | this._items = []; |
| 12 | 16 | this._storages = []; |
| 13 | } | |
| 14 | ||
| 15 | 1 | StorageArea.prototype._fire = function(source, key, oldValue, newValue) { |
| 16 | 34 | var event, storage, window, _i, _len, _ref, _ref1, _results; |
| 17 | 34 | _ref = this._storages; |
| 18 | 34 | _results = []; |
| 19 | 34 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 20 | 0 | _ref1 = _ref[_i], storage = _ref1[0], window = _ref1[1]; |
| 21 | 0 | if (storage === source) { |
| 22 | 0 | continue; |
| 23 | } | |
| 24 | 0 | event = new StorageEvent(storage, window.location.href, key, oldValue, newValue); |
| 25 | 0 | _results.push(window.browser.dispatchEvent(window, event)); |
| 26 | } | |
| 27 | 34 | return _results; |
| 28 | }; | |
| 29 | ||
| 30 | 1 | StorageArea.prototype.__defineGetter__("length", function() { |
| 31 | 12 | var i, k; |
| 32 | 12 | i = 0; |
| 33 | 12 | for (k in this._items) { |
| 34 | 12 | ++i; |
| 35 | } | |
| 36 | 12 | return i; |
| 37 | }); | |
| 38 | ||
| 39 | 1 | StorageArea.prototype.key = function(index) { |
| 40 | 20 | var i, k; |
| 41 | 20 | i = 0; |
| 42 | 20 | for (k in this._items) { |
| 43 | 22 | if (i === index) { |
| 44 | 14 | return k; |
| 45 | } | |
| 46 | 8 | ++i; |
| 47 | } | |
| 48 | }; | |
| 49 | ||
| 50 | 1 | StorageArea.prototype.get = function(key) { |
| 51 | 24 | return this._items[key]; |
| 52 | }; | |
| 53 | ||
| 54 | 1 | StorageArea.prototype.set = function(source, key, value) { |
| 55 | 26 | var oldValue; |
| 56 | 26 | oldValue = this._items[key]; |
| 57 | 26 | this._items[key] = value; |
| 58 | 26 | return this._fire(source, key, oldValue, value); |
| 59 | }; | |
| 60 | ||
| 61 | 1 | StorageArea.prototype.remove = function(source, key) { |
| 62 | 4 | var oldValue; |
| 63 | 4 | oldValue = this._items[key]; |
| 64 | 4 | delete this._items[key]; |
| 65 | 4 | return this._fire(source, key, oldValue); |
| 66 | }; | |
| 67 | ||
| 68 | 1 | StorageArea.prototype.clear = function(source) { |
| 69 | 4 | this._items = []; |
| 70 | 4 | return this._fire(source); |
| 71 | }; | |
| 72 | ||
| 73 | 1 | StorageArea.prototype.associate = function(storage, window) { |
| 74 | 0 | return this._storages.push([storage, window]); |
| 75 | }; | |
| 76 | ||
| 77 | 1 | StorageArea.prototype.__defineGetter__("pairs", function() { |
| 78 | 2 | var k, v; |
| 79 | 2 | return (function() { |
| 80 | 2 | var _ref, _results; |
| 81 | 2 | _ref = this._items; |
| 82 | 2 | _results = []; |
| 83 | 2 | for (k in _ref) { |
| 84 | 2 | v = _ref[k]; |
| 85 | 2 | _results.push([k, v]); |
| 86 | } | |
| 87 | 2 | return _results; |
| 88 | }).call(this); | |
| 89 | }); | |
| 90 | ||
| 91 | 1 | StorageArea.prototype.toString = function() { |
| 92 | 0 | var k, v; |
| 93 | 0 | return ((function() { |
| 94 | 0 | var _ref, _results; |
| 95 | 0 | _ref = this._items; |
| 96 | 0 | _results = []; |
| 97 | 0 | for (k in _ref) { |
| 98 | 0 | v = _ref[k]; |
| 99 | 0 | _results.push("" + k + " = " + v); |
| 100 | } | |
| 101 | 0 | return _results; |
| 102 | }).call(this)).join("\n"); | |
| 103 | }; | |
| 104 | ||
| 105 | 1 | return StorageArea; |
| 106 | ||
| 107 | })(); | |
| 108 | ||
| 109 | 1 | Storage = (function() { |
| 110 | ||
| 111 | 1 | function Storage(_area) { |
| 112 | 22 | this._area = _area; |
| 113 | } | |
| 114 | ||
| 115 | 1 | Storage.prototype.__defineGetter__("length", function() { |
| 116 | 12 | return this._area.length; |
| 117 | }); | |
| 118 | ||
| 119 | 1 | Storage.prototype.key = function(index) { |
| 120 | 20 | return this._area.key(index); |
| 121 | }; | |
| 122 | ||
| 123 | 1 | Storage.prototype.getItem = function(key) { |
| 124 | 24 | return this._area.get(key.toString()); |
| 125 | }; | |
| 126 | ||
| 127 | 1 | Storage.prototype.setItem = function(key, value) { |
| 128 | 26 | return this._area.set(this, key.toString(), value); |
| 129 | }; | |
| 130 | ||
| 131 | 1 | Storage.prototype.removeItem = function(key) { |
| 132 | 4 | return this._area.remove(this, key.toString()); |
| 133 | }; | |
| 134 | ||
| 135 | 1 | Storage.prototype.clear = function() { |
| 136 | 4 | return this._area.clear(this); |
| 137 | }; | |
| 138 | ||
| 139 | 1 | Storage.prototype.dump = function() { |
| 140 | 0 | return this._area.dump(); |
| 141 | }; | |
| 142 | ||
| 143 | 1 | return Storage; |
| 144 | ||
| 145 | })(); | |
| 146 | ||
| 147 | 1 | StorageEvent = function(storage, url, key, oldValue, newValue) { |
| 148 | 0 | Event.call(this, "storage"); |
| 149 | 0 | this.__defineGetter__("url", function() { |
| 150 | 0 | return url; |
| 151 | }); | |
| 152 | 0 | this.__defineGetter__("storageArea", function() { |
| 153 | 0 | return storage; |
| 154 | }); | |
| 155 | 0 | this.__defineGetter__("key", function() { |
| 156 | 0 | return key; |
| 157 | }); | |
| 158 | 0 | this.__defineGetter__("oldValue", function() { |
| 159 | 0 | return oldValue; |
| 160 | }); | |
| 161 | 0 | return this.__defineGetter__("newValue", function() { |
| 162 | 0 | return newValue; |
| 163 | }); | |
| 164 | }; | |
| 165 | ||
| 166 | 1 | StorageEvent.prototype.__proto__ = Event.prototype; |
| 167 | ||
| 168 | 1 | HTML.SECURITY_ERR = 18; |
| 169 | ||
| 170 | 1 | Storages = (function() { |
| 171 | ||
| 172 | 1 | function Storages() { |
| 173 | 195 | this._locals = {}; |
| 174 | 195 | this._sessions = {}; |
| 175 | } | |
| 176 | ||
| 177 | 1 | Storages.prototype.local = function(host) { |
| 178 | 11 | var area, _base, _ref; |
| 179 | 11 | area = (_ref = (_base = this._locals)[host]) != null ? _ref : _base[host] = new StorageArea(); |
| 180 | 11 | return new Storage(area); |
| 181 | }; | |
| 182 | ||
| 183 | 1 | Storages.prototype.session = function(host) { |
| 184 | 11 | var area, _base, _ref; |
| 185 | 11 | area = (_ref = (_base = this._sessions)[host]) != null ? _ref : _base[host] = new StorageArea(); |
| 186 | 11 | return new Storage(area); |
| 187 | }; | |
| 188 | ||
| 189 | 1 | Storages.prototype.extend = function(window) { |
| 190 | 223 | var storages; |
| 191 | 223 | storages = this; |
| 192 | 223 | window.StorageEvent = StorageEvent; |
| 193 | 223 | Object.defineProperty(window, "localStorage", { |
| 194 | get: function() { | |
| 195 | 6 | var _ref; |
| 196 | 6 | return (_ref = this.document) != null ? _ref._localStorage || (_ref._localStorage = storages.local(this.location.host)) : void 0; |
| 197 | } | |
| 198 | }); | |
| 199 | 223 | return Object.defineProperty(window, "sessionStorage", { |
| 200 | get: function() { | |
| 201 | 6 | var _ref; |
| 202 | 6 | return (_ref = this.document) != null ? _ref._sessionStorage || (_ref._sessionStorage = storages.session(this.location.host)) : void 0; |
| 203 | } | |
| 204 | }); | |
| 205 | }; | |
| 206 | ||
| 207 | 1 | Storages.prototype.dump = function() { |
| 208 | 0 | var area, domain, pair, pairs, serialized, _i, _j, _len, _len1, _ref, _ref1; |
| 209 | 0 | serialized = []; |
| 210 | 0 | _ref = this._locals; |
| 211 | 0 | for (domain in _ref) { |
| 212 | 0 | area = _ref[domain]; |
| 213 | 0 | pairs = area.pairs; |
| 214 | 0 | serialized.push("" + domain + " local:"); |
| 215 | 0 | for (_i = 0, _len = pairs.length; _i < _len; _i++) { |
| 216 | 0 | pair = pairs[_i]; |
| 217 | 0 | serialized.push(" " + pair[0] + " = " + pair[1]); |
| 218 | } | |
| 219 | } | |
| 220 | 0 | _ref1 = this._sessions; |
| 221 | 0 | for (domain in _ref1) { |
| 222 | 0 | area = _ref1[domain]; |
| 223 | 0 | pairs = area.pairs; |
| 224 | 0 | serialized.push("" + domain + " session:"); |
| 225 | 0 | for (_j = 0, _len1 = pairs.length; _j < _len1; _j++) { |
| 226 | 0 | pair = pairs[_j]; |
| 227 | 0 | serialized.push(" " + pair[0] + " = " + pair[1]); |
| 228 | } | |
| 229 | } | |
| 230 | 0 | return serialized; |
| 231 | }; | |
| 232 | ||
| 233 | 1 | Storages.prototype.save = function() { |
| 234 | 1 | var area, domain, pair, pairs, serialized, _i, _j, _len, _len1, _ref, _ref1; |
| 235 | 1 | serialized = ["# Saved on " + (new Date().toISOString())]; |
| 236 | 1 | _ref = this._locals; |
| 237 | 1 | for (domain in _ref) { |
| 238 | 1 | area = _ref[domain]; |
| 239 | 1 | pairs = area.pairs; |
| 240 | 1 | if (pairs.length > 0) { |
| 241 | 1 | serialized.push("" + domain + " local:"); |
| 242 | 1 | for (_i = 0, _len = pairs.length; _i < _len; _i++) { |
| 243 | 1 | pair = pairs[_i]; |
| 244 | 1 | serialized.push(" " + (escape(pair[0])) + " = " + (escape(pair[1]))); |
| 245 | } | |
| 246 | } | |
| 247 | } | |
| 248 | 1 | _ref1 = this._sessions; |
| 249 | 1 | for (domain in _ref1) { |
| 250 | 1 | area = _ref1[domain]; |
| 251 | 1 | pairs = area.pairs; |
| 252 | 1 | if (pairs.length > 0) { |
| 253 | 1 | serialized.push("" + domain + " session:"); |
| 254 | 1 | for (_j = 0, _len1 = pairs.length; _j < _len1; _j++) { |
| 255 | 1 | pair = pairs[_j]; |
| 256 | 1 | serialized.push(" " + (escape(pair[0])) + " = " + (escape(pair[1]))); |
| 257 | } | |
| 258 | } | |
| 259 | } | |
| 260 | 1 | return serialized.join("\n") + "\n"; |
| 261 | }; | |
| 262 | ||
| 263 | 1 | Storages.prototype.load = function(serialized) { |
| 264 | 1 | var domain, item, key, storage, type, value, _i, _len, _ref, _ref1, _ref2, _results; |
| 265 | 1 | storage = null; |
| 266 | 1 | _ref = serialized.split(/\n+/); |
| 267 | 1 | _results = []; |
| 268 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 269 | 6 | item = _ref[_i]; |
| 270 | 6 | if (item[0] === "#" || item === "") { |
| 271 | 2 | continue; |
| 272 | } | |
| 273 | 4 | if (item[0] === " ") { |
| 274 | 2 | _ref1 = item.split("="), key = _ref1[0], value = _ref1[1]; |
| 275 | 2 | if (storage) { |
| 276 | 2 | _results.push(storage.setItem(unescape(key.trim()), unescape(value.trim()))); |
| 277 | } else { | |
| 278 | 0 | throw "Must specify storage type using local: or session:"; |
| 279 | } | |
| 280 | } else { | |
| 281 | 2 | _ref2 = item.split(" "), domain = _ref2[0], type = _ref2[1]; |
| 282 | 2 | if (type === "local:") { |
| 283 | 1 | _results.push(storage = this.local(domain)); |
| 284 | 1 | } else if (type === "session:") { |
| 285 | 1 | _results.push(storage = this.session(domain)); |
| 286 | } else { | |
| 287 | 0 | throw "Unkown storage type " + type; |
| 288 | } | |
| 289 | } | |
| 290 | } | |
| 291 | 1 | return _results; |
| 292 | }; | |
| 293 | ||
| 294 | 1 | return Storages; |
| 295 | ||
| 296 | })(); | |
| 297 | ||
| 298 | 1 | module.exports = Storages; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Console, EventSource, Events, File, HTML, History, JSDOM, Screen, URL, WebSocket, Windows; |
| 3 | ||
| 4 | 1 | Console = require("./console"); |
| 5 | ||
| 6 | 1 | History = require("./history"); |
| 7 | ||
| 8 | 1 | JSDOM = require("jsdom"); |
| 9 | ||
| 10 | 1 | HTML = JSDOM.dom.level3.html; |
| 11 | ||
| 12 | 1 | URL = require("url"); |
| 13 | ||
| 14 | 1 | EventSource = require("eventsource"); |
| 15 | ||
| 16 | 1 | WebSocket = require("ws"); |
| 17 | ||
| 18 | 1 | Events = JSDOM.dom.level3.events; |
| 19 | ||
| 20 | 1 | Windows = (function() { |
| 21 | ||
| 22 | 1 | function Windows(browser) { |
| 23 | 195 | this._browser = browser; |
| 24 | 195 | this._named = {}; |
| 25 | 195 | this._stack = []; |
| 26 | 195 | this.open({}); |
| 27 | } | |
| 28 | ||
| 29 | 1 | Windows.prototype.open = function(options) { |
| 30 | 224 | var name, window, _base; |
| 31 | 224 | if (options == null) { |
| 32 | 0 | options = {}; |
| 33 | } | |
| 34 | 224 | name = options.name || this._browser.name || ""; |
| 35 | 224 | if (options.parent) { |
| 36 | 19 | window = this._create(name, options); |
| 37 | } else { | |
| 38 | 205 | if (name === "_blank") { |
| 39 | 1 | window = this._create(name, options); |
| 40 | } else { | |
| 41 | 204 | window = (_base = this._named)[name] || (_base[name] = this._create(name, options)); |
| 42 | } | |
| 43 | 205 | this._stack.push(window); |
| 44 | } | |
| 45 | 224 | if (options.url) { |
| 46 | 3 | window.location = options.url; |
| 47 | 221 | } else if (!window.document) { |
| 48 | 220 | window.location = "about:blank"; |
| 49 | } | |
| 50 | 224 | if (!options.parent) { |
| 51 | 205 | this.select(window); |
| 52 | } | |
| 53 | 224 | return window; |
| 54 | }; | |
| 55 | ||
| 56 | 1 | Windows.prototype.get = function(name_or_index) { |
| 57 | 17 | return this._named[name_or_index] || this._stack[name_or_index]; |
| 58 | }; | |
| 59 | ||
| 60 | 1 | Windows.prototype.all = function() { |
| 61 | 7 | return this._stack.slice(); |
| 62 | }; | |
| 63 | ||
| 64 | 1 | Windows.prototype.__defineGetter__("count", function() { |
| 65 | 9 | return this._stack.length; |
| 66 | }); | |
| 67 | ||
| 68 | 1 | Windows.prototype.close = function(window) { |
| 69 | 5 | var index; |
| 70 | 5 | window = this._named[window] || this._stack[window] || window || this._current; |
| 71 | 5 | index = this._stack.indexOf(window); |
| 72 | 5 | if (!(index >= 0)) { |
| 73 | 0 | return; |
| 74 | } | |
| 75 | 5 | if (!window.closed) { |
| 76 | 5 | window.closed = true; |
| 77 | 5 | window._close(); |
| 78 | } | |
| 79 | 5 | delete this._named[window.name]; |
| 80 | 5 | this._stack.splice(index, 1); |
| 81 | 5 | if (window === this._current) { |
| 82 | 4 | this._current = null; |
| 83 | 4 | if (index > 0) { |
| 84 | 2 | this.select(this._stack[index - 1]); |
| 85 | } else { | |
| 86 | 2 | this.select(this._stack[0]); |
| 87 | } | |
| 88 | } | |
| 89 | }; | |
| 90 | ||
| 91 | 1 | Windows.prototype.select = function(window) { |
| 92 | 225 | var onblur, onfocus, previous, _ref; |
| 93 | 225 | window = this._named[window] || this._stack[window] || window; |
| 94 | 225 | if (!~this._stack.indexOf(window)) { |
| 95 | 5 | return; |
| 96 | } | |
| 97 | 220 | _ref = [this._current, window], previous = _ref[0], this._current = _ref[1]; |
| 98 | 220 | if (window.document && previous !== window) { |
| 99 | 212 | onfocus = window.document.createEvent("HTMLEvents"); |
| 100 | 212 | onfocus.initEvent("focus", false, false); |
| 101 | 212 | window.dispatchEvent(onfocus); |
| 102 | 212 | if (previous) { |
| 103 | 14 | onblur = window.document.createEvent("HTMLEvents"); |
| 104 | 14 | onblur.initEvent("blur", false, false); |
| 105 | 14 | previous.dispatchEvent(onblur); |
| 106 | } | |
| 107 | } | |
| 108 | }; | |
| 109 | ||
| 110 | 1 | Windows.prototype.__defineGetter__("current", function() { |
| 111 | 1574 | return this._current; |
| 112 | }); | |
| 113 | ||
| 114 | 1 | Windows.prototype._create = function(name, _arg) { |
| 115 | 223 | var eventloop, global, opener, parent, window, |
| 116 | _this = this; | |
| 117 | 223 | parent = _arg.parent, opener = _arg.opener; |
| 118 | 223 | window = JSDOM.createWindow(HTML); |
| 119 | 223 | global = window.getGlobal(); |
| 120 | 223 | Object.defineProperty(window, "browser", { |
| 121 | value: this._browser | |
| 122 | }); | |
| 123 | 223 | eventloop = this._browser._eventloop; |
| 124 | 223 | eventloop.apply(window); |
| 125 | 223 | Object.defineProperty(window, "name", { |
| 126 | value: name || "" | |
| 127 | }); | |
| 128 | 223 | if (parent) { |
| 129 | 19 | Object.defineProperty(window, "parent", { |
| 130 | value: parent.getGlobal() | |
| 131 | }); | |
| 132 | 19 | Object.defineProperty(window, "top", { |
| 133 | value: parent.top.getGlobal() | |
| 134 | }); | |
| 135 | } else { | |
| 136 | 204 | Object.defineProperty(window, "parent", { |
| 137 | value: window.getGlobal() | |
| 138 | }); | |
| 139 | 204 | Object.defineProperty(window, "top", { |
| 140 | value: window.getGlobal() | |
| 141 | }); | |
| 142 | } | |
| 143 | 223 | Object.defineProperty(window, "history", { |
| 144 | value: new History(window) | |
| 145 | }); | |
| 146 | 223 | Object.defineProperty(window, "opener", { |
| 147 | value: opener != null ? opener.getGlobal() : void 0 | |
| 148 | }); | |
| 149 | 223 | Object.defineProperty(window, "title", { |
| 150 | get: function() { | |
| 151 | 3 | return this.document.title; |
| 152 | }, | |
| 153 | set: function(title) { | |
| 154 | 1 | return this.document.title = title; |
| 155 | } | |
| 156 | }); | |
| 157 | 223 | window.closed = false; |
| 158 | 223 | Object.defineProperties(window.navigator, { |
| 159 | cookieEnabled: { | |
| 160 | value: true | |
| 161 | }, | |
| 162 | javaEnabled: { | |
| 163 | value: function() { | |
| 164 | 1 | return false; |
| 165 | } | |
| 166 | }, | |
| 167 | plugins: { | |
| 168 | value: [] | |
| 169 | }, | |
| 170 | vendor: { | |
| 171 | value: "Zombie Industries" | |
| 172 | } | |
| 173 | }); | |
| 174 | 223 | this._browser._cookies.extend(window); |
| 175 | 223 | this._browser._storages.extend(window); |
| 176 | 223 | this._browser._interact.extend(window); |
| 177 | 223 | this._browser._xhr.extend(window); |
| 178 | 223 | Object.defineProperties(window, { |
| 179 | File: { | |
| 180 | value: File | |
| 181 | }, | |
| 182 | Event: { | |
| 183 | value: Events.Event | |
| 184 | }, | |
| 185 | screen: { | |
| 186 | value: new Screen() | |
| 187 | }, | |
| 188 | MouseEvent: { | |
| 189 | value: Events.MouseEvent | |
| 190 | }, | |
| 191 | MutationEvent: { | |
| 192 | value: Events.MutationEvent | |
| 193 | }, | |
| 194 | UIEvent: { | |
| 195 | value: Events.UIEvent | |
| 196 | } | |
| 197 | }); | |
| 198 | 223 | window.atob = function(string) { |
| 199 | 1 | return new Buffer(string, "base64").toString("utf8"); |
| 200 | }; | |
| 201 | 223 | window.btoa = function(string) { |
| 202 | 1 | return new Buffer(string, "utf8").toString("base64"); |
| 203 | }; | |
| 204 | 223 | window.EventSource = function(url) { |
| 205 | 1 | url = URL.resolve(window.location, url); |
| 206 | 1 | window.setInterval((function() {}), 100); |
| 207 | 1 | return new EventSource(url); |
| 208 | }; | |
| 209 | 223 | window.WebSocket = function(url, protocol) { |
| 210 | 4 | var origin; |
| 211 | 4 | origin = "" + window.location.protocol + "//" + window.location.host; |
| 212 | 4 | return new WebSocket(url, { |
| 213 | origin: origin, | |
| 214 | protocol: protocol | |
| 215 | }); | |
| 216 | }; | |
| 217 | 223 | window.Image = function(width, height) { |
| 218 | 12 | var img; |
| 219 | 12 | img = new HTML.HTMLImageElement(window.document); |
| 220 | 12 | img.width = width; |
| 221 | 12 | img.height = height; |
| 222 | 12 | return img; |
| 223 | }; | |
| 224 | 223 | window.console = new Console(this._browser.silent); |
| 225 | 223 | window.resizeTo = function(width, height) { |
| 226 | 1 | window.outerWidth = window.innerWidth = width; |
| 227 | 1 | return window.outerHeight = window.innerHeight = height; |
| 228 | }; | |
| 229 | 223 | window.resizeBy = function(width, height) { |
| 230 | 1 | return window.resizeTo(window.outerWidth + width, window.outerHeight + height); |
| 231 | }; | |
| 232 | 223 | window.postMessage = function(data, targetOrigin) { |
| 233 | 7 | var document, event, origin; |
| 234 | 7 | document = window.document; |
| 235 | 7 | if (!document) { |
| 236 | 0 | return; |
| 237 | } | |
| 238 | 7 | event = document.createEvent("MessageEvent"); |
| 239 | 7 | event.initEvent("message", false, false); |
| 240 | 7 | event.data = data; |
| 241 | 7 | event.source = Windows.inContext; |
| 242 | 7 | origin = event.source.location; |
| 243 | 7 | event.origin = URL.format({ |
| 244 | protocol: origin.protocol, | |
| 245 | host: origin.host | |
| 246 | }); | |
| 247 | 7 | return process.nextTick(function() { |
| 248 | 7 | return eventloop.dispatch(window, event); |
| 249 | }); | |
| 250 | }; | |
| 251 | 223 | window.addEventListener("focus", function(event) { |
| 252 | 212 | var onfocus; |
| 253 | 212 | if (window.document.activeElement) { |
| 254 | 0 | onfocus = window.document.createEvent("HTMLEvents"); |
| 255 | 0 | onfocus.initEvent("focus", false, false); |
| 256 | 0 | return window.document.activeElement.dispatchEvent(onfocus); |
| 257 | } | |
| 258 | }); | |
| 259 | 223 | window.addEventListener("blur", function(event) { |
| 260 | 14 | var onblur; |
| 261 | 14 | if (window.document.activeElement) { |
| 262 | 0 | onblur = window.document.createEvent("HTMLEvents"); |
| 263 | 0 | onblur.initEvent("blur", false, false); |
| 264 | 0 | return window.document.activeElement.dispatchEvent(onblur); |
| 265 | } | |
| 266 | }); | |
| 267 | 223 | window._evaluate = function(code, filename) { |
| 268 | 739 | try { |
| 269 | 739 | Windows.inContext = window; |
| 270 | 739 | if (typeof code === "string" || code instanceof String) { |
| 271 | 252 | return global.run(code, filename); |
| 272 | 487 | } else if (code) { |
| 273 | 487 | return code.call(global); |
| 274 | } | |
| 275 | } finally { | |
| 276 | 739 | Windows.inContext = null; |
| 277 | } | |
| 278 | }; | |
| 279 | 223 | window.onerror = function(event) { |
| 280 | 4 | var error; |
| 281 | 4 | error = event.error || new Error("Error loading script"); |
| 282 | 4 | return _this._browser.emit("error", error); |
| 283 | }; | |
| 284 | 223 | window.open = function(url, name, features) { |
| 285 | 5 | if (url) { |
| 286 | 3 | url = URL.resolve(window.location, url); |
| 287 | } | |
| 288 | 5 | return _this.open({ |
| 289 | url: url, | |
| 290 | name: name, | |
| 291 | opener: window | |
| 292 | }); | |
| 293 | }; | |
| 294 | 223 | window._close = window.close; |
| 295 | 223 | window.close = function() { |
| 296 | 2 | if (opener) { |
| 297 | 1 | _this.close(window); |
| 298 | } else { | |
| 299 | 1 | _this._browser.log("Scripts may not close windows that were not opened by script"); |
| 300 | } | |
| 301 | }; | |
| 302 | 223 | return window; |
| 303 | }; | |
| 304 | ||
| 305 | 1 | return Windows; |
| 306 | ||
| 307 | })(); | |
| 308 | ||
| 309 | 1 | Screen = (function() { |
| 310 | ||
| 311 | 1 | function Screen() { |
| 312 | 223 | this.width = 1280; |
| 313 | 223 | this.height = 800; |
| 314 | 223 | this.left = 0; |
| 315 | 223 | this.top = 0; |
| 316 | } | |
| 317 | ||
| 318 | 1 | Screen.prototype.__defineGetter__("availLeft", function() { |
| 319 | 1 | return 0; |
| 320 | }); | |
| 321 | ||
| 322 | 1 | Screen.prototype.__defineGetter__("availTop", function() { |
| 323 | 1 | return 0; |
| 324 | }); | |
| 325 | ||
| 326 | 1 | Screen.prototype.__defineGetter__("availWidth", function() { |
| 327 | 1 | return this.width; |
| 328 | }); | |
| 329 | ||
| 330 | 1 | Screen.prototype.__defineGetter__("availHeight", function() { |
| 331 | 1 | return this.height; |
| 332 | }); | |
| 333 | ||
| 334 | 1 | Screen.prototype.__defineGetter__("colorDepth", function() { |
| 335 | 1 | return 24; |
| 336 | }); | |
| 337 | ||
| 338 | 1 | Screen.prototype.__defineGetter__("pixelDepth", function() { |
| 339 | 1 | return 24; |
| 340 | }); | |
| 341 | ||
| 342 | 1 | return Screen; |
| 343 | ||
| 344 | })(); | |
| 345 | ||
| 346 | 1 | File = (function() { |
| 347 | ||
| 348 | 1 | function File() {} |
| 349 | ||
| 350 | 1 | return File; |
| 351 | ||
| 352 | })(); | |
| 353 | ||
| 354 | 1 | module.exports = Windows; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var Console, Util; |
| 3 | ||
| 4 | 1 | Util = require("util"); |
| 5 | ||
| 6 | 1 | Console = (function() { |
| 7 | ||
| 8 | 1 | function Console(_silent) { |
| 9 | 223 | this._silent = _silent; |
| 10 | } | |
| 11 | ||
| 12 | 1 | Console.prototype.assert = console.assert.bind(console); |
| 13 | ||
| 14 | 1 | Console.prototype.count = function(name) { |
| 15 | 0 | var _base; |
| 16 | 0 | this._counters || (this._counters = {}); |
| 17 | 0 | (_base = this._counters)[name] || (_base[name] = 0); |
| 18 | 0 | this._counters[name]++; |
| 19 | 0 | return this.log("" + name + ": " + this._counters[name]); |
| 20 | }; | |
| 21 | ||
| 22 | 1 | Console.prototype.debug = function() { |
| 23 | 0 | return this.log.apply(this, arguments); |
| 24 | }; | |
| 25 | ||
| 26 | 1 | Console.prototype.error = function() { |
| 27 | 0 | return this.log.apply(this, arguments); |
| 28 | }; | |
| 29 | ||
| 30 | 1 | Console.prototype.group = function() {}; |
| 31 | ||
| 32 | 1 | Console.prototype.groupCollapsed = function() {}; |
| 33 | ||
| 34 | 1 | Console.prototype.groupEnd = function() {}; |
| 35 | ||
| 36 | 1 | Console.prototype.info = function() { |
| 37 | 0 | return this.log.apply(this, arguments); |
| 38 | }; | |
| 39 | ||
| 40 | 1 | Console.prototype.log = function() { |
| 41 | 8 | var arg, formatted, output; |
| 42 | 8 | formatted = (function() { |
| 43 | 8 | var _i, _len, _results; |
| 44 | 8 | _results = []; |
| 45 | 8 | for (_i = 0, _len = arguments.length; _i < _len; _i++) { |
| 46 | 25 | arg = arguments[_i]; |
| 47 | 25 | _results.push(typeof arg === "string" ? arg : Util.inspect(arg, console.showHidden, console.depth)); |
| 48 | } | |
| 49 | 8 | return _results; |
| 50 | }).apply(this, arguments); | |
| 51 | 8 | if (typeof Util.format === "function") { |
| 52 | 8 | output = Util.format.apply(this, formatted) + "\n"; |
| 53 | } else { | |
| 54 | 0 | output = formatted.join(" ") + "\n"; |
| 55 | } | |
| 56 | 8 | this._output || (this._output = []); |
| 57 | 8 | this._output.push(output); |
| 58 | 8 | if (!this._silent) { |
| 59 | 0 | return process.stdout.write(output); |
| 60 | } | |
| 61 | }; | |
| 62 | ||
| 63 | 1 | Console.prototype.warn = function() { |
| 64 | 0 | return this.log.apply(this, arguments); |
| 65 | }; | |
| 66 | ||
| 67 | 1 | Console.prototype.time = function(name) { |
| 68 | 0 | this._timers || (this._timers = {}); |
| 69 | 0 | return this._timers[name] = Date.now(); |
| 70 | }; | |
| 71 | ||
| 72 | 1 | Console.prototype.timeEnd = function(name) { |
| 73 | 0 | var start; |
| 74 | 0 | if (!this._timers) { |
| 75 | 0 | return; |
| 76 | } | |
| 77 | 0 | start = this._timers[name]; |
| 78 | 0 | if (!start) { |
| 79 | 0 | return; |
| 80 | } | |
| 81 | 0 | delete this._timers[name]; |
| 82 | 0 | return this.log("" + name + ": " + (Date.now() - start) + "ms"); |
| 83 | }; | |
| 84 | ||
| 85 | 1 | Console.prototype.trace = function() { |
| 86 | 0 | var stack; |
| 87 | 0 | stack = (new Error).stack.split("\n"); |
| 88 | 0 | stack[0] = "console.trace()"; |
| 89 | 0 | return this.log(stack.join("\n")); |
| 90 | }; | |
| 91 | ||
| 92 | 1 | Console.prototype.__defineGetter__("output", function() { |
| 93 | 0 | return (this._output ? this._output.join("\n") : ""); |
| 94 | }); | |
| 95 | ||
| 96 | 1 | return Console; |
| 97 | ||
| 98 | })(); | |
| 99 | ||
| 100 | 1 | module.exports = Console; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var ABOUT_BLANK, Entry, HTML, History, JSDOM, Location, Scripts, URL, util; |
| 3 | ||
| 4 | 1 | util = require("util"); |
| 5 | ||
| 6 | 1 | JSDOM = require("jsdom"); |
| 7 | ||
| 8 | 1 | HTML = JSDOM.dom.level3.html; |
| 9 | ||
| 10 | 1 | Scripts = require("./scripts"); |
| 11 | ||
| 12 | 1 | URL = require("url"); |
| 13 | ||
| 14 | 1 | ABOUT_BLANK = URL.parse("about:blank"); |
| 15 | ||
| 16 | 1 | Entry = (function() { |
| 17 | ||
| 18 | 1 | function Entry(url, options) { |
| 19 | 486 | if (options) { |
| 20 | 8 | this.state = options.state; |
| 21 | 8 | this.title = options.title; |
| 22 | 8 | this.pop = !!options.pop; |
| 23 | } | |
| 24 | 486 | this.update(url); |
| 25 | } | |
| 26 | ||
| 27 | 1 | Entry.prototype.update = function(url) { |
| 28 | 956 | if (/^file:/i.test(url)) { |
| 29 | 2 | return this.url = { |
| 30 | protocol: "file:", | |
| 31 | hostname: "", | |
| 32 | pathname: url.slice(6), | |
| 33 | href: url | |
| 34 | }; | |
| 35 | } else { | |
| 36 | 954 | return this.url = URL.parse(URL.format(url)); |
| 37 | } | |
| 38 | }; | |
| 39 | ||
| 40 | 1 | return Entry; |
| 41 | ||
| 42 | })(); | |
| 43 | ||
| 44 | 1 | History = (function() { |
| 45 | ||
| 46 | 1 | function History(window) { |
| 47 | 223 | var _this = this; |
| 48 | 223 | this._use(window); |
| 49 | 223 | this._stack = []; |
| 50 | 223 | this._index = 0; |
| 51 | 223 | this._location = new Location(this); |
| 52 | 223 | Object.defineProperty(this, "current", { |
| 53 | get: function() { | |
| 54 | 590 | var _ref; |
| 55 | 590 | return ((_ref = _this._stack[_this._index]) != null ? _ref.url : void 0) || ABOUT_BLANK; |
| 56 | } | |
| 57 | }); | |
| 58 | } | |
| 59 | ||
| 60 | 1 | History.prototype._use = function(window) { |
| 61 | 223 | var _this = this; |
| 62 | 223 | this._window = window; |
| 63 | 223 | this._browser = this._window.browser; |
| 64 | 223 | return Object.defineProperty(this._window, "location", { |
| 65 | get: function() { | |
| 66 | 428 | return _this._location; |
| 67 | }, | |
| 68 | set: function(url) { | |
| 69 | 263 | return _this._assign(_this._resolve(url)); |
| 70 | } | |
| 71 | }); | |
| 72 | }; | |
| 73 | ||
| 74 | 1 | History.prototype._pageChanged = function(was) { |
| 75 | 461 | var evt, url, _ref; |
| 76 | 461 | url = (_ref = this._stack[this._index]) != null ? _ref.url : void 0; |
| 77 | 461 | if (!was || was.host !== url.host || was.pathname !== url.pathname || was.query !== url.query) { |
| 78 | 451 | return this._resource(url); |
| 79 | 10 | } else if (was.hash !== url.hash) { |
| 80 | 6 | evt = this._window.document.createEvent("HTMLEvents"); |
| 81 | 6 | evt.initEvent("hashchange", true, false); |
| 82 | 6 | return this._browser.dispatchEvent(this._window, evt); |
| 83 | } else { | |
| 84 | 4 | return this._resource(url); |
| 85 | } | |
| 86 | }; | |
| 87 | ||
| 88 | 1 | History.prototype._resource = function(url, method, data, headers) { |
| 89 | 474 | var referer, _ref, _ref1, |
| 90 | _this = this; | |
| 91 | 474 | switch (url.protocol) { |
| 92 | case "about:": | |
| 93 | 220 | this._createDocument(this._window, ABOUT_BLANK); |
| 94 | 220 | this._stack[this._index].update(url); |
| 95 | 220 | return this._browser.emit("loaded", this._browser); |
| 96 | case "javascript:": | |
| 97 | 4 | this._createDocument(this._window, ABOUT_BLANK); |
| 98 | 4 | if (!this._stack[this._index]) { |
| 99 | 0 | this._stack[this._index].update(ABOUT_BLANK); |
| 100 | } | |
| 101 | 4 | try { |
| 102 | 4 | this._window._evaluate(url.pathname, "javascript:"); |
| 103 | 4 | return this._browser.emit("loaded", this._browser); |
| 104 | } catch (error) { | |
| 105 | 0 | return this._browser.emit("error", error); |
| 106 | } | |
| 107 | 0 | break; |
| 108 | case "http:": | |
| 109 | case "https:": | |
| 110 | case "file:": | |
| 111 | 250 | headers = headers ? JSON.parse(JSON.stringify(headers)) : {}; |
| 112 | 250 | referer = ((_ref = this._stack[this._index - 1]) != null ? (_ref1 = _ref.url) != null ? _ref1.href : void 0 : void 0) || this._browser.referer; |
| 113 | 250 | if (referer) { |
| 114 | 44 | headers["referer"] = referer; |
| 115 | } | |
| 116 | 250 | method = (method || "GET").toUpperCase(); |
| 117 | 250 | return this._browser.resources.request(method, url, data, headers, function(error, response) { |
| 118 | 250 | var document, evt; |
| 119 | 250 | if (error) { |
| 120 | 0 | document = _this._createDocument(_this._window, url); |
| 121 | 0 | document.open(); |
| 122 | 0 | document.write(error.message); |
| 123 | 0 | document.close(); |
| 124 | 0 | return _this._browser.emit("error", error); |
| 125 | } else { | |
| 126 | 250 | document = _this._createDocument(_this._window, response.url); |
| 127 | 250 | _this._browser.response = [response.statusCode, response.headers, response.body]; |
| 128 | 250 | url = URL.parse(response.url); |
| 129 | 250 | _this._stack[_this._index].update(url); |
| 130 | 250 | if (response.body) { |
| 131 | 228 | document.open(); |
| 132 | 228 | document.write(response.body); |
| 133 | 228 | document.close(); |
| 134 | } | |
| 135 | 250 | if (url.hash) { |
| 136 | 4 | evt = _this._window.document.createEvent("HTMLEvents"); |
| 137 | 4 | evt.initEvent("hashchange", true, false); |
| 138 | 4 | _this._browser.dispatchEvent(_this._window, evt); |
| 139 | } | |
| 140 | 250 | if (response.statusCode >= 400) { |
| 141 | 11 | return _this._browser.emit("error", new Error("Server returned status code " + response.statusCode)); |
| 142 | 239 | } else if (document.documentElement) { |
| 143 | 239 | return _this._browser.emit("loaded", _this._browser); |
| 144 | } else { | |
| 145 | 0 | return _this._browser.emit("error", new Error("Could not parse document at " + (URL.format(url)))); |
| 146 | } | |
| 147 | } | |
| 148 | }); | |
| 149 | default: | |
| 150 | 0 | throw new Error("Cannot load resource: " + (URL.format(url))); |
| 151 | } | |
| 152 | }; | |
| 153 | ||
| 154 | 1 | History.prototype._createDocument = function(window, url) { |
| 155 | 474 | var document, jsdom_opts, |
| 156 | _this = this; | |
| 157 | 474 | jsdom_opts = { |
| 158 | deferClose: true, | |
| 159 | features: { | |
| 160 | MutationEvents: "2.0", | |
| 161 | ProcessExternalResources: [], | |
| 162 | FetchExternalResources: ["iframe"] | |
| 163 | }, | |
| 164 | parser: this._browser.htmlParser, | |
| 165 | url: URL.format(url) | |
| 166 | }; | |
| 167 | 474 | if (this._browser.runScripts) { |
| 168 | 469 | jsdom_opts.features.ProcessExternalResources.push("script"); |
| 169 | 469 | jsdom_opts.features.FetchExternalResources.push("script"); |
| 170 | } | |
| 171 | 474 | if (this._browser.loadCSS) { |
| 172 | 474 | jsdom_opts.features.FetchExternalResources.push("css"); |
| 173 | } | |
| 174 | 474 | document = JSDOM.jsdom(null, HTML, jsdom_opts); |
| 175 | 474 | if (this._browser.runScripts) { |
| 176 | 469 | Scripts.addInlineScriptSupport(document); |
| 177 | } | |
| 178 | 474 | window.document = document; |
| 179 | 474 | document.window = document.parentWindow = window; |
| 180 | 474 | window.navigator.userAgent = this._browser.userAgent; |
| 181 | 474 | document.addEventListener("DOMContentLoaded", function(event) { |
| 182 | 229 | var onload; |
| 183 | 229 | onload = document.createEvent("HTMLEvents"); |
| 184 | 229 | onload.initEvent("load", false, false); |
| 185 | 229 | return window.dispatchEvent(onload); |
| 186 | }); | |
| 187 | 474 | return document; |
| 188 | }; | |
| 189 | ||
| 190 | 1 | History.prototype.forward = function() { |
| 191 | 2 | return this.go(1); |
| 192 | }; | |
| 193 | ||
| 194 | 1 | History.prototype.back = function() { |
| 195 | 5 | return this.go(-1); |
| 196 | }; | |
| 197 | ||
| 198 | 1 | History.prototype.go = function(amount) { |
| 199 | 7 | var entry, new_index, popstate, was, _ref, _ref1, _ref2; |
| 200 | 7 | was = (_ref = this._stack[this._index]) != null ? _ref.url : void 0; |
| 201 | 7 | new_index = this._index + amount; |
| 202 | 7 | if (new_index < 0) { |
| 203 | 1 | new_index = 0; |
| 204 | } | |
| 205 | 7 | if (this._stack.length > 0 && new_index >= this._stack.length) { |
| 206 | 1 | new_index = this._stack.length - 1; |
| 207 | } | |
| 208 | 7 | if (new_index !== this._index && (entry = this._stack[new_index])) { |
| 209 | 5 | this._index = new_index; |
| 210 | 5 | if (entry.pop) { |
| 211 | 3 | if (was.host !== ((_ref1 = this._stack[this._index]) != null ? (_ref2 = _ref1.url) != null ? _ref2.host : void 0 : void 0)) { |
| 212 | 0 | this._resource(this._stack[this._index].url); |
| 213 | } else { | |
| 214 | 3 | popstate = this._window.document.createEvent("HTMLEvents"); |
| 215 | 3 | popstate.initEvent("popstate", false, false); |
| 216 | 3 | popstate.state = entry.state; |
| 217 | 3 | this._browser.dispatchEvent(this._window, popstate); |
| 218 | } | |
| 219 | } else { | |
| 220 | 2 | this._pageChanged(was); |
| 221 | } | |
| 222 | } | |
| 223 | }; | |
| 224 | ||
| 225 | 1 | History.prototype.__defineGetter__("length", function() { |
| 226 | 21 | return this._stack.length; |
| 227 | }); | |
| 228 | ||
| 229 | 1 | History.prototype.pushState = function(state, title, url) { |
| 230 | 6 | url = this._resolve(url); |
| 231 | 6 | this._advance(); |
| 232 | 6 | return this._stack[this._index] = new Entry(url, { |
| 233 | state: state, | |
| 234 | title: title, | |
| 235 | pop: true | |
| 236 | }); | |
| 237 | }; | |
| 238 | ||
| 239 | 1 | History.prototype.replaceState = function(state, title, url) { |
| 240 | 2 | if (this._index < 0) { |
| 241 | 0 | this._index = 0; |
| 242 | } | |
| 243 | 2 | url = this._resolve(url); |
| 244 | 2 | return this._stack[this._index] = new Entry(url, { |
| 245 | state: state, | |
| 246 | title: title, | |
| 247 | pop: true | |
| 248 | }); | |
| 249 | }; | |
| 250 | ||
| 251 | 1 | History.prototype._resolve = function(url) { |
| 252 | 748 | var _ref, _ref1; |
| 253 | 748 | if (url) { |
| 254 | 741 | if (/^\w+:/i.test(url)) { |
| 255 | 721 | return url; |
| 256 | } else { | |
| 257 | 20 | return URL.resolve((_ref = this._stack[this._index]) != null ? _ref.url : void 0, url); |
| 258 | } | |
| 259 | } else { | |
| 260 | 7 | return (_ref1 = this._stack[this._index]) != null ? _ref1.url : void 0; |
| 261 | } | |
| 262 | }; | |
| 263 | ||
| 264 | 1 | History.prototype._assign = function(url) { |
| 265 | 458 | var was, _ref; |
| 266 | 458 | url = this._resolve(url); |
| 267 | 458 | was = (_ref = this._stack[this._index]) != null ? _ref.url : void 0; |
| 268 | 458 | this._stack = this._stack.slice(0, this._index + 1 || 9e9); |
| 269 | 458 | this._advance(); |
| 270 | 458 | this._stack[this._index] = new Entry(url); |
| 271 | 458 | return this._pageChanged(was); |
| 272 | }; | |
| 273 | ||
| 274 | 1 | History.prototype._replace = function(url) { |
| 275 | 1 | var was, _ref; |
| 276 | 1 | url = this._resolve(url); |
| 277 | 1 | was = (_ref = this._stack[this._index]) != null ? _ref.url : void 0; |
| 278 | 1 | if (this._index < 0) { |
| 279 | 0 | this._index = 0; |
| 280 | } | |
| 281 | 1 | this._stack[this._index] = new Entry(url); |
| 282 | 1 | return this._pageChanged(was); |
| 283 | }; | |
| 284 | ||
| 285 | 1 | History.prototype._loadPage = function(force) { |
| 286 | 1 | if (this._stack[this._index]) { |
| 287 | 1 | return this._resource(this._stack[this._index].url); |
| 288 | } | |
| 289 | }; | |
| 290 | ||
| 291 | 1 | History.prototype._submit = function(url, method, data, enctype) { |
| 292 | 18 | var headers; |
| 293 | 18 | headers = { |
| 294 | "content-type": enctype || "application/x-www-form-urlencoded" | |
| 295 | }; | |
| 296 | 18 | this._stack = this._stack.slice(0, this._index + 1 || 9e9); |
| 297 | 18 | url = this._resolve(url); |
| 298 | 18 | this._advance(); |
| 299 | 18 | this._stack[this._index] = new Entry(url); |
| 300 | 18 | return this._resource(this._stack[this._index].url, method, data, headers); |
| 301 | }; | |
| 302 | ||
| 303 | 1 | History.prototype.dump = function() { |
| 304 | 0 | var dump, entry, i, line, _ref; |
| 305 | 0 | dump = []; |
| 306 | 0 | _ref = this._stack; |
| 307 | 0 | for (i in _ref) { |
| 308 | 0 | entry = _ref[i]; |
| 309 | 0 | i = Number(i); |
| 310 | 0 | line = i === this._index ? "" + (i + 1) + ": " : "" + (i + 1) + ". "; |
| 311 | 0 | line += URL.format(entry.url); |
| 312 | 0 | if (entry.state) { |
| 313 | 0 | line += " state: " + util.inspect(entry.state); |
| 314 | } | |
| 315 | 0 | dump.push(line); |
| 316 | } | |
| 317 | 0 | return dump; |
| 318 | }; | |
| 319 | ||
| 320 | 1 | History.prototype.save = function() { |
| 321 | 1 | var entry, i, line, serialized, _ref; |
| 322 | 1 | serialized = []; |
| 323 | 1 | _ref = this._stack; |
| 324 | 1 | for (i in _ref) { |
| 325 | 1 | entry = _ref[i]; |
| 326 | 1 | line = URL.format(entry.url); |
| 327 | 1 | if (entry.pop) { |
| 328 | 0 | line += " " + (JSON.stringify(entry.state)); |
| 329 | } | |
| 330 | 1 | serialized.push(line); |
| 331 | } | |
| 332 | 1 | return serialized.join("\n") + "\n"; |
| 333 | }; | |
| 334 | ||
| 335 | 1 | History.prototype.load = function(serialized) { |
| 336 | 1 | var line, options, state, url, _i, _len, _ref, _ref1, _results; |
| 337 | 1 | _ref = serialized.split(/\n+/); |
| 338 | 1 | _results = []; |
| 339 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 340 | 2 | line = _ref[_i]; |
| 341 | 2 | line = line.trim(); |
| 342 | 2 | if (line[0] === "#" || line === "") { |
| 343 | 1 | continue; |
| 344 | } | |
| 345 | 1 | _ref1 = line.split(/\s/), url = _ref1[0], state = _ref1[1]; |
| 346 | 1 | options = state && { |
| 347 | state: JSON.parse(state), | |
| 348 | title: null, | |
| 349 | pop: true | |
| 350 | }; | |
| 351 | 1 | this._advance(); |
| 352 | 1 | _results.push(this._stack[this._index] = new Entry(url, state)); |
| 353 | } | |
| 354 | 1 | return _results; |
| 355 | }; | |
| 356 | ||
| 357 | 1 | History.prototype._advance = function() { |
| 358 | 483 | var current; |
| 359 | 483 | current = this._stack[this._index]; |
| 360 | 483 | if (current && ~["http:", "https:", "file:"].indexOf(current.url.protocol)) { |
| 361 | 55 | return ++this._index; |
| 362 | } | |
| 363 | }; | |
| 364 | ||
| 365 | 1 | return History; |
| 366 | ||
| 367 | })(); | |
| 368 | ||
| 369 | 1 | Location = (function() { |
| 370 | 1 | var prop, _fn, _i, _len, _ref, |
| 371 | _this = this; | |
| 372 | ||
| 373 | 1 | function Location(_history) { |
| 374 | 223 | this._history = _history; |
| 375 | } | |
| 376 | ||
| 377 | 1 | Location.prototype.assign = function(newUrl) { |
| 378 | 1 | return this._history._assign(newUrl); |
| 379 | }; | |
| 380 | ||
| 381 | 1 | Location.prototype.replace = function(newUrl) { |
| 382 | 1 | return this._history._replace(newUrl); |
| 383 | }; | |
| 384 | ||
| 385 | 1 | Location.prototype.reload = function(force) { |
| 386 | 1 | return this._history._loadPage(force); |
| 387 | }; | |
| 388 | ||
| 389 | 1 | Location.prototype.toString = function() { |
| 390 | 88 | return URL.format(this._history.current); |
| 391 | }; | |
| 392 | ||
| 393 | 1 | Location.prototype.__defineGetter__("href", function() { |
| 394 | 186 | var _ref; |
| 395 | 186 | return (_ref = this._history.current) != null ? _ref.href : void 0; |
| 396 | }); | |
| 397 | ||
| 398 | 1 | Location.prototype.__defineSetter__("href", function(new_url) { |
| 399 | 1 | return this._history._assign(new_url); |
| 400 | }); | |
| 401 | ||
| 402 | 1 | _ref = ["hash", "host", "hostname", "pathname", "port", "protocol", "search"]; |
| 403 | 1 | _fn = function(prop) { |
| 404 | 7 | Location.prototype.__defineGetter__(prop, function() { |
| 405 | 314 | var _ref1; |
| 406 | 314 | return ((_ref1 = this._history.current) != null ? _ref1[prop] : void 0) || ""; |
| 407 | }); | |
| 408 | 7 | return Location.prototype.__defineSetter__(prop, function(value) { |
| 409 | 2 | var newUrl, _ref1; |
| 410 | 2 | newUrl = URL.parse((_ref1 = this._history.current) != null ? _ref1.href : void 0); |
| 411 | 2 | newUrl[prop] = value; |
| 412 | 2 | return this._history._assign(URL.format(newUrl)); |
| 413 | }); | |
| 414 | }; | |
| 415 | 1 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 416 | 7 | prop = _ref[_i]; |
| 417 | 7 | _fn(prop); |
| 418 | } | |
| 419 | ||
| 420 | 1 | return Location; |
| 421 | ||
| 422 | }).call(this); | |
| 423 | ||
| 424 | 1 | HTML.HTMLDocument.prototype.__defineGetter__("location", function() { |
| 425 | 98 | return this.parentWindow.location; |
| 426 | }); | |
| 427 | ||
| 428 | 1 | HTML.HTMLDocument.prototype.__defineSetter__("location", function(url) { |
| 429 | 1 | if (this._parentWindow) { |
| 430 | 1 | return this.parentWindow.location = url; |
| 431 | } | |
| 432 | }); | |
| 433 | ||
| 434 | 1 | module.exports = History; |
| Line | Hits | Source |
|---|---|---|
| 1 | // Generated by CoffeeScript 1.3.3 | |
| 2 | 1 | var URL, XMLHttpRequest, html, http, raise; |
| 3 | ||
| 4 | 1 | html = require("jsdom").dom.level3.html; |
| 5 | ||
| 6 | 1 | http = require("http"); |
| 7 | ||
| 8 | 1 | URL = require("url"); |
| 9 | ||
| 10 | 1 | raise = require("./scripts").raise; |
| 11 | ||
| 12 | 1 | html.SECURITY_ERR = 18; |
| 13 | ||
| 14 | 1 | html.NETWORK_ERR = 19; |
| 15 | ||
| 16 | 1 | html.ABORT_ERR = 20; |
| 17 | ||
| 18 | 1 | XMLHttpRequest = function(window) { |
| 19 | 39 | var reset, stateChanged, |
| 20 | _this = this; | |
| 21 | 39 | stateChanged = function(state) { |
| 22 | 36 | _this.__defineGetter__("readyState", function() { |
| 23 | 24 | return state; |
| 24 | }); | |
| 25 | 36 | if (_this.onreadystatechange) { |
| 26 | 24 | return window.browser._eventloop.perform(function(done) { |
| 27 | 24 | return process.nextTick(function() { |
| 28 | 24 | try { |
| 29 | 24 | return _this.onreadystatechange.call(_this); |
| 30 | } catch (error) { | |
| 31 | 0 | return raise({ |
| 32 | element: window.document, | |
| 33 | from: __filename, | |
| 34 | scope: "XHR", | |
| 35 | error: error | |
| 36 | }); | |
| 37 | } finally { | |
| 38 | 24 | done(); |
| 39 | } | |
| 40 | }); | |
| 41 | }); | |
| 42 | } | |
| 43 | }; | |
| 44 | 39 | reset = function() { |
| 45 | 39 | _this.__defineGetter__("readyState", function() { |
| 46 | 0 | return 0; |
| 47 | }); | |
| 48 | 39 | _this.__defineGetter__("status", function() { |
| 49 | 0 | return 0; |
| 50 | }); | |
| 51 | 39 | _this.__defineGetter__("statusText", function() {}); |
| 52 | 39 | _this.abort = function() {}; |
| 53 | 39 | _this.setRequestHeader = _this.send = function() { |
| 54 | 0 | throw new html.DOMException(html.INVALID_STATE_ERR, "Invalid state"); |
| 55 | }; | |
| 56 | 39 | _this.getResponseHeader = _this.getAllResponseHeaders = function() {}; |
| 57 | 39 | return _this.open = function(method, url, async, user, password) { |
| 58 | 12 | var aborted, headers, _ref, _ref1; |
| 59 | 12 | method = method.toUpperCase(); |
| 60 | 12 | if (/^(CONNECT|TRACE|TRACK)$/.test(method)) { |
| 61 | 0 | throw new html.DOMException(html.SECURITY_ERR, "Unsupported HTTP method"); |
| 62 | } | |
| 63 | 12 | if (!/^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/.test(method)) { |
| 64 | 0 | throw new html.DOMException(html.SYNTAX_ERR, "Unsupported HTTP method"); |
| 65 | } | |
| 66 | 12 | url = URL.parse(URL.resolve(window.location.href, url)); |
| 67 | 12 | url.hostname || (url.hostname = window.location.hostname); |
| 68 | 12 | url.host = url.port ? "" + url.hostname + ":" + url.port : url.hostname; |
| 69 | 12 | url.hash = null; |
| 70 | 12 | if (url.host !== window.location.host) { |
| 71 | 0 | throw new html.DOMException(html.SECURITY_ERR, "Cannot make request to different domain"); |
| 72 | } | |
| 73 | 12 | if ((_ref = url.protocol) !== "http:" && _ref !== "https:") { |
| 74 | 0 | throw new html.DOMException(html.NOT_SUPPORTED_ERR, "Only HTTP/S protocol supported"); |
| 75 | } | |
| 76 | 12 | if (url.auth) { |
| 77 | 0 | _ref1 = url.auth.split(":"), user = _ref1[0], password = _ref1[1]; |
| 78 | } | |
| 79 | 12 | this._error = null; |
| 80 | 12 | aborted = false; |
| 81 | 12 | this.abort = function() { |
| 82 | 0 | aborted = true; |
| 83 | 0 | return reset(); |
| 84 | }; | |
| 85 | 12 | headers = {}; |
| 86 | 12 | this.setRequestHeader = function(header, value) { |
| 87 | 29 | return headers[header.toString().toLowerCase()] = value.toString(); |
| 88 | }; | |
| 89 | 12 | this.send = function(data) { |
| 90 | 12 | var _this = this; |
| 91 | 12 | this.abort = function() { |
| 92 | 0 | aborted = true; |
| 93 | 0 | this._error = new html.DOMException(html.ABORT_ERR, "Request aborted"); |
| 94 | 0 | stateChanged(4); |
| 95 | 0 | return reset(); |
| 96 | }; | |
| 97 | 12 | return window.browser.resources.request(method, url, data, headers, function(error, response) { |
| 98 | 12 | if (error) { |
| 99 | 0 | _this._error = new html.DOMException(html.NETWORK_ERR, error.message); |
| 100 | 0 | stateChanged(4); |
| 101 | 0 | return reset(); |
| 102 | } else { | |
| 103 | 12 | _this.getResponseHeader = function(header) { |
| 104 | 1 | return response.headers[header.toLowerCase()]; |
| 105 | }; | |
| 106 | 12 | _this.getAllResponseHeaders = function() { |
| 107 | 13 | var header, headerStrings, value; |
| 108 | 13 | headerStrings = (function() { |
| 109 | 13 | var _ref2, _results; |
| 110 | 13 | _ref2 = response.headers; |
| 111 | 13 | _results = []; |
| 112 | 13 | for (header in _ref2) { |
| 113 | 69 | value = _ref2[header]; |
| 114 | 69 | _results.push("" + header + ": " + value); |
| 115 | } | |
| 116 | 13 | return _results; |
| 117 | })(); | |
| 118 | 13 | return headerStrings.join("\n"); |
| 119 | }; | |
| 120 | 12 | _this.__defineGetter__("status", function() { |
| 121 | 16 | return response.statusCode; |
| 122 | }); | |
| 123 | 12 | _this.__defineGetter__("statusText", function() { |
| 124 | 9 | return response.statusText; |
| 125 | }); | |
| 126 | 12 | stateChanged(2); |
| 127 | 12 | if (!aborted) { |
| 128 | 12 | _this.__defineGetter__("responseText", function() { |
| 129 | 14 | return response.body; |
| 130 | }); | |
| 131 | 12 | _this.__defineGetter__("responseXML", function() {}); |
| 132 | 12 | return stateChanged(4); |
| 133 | } | |
| 134 | } | |
| 135 | }); | |
| 136 | }; | |
| 137 | 12 | this.open = function(method, url, async, user, password) { |
| 138 | 0 | this.abort(); |
| 139 | 0 | return this.open(method, url, async, user, password); |
| 140 | }; | |
| 141 | 12 | return stateChanged(1); |
| 142 | }; | |
| 143 | }; | |
| 144 | 39 | reset(); |
| 145 | }; | |
| 146 | ||
| 147 | 1 | XMLHttpRequest.UNSENT = 0; |
| 148 | ||
| 149 | 1 | XMLHttpRequest.OPENED = 1; |
| 150 | ||
| 151 | 1 | XMLHttpRequest.HEADERS_RECEIVED = 2; |
| 152 | ||
| 153 | 1 | XMLHttpRequest.LOADING = 3; |
| 154 | ||
| 155 | 1 | XMLHttpRequest.DONE = 4; |
| 156 | ||
| 157 | 1 | exports.use = function() { |
| 158 | 195 | var extend; |
| 159 | 195 | extend = function(window) { |
| 160 | 223 | return window.XMLHttpRequest = function() { |
| 161 | 39 | return XMLHttpRequest.call(this, window); |
| 162 | }; | |
| 163 | }; | |
| 164 | 195 | return { |
| 165 | extend: extend | |
| 166 | }; | |
| 167 | }; |