UNPKG

zombie-globbies

Version:

A very quick fix for [**Zombie**](https://github.com/assaf/zombie) to permit to crawl correctly webpages with attributes on the html tag (eg: html lang="en").

1,141 lines (1,008 loc) 33.2 kB
var Assert, BROWSER_FEATURES, BROWSER_OPTIONS, Browser, Console, Cookie, Cookies, Credentials, DEFAULT_FEATURES, DNSMask, Debug, EventEmitter, EventLoop, File, HTML, Interact, JSDOM_PATH, MOUSE_EVENT_NAMES, Mime, Path, PortMap, Promise, Resources, Storages, Tough, URL, XPathResult, assert, createTabs, debug, format, ms, __hasProp = {}.hasOwnProperty, __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; }, __slice = [].slice; Path = require("path"); JSDOM_PATH = require.resolve("jsdom"); assert = require("assert"); Assert = require("./assert"); createTabs = require("./tabs"); Console = require("./console"); Cookies = require("./cookies"); Debug = require("debug"); DNSMask = require("./dns_mask"); EventEmitter = require("events").EventEmitter; EventLoop = require("./eventloop"); format = require("util").format; File = require("fs"); Interact = require("./interact"); HTML = require("jsdom").defaultLevel; Mime = require("mime"); ms = require("ms"); Promise = require("bluebird").Promise; PortMap = require("./port_map"); Resources = require("./resources"); Storages = require("./storage"); Tough = require("tough-cookie"); Cookie = Tough.Cookie; URL = require("url"); XPathResult = require("" + JSDOM_PATH + "/../jsdom/level3/xpath").XPathResult; require("./jsdom_patches"); require("./forms"); require("./dom_focus"); require("./dom_iframe"); debug = Debug("zombie"); BROWSER_OPTIONS = ["features", "headers", "htmlParser", "waitDuration", "proxy", "referer", "silent", "site", "strictSSL", "userAgent", "maxRedirects", "language", "runScripts", "localAddress"]; BROWSER_FEATURES = ["scripts", "css", "img", "iframe"]; DEFAULT_FEATURES = "scripts no-css no-img iframe"; MOUSE_EVENT_NAMES = ["mousedown", "mousemove", "mouseup"]; Browser = (function(_super) { __extends(Browser, _super); function Browser(options) { var browser, extension, name, _i, _j, _len, _len1, _ref; if (options == null) { options = {}; } browser = this; this.cookies = new Cookies(); this._storages = new Storages(); this._interact = Interact.use(this); this._windowInScope = null; this.assert = new Assert(this); this.console = new Console(this); this.on("console", function(level, message) { if (browser.silent) { return debug(">> " + message); } else { return console.log(message); } }); this.on("log", function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return debug.apply(null, args); }); this.referer = null; this.resources = new Resources(this); this.on("request", function(request) {}); this.on("response", function(request, response) { return browser.log("" + (request.method || "GET") + " " + response.url + " => " + response.statusCode); }); this.on("redirect", function(request, response, redirectRequest) { return browser.log("" + (request.method || "GET") + " " + request.url + " => " + response.statusCode + " " + response.url); }); this.on("loaded", function(document) { return browser.log("Loaded document", document.location.href); }); this.tabs = createTabs(this); this.on("opened", function(window) { return browser.log("Opened window", window.location.href, window.name || ""); }); this.on("closed", function(window) { return browser.log("Closed window", window.location.href, window.name || ""); }); this.on("active", function(window) { var element, onfocus; onfocus = window.document.createEvent("HTMLEvents"); onfocus.initEvent("focus", false, false); window.dispatchEvent(onfocus); if (element = window.document.activeElement) { onfocus = window.document.createEvent("HTMLEvents"); onfocus.initEvent("focus", false, false); return element.dispatchEvent(onfocus); } }); this.on("inactive", function(window) { var element, onblur; if (element = window.document.activeElement) { onblur = window.document.createEvent("HTMLEvents"); onblur.initEvent("blur", false, false); element.dispatchEvent(onblur); } onblur = window.document.createEvent("HTMLEvents"); onblur.initEvent("blur", false, false); return window.dispatchEvent(onblur); }); this.eventLoop = new EventLoop(this); this.errors = []; this.on("error", (function(_this) { return function(error) { _this.errors.push(error); return _this.log(error.message, error.stack); }; })(this)); this.on("done", (function(_this) { return function(timedOut) { if (timedOut) { return _this.log("Event loop timed out"); } else { return _this.log("Event loop is empty"); } }; })(this)); this.on("timeout", (function(_this) { return function(fn, delay) { return _this.log("Fired timeout after " + delay + "ms delay"); }; })(this)); this.on("interval", (function(_this) { return function(fn, interval) { return _this.log("Fired interval every " + interval + "ms"); }; })(this)); this.on("link", (function(_this) { return function(url, target) { return _this.log("Follow link to " + url); }; })(this)); this.on("submit", (function(_this) { return function(url, target) { return _this.log("Submit form to " + url); }; })(this)); for (_i = 0, _len = BROWSER_OPTIONS.length; _i < _len; _i++) { name = BROWSER_OPTIONS[_i]; if (options.hasOwnProperty(name)) { this[name] = options[name]; } else if (Browser["default"].hasOwnProperty(name)) { this[name] = Browser["default"][name]; } } _ref = Browser._extensions; for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { extension = _ref[_j]; extension(this); } } Browser.extend = function(extension) { return Browser._extensions.push(extension); }; Browser._extensions = []; Browser.prototype.hasFeature = function(name, ifMissing) { var features; if (ifMissing == null) { ifMissing = true; } if (this.features) { features = this.features.split(/\s+/); if (~features.indexOf(name)) { return true; } if (~features.indexOf("no-" + name)) { return false; } } return ifMissing; }; Browser.prototype.withOptions = function(options, fn) { var k, restore, v, _ref; console.log("visit with options is deprecated and will be removed soon"); if (options) { restore = {}; for (k in options) { v = options[k]; if (~BROWSER_OPTIONS.indexOf(k)) { _ref = [this[k], v], restore[k] = _ref[0], this[k] = _ref[1]; } } return (function(_this) { return function() { for (k in restore) { v = restore[k]; _this[k] = v; } }; })(this); } else { return function() {}; } }; Browser.prototype.fork = function() { var forked, name, opt, _i, _len; opt = {}; for (_i = 0, _len = BROWSER_OPTIONS.length; _i < _len; _i++) { name = BROWSER_OPTIONS[_i]; opt[name] = this[name]; } forked = Browser.create(opt); forked.loadCookies(this.saveCookies()); forked.loadStorage(this.saveStorage()); forked.location = this.location.href; return forked; }; Browser.prototype.__defineGetter__("window", function() { return this.tabs.current; }); Browser.prototype.open = function(options) { var name, referer, url; if (options) { url = options.url, name = options.name, referer = options.referer; } return this.tabs.open({ url: url, name: name, referer: referer }); }; Browser.prototype.__defineGetter__("error", function() { return this.errors[this.errors.length - 1]; }); Browser.prototype.wait = function(options, callback) { var completionFunction, promise, waitDuration, _ref; if (arguments.length === 1 && typeof options === "function") { _ref = [options, null], callback = _ref[0], options = _ref[1]; } assert(!callback || typeof callback === "function", "Second argument expected to be a callback function or null"); if (typeof options === "number") { waitDuration = options; } else if (typeof options === "string") { waitDuration = options; } else if (typeof options === "function") { waitDuration = this.waitDuration; completionFunction = options; } else if (options) { waitDuration = options.duration || this.waitDuration; if (options.element) { completionFunction = function(window) { return !!window.document.querySelector(options.element); }; } else { completionFunction = options["function"]; } } else { waitDuration = this.waitDuration; } if (this.window) { promise = this.eventLoop.wait(waitDuration, completionFunction); } else { promise = Promise.reject(new Error("No window open")); } if (callback) { promise.done(callback, callback); } else { return promise; } }; Browser.prototype.waitForServer = function(options, callback) { var promise, _ref; assert(this.window, "No window open"); if (arguments.length === 1 && typeof options === "function") { _ref = [options, null], callback = _ref[0], options = _ref[1]; } promise = new Promise((function(_this) { return function(resolve, reject) { return _this.eventLoop.once("server", function() { return resolve(_this.wait(options, null)); }); }; })(this)); if (callback) { promise.done(callback, callback); } else { return promise; } }; Browser.prototype.fire = function(selector, eventName, callback) { var event, eventType, target; assert(this.window, "No window open"); target = this.query(selector); assert(target && target.dispatchEvent, "No target element (note: call with selector/element, event name and callback)"); if (~MOUSE_EVENT_NAMES.indexOf(eventName)) { eventType = "MouseEvents"; } else { eventType = "HTMLEvents"; } event = this.document.createEvent(eventType); event.initEvent(eventName, true, true); target.dispatchEvent(event); if (callback !== false) { return this.wait(callback); } }; Browser.prototype.click = function(selector, callback) { return this.fire(selector, "click", callback); }; Browser.prototype.dispatchEvent = function(selector, event) { var target; target = this.query(selector); assert(this.window, "No window open"); return target.dispatchEvent(event); }; Browser.prototype.queryAll = function(selector, context) { var elements; if (Array.isArray(selector)) { return selector; } else if (selector instanceof HTML.Element) { return [selector]; } else if (selector) { context || (context = this.document); elements = context.querySelectorAll(selector); return Array.prototype.slice.call(elements, 0); } else { return []; } }; Browser.prototype.query = function(selector, context) { if (selector instanceof HTML.Element) { return selector; } if (selector) { context || (context = this.document); return context.querySelector(selector); } else { return context; } }; Browser.prototype.$$ = function(selector, context) { return this.query(selector, context); }; Browser.prototype.querySelector = function(selector) { return this.document.querySelector(selector); }; Browser.prototype.querySelectorAll = function(selector) { return this.document.querySelectorAll(selector); }; Browser.prototype.text = function(selector, context) { if (this.document.documentElement) { return this.queryAll(selector || "html", context).map(function(e) { return e.textContent; }).join("").trim().replace(/\s+/g, " "); } else if (this.source) { return this.source.toString(); } else { return ""; } }; Browser.prototype.html = function(selector, context) { if (this.document.documentElement) { return this.queryAll(selector || "html", context).map(function(e) { return e.outerHTML.trim(); }).join(""); } else if (this.source) { return this.source.toString(); } else { return ""; } }; Browser.prototype.xpath = function(expression, context) { return this.document.evaluate(expression, context || this.document.documentElement, null, XPathResult.ANY_TYPE); }; Browser.prototype.__defineGetter__("document", function() { if (this.window) { return this.window.document; } }); Browser.prototype.__defineGetter__("body", function() { return this.document.querySelector("body"); }); Browser.prototype.__defineGetter__("activeElement", function() { return this.document.activeElement; }); Browser.prototype.close = function(window) { return this.tabs.close.apply(this.tabs, arguments); }; Browser.prototype.destroy = function() { if (this.tabs) { this.tabs.closeAll(); return this.tabs = null; } }; Browser.prototype.visit = function(url, options, callback) { var promise, resetOptions, site, _ref; if (typeof options === "function" && !callback) { _ref = [options, null], callback = _ref[0], options = _ref[1]; } if (options) { resetOptions = this.withOptions(options); } if (site = this.site) { if (!/^(https?:|file:)/i.test(site)) { site = "http://" + site; } url = URL.resolve(site, URL.parse(URL.format(url))); } if (this.window) { this.tabs.close(this.window); } this.tabs.open({ url: url, referer: this.referer }); if (options) { promise = this.wait(options)["finally"](resetOptions); } else { promise = this.wait(options); } if (callback) { promise.done(callback, callback); } else { return promise; } }; Browser.prototype.load = function(html, callback) { var promise; this.location = "about:blank"; promise = this.wait().then((function(_this) { return function() { _this.errors = []; _this.document.readyState = "loading"; _this.document.open(); _this.document.write(html); _this.document.close(); return _this.wait; }; })(this)); if (callback) { promise.done(callback, callback); } else { return promise; } }; Browser.prototype.__defineGetter__("location", function() { if (this.window) { return this.window.location; } }); Browser.prototype.__defineSetter__("location", function(url) { if (this.window) { return this.window.location = url; } else { return this.open({ url: url }); } }); Browser.prototype.__defineGetter__("url", function() { if (this.window) { return URL.format(this.window.location); } }); Browser.prototype.link = function(selector) { var error, link, _i, _len, _ref; if (selector instanceof HTML.Element) { return selector; } try { link = this.querySelector(selector); } catch (_error) { error = _error; link = null; } if (link && link.tagName === "A") { return link; } _ref = this.querySelectorAll("body a"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; if (link.textContent.trim() === selector) { return link; } } return null; }; Browser.prototype.clickLink = function(selector, callback) { var link; link = this.link(selector); assert(link, "No link matching '" + selector + "'"); return this.click(link, callback); }; Browser.prototype.__defineGetter__("history", function() { if (!this.window) { this.open(); } return this.window.history; }); Browser.prototype.back = function(callback) { this.window.history.back(); return this.wait(callback); }; Browser.prototype.reload = function(callback) { this.window.location.reload(); return this.wait(callback); }; Browser.prototype.authenticate = function(host, create) { var credentials, _ref; if (create == null) { create = true; } host || (host = "*"); credentials = (_ref = this._credentials) != null ? _ref[host] : void 0; if (!credentials) { if (create) { credentials = new Credentials(); this._credentials || (this._credentials = {}); this._credentials[host] = credentials; } else { credentials = this.authenticate(); } } return credentials; }; Browser.prototype.saveHistory = function() { return this.window.history.save(); }; Browser.prototype.loadHistory = function(serialized) { return this.window.history.load(serialized); }; Browser.prototype.field = function(selector) { var error, field, forAttr, label, _i, _j, _len, _len1, _ref, _ref1; if (selector instanceof HTML.Element) { return selector; } try { field = this.query(selector); if (field && (field.tagName === "INPUT" || field.tagName === "TEXTAREA" || field.tagName === "SELECT")) { return field; } } catch (_error) { error = _error; } _ref = this.queryAll("input[name],textarea[name],select[name]"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { field = _ref[_i]; if (field.getAttribute("name") === selector) { return field; } } _ref1 = this.queryAll("label"); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { label = _ref1[_j]; if (label.textContent.trim() === selector) { if (forAttr = label.getAttribute("for")) { return this.document.getElementById(forAttr); } else { return label.querySelector("input,textarea,select"); } } } }; Browser.prototype.focus = function(selector) { var field; field = this.field(selector) || this.query(selector); assert(field, "No form field matching '" + selector + "'"); field.focus(); return this; }; Browser.prototype.fill = function(selector, value) { var field; field = this.field(selector); assert(field && (field.tagName === "TEXTAREA" || (field.tagName === "INPUT")), "No INPUT matching '" + selector + "'"); assert(!field.getAttribute("disabled"), "This INPUT field is disabled"); assert(!field.getAttribute("readonly"), "This INPUT field is readonly"); field.focus(); field.value = value; this.fire(field, "input", false); field.blur(); return this; }; Browser.prototype._setCheckbox = function(selector, value) { var field; field = this.field(selector); assert(field && field.tagName === "INPUT" && field.type === "checkbox", "No checkbox INPUT matching '" + selector + "'"); assert(!field.getAttribute("disabled"), "This INPUT field is disabled"); assert(!field.getAttribute("readonly"), "This INPUT field is readonly"); if (field.checked ^ value) { field.click(); } return this; }; Browser.prototype.check = function(selector) { return this._setCheckbox(selector, true); }; Browser.prototype.uncheck = function(selector) { return this._setCheckbox(selector, false); }; Browser.prototype.choose = function(selector) { var field; field = this.field(selector) || this.field("input[type=radio][value=\"" + (escape(selector)) + "\"]"); assert(field && field.tagName === "INPUT" && field.type === "radio", "No radio INPUT matching '" + selector + "'"); field.click(); return this; }; Browser.prototype._findOption = function(selector, value) { var field, option, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; field = this.field(selector); assert(field && field.tagName === "SELECT", "No SELECT matching '" + selector + "'"); assert(!field.getAttribute("disabled"), "This SELECT field is disabled"); assert(!field.getAttribute("readonly"), "This SELECT field is readonly"); _ref = field.options; for (_i = 0, _len = _ref.length; _i < _len; _i++) { option = _ref[_i]; if (option.value === value) { return option; } } _ref1 = field.options; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { option = _ref1[_j]; if (option.label === value) { return option; } } _ref2 = field.options; for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { option = _ref2[_k]; if (option.textContent.trim() === value) { return option; } } throw new Error("No OPTION '" + value + "'"); }; Browser.prototype.select = function(selector, value) { var option; option = this._findOption(selector, value); this.selectOption(option); return this; }; Browser.prototype.selectOption = function(selector) { var option, select; option = this.query(selector); if (option && !option.getAttribute("selected")) { select = this.xpath("./ancestor::select", option).iterateNext(); option.setAttribute("selected", "selected"); select.focus(); this.fire(select, "change", false); } return this; }; Browser.prototype.unselect = function(selector, value) { var option; option = this._findOption(selector, value); this.unselectOption(option); return this; }; Browser.prototype.unselectOption = function(selector) { var option, select; option = this.query(selector); if (option && option.getAttribute("selected")) { select = this.xpath("./ancestor::select", option).iterateNext(); assert(select.multiple, "Cannot unselect in single select"); option.removeAttribute("selected"); select.focus(); this.fire(select, "change", false); } return this; }; Browser.prototype.attach = function(selector, filename) { var field, file, stat; field = this.field(selector); assert(field && field.tagName === "INPUT" && field.type === "file", "No file INPUT matching '" + selector + "'"); if (filename) { stat = File.statSync(filename); file = new this.window.File(); file.name = Path.basename(filename); file.type = Mime.lookup(filename); file.size = stat.size; field.files || (field.files = []); field.files.push(file); field.value = filename; } field.focus(); this.fire(field, "change", false); return this; }; Browser.prototype.button = function(selector) { var button, error, input, inputs, _i, _j, _k, _len, _len1, _len2, _ref; if (selector instanceof HTML.Element) { return selector; } try { if (button = this.querySelector(selector)) { if (button.tagName === "BUTTON" || button.tagName === "INPUT") { return button; } } } catch (_error) { error = _error; } _ref = this.querySelectorAll("button"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { button = _ref[_i]; if (button.textContent.trim() === selector) { return button; } } inputs = this.querySelectorAll("input[type=submit],button"); for (_j = 0, _len1 = inputs.length; _j < _len1; _j++) { input = inputs[_j]; if (input.name === selector) { return input; } } for (_k = 0, _len2 = inputs.length; _k < _len2; _k++) { input = inputs[_k]; if (input.value === selector) { return input; } } }; Browser.prototype.pressButton = function(selector, callback) { var button; assert(button = this.button(selector), "No BUTTON '" + selector + "'"); assert(!button.getAttribute("disabled"), "This button is disabled"); button.focus(); return this.fire(button, "click", callback); }; Browser.prototype.getCookie = function(identifier, allProperties) { var cookie; identifier = this._cookieIdentifier(identifier); assert(identifier.name, "Missing cookie name"); assert(identifier.domain, "No domain specified and no open page"); cookie = this.cookies.select(identifier)[0]; if (cookie) { if (allProperties) { return this._cookieProperties(cookie); } else { return cookie.value; } } else { return null; } }; Browser.prototype.deleteCookie = function(identifier) { var cookie; identifier = this._cookieIdentifier(identifier); assert(identifier.name, "Missing cookie name"); assert(identifier.domain, "No domain specified and no open page"); cookie = this.cookies.select(identifier)[0]; if (cookie) { this.cookies["delete"](cookie); return true; } else { return false; } }; Browser.prototype.setCookie = function(nameOrOptions, value) { var domain, location; if (location = this.location) { domain = location.hostname; } if (typeof nameOrOptions === "string") { this.cookies.set({ name: nameOrOptions, value: value || "", domain: domain, path: "/", secure: false, httpOnly: false }); } else { assert(nameOrOptions.name, "Missing cookie name"); this.cookies.set({ name: nameOrOptions.name, value: nameOrOptions.value || value || "", domain: nameOrOptions.domain || domain, path: nameOrOptions.path || "/", secure: !!nameOrOptions.secure, httpOnly: !!nameOrOptions.httpOnly, expires: nameOrOptions.expires, "max-age": nameOrOptions["max-age"] }); } }; Browser.prototype.deleteCookies = function() { this.cookies.deleteAll(); }; Browser.prototype.saveCookies = function() { var cookie, serialized, _i, _len, _ref; serialized = ["# Saved on " + (new Date().toISOString())]; _ref = this.cookies.sort(Tough.cookieCompare); for (_i = 0, _len = _ref.length; _i < _len; _i++) { cookie = _ref[_i]; serialized.push(cookie.toString()); } return serialized.join("\n") + "\n"; }; Browser.prototype.loadCookies = function(serialized) { var line, _i, _len, _ref, _results; _ref = serialized.split(/\n+/); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { line = _ref[_i]; line = line.trim(); if (line[0] === "#" || line === "") { continue; } _results.push(this.cookies.push(Cookie.parse(line))); } return _results; }; Browser.prototype._cookieProperties = function(cookie) { var properties; properties = { name: cookie.key, value: cookie.value, domain: cookie.domain, path: cookie.path }; if (cookie.secure) { properties.secure = true; } if (cookie.httpOnly) { properties.httpOnly = true; } if (cookie.expires && cookie.expires < Infinity) { properties.expires = cookie.expires; } return properties; }; Browser.prototype._cookieIdentifier = function(identifier) { var domain, location, path; location = this.location; domain = location && location.hostname; path = location && location.pathname || "/"; if (typeof identifier === "string") { identifier = { name: identifier, domain: domain, path: path }; } else { identifier = { name: identifier.name, domain: identifier.domain || domain, path: identifier.path || path }; } return identifier; }; Browser.prototype.localStorage = function(host) { return this._storages.local(host); }; Browser.prototype.sessionStorage = function(host) { return this._storages.session(host); }; Browser.prototype.saveStorage = function() { return this._storages.save(); }; Browser.prototype.loadStorage = function(serialized) { return this._storages.load(serialized); }; Browser.prototype.evaluate = function(code, filename) { if (!this.window) { this.open(); } return this.window._evaluate(code, filename); }; Browser.prototype.onalert = function(fn) { return this._interact.onalert(fn); }; Browser.prototype.onconfirm = function(question, response) { return this._interact.onconfirm(question, response); }; Browser.prototype.onprompt = function(message, response) { return this._interact.onprompt(message, response); }; Browser.prototype.prompted = function(message) { return this._interact.prompted(message); }; Browser.prototype.__defineGetter__("statusCode", function() { if (this.window && this.window._response) { return this.window._response.statusCode; } else { return null; } }); Browser.prototype.__defineGetter__("success", function() { var statusCode; statusCode = this.statusCode; return statusCode >= 200 && statusCode < 400; }); Browser.prototype.__defineGetter__("redirected", function() { return this.window && this.window._response && this.window._response.redirects > 0; }); Browser.prototype.__defineGetter__("source", function() { if (this.window && this.window._response) { return this.window._response.body; } else { return null; } }); Browser.prototype.viewInBrowser = function(browser) { return require("./bcat").bcat(this.html()); }; Browser.prototype.log = function() { var args; if (typeof arguments[0] === "function") { args = [arguments[0]()]; } else { args = arguments; } return this.emit("log", format.apply(null, args)); }; Browser.prototype.dump = function() { var html, indent; indent = function(lines) { return lines.map(function(l) { return " " + l + "\n"; }).join(""); }; process.stdout.write("Zombie: " + Browser.VERSION + "\n\n"); process.stdout.write("URL: " + this.window.location.href + "\n"); process.stdout.write("History:\n" + (indent(this.window.history.dump())) + "\n"); process.stdout.write("Cookies:\n" + (indent(this.cookies.dump())) + "\n"); process.stdout.write("Storage:\n" + (indent(this._storages.dump())) + "\n"); process.stdout.write("Eventloop:\n" + (indent(this.eventLoop.dump())) + "\n"); if (this.document) { html = this.document.outerHTML; if (html.length > 497) { html = html.slice(0, 497) + "..."; } return process.stdout.write("Document:\n" + (indent(html.split("\n"))) + "\n"); } else { if (!this.document) { return process.stdout.write("No document\n"); } } }; return Browser; })(EventEmitter); Browser.VERSION = JSON.parse(File.readFileSync("" + __dirname + "/../../package.json")).version; Browser["default"] = { features: DEFAULT_FEATURES, htmlParser: null, maxRedirects: 5, proxy: null, silent: false, site: void 0, strictSSL: false, localAddress: '0.0.0.0', userAgent: "Mozilla/5.0 Chrome/10.0.613.0 Safari/534.15 Zombie.js/" + Browser.VERSION, language: "en-US", waitDuration: "5s", runScripts: true }; Browser.create = function(options) { return new Browser(options); }; Browser.debug = function() { if (!Debug.enabled("zombie")) { Debug.enable("zombie"); return debug = Debug("zombie"); } }; Browser.dns = new DNSMask(); Browser.ports = new PortMap(); Browser.localhost = function(hostname, port) { Browser.dns.localhost(hostname); Browser.ports.map(hostname, port); if (!Browser["default"].site) { return Browser["default"].site = hostname.replace(/^\*\./, ""); } }; Credentials = (function() { function Credentials() {} Credentials.prototype.apply = function(headers) { var base64; switch (this.scheme) { case "basic": base64 = new Buffer(this.user + ":" + this.password).toString("base64"); return headers["authorization"] = "Basic " + base64; case "bearer": return headers["authorization"] = "Bearer " + this.token; case "oauth": return headers["authorization"] = "OAuth " + this.token; } }; Credentials.prototype.basic = function(user, password) { this.user = user; this.password = password; return this.scheme = "basic"; }; Credentials.prototype.bearer = function(token) { this.token = token; return this.scheme = "bearer"; }; Credentials.prototype.oauth = function(token) { this.token = token; return this.scheme = "oauth"; }; Credentials.prototype.reset = function() { delete this.scheme; delete this.token; delete this.user; return delete this.password; }; return Credentials; })(); module.exports = Browser;