UNPKG

adextent-phantom

Version:
183 lines (154 loc) 6.55 kB
# Require gets overwritten by browserify, so we have to reimplement it from scratch - boo :( webpage = core_require('webpage'); shoe = require('shoe'); dnode = require('dnode'); system = core_require('system'); port = system.args[1] hostname = system.args[2] # controlPage = webpage.create() fnwrap = (target) -> -> target.apply this, arguments # Descend into objects with dotted keys descend = (op, obj, key, val) -> cur = obj keys = key.split '.' cur = cur[keys.shift()] while keys.length > 1 cur[keys[0]] = val if op is 'set' cur[keys[0]] _transform = (val) -> if typeof val is "string" and val.indexOf('__phantomCallback__') is 0 val = 'return ' + val.replace('__phantomCallback__', ''); val = phantom.callback(new Function(val)()); return val; transform = (obj) -> if typeof obj is "string" _transform(obj) else if typeof obj is "object" for key of obj if typeof obj[key] is "object" transform(obj[key]) else obj[key] = _transform(obj[key]) return obj mkwrap = (src, pass=[], special={}) -> obj = set: (key, val, cb=->) -> #Fnwrap so PhantomJS doesn't segfault when it tries to call the callback val = fnwrap val if typeof val is "function" val = transform(val) cb descend 'set', src, key, val get: (key, cb) -> cb descend 'get', src, key for k in pass do (k) -> obj[k] = (args...) -> # This idempotent tomfoolery is required to stop PhantomJS from segfaulting args[i] = fnwrap arg for arg, i in args when typeof arg is 'function' src[k] args... for own k of special obj[k] = special[k] obj pageWrap = (page) -> mkwrap page, ['open','close','includeJs','sendEvent','release','uploadFile','goBack','goForward','reload', 'switchToFrame', 'switchToMainFrame', 'switchToParentFrame', 'switchToFocusedFrame'] # this is here to let the user pass in a function that has access to request.abort() and other functions on the request object. onPageCreated:(cb=(->))-> page.onPageCreated = (newpage) -> cb pageWrap newpage onConsoleMessage: (cb=(->)) -> page.onConsoleMessage = -> cb.apply(this, arguments) onError: (cb=(->)) -> page.onError = -> cb.apply(this, arguments) onCallback: (cb=(->)) -> page.onCallback = -> cb.apply(this, arguments) onResourceReceived: (fn, cb=(->), args...) -> page.onResourceReceived = -> # prepare a arguments with the extra args argumentsWithExtraArgs = [].slice.apply(arguments).concat(args) # give a name to the anonymouse function so that we can call it fn = fn.replace /function.*\(/, 'function x(' # the only way we can access the request object is by passing a function to this point as a string and expanding it eval(fn) # :( # this function has access to request.abort() x.apply(this, argumentsWithExtraArgs) # this function does not have access to request.abort() cb.apply(this, argumentsWithExtraArgs) onResourceTimeout: (fn, cb=(->), args...) -> page.onResourceTimeout = -> argumentsWithExtraArgs = [].slice.apply(arguments).concat(args) fn = fn.replace /function.*\(/, 'function x(' eval(fn) # :( x.apply(this, argumentsWithExtraArgs) cb.apply(this, argumentsWithExtraArgs) onResourceError: (fn, cb=(->), args...) -> page.onResourceError = -> # prepare a arguments with the extra args argumentsWithExtraArgs = [].slice.apply(arguments).concat(args) # give a name to the anonymouse function so that we can call it fn = fn.replace /function.*\(/, 'function x(' # the only way we can access the request object is by passing a function to this point as a string and expanding it eval(fn) # :( # this function has access to request.abort() x.apply(this, argumentsWithExtraArgs) # this function does not have access to request.abort() cb.apply(this, argumentsWithExtraArgs) onResourceRequested: (fn, cb=(->), args...) -> page.onResourceRequested = -> # prepare a arguments with the extra args argumentsWithExtraArgs = [].slice.apply(arguments).concat(args) # give a name to the anonymouse function so that we can call it fn = fn.replace /function.*\(/, 'function x(' # the only way we can access the request object is by passing a function to this point as a string and expanding it eval(fn) # :( # this function has access to request.abort() x.apply(this, argumentsWithExtraArgs) # this function does not have access to request.abort() cb.apply(this, argumentsWithExtraArgs) onLoadFinished: (fn, cb=(->), args...) -> page.onLoadFinished = -> argumentsWithExtraArgs = [].slice.apply(arguments).concat(args) fn = fn.replace /function.*\(/, 'function x(' eval(fn) # :( x.apply(this, argumentsWithExtraArgs) cb.apply(this, argumentsWithExtraArgs) injectJs: (js, cb=->) -> cb page.injectJs js evaluate: (fn, cb=(->), args...) -> cb page.evaluate.apply(page, [fn].concat(args)) render: (file, opts={}, cb) -> unless cb? if typeof opts is 'function' cb = opts opts = {} else cb = -> page.render file, opts; cb() getContent: (cb=->) -> cb page.content getCookies: (cb=->) -> cb page.cookies renderBase64: (type, cb=->) -> cb page.renderBase64 type setHeaders: (headers, cb=->) -> page.customHeaders = headers; cb() setContent: (html, url, cb=->) -> page.onLoadFinished = (status) -> page.onLoadFinished = null cb status page.setContent html, url setViewportSize: (width, height, cb=->) -> page.viewportSize = {width:width, height:height}; cb() setPaperSize: (options, cb=->) -> page.paperSize = transform(options); cb() setZoomFactor: (zoomFactor, cb=->) -> page.zoomFactor = zoomFactor; cb() setFileOnPicker: (fileName, cb=->) -> page.onFilePicker = -> cb.apply(this, arguments) fileName _phantom = mkwrap phantom, ['exit'], injectJs: (js, cb=->) -> cb phantom.injectJs js getCookies: (cb=->) -> cb(phantom.cookies) addCookie: (cookie, cb=->) -> cb(phantom.addCookie(cookie)) clearCookies: (cb=->) -> cb phantom.clearCookies() createPage: (cb) -> cb pageWrap webpage.create() setProxy: (host, port, type, user, password, cb=->) -> cb(phantom.setProxy(host, port, type, user, password)) stream = shoe('http://' + hostname + ':' + port + '/dnode') d = dnode _phantom d.pipe stream stream.pipe d