mirror of https://github.com/vitalif/phantomjs
parent
64b6fd2f4b
commit
48fabe0646
|
@ -1,7 +0,0 @@
|
||||||
system = require 'system'
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log 'Try to pass some args when invoking this script!'
|
|
||||||
else
|
|
||||||
for arg, i in system.args
|
|
||||||
console.log i + ': ' + arg
|
|
||||||
phantom.exit()
|
|
|
@ -1,20 +0,0 @@
|
||||||
{spawn, execFile} = require "child_process"
|
|
||||||
|
|
||||||
child = spawn "ls", ["-lF", "/rooot"]
|
|
||||||
|
|
||||||
child.stdout.on "data", (data) ->
|
|
||||||
console.log "spawnSTDOUT:", JSON.stringify data
|
|
||||||
|
|
||||||
child.stderr.on "data", (data) ->
|
|
||||||
console.log "spawnSTDERR:", JSON.stringify data
|
|
||||||
|
|
||||||
child.on "exit", (code) ->
|
|
||||||
console.log "spawnEXIT:", code
|
|
||||||
|
|
||||||
#child.kill "SIGKILL"
|
|
||||||
|
|
||||||
execFile "ls", ["-lF", "/usr"], null, (err, stdout, stderr) ->
|
|
||||||
console.log "execFileSTDOUT:", JSON.stringify stdout
|
|
||||||
console.log "execFileSTDERR:", JSON.stringify stderr
|
|
||||||
|
|
||||||
setTimeout (-> phantom.exit 0), 2000
|
|
|
@ -1,46 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
page.viewportSize = { width: 400, height : 400 }
|
|
||||||
page.content = '<html><body><canvas id="surface"></canvas></body></html>'
|
|
||||||
|
|
||||||
page.evaluate ->
|
|
||||||
el = document.getElementById 'surface'
|
|
||||||
context = el.getContext '2d'
|
|
||||||
width = window.innerWidth
|
|
||||||
height = window.innerHeight
|
|
||||||
cx = width / 2
|
|
||||||
cy = height / 2
|
|
||||||
radius = width / 2.3
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
el.width = width
|
|
||||||
el.height = height
|
|
||||||
imageData = context.createImageData(width, height)
|
|
||||||
pixels = imageData.data
|
|
||||||
|
|
||||||
for y in [0...height]
|
|
||||||
for x in [0...width]
|
|
||||||
i = i + 4
|
|
||||||
rx = x - cx
|
|
||||||
ry = y - cy
|
|
||||||
d = rx * rx + ry * ry
|
|
||||||
if d < radius * radius
|
|
||||||
hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI)
|
|
||||||
sat = Math.sqrt(d) / radius
|
|
||||||
g = Math.floor(hue)
|
|
||||||
f = hue - g
|
|
||||||
u = 255 * (1 - sat)
|
|
||||||
v = 255 * (1 - sat * f)
|
|
||||||
w = 255 * (1 - sat * (1 - f))
|
|
||||||
pixels[i] = [255, v, u, u, w, 255, 255][g]
|
|
||||||
pixels[i + 1] = [w, 255, 255, v, u, u, w][g]
|
|
||||||
pixels[i + 2] = [u, u, w, 255, 255, v, u][g]
|
|
||||||
pixels[i + 3] = 255
|
|
||||||
|
|
||||||
context.putImageData imageData, 0, 0
|
|
||||||
document.body.style.backgroundColor = 'white'
|
|
||||||
document.body.style.margin = '0px'
|
|
||||||
|
|
||||||
page.render('colorwheel.png')
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -1,8 +0,0 @@
|
||||||
t = 10
|
|
||||||
interval = setInterval ->
|
|
||||||
if t > 0
|
|
||||||
console.log t--
|
|
||||||
else
|
|
||||||
console.log 'BLAST OFF!'
|
|
||||||
phantom.exit()
|
|
||||||
, 1000
|
|
|
@ -1,42 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
page.onInitialized = ->
|
|
||||||
page.evaluate ->
|
|
||||||
userAgent = window.navigator.userAgent
|
|
||||||
platform = window.navigator.platform
|
|
||||||
window.navigator =
|
|
||||||
appCodeName: 'Mozilla'
|
|
||||||
appName: 'Netscape'
|
|
||||||
cookieEnabled: false
|
|
||||||
sniffed: false
|
|
||||||
|
|
||||||
window.navigator.__defineGetter__ 'userAgent', ->
|
|
||||||
window.navigator.sniffed = true
|
|
||||||
userAgent
|
|
||||||
|
|
||||||
window.navigator.__defineGetter__ 'platform', ->
|
|
||||||
window.navigator.sniffed = true
|
|
||||||
platform
|
|
||||||
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log 'Usage: detectsniff.coffee <some URL>'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
address = system.args[1]
|
|
||||||
console.log 'Checking ' + address + '...'
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'FAIL to load the address'
|
|
||||||
phantom.exit()
|
|
||||||
else
|
|
||||||
window.setTimeout ->
|
|
||||||
sniffed = page.evaluate(->
|
|
||||||
navigator.sniffed
|
|
||||||
)
|
|
||||||
if sniffed
|
|
||||||
console.log 'The page tried to sniff the user agent.'
|
|
||||||
else
|
|
||||||
console.log 'The page did not try to sniff the user agent.'
|
|
||||||
phantom.exit()
|
|
||||||
, 1500
|
|
|
@ -1,30 +0,0 @@
|
||||||
# Get driving direction using Google Directions API.
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length < 3
|
|
||||||
console.log 'Usage: direction.coffee origin destination'
|
|
||||||
console.log 'Example: direction.coffee "San Diego" "Palo Alto"'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
origin = system.args[1]
|
|
||||||
dest = system.args[2]
|
|
||||||
page.open encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin +
|
|
||||||
'&destination=' + dest + '&units=imperial&mode=driving&sensor=false'),
|
|
||||||
(status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
else
|
|
||||||
steps = page.content.match(/<html_instructions>(.*)<\/html_instructions>/ig)
|
|
||||||
if not steps
|
|
||||||
console.log 'No data available for ' + origin + ' to ' + dest
|
|
||||||
else
|
|
||||||
for ins in steps
|
|
||||||
ins = ins.replace(/\</ig, '<').replace(/\>/ig, '>')
|
|
||||||
ins = ins.replace(/\<div/ig, '\n<div')
|
|
||||||
ins = ins.replace(/<.*?>/g, '')
|
|
||||||
console.log(ins)
|
|
||||||
console.log ''
|
|
||||||
console.log page.content.match(/<copyrights>.*<\/copyrights>/ig).join('').replace(/<.*?>/g, '')
|
|
||||||
phantom.exit()
|
|
|
@ -1,19 +0,0 @@
|
||||||
# echoToFile.coffee - Write in a given file all the parameters passed on the CLI
|
|
||||||
fs = require 'fs'
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length < 3
|
|
||||||
console.log "Usage: echoToFile.coffee DESTINATION_FILE <arguments to echo...>"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
content = ""
|
|
||||||
f = null
|
|
||||||
i = 2
|
|
||||||
while i < system.args.length
|
|
||||||
content += system.args[i] + (if i == system.args.length - 1 then "" else " ")
|
|
||||||
++i
|
|
||||||
try
|
|
||||||
fs.write system.args[1], content, "w"
|
|
||||||
catch e
|
|
||||||
console.log e
|
|
||||||
phantom.exit()
|
|
|
@ -1,23 +0,0 @@
|
||||||
feature = undefined
|
|
||||||
supported = []
|
|
||||||
unsupported = []
|
|
||||||
phantom.injectJs "modernizr.js"
|
|
||||||
console.log "Detected features (using Modernizr " + Modernizr._version + "):"
|
|
||||||
for feature of Modernizr
|
|
||||||
if Modernizr.hasOwnProperty(feature)
|
|
||||||
if feature[0] isnt "_" and typeof Modernizr[feature] isnt "function" and feature isnt "input" and feature isnt "inputtypes"
|
|
||||||
if Modernizr[feature]
|
|
||||||
supported.push feature
|
|
||||||
else
|
|
||||||
unsupported.push feature
|
|
||||||
console.log ""
|
|
||||||
console.log "Supported:"
|
|
||||||
supported.forEach (e) ->
|
|
||||||
console.log " " + e
|
|
||||||
|
|
||||||
console.log ""
|
|
||||||
console.log "Not supported:"
|
|
||||||
unsupported.forEach (e) ->
|
|
||||||
console.log " " + e
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -1,8 +0,0 @@
|
||||||
fibs = [0, 1]
|
|
||||||
f = ->
|
|
||||||
console.log fibs[fibs.length - 1]
|
|
||||||
fibs.push fibs[fibs.length - 1] + fibs[fibs.length - 2]
|
|
||||||
if fibs.length > 10
|
|
||||||
window.clearInterval ticker
|
|
||||||
phantom.exit()
|
|
||||||
ticker = window.setInterval(f, 300)
|
|
|
@ -1,33 +0,0 @@
|
||||||
# List following and followers from several accounts
|
|
||||||
|
|
||||||
users = [
|
|
||||||
'PhantomJS'
|
|
||||||
'ariyahidayat'
|
|
||||||
'detronizator'
|
|
||||||
'KDABQt'
|
|
||||||
'lfranchi'
|
|
||||||
'jonleighton'
|
|
||||||
'_jamesmgreene'
|
|
||||||
'Vitalliumm'
|
|
||||||
]
|
|
||||||
|
|
||||||
follow = (user, callback) ->
|
|
||||||
page = require('webpage').create()
|
|
||||||
page.open 'http://mobile.twitter.com/' + user, (status) ->
|
|
||||||
if status is 'fail'
|
|
||||||
console.log user + ': ?'
|
|
||||||
else
|
|
||||||
data = page.evaluate -> document.querySelector('div.profile td.stat.stat-last div.statnum').innerText;
|
|
||||||
console.log user + ': ' + data
|
|
||||||
page.close()
|
|
||||||
callback.apply()
|
|
||||||
|
|
||||||
process = () ->
|
|
||||||
if (users.length > 0)
|
|
||||||
user = users[0]
|
|
||||||
users.splice(0, 1)
|
|
||||||
follow(user, process)
|
|
||||||
else
|
|
||||||
phantom.exit()
|
|
||||||
|
|
||||||
process()
|
|
|
@ -1,2 +0,0 @@
|
||||||
console.log 'Hello, world!'
|
|
||||||
phantom.exit()
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Upload an image to imagebin.org
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log 'Usage: imagebin.coffee filename'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
fname = system.args[1]
|
|
||||||
page.open 'http://imagebin.org/index.php?page=add', ->
|
|
||||||
page.uploadFile 'input[name=image]', fname
|
|
||||||
page.evaluate ->
|
|
||||||
document.querySelector('input[name=nickname]').value = 'phantom'
|
|
||||||
document.querySelector('input[name=disclaimer_agree]').click()
|
|
||||||
document.querySelector('form').submit()
|
|
||||||
|
|
||||||
window.setTimeout ->
|
|
||||||
phantom.exit()
|
|
||||||
, 3000
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Use 'page.injectJs()' to load the script itself in the Page context
|
|
||||||
|
|
||||||
if phantom?
|
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
# Route "console.log()" calls from within the Page context to the main
|
|
||||||
# Phantom context (i.e. current "this")
|
|
||||||
page.onConsoleMessage = (msg) -> console.log(msg)
|
|
||||||
|
|
||||||
page.onAlert = (msg) -> console.log(msg)
|
|
||||||
|
|
||||||
console.log "* Script running in the Phantom context."
|
|
||||||
console.log "* Script will 'inject' itself in a page..."
|
|
||||||
page.open "about:blank", (status) ->
|
|
||||||
if status is "success"
|
|
||||||
if page.injectJs("injectme.coffee")
|
|
||||||
console.log "... done injecting itself!"
|
|
||||||
else
|
|
||||||
console.log "... fail! Check the $PWD?!"
|
|
||||||
phantom.exit()
|
|
||||||
else
|
|
||||||
alert "* Script running in the Page context."
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Give the estimated location based on the IP address.
|
|
||||||
|
|
||||||
window.cb = (data) ->
|
|
||||||
loc = data.city
|
|
||||||
if data.region_name.length > 0
|
|
||||||
loc = loc + ', ' + data.region_name
|
|
||||||
console.log 'IP address: ' + data.ip
|
|
||||||
console.log 'Estimated location: ' + loc
|
|
||||||
phantom.exit()
|
|
||||||
|
|
||||||
el = document.createElement 'script'
|
|
||||||
el.src = 'http://freegeoip.net/json/?callback=window.cb'
|
|
||||||
document.body.appendChild el
|
|
|
@ -1,18 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log 'Usage: loadspeed.coffee <some URL>'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
t = Date.now()
|
|
||||||
address = system.args[1]
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log('FAIL to load the address')
|
|
||||||
else
|
|
||||||
t = Date.now() - t
|
|
||||||
console.log('Page title is ' + page.evaluate( (-> document.title) ))
|
|
||||||
console.log('Loading time ' + t + ' msec')
|
|
||||||
phantom.exit()
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
page = require("webpage").create()
|
|
||||||
system = require("system")
|
|
||||||
|
|
||||||
if system.args.length < 2
|
|
||||||
console.log "Usage: loadurlwithoutcss.js URL"
|
|
||||||
phantom.exit()
|
|
||||||
|
|
||||||
address = system.args[1]
|
|
||||||
|
|
||||||
page.onResourceRequested = (requestData, request) ->
|
|
||||||
if (/http:\/\/.+?\.css/g).test(requestData["url"]) or requestData.headers["Content-Type"] is "text/css"
|
|
||||||
console.log "The url of the request is matching. Aborting: " + requestData["url"]
|
|
||||||
request.abort()
|
|
||||||
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status is "success"
|
|
||||||
phantom.exit()
|
|
||||||
else
|
|
||||||
console.log "Unable to load the address!"
|
|
||||||
phantom.exit()
|
|
|
@ -1,4 +0,0 @@
|
||||||
universe = require './universe'
|
|
||||||
universe.start()
|
|
||||||
console.log 'The answer is' + universe.answer
|
|
||||||
phantom.exit()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# List movies from kids-in-mind.com
|
|
||||||
|
|
||||||
window.cbfunc = (data) ->
|
|
||||||
globaldata = data
|
|
||||||
list = data.query.results.movie
|
|
||||||
for item in list
|
|
||||||
console.log item.title + ' [' + item.rating.MPAA.content + ']'
|
|
||||||
phantom.exit()
|
|
||||||
|
|
||||||
el = document.createElement 'script'
|
|
||||||
el.src =
|
|
||||||
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=window.cbfunc"
|
|
||||||
document.body.appendChild el
|
|
|
@ -1,18 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log 'Usage: netlog.coffee <some URL>'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
address = system.args[1]
|
|
||||||
page.onResourceRequested = (req) ->
|
|
||||||
console.log 'requested ' + JSON.stringify(req, undefined, 4)
|
|
||||||
|
|
||||||
page.onResourceReceived = (res) ->
|
|
||||||
console.log 'received ' + JSON.stringify(res, undefined, 4)
|
|
||||||
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'FAIL to load the address'
|
|
||||||
phantom.exit()
|
|
|
@ -1,114 +0,0 @@
|
||||||
if not Date::toISOString
|
|
||||||
Date::toISOString = ->
|
|
||||||
pad = (n) ->
|
|
||||||
if n < 10 then '0' + n else n
|
|
||||||
ms = (n) ->
|
|
||||||
if n < 10 then '00' + n else (if n < 100 then '0' + n else n)
|
|
||||||
@getFullYear() + '-' +
|
|
||||||
pad(@getMonth() + 1) + '-' +
|
|
||||||
pad(@getDate()) + 'T' +
|
|
||||||
pad(@getHours()) + ':' +
|
|
||||||
pad(@getMinutes()) + ':' +
|
|
||||||
pad(@getSeconds()) + '.' +
|
|
||||||
ms(@getMilliseconds()) + 'Z'
|
|
||||||
|
|
||||||
createHAR = (address, title, startTime, resources) ->
|
|
||||||
entries = []
|
|
||||||
|
|
||||||
resources.forEach (resource) ->
|
|
||||||
request = resource.request
|
|
||||||
startReply = resource.startReply
|
|
||||||
endReply = resource.endReply
|
|
||||||
|
|
||||||
if not request or not startReply or not endReply
|
|
||||||
return
|
|
||||||
|
|
||||||
entries.push
|
|
||||||
startedDateTime: request.time.toISOString()
|
|
||||||
time: endReply.time - request.time
|
|
||||||
request:
|
|
||||||
method: request.method
|
|
||||||
url: request.url
|
|
||||||
httpVersion: 'HTTP/1.1'
|
|
||||||
cookies: []
|
|
||||||
headers: request.headers
|
|
||||||
queryString: []
|
|
||||||
headersSize: -1
|
|
||||||
bodySize: -1
|
|
||||||
|
|
||||||
response:
|
|
||||||
status: endReply.status
|
|
||||||
statusText: endReply.statusText
|
|
||||||
httpVersion: 'HTTP/1.1'
|
|
||||||
cookies: []
|
|
||||||
headers: endReply.headers
|
|
||||||
redirectURL: ''
|
|
||||||
headersSize: -1
|
|
||||||
bodySize: startReply.bodySize
|
|
||||||
content:
|
|
||||||
size: startReply.bodySize
|
|
||||||
mimeType: endReply.contentType
|
|
||||||
|
|
||||||
cache: {}
|
|
||||||
timings:
|
|
||||||
blocked: 0
|
|
||||||
dns: -1
|
|
||||||
connect: -1
|
|
||||||
send: 0
|
|
||||||
wait: startReply.time - request.time
|
|
||||||
receive: endReply.time - startReply.time
|
|
||||||
ssl: -1
|
|
||||||
pageref: address
|
|
||||||
|
|
||||||
log:
|
|
||||||
version: '1.2'
|
|
||||||
creator:
|
|
||||||
name: 'PhantomJS'
|
|
||||||
version: phantom.version.major + '.' + phantom.version.minor + '.' + phantom.version.patch
|
|
||||||
|
|
||||||
pages: [
|
|
||||||
startedDateTime: startTime.toISOString()
|
|
||||||
id: address
|
|
||||||
title: title
|
|
||||||
pageTimings:
|
|
||||||
onLoad: page.endTime - page.startTime
|
|
||||||
]
|
|
||||||
entries: entries
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log 'Usage: netsniff.coffee <some URL>'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
page.address = system.args[1]
|
|
||||||
page.resources = []
|
|
||||||
|
|
||||||
page.onLoadStarted = ->
|
|
||||||
page.startTime = new Date()
|
|
||||||
|
|
||||||
page.onResourceRequested = (req) ->
|
|
||||||
page.resources[req.id] =
|
|
||||||
request: req
|
|
||||||
startReply: null
|
|
||||||
endReply: null
|
|
||||||
|
|
||||||
page.onResourceReceived = (res) ->
|
|
||||||
if res.stage is 'start'
|
|
||||||
page.resources[res.id].startReply = res
|
|
||||||
if res.stage is 'end'
|
|
||||||
page.resources[res.id].endReply = res
|
|
||||||
|
|
||||||
page.open page.address, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'FAIL to load the address'
|
|
||||||
phantom.exit(1)
|
|
||||||
else
|
|
||||||
page.endTime = new Date()
|
|
||||||
page.title = page.evaluate ->
|
|
||||||
document.title
|
|
||||||
|
|
||||||
har = createHAR page.address, page.title, page.startTime, page.resources
|
|
||||||
console.log JSON.stringify har, undefined, 4
|
|
||||||
phantom.exit()
|
|
|
@ -1,22 +0,0 @@
|
||||||
page = require("webpage").create()
|
|
||||||
system = require("system")
|
|
||||||
host = undefined
|
|
||||||
port = undefined
|
|
||||||
address = undefined
|
|
||||||
if system.args.length < 4
|
|
||||||
console.log "Usage: openurlwithproxy.js <proxyHost> <proxyPort> <URL>"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
host = system.args[1]
|
|
||||||
port = system.args[2]
|
|
||||||
address = system.args[3]
|
|
||||||
phantom.setProxy host, port, "manual", "", ""
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "FAIL to load the address \"" + address + "\" using proxy \"" + host + ":" + port + "\""
|
|
||||||
else
|
|
||||||
console.log "Page title is " + page.evaluate(->
|
|
||||||
document.title
|
|
||||||
)
|
|
||||||
phantom.exit()
|
|
||||||
return
|
|
|
@ -1,12 +0,0 @@
|
||||||
helloWorld = () -> console.log phantom.outputEncoding + ": こんにちは、世界!"
|
|
||||||
|
|
||||||
console.log "Using default encoding..."
|
|
||||||
helloWorld()
|
|
||||||
|
|
||||||
console.log "\nUsing other encodings..."
|
|
||||||
for enc in ["euc-jp", "sjis", "utf8", "System"]
|
|
||||||
do (enc) ->
|
|
||||||
phantom.outputEncoding = enc
|
|
||||||
helloWorld()
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -1,136 +0,0 @@
|
||||||
# The purpose of this is to show how and when events fire, considering 5 steps
|
|
||||||
# happening as follows:
|
|
||||||
#
|
|
||||||
# 1. Load URL
|
|
||||||
# 2. Load same URL, but adding an internal FRAGMENT to it
|
|
||||||
# 3. Click on an internal Link, that points to another internal FRAGMENT
|
|
||||||
# 4. Click on an external Link, that will send the page somewhere else
|
|
||||||
# 5. Close page
|
|
||||||
#
|
|
||||||
# Take particular care when going through the output, to understand when
|
|
||||||
# things happen (and in which order). Particularly, notice what DOESN'T
|
|
||||||
# happen during step 3.
|
|
||||||
#
|
|
||||||
# If invoked with "-v" it will print out the Page Resources as they are
|
|
||||||
# Requested and Received.
|
|
||||||
#
|
|
||||||
# NOTE.1: The "onConsoleMessage/onAlert/onPrompt/onConfirm" events are
|
|
||||||
# registered but not used here. This is left for you to have fun with.
|
|
||||||
# NOTE.2: This script is not here to teach you ANY JavaScript. It's aweful!
|
|
||||||
# NOTE.3: Main audience for this are people new to PhantomJS.
|
|
||||||
printArgs = ->
|
|
||||||
i = undefined
|
|
||||||
ilen = undefined
|
|
||||||
i = 0
|
|
||||||
ilen = arguments_.length
|
|
||||||
|
|
||||||
while i < ilen
|
|
||||||
console.log " arguments[" + i + "] = " + JSON.stringify(arguments_[i])
|
|
||||||
++i
|
|
||||||
console.log ""
|
|
||||||
sys = require("system")
|
|
||||||
page = require("webpage").create()
|
|
||||||
logResources = false
|
|
||||||
step1url = "http://en.wikipedia.org/wiki/DOM_events"
|
|
||||||
step2url = "http://en.wikipedia.org/wiki/DOM_events#Event_flow"
|
|
||||||
logResources = true if sys.args.length > 1 and sys.args[1] is "-v"
|
|
||||||
|
|
||||||
#//////////////////////////////////////////////////////////////////////////////
|
|
||||||
page.onInitialized = ->
|
|
||||||
console.log "page.onInitialized"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onLoadStarted = ->
|
|
||||||
console.log "page.onLoadStarted"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onLoadFinished = ->
|
|
||||||
console.log "page.onLoadFinished"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onUrlChanged = ->
|
|
||||||
console.log "page.onUrlChanged"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onNavigationRequested = ->
|
|
||||||
console.log "page.onNavigationRequested"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onRepaintRequested = ->
|
|
||||||
console.log "page.onRepaintRequested"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
if logResources is true
|
|
||||||
page.onResourceRequested = ->
|
|
||||||
console.log "page.onResourceRequested"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
page.onResourceReceived = ->
|
|
||||||
console.log "page.onResourceReceived"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
page.onClosing = ->
|
|
||||||
console.log "page.onClosing"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
|
|
||||||
# window.console.log(msg);
|
|
||||||
page.onConsoleMessage = ->
|
|
||||||
console.log "page.onConsoleMessage"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
|
|
||||||
# window.alert(msg);
|
|
||||||
page.onAlert = ->
|
|
||||||
console.log "page.onAlert"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
|
|
||||||
# var confirmed = window.confirm(msg);
|
|
||||||
page.onConfirm = ->
|
|
||||||
console.log "page.onConfirm"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
|
|
||||||
# var user_value = window.prompt(msg, default_value);
|
|
||||||
page.onPrompt = ->
|
|
||||||
console.log "page.onPrompt"
|
|
||||||
printArgs.apply this, arguments_
|
|
||||||
|
|
||||||
|
|
||||||
#//////////////////////////////////////////////////////////////////////////////
|
|
||||||
setTimeout (->
|
|
||||||
console.log ""
|
|
||||||
console.log "### STEP 1: Load '" + step1url + "'"
|
|
||||||
page.open step1url
|
|
||||||
), 0
|
|
||||||
setTimeout (->
|
|
||||||
console.log ""
|
|
||||||
console.log "### STEP 2: Load '" + step2url + "' (load same URL plus FRAGMENT)"
|
|
||||||
page.open step2url
|
|
||||||
), 5000
|
|
||||||
setTimeout (->
|
|
||||||
console.log ""
|
|
||||||
console.log "### STEP 3: Click on page internal link (aka FRAGMENT)"
|
|
||||||
page.evaluate ->
|
|
||||||
ev = document.createEvent("MouseEvents")
|
|
||||||
ev.initEvent "click", true, true
|
|
||||||
document.querySelector("a[href='#Event_object']").dispatchEvent ev
|
|
||||||
|
|
||||||
), 10000
|
|
||||||
setTimeout (->
|
|
||||||
console.log ""
|
|
||||||
console.log "### STEP 4: Click on page external link"
|
|
||||||
page.evaluate ->
|
|
||||||
ev = document.createEvent("MouseEvents")
|
|
||||||
ev.initEvent "click", true, true
|
|
||||||
document.querySelector("a[title='JavaScript']").dispatchEvent ev
|
|
||||||
|
|
||||||
), 15000
|
|
||||||
setTimeout (->
|
|
||||||
console.log ""
|
|
||||||
console.log "### STEP 5: Close page and shutdown (with a delay)"
|
|
||||||
page.close()
|
|
||||||
setTimeout (->
|
|
||||||
phantom.exit()
|
|
||||||
), 100
|
|
||||||
), 20000
|
|
|
@ -1,16 +0,0 @@
|
||||||
p = require("webpage").create()
|
|
||||||
|
|
||||||
p.onConsoleMessage = (msg) ->
|
|
||||||
console.log msg
|
|
||||||
|
|
||||||
# Calls to "callPhantom" within the page 'p' arrive here
|
|
||||||
p.onCallback = (msg) ->
|
|
||||||
console.log "Received by the 'phantom' main context: " + msg
|
|
||||||
"Hello there, I'm coming to you from the 'phantom' context instead"
|
|
||||||
|
|
||||||
p.evaluate ->
|
|
||||||
# Return-value of the "onCallback" handler arrive here
|
|
||||||
callbackResponse = window.callPhantom "Hello, I'm coming to you from the 'page' context"
|
|
||||||
console.log "Received by the 'page' context: " + callbackResponse
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Read the Phantom webpage '#intro' element text using jQuery and "includeJs"
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
page.onConsoleMessage = (msg) -> console.log msg
|
|
||||||
|
|
||||||
page.open "http://www.phantomjs.org", (status) ->
|
|
||||||
if status is "success"
|
|
||||||
page.includeJs "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", ->
|
|
||||||
page.evaluate ->
|
|
||||||
console.log "$(\"#intro\").text() -> " + $("#intro").text()
|
|
||||||
phantom.exit()
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Find pizza in Mountain View using Yelp
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
url = 'http://lite.yelp.com/search?find_desc=pizza&find_loc=94040&find_submit=Search'
|
|
||||||
|
|
||||||
page.open url,
|
|
||||||
(status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
else
|
|
||||||
results = page.evaluate ->
|
|
||||||
pizza = []
|
|
||||||
list = document.querySelectorAll 'address'
|
|
||||||
for item in list
|
|
||||||
pizza.push(item.innerText)
|
|
||||||
return pizza
|
|
||||||
console.log results.join('\n')
|
|
||||||
phantom.exit()
|
|
|
@ -1,12 +0,0 @@
|
||||||
# Example using HTTP POST operation
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
server = 'http://posttestserver.com/post.php?dump'
|
|
||||||
data = 'universe=expanding&answer=42'
|
|
||||||
|
|
||||||
page.open server, 'post', data, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to post!'
|
|
||||||
else
|
|
||||||
console.log page.content
|
|
||||||
phantom.exit()
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Example using HTTP POST operation
|
|
||||||
|
|
||||||
page = require("webpage").create()
|
|
||||||
server = "http://posttestserver.com/post.php?dump"
|
|
||||||
data = "{\"universe\": \"expanding\", \"answer\": 42}"
|
|
||||||
headers = "Content-Type": "application/json"
|
|
||||||
|
|
||||||
page.open server, "post", data, headers, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "Unable to post!"
|
|
||||||
else
|
|
||||||
console.log page.content
|
|
||||||
phantom.exit()
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Example using HTTP POST operation
|
|
||||||
page = require("webpage").create()
|
|
||||||
server = require("webserver").create()
|
|
||||||
system = require("system")
|
|
||||||
data = "universe=expanding&answer=42"
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log "Usage: postserver.js <portnumber>"
|
|
||||||
phantom.exit 1
|
|
||||||
port = system.args[1]
|
|
||||||
service = server.listen(port, (request, response) ->
|
|
||||||
console.log "Request received at " + new Date()
|
|
||||||
response.statusCode = 200
|
|
||||||
response.headers =
|
|
||||||
Cache: "no-cache"
|
|
||||||
"Content-Type": "text/plain;charset=utf-8"
|
|
||||||
|
|
||||||
response.write JSON.stringify(request, null, 4)
|
|
||||||
response.close()
|
|
||||||
)
|
|
||||||
page.open "http://localhost:" + port + "/", "post", data, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "Unable to post!"
|
|
||||||
else
|
|
||||||
console.log page.plainText
|
|
||||||
phantom.exit()
|
|
|
@ -1,6 +0,0 @@
|
||||||
system = require("system")
|
|
||||||
env = system.env
|
|
||||||
key = undefined
|
|
||||||
for key of env
|
|
||||||
console.log key + "=" + env[key] if env.hasOwnProperty(key)
|
|
||||||
phantom.exit()
|
|
|
@ -1,88 +0,0 @@
|
||||||
someCallback = (pageNum, numPages) ->
|
|
||||||
"<h1> someCallback: " + pageNum + " / " + numPages + "</h1>"
|
|
||||||
page = require("webpage").create()
|
|
||||||
system = require("system")
|
|
||||||
if system.args.length < 3
|
|
||||||
console.log "Usage: printheaderfooter.js URL filename"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
address = system.args[1]
|
|
||||||
output = system.args[2]
|
|
||||||
page.viewportSize =
|
|
||||||
width: 600
|
|
||||||
height: 600
|
|
||||||
|
|
||||||
page.paperSize =
|
|
||||||
format: "A4"
|
|
||||||
margin: "1cm"
|
|
||||||
|
|
||||||
# default header/footer for pages that don't have custom overwrites (see below)
|
|
||||||
header:
|
|
||||||
height: "1cm"
|
|
||||||
contents: phantom.callback((pageNum, numPages) ->
|
|
||||||
return "" if pageNum is 1
|
|
||||||
"<h1>Header <span style='float:right'>" + pageNum + " / " + numPages + "</span></h1>"
|
|
||||||
)
|
|
||||||
|
|
||||||
footer:
|
|
||||||
height: "1cm"
|
|
||||||
contents: phantom.callback((pageNum, numPages) ->
|
|
||||||
return "" if pageNum is numPages
|
|
||||||
"<h1>Footer <span style='float:right'>" + pageNum + " / " + numPages + "</span></h1>"
|
|
||||||
)
|
|
||||||
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "Unable to load the address!"
|
|
||||||
else
|
|
||||||
|
|
||||||
# check whether the loaded page overwrites the header/footer setting,
|
|
||||||
# i.e. whether a PhantomJSPriting object exists. Use that then instead
|
|
||||||
# of our defaults above.
|
|
||||||
#
|
|
||||||
# example:
|
|
||||||
# <html>
|
|
||||||
# <head>
|
|
||||||
# <script type="text/javascript">
|
|
||||||
# var PhantomJSPrinting = {
|
|
||||||
# header: {
|
|
||||||
# height: "1cm",
|
|
||||||
# contents: function(pageNum, numPages) { return pageNum + "/" + numPages; }
|
|
||||||
# },
|
|
||||||
# footer: {
|
|
||||||
# height: "1cm",
|
|
||||||
# contents: function(pageNum, numPages) { return pageNum + "/" + numPages; }
|
|
||||||
# }
|
|
||||||
# };
|
|
||||||
# </script>
|
|
||||||
# </head>
|
|
||||||
# <body><h1>asdfadsf</h1><p>asdfadsfycvx</p></body>
|
|
||||||
# </html>
|
|
||||||
#
|
|
||||||
if page.evaluate(->
|
|
||||||
typeof PhantomJSPrinting is "object"
|
|
||||||
)
|
|
||||||
paperSize = page.paperSize
|
|
||||||
paperSize.header.height = page.evaluate(->
|
|
||||||
PhantomJSPrinting.header.height
|
|
||||||
)
|
|
||||||
paperSize.header.contents = phantom.callback((pageNum, numPages) ->
|
|
||||||
page.evaluate ((pageNum, numPages) ->
|
|
||||||
PhantomJSPrinting.header.contents pageNum, numPages
|
|
||||||
), pageNum, numPages
|
|
||||||
)
|
|
||||||
paperSize.footer.height = page.evaluate(->
|
|
||||||
PhantomJSPrinting.footer.height
|
|
||||||
)
|
|
||||||
paperSize.footer.contents = phantom.callback((pageNum, numPages) ->
|
|
||||||
page.evaluate ((pageNum, numPages) ->
|
|
||||||
PhantomJSPrinting.footer.contents pageNum, numPages
|
|
||||||
), pageNum, numPages
|
|
||||||
)
|
|
||||||
page.paperSize = paperSize
|
|
||||||
console.log page.paperSize.header.height
|
|
||||||
console.log page.paperSize.footer.height
|
|
||||||
window.setTimeout (->
|
|
||||||
page.render output
|
|
||||||
phantom.exit()
|
|
||||||
), 200
|
|
|
@ -1,33 +0,0 @@
|
||||||
page = require("webpage").create()
|
|
||||||
system = require("system")
|
|
||||||
if system.args.length < 7
|
|
||||||
console.log "Usage: printmargins.js URL filename LEFT TOP RIGHT BOTTOM"
|
|
||||||
console.log " margin examples: \"1cm\", \"10px\", \"7mm\", \"5in\""
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
address = system.args[1]
|
|
||||||
output = system.args[2]
|
|
||||||
marginLeft = system.args[3]
|
|
||||||
marginTop = system.args[4]
|
|
||||||
marginRight = system.args[5]
|
|
||||||
marginBottom = system.args[6]
|
|
||||||
page.viewportSize =
|
|
||||||
width: 600
|
|
||||||
height: 600
|
|
||||||
|
|
||||||
page.paperSize =
|
|
||||||
format: "A4"
|
|
||||||
margin:
|
|
||||||
left: marginLeft
|
|
||||||
top: marginTop
|
|
||||||
right: marginRight
|
|
||||||
bottom: marginBottom
|
|
||||||
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "Unable to load the address!"
|
|
||||||
else
|
|
||||||
window.setTimeout (->
|
|
||||||
page.render output
|
|
||||||
phantom.exit()
|
|
||||||
), 200
|
|
|
@ -1,23 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length < 3 or system.args.length > 4
|
|
||||||
console.log 'Usage: rasterize.coffee URL filename [paperwidth*paperheight|paperformat]'
|
|
||||||
console.log ' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
address = system.args[1]
|
|
||||||
output = system.args[2]
|
|
||||||
page.viewportSize = { width: 600, height: 600 }
|
|
||||||
if system.args.length is 4 and system.args[2].substr(-4) is ".pdf"
|
|
||||||
size = system.args[3].split '*'
|
|
||||||
if size.length is 2
|
|
||||||
page.paperSize = { width: size[0], height: size[1], border: '0px' }
|
|
||||||
else
|
|
||||||
page.paperSize = { format: system.args[3], orientation: 'portrait', border: '1cm' }
|
|
||||||
page.open address, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to load the address!'
|
|
||||||
phantom.exit()
|
|
||||||
else
|
|
||||||
window.setTimeout (-> page.render output; phantom.exit()), 200
|
|
|
@ -1,60 +0,0 @@
|
||||||
# Render Multiple URLs to file
|
|
||||||
|
|
||||||
system = require("system")
|
|
||||||
|
|
||||||
# Render given urls
|
|
||||||
# @param array of URLs to render
|
|
||||||
# @param callbackPerUrl Function called after finishing each URL, including the last URL
|
|
||||||
# @param callbackFinal Function called after finishing everything
|
|
||||||
RenderUrlsToFile = (urls, callbackPerUrl, callbackFinal) ->
|
|
||||||
urlIndex = 0 # only for easy file naming
|
|
||||||
webpage = require("webpage")
|
|
||||||
page = null
|
|
||||||
getFilename = ->
|
|
||||||
"rendermulti-" + urlIndex + ".png"
|
|
||||||
|
|
||||||
next = (status, url, file) ->
|
|
||||||
page.close()
|
|
||||||
callbackPerUrl status, url, file
|
|
||||||
retrieve()
|
|
||||||
|
|
||||||
retrieve = ->
|
|
||||||
if urls.length > 0
|
|
||||||
url = urls.shift()
|
|
||||||
urlIndex++
|
|
||||||
page = webpage.create()
|
|
||||||
page.viewportSize =
|
|
||||||
width: 800
|
|
||||||
height: 600
|
|
||||||
|
|
||||||
page.settings.userAgent = "Phantom.js bot"
|
|
||||||
page.open "http://" + url, (status) ->
|
|
||||||
file = getFilename()
|
|
||||||
if status is "success"
|
|
||||||
window.setTimeout (->
|
|
||||||
page.render file
|
|
||||||
next status, url, file
|
|
||||||
), 200
|
|
||||||
else
|
|
||||||
next status, url, file
|
|
||||||
|
|
||||||
else
|
|
||||||
callbackFinal()
|
|
||||||
|
|
||||||
retrieve()
|
|
||||||
arrayOfUrls = null
|
|
||||||
if system.args.length > 1
|
|
||||||
arrayOfUrls = Array::slice.call(system.args, 1)
|
|
||||||
else
|
|
||||||
# Default (no args passed)
|
|
||||||
console.log "Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]"
|
|
||||||
arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "www.phantomjs.org"]
|
|
||||||
|
|
||||||
RenderUrlsToFile arrayOfUrls, ((status, url, file) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "Unable to render '" + url + "'"
|
|
||||||
else
|
|
||||||
console.log "Rendered '" + url + "' at '" + file + "'"
|
|
||||||
), ->
|
|
||||||
phantom.exit()
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
##
|
|
||||||
# Wait until the test condition is true or a timeout occurs. Useful for waiting
|
|
||||||
# on a server response or for a ui change (fadeIn, etc.) to occur.
|
|
||||||
#
|
|
||||||
# @param testFx javascript condition that evaluates to a boolean,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param onReady what to do when testFx condition is fulfilled,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
|
|
||||||
##
|
|
||||||
waitFor = (testFx, onReady, timeOutMillis=3000) ->
|
|
||||||
start = new Date().getTime()
|
|
||||||
condition = false
|
|
||||||
f = ->
|
|
||||||
if (new Date().getTime() - start < timeOutMillis) and not condition
|
|
||||||
# If not time-out yet and condition not yet fulfilled
|
|
||||||
condition = (if typeof testFx is 'string' then eval testFx else testFx()) #< defensive code
|
|
||||||
else
|
|
||||||
if not condition
|
|
||||||
# If condition still not fulfilled (timeout but condition is 'false')
|
|
||||||
console.log "'waitFor()' timeout"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
# Condition fulfilled (timeout and/or condition is 'true')
|
|
||||||
console.log "'waitFor()' finished in #{new Date().getTime() - start}ms."
|
|
||||||
if typeof onReady is 'string' then eval onReady else onReady() #< Do what it's supposed to do once the condition is fulfilled
|
|
||||||
clearInterval interval #< Stop this interval
|
|
||||||
interval = setInterval f, 100 #< repeat check every 100ms
|
|
||||||
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log 'Usage: run-jasmine.coffee URL'
|
|
||||||
phantom.exit 1
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
|
|
||||||
page.onConsoleMessage = (msg) ->
|
|
||||||
console.log msg
|
|
||||||
|
|
||||||
page.open system.args[1], (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
phantom.exit()
|
|
||||||
else
|
|
||||||
waitFor ->
|
|
||||||
page.evaluate ->
|
|
||||||
if document.body.querySelector '.finished-at'
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
, ->
|
|
||||||
page.evaluate ->
|
|
||||||
console.log document.body.querySelector('.description').innerText
|
|
||||||
list = document.body.querySelectorAll('.failed > .description, .failed > .messages > .resultMessage')
|
|
||||||
for el in list
|
|
||||||
console.log el.innerText
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -1,64 +0,0 @@
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
##
|
|
||||||
# Wait until the test condition is true or a timeout occurs. Useful for waiting
|
|
||||||
# on a server response or for a ui change (fadeIn, etc.) to occur.
|
|
||||||
#
|
|
||||||
# @param testFx javascript condition that evaluates to a boolean,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param onReady what to do when testFx condition is fulfilled,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
|
|
||||||
##
|
|
||||||
waitFor = (testFx, onReady, timeOutMillis=3000) ->
|
|
||||||
start = new Date().getTime()
|
|
||||||
condition = false
|
|
||||||
f = ->
|
|
||||||
if (new Date().getTime() - start < timeOutMillis) and not condition
|
|
||||||
# If not time-out yet and condition not yet fulfilled
|
|
||||||
condition = (if typeof testFx is 'string' then eval testFx else testFx()) #< defensive code
|
|
||||||
else
|
|
||||||
if not condition
|
|
||||||
# If condition still not fulfilled (timeout but condition is 'false')
|
|
||||||
console.log "'waitFor()' timeout"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
# Condition fulfilled (timeout and/or condition is 'true')
|
|
||||||
console.log "'waitFor()' finished in #{new Date().getTime() - start}ms."
|
|
||||||
if typeof onReady is 'string' then eval onReady else onReady() #< Do what it's supposed to do once the condition is fulfilled
|
|
||||||
clearInterval interval #< Stop this interval
|
|
||||||
interval = setInterval f, 100 #< repeat check every 100ms
|
|
||||||
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log 'Usage: run-qunit.coffee URL'
|
|
||||||
phantom.exit 1
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
|
|
||||||
page.onConsoleMessage = (msg) ->
|
|
||||||
console.log msg
|
|
||||||
|
|
||||||
page.open system.args[1], (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
waitFor ->
|
|
||||||
page.evaluate ->
|
|
||||||
el = document.getElementById 'qunit-testresult'
|
|
||||||
if el and el.innerText.match 'completed'
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
, ->
|
|
||||||
failedNum = page.evaluate ->
|
|
||||||
el = document.getElementById 'qunit-testresult'
|
|
||||||
console.log el.innerText
|
|
||||||
try
|
|
||||||
return el.getElementsByClassName('failed')[0].innerHTML
|
|
||||||
catch e
|
|
||||||
return 10000
|
|
||||||
|
|
||||||
phantom.exit if parseInt(failedNum, 10) > 0 then 1 else 0
|
|
|
@ -1,16 +0,0 @@
|
||||||
# List all the files in a Tree of Directories
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length != 2
|
|
||||||
console.log "Usage: phantomjs scandir.coffee DIRECTORY_TO_SCAN"
|
|
||||||
phantom.exit 1
|
|
||||||
scanDirectory = (path) ->
|
|
||||||
fs = require 'fs'
|
|
||||||
if fs.exists(path) and fs.isFile(path)
|
|
||||||
console.log path
|
|
||||||
else if fs.isDirectory(path)
|
|
||||||
fs.list(path).forEach (e) ->
|
|
||||||
scanDirectory path + "/" + e if e != "." and e != ".."
|
|
||||||
|
|
||||||
scanDirectory system.args[1]
|
|
||||||
phantom.exit()
|
|
|
@ -1,17 +0,0 @@
|
||||||
# Show BBC seasonal food list.
|
|
||||||
|
|
||||||
window.cbfunc = (data) ->
|
|
||||||
list = data.query.results.results.result
|
|
||||||
names = ['January', 'February', 'March',
|
|
||||||
'April', 'May', 'June',
|
|
||||||
'July', 'August', 'September',
|
|
||||||
'October', 'November', 'December']
|
|
||||||
for item in list
|
|
||||||
console.log [item.name.replace(/\s/ig, ' '), ':',
|
|
||||||
names[item.atItsBestUntil], 'to',
|
|
||||||
names[item.atItsBestFrom]].join(' ')
|
|
||||||
phantom.exit()
|
|
||||||
|
|
||||||
el = document.createElement 'script'
|
|
||||||
el.src = 'http://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20bbc.goodfood.seasonal%3B&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=window.cbfunc'
|
|
||||||
document.body.appendChild el
|
|
|
@ -1,45 +0,0 @@
|
||||||
page = require("webpage").create()
|
|
||||||
server = require("webserver").create()
|
|
||||||
system = require("system")
|
|
||||||
host = undefined
|
|
||||||
port = undefined
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log "Usage: server.js <some port>"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
port = system.args[1]
|
|
||||||
listening = server.listen(port, (request, response) ->
|
|
||||||
console.log "GOT HTTP REQUEST"
|
|
||||||
console.log JSON.stringify(request, null, 4)
|
|
||||||
|
|
||||||
# we set the headers here
|
|
||||||
response.statusCode = 200
|
|
||||||
response.headers =
|
|
||||||
Cache: "no-cache"
|
|
||||||
"Content-Type": "text/html"
|
|
||||||
|
|
||||||
|
|
||||||
# this is also possible:
|
|
||||||
response.setHeader "foo", "bar"
|
|
||||||
|
|
||||||
# now we write the body
|
|
||||||
# note: the headers above will now be sent implictly
|
|
||||||
response.write "<html><head><title>YES!</title></head>"
|
|
||||||
|
|
||||||
# note: writeBody can be called multiple times
|
|
||||||
response.write "<body><p>pretty cool :)</body></html>"
|
|
||||||
response.close()
|
|
||||||
)
|
|
||||||
unless listening
|
|
||||||
console.log "could not create web server listening on port " + port
|
|
||||||
phantom.exit()
|
|
||||||
url = "http://localhost:" + port + "/foo/bar.php?asdf=true"
|
|
||||||
console.log "SENDING REQUEST TO:"
|
|
||||||
console.log url
|
|
||||||
page.open url, (status) ->
|
|
||||||
if status isnt "success"
|
|
||||||
console.log "FAIL to load the address"
|
|
||||||
else
|
|
||||||
console.log "GOT REPLY FROM SERVER:"
|
|
||||||
console.log page.content
|
|
||||||
phantom.exit()
|
|
|
@ -1,32 +0,0 @@
|
||||||
port = undefined
|
|
||||||
server = undefined
|
|
||||||
service = undefined
|
|
||||||
system = require("system")
|
|
||||||
if system.args.length isnt 2
|
|
||||||
console.log "Usage: serverkeepalive.js <portnumber>"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
port = system.args[1]
|
|
||||||
server = require("webserver").create()
|
|
||||||
service = server.listen(port,
|
|
||||||
keepAlive: true
|
|
||||||
, (request, response) ->
|
|
||||||
console.log "Request at " + new Date()
|
|
||||||
console.log JSON.stringify(request, null, 4)
|
|
||||||
body = JSON.stringify(request, null, 4)
|
|
||||||
response.statusCode = 200
|
|
||||||
response.headers =
|
|
||||||
Cache: "no-cache"
|
|
||||||
"Content-Type": "text/plain"
|
|
||||||
Connection: "Keep-Alive"
|
|
||||||
"Keep-Alive": "timeout=5, max=100"
|
|
||||||
"Content-Length": body.length
|
|
||||||
|
|
||||||
response.write body
|
|
||||||
response.close()
|
|
||||||
)
|
|
||||||
if service
|
|
||||||
console.log "Web server running on port " + port
|
|
||||||
else
|
|
||||||
console.log "Error: Could not create web server listening on port " + port
|
|
||||||
phantom.exit()
|
|
|
@ -1,38 +0,0 @@
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length is 1
|
|
||||||
console.log "Usage: simpleserver.coffee <portnumber>"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
port = system.args[1]
|
|
||||||
server = require("webserver").create()
|
|
||||||
|
|
||||||
service = server.listen(port, (request, response) ->
|
|
||||||
|
|
||||||
console.log "Request at " + new Date()
|
|
||||||
console.log JSON.stringify(request, null, 4)
|
|
||||||
|
|
||||||
response.statusCode = 200
|
|
||||||
response.headers =
|
|
||||||
Cache: "no-cache"
|
|
||||||
"Content-Type": "text/html"
|
|
||||||
|
|
||||||
response.write "<html>"
|
|
||||||
response.write "<head>"
|
|
||||||
response.write "<title>Hello, world!</title>"
|
|
||||||
response.write "</head>"
|
|
||||||
response.write "<body>"
|
|
||||||
response.write "<p>This is from PhantomJS web server.</p>"
|
|
||||||
response.write "<p>Request data:</p>"
|
|
||||||
response.write "<pre>"
|
|
||||||
response.write JSON.stringify(request, null, 4)
|
|
||||||
response.write "</pre>"
|
|
||||||
response.write "</body>"
|
|
||||||
response.write "</html>"
|
|
||||||
response.close()
|
|
||||||
)
|
|
||||||
if service
|
|
||||||
console.log "Web server running on port " + port
|
|
||||||
else
|
|
||||||
console.log "Error: Could not create web server listening on port " + port
|
|
||||||
phantom.exit()
|
|
|
@ -1,20 +0,0 @@
|
||||||
###
|
|
||||||
Sort integers from the command line in a very ridiculous way: leveraging timeouts :P
|
|
||||||
###
|
|
||||||
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
if system.args.length < 2
|
|
||||||
console.log "Usage: phantomjs sleepsort.coffee PUT YOUR INTEGERS HERE SEPARATED BY SPACES"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
sortedCount = 0
|
|
||||||
args = Array.prototype.slice.call(system.args, 1)
|
|
||||||
for int in args
|
|
||||||
setTimeout (do (int) ->
|
|
||||||
->
|
|
||||||
console.log int
|
|
||||||
++sortedCount
|
|
||||||
phantom.exit() if sortedCount is args.length),
|
|
||||||
int
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
system.stdout.write 'Hello, system.stdout.write!'
|
|
||||||
system.stdout.writeLine '\nHello, system.stdout.writeLine!'
|
|
||||||
|
|
||||||
system.stderr.write 'Hello, system.stderr.write!'
|
|
||||||
system.stderr.writeLine '\nHello, system.stderr.writeLine!'
|
|
||||||
|
|
||||||
system.stdout.writeLine 'system.stdin.readLine(): '
|
|
||||||
line = system.stdin.readLine()
|
|
||||||
system.stdout.writeLine JSON.stringify line
|
|
||||||
|
|
||||||
# This is essentially a `readAll`
|
|
||||||
system.stdout.writeLine 'system.stdin.read(5): (ctrl+D to end)'
|
|
||||||
input = system.stdin.read 5
|
|
||||||
system.stdout.writeLine JSON.stringify input
|
|
||||||
|
|
||||||
phantom.exit 0
|
|
|
@ -1,17 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
page.viewportSize = { width: 320, height: 480 }
|
|
||||||
|
|
||||||
page.open 'http://news.google.com/news/i/section?&topic=t',
|
|
||||||
(status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access the network!'
|
|
||||||
else
|
|
||||||
page.evaluate ->
|
|
||||||
body = document.body
|
|
||||||
body.style.backgroundColor = '#fff'
|
|
||||||
body.querySelector('div#title-block').style.display = 'none'
|
|
||||||
body.querySelector('form#edition-picker-form')
|
|
||||||
.parentElement.parentElement.style.display = 'none'
|
|
||||||
page.render 'technews.png'
|
|
||||||
phantom.exit()
|
|
|
@ -1,31 +0,0 @@
|
||||||
# Get twitter status for given account (or for the default one, "PhantomJS")
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
twitterId = 'PhantomJS' #< default value
|
|
||||||
|
|
||||||
# Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
|
|
||||||
page.onConsoleMessage = (msg) ->
|
|
||||||
console.log msg
|
|
||||||
|
|
||||||
# Print usage message, if no twitter ID is passed
|
|
||||||
if system.args.length < 2
|
|
||||||
console.log 'Usage: tweets.coffee [twitter ID]'
|
|
||||||
else
|
|
||||||
twitterId = system.args[1]
|
|
||||||
|
|
||||||
# Heading
|
|
||||||
console.log "*** Latest tweets from @#{twitterId} ***\n"
|
|
||||||
|
|
||||||
# Open Twitter Mobile and, onPageLoad, do...
|
|
||||||
page.open encodeURI("http://mobile.twitter.com/#{twitterId}"), (status) ->
|
|
||||||
# Check for page load success
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
else
|
|
||||||
# Execute some DOM inspection within the page context
|
|
||||||
page.evaluate ->
|
|
||||||
list = document.querySelectorAll 'div.tweet-text'
|
|
||||||
for i, j in list
|
|
||||||
console.log "#{j + 1}: #{i.innerText}"
|
|
||||||
phantom.exit()
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Modify global object at the page initialization.
|
|
||||||
# In this example, effectively Math.random() always returns 0.42.
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
page.onInitialized = ->
|
|
||||||
page.evaluate ->
|
|
||||||
Math.random = ->
|
|
||||||
42 / 100
|
|
||||||
|
|
||||||
page.open "http://ariya.github.com/js/random/", (status) ->
|
|
||||||
if status != "success"
|
|
||||||
console.log "Network error."
|
|
||||||
else
|
|
||||||
console.log page.evaluate(->
|
|
||||||
document.getElementById("numbers").textContent
|
|
||||||
)
|
|
||||||
phantom.exit()
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
console.log 'The default user agent is ' + page.settings.userAgent
|
|
||||||
|
|
||||||
page.settings.userAgent = 'SpecialAgent'
|
|
||||||
page.open 'http://www.httpuseragent.org', (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
else
|
|
||||||
console.log page.evaluate -> document.getElementById('myagent').innerText
|
|
||||||
phantom.exit()
|
|
|
@ -1,5 +0,0 @@
|
||||||
console.log 'using PhantomJS version ' +
|
|
||||||
phantom.version.major + '.' +
|
|
||||||
phantom.version.minor + '.' +
|
|
||||||
phantom.version.patch
|
|
||||||
phantom.exit()
|
|
|
@ -1,48 +0,0 @@
|
||||||
##
|
|
||||||
# Wait until the test condition is true or a timeout occurs. Useful for waiting
|
|
||||||
# on a server response or for a ui change (fadeIn, etc.) to occur.
|
|
||||||
#
|
|
||||||
# @param testFx javascript condition that evaluates to a boolean,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param onReady what to do when testFx condition is fulfilled,
|
|
||||||
# it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
|
||||||
# as a callback function.
|
|
||||||
# @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
|
|
||||||
##
|
|
||||||
waitFor = (testFx, onReady, timeOutMillis=3000) ->
|
|
||||||
start = new Date().getTime()
|
|
||||||
condition = false
|
|
||||||
f = ->
|
|
||||||
if (new Date().getTime() - start < timeOutMillis) and not condition
|
|
||||||
# If not time-out yet and condition not yet fulfilled
|
|
||||||
condition = (if typeof testFx is 'string' then eval testFx else testFx()) #< defensive code
|
|
||||||
else
|
|
||||||
if not condition
|
|
||||||
# If condition still not fulfilled (timeout but condition is 'false')
|
|
||||||
console.log "'waitFor()' timeout"
|
|
||||||
phantom.exit 1
|
|
||||||
else
|
|
||||||
# Condition fulfilled (timeout and/or condition is 'true')
|
|
||||||
console.log "'waitFor()' finished in #{new Date().getTime() - start}ms."
|
|
||||||
if typeof onReady is 'string' then eval onReady else onReady() #< Do what it's supposed to do once the condition is fulfilled
|
|
||||||
clearInterval interval #< Stop this interval
|
|
||||||
interval = setInterval f, 250 #< repeat check every 250ms
|
|
||||||
|
|
||||||
|
|
||||||
page = require('webpage').create()
|
|
||||||
|
|
||||||
# Open Twitter on 'sencha' profile and, onPageLoad, do...
|
|
||||||
page.open 'http://twitter.com/#!/sencha', (status) ->
|
|
||||||
# Check for page load success
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Unable to access network'
|
|
||||||
else
|
|
||||||
# Wait for 'signin-dropdown' to be visible
|
|
||||||
waitFor ->
|
|
||||||
# Check in the page if a specific element is now visible
|
|
||||||
page.evaluate ->
|
|
||||||
$('#signin-dropdown').is ':visible'
|
|
||||||
, ->
|
|
||||||
console.log 'The sign-in dialog should be visible now.'
|
|
||||||
phantom.exit()
|
|
|
@ -1,66 +0,0 @@
|
||||||
pageTitle = (page) ->
|
|
||||||
page.evaluate ->
|
|
||||||
window.document.title
|
|
||||||
setPageTitle = (page, newTitle) ->
|
|
||||||
page.evaluate ((newTitle) ->
|
|
||||||
window.document.title = newTitle
|
|
||||||
), newTitle
|
|
||||||
p = require("webpage").create()
|
|
||||||
p.open "../test/webpage-spec-frames/index.html", (status) ->
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToChildFrame(\"frame1\"): " + p.switchToChildFrame("frame1")
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToChildFrame(\"frame1-2\"): " + p.switchToChildFrame("frame1-2")
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToParentFrame(): " + p.switchToParentFrame()
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToChildFrame(0): " + p.switchToChildFrame(0)
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToMainFrame()"
|
|
||||||
p.switchToMainFrame()
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
console.log "p.switchToChildFrame(\"frame2\"): " + p.switchToChildFrame("frame2")
|
|
||||||
console.log "pageTitle(): " + pageTitle(p)
|
|
||||||
console.log "currentFrameName(): " + p.currentFrameName()
|
|
||||||
console.log "childFramesCount(): " + p.childFramesCount()
|
|
||||||
console.log "childFramesName(): " + p.childFramesName()
|
|
||||||
console.log "setPageTitle(CURRENT TITLE+'-visited')"
|
|
||||||
setPageTitle p, pageTitle(p) + "-visited"
|
|
||||||
console.log ""
|
|
||||||
phantom.exit()
|
|
|
@ -1,29 +0,0 @@
|
||||||
page = require('webpage').create()
|
|
||||||
system = require 'system'
|
|
||||||
|
|
||||||
city = 'Mountain View, California'; # default
|
|
||||||
if system.args.length > 1
|
|
||||||
city = Array.prototype.slice.call(system.args, 1).join(' ')
|
|
||||||
url = encodeURI 'http://api.openweathermap.org/data/2.1/find/name?q=' + city
|
|
||||||
|
|
||||||
console.log 'Checking weather condition for', city, '...'
|
|
||||||
|
|
||||||
page.open url, (status) ->
|
|
||||||
if status isnt 'success'
|
|
||||||
console.log 'Error: Unable to access network!'
|
|
||||||
else
|
|
||||||
result = page.evaluate ->
|
|
||||||
return document.body.innerText
|
|
||||||
try
|
|
||||||
data = JSON.parse result
|
|
||||||
data = data.list[0]
|
|
||||||
console.log ''
|
|
||||||
console.log 'City:', data.name
|
|
||||||
console.log 'Condition:', data.weather.map (entry) ->
|
|
||||||
return entry.main
|
|
||||||
console.log 'Temperature:', Math.round(data.main.temp - 273.15), 'C'
|
|
||||||
console.log 'Humidity:', Math.round(data.main.humidity), '%'
|
|
||||||
catch e
|
|
||||||
console.log 'Error:', e.toString()
|
|
||||||
|
|
||||||
phantom.exit()
|
|
|
@ -320,11 +320,6 @@ phantom.callback = function(callback) {
|
||||||
cwd = fs.absolute(phantom.libraryPath);
|
cwd = fs.absolute(phantom.libraryPath);
|
||||||
mainFilename = joinPath(cwd, basename(require('system').args[0]) || 'repl');
|
mainFilename = joinPath(cwd, basename(require('system').args[0]) || 'repl');
|
||||||
mainModule._setFilename(mainFilename);
|
mainModule._setFilename(mainFilename);
|
||||||
|
|
||||||
// include CoffeeScript which takes care of adding .coffee extension (only if not in Webdriver mode)
|
|
||||||
if (!phantom.webdriverMode) {
|
|
||||||
require('_coffee-script');
|
|
||||||
}
|
|
||||||
}());
|
}());
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
raw
|
|
||||||
presentation
|
|
||||||
test.coffee
|
|
||||||
parser.output
|
|
||||||
test/fixtures/underscore
|
|
||||||
test/*.js
|
|
||||||
examples/beautiful_code/parse.coffee
|
|
||||||
*.gem
|
|
||||||
/node_modules
|
|
|
@ -1,11 +0,0 @@
|
||||||
*.coffee
|
|
||||||
*.html
|
|
||||||
.DS_Store
|
|
||||||
.git*
|
|
||||||
Cakefile
|
|
||||||
documentation/
|
|
||||||
examples/
|
|
||||||
extras/coffee-script.js
|
|
||||||
raw/
|
|
||||||
src/
|
|
||||||
test/
|
|
|
@ -1,22 +0,0 @@
|
||||||
Copyright (c) 2009-2012 Jeremy Ashkenas
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,51 +0,0 @@
|
||||||
|
|
||||||
{
|
|
||||||
} } {
|
|
||||||
{ { } }
|
|
||||||
} }{ {
|
|
||||||
{ }{ } } _____ __ __
|
|
||||||
( }{ }{ { ) / ____| / _|/ _|
|
|
||||||
.- { { } { }} -. | | ___ | |_| |_ ___ ___
|
|
||||||
( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
|
|
||||||
|`-..________ ..-'| | |___| (_) | | | || __/ __/
|
|
||||||
| | \_____\___/|_| |_| \___|\___|
|
|
||||||
| ;--.
|
|
||||||
| (__ \ _____ _ _
|
|
||||||
| | ) ) / ____| (_) | |
|
|
||||||
| |/ / | (___ ___ _ __ _ _ __ | |_
|
|
||||||
| ( / \___ \ / __| '__| | '_ \| __|
|
|
||||||
| |/ ____) | (__| | | | |_) | |_
|
|
||||||
| | |_____/ \___|_| |_| .__/ \__|
|
|
||||||
`-.._________..-' | |
|
|
||||||
|_|
|
|
||||||
|
|
||||||
|
|
||||||
CoffeeScript is a little language that compiles into JavaScript.
|
|
||||||
|
|
||||||
Install Node.js, and then the CoffeeScript compiler:
|
|
||||||
sudo bin/cake install
|
|
||||||
|
|
||||||
Or, if you have the Node Package Manager installed:
|
|
||||||
npm install -g coffee-script
|
|
||||||
(Leave off the -g if you don't wish to install globally.)
|
|
||||||
|
|
||||||
Execute a script:
|
|
||||||
coffee /path/to/script.coffee
|
|
||||||
|
|
||||||
Compile a script:
|
|
||||||
coffee -c /path/to/script.coffee
|
|
||||||
|
|
||||||
For documentation, usage, and examples, see:
|
|
||||||
http://coffeescript.org/
|
|
||||||
|
|
||||||
To suggest a feature, report a bug, or general discussion:
|
|
||||||
http://github.com/jashkenas/coffee-script/issues/
|
|
||||||
|
|
||||||
If you'd like to chat, drop by #coffeescript on Freenode IRC,
|
|
||||||
or on webchat.freenode.net.
|
|
||||||
|
|
||||||
The source repository:
|
|
||||||
git://github.com/jashkenas/coffee-script.git
|
|
||||||
|
|
||||||
All contributors are listed here:
|
|
||||||
http://github.com/jashkenas/coffee-script/contributors
|
|
File diff suppressed because one or more lines are too long
|
@ -1,92 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var CoffeeScript, runScripts;
|
|
||||||
|
|
||||||
CoffeeScript = require('./coffee-script');
|
|
||||||
|
|
||||||
CoffeeScript.require = require;
|
|
||||||
|
|
||||||
CoffeeScript["eval"] = function(code, options) {
|
|
||||||
var _ref;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
if ((_ref = options.bare) == null) {
|
|
||||||
options.bare = true;
|
|
||||||
}
|
|
||||||
return eval(CoffeeScript.compile(code, options));
|
|
||||||
};
|
|
||||||
|
|
||||||
CoffeeScript.run = function(code, options) {
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
options.bare = true;
|
|
||||||
return Function(CoffeeScript.compile(code, options))();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof window === "undefined" || window === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CoffeeScript.load = function(url, callback) {
|
|
||||||
var xhr;
|
|
||||||
xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
|
|
||||||
xhr.open('GET', url, true);
|
|
||||||
if ('overrideMimeType' in xhr) {
|
|
||||||
xhr.overrideMimeType('text/plain');
|
|
||||||
}
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
var _ref;
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if ((_ref = xhr.status) === 0 || _ref === 200) {
|
|
||||||
CoffeeScript.run(xhr.responseText);
|
|
||||||
} else {
|
|
||||||
throw new Error("Could not load " + url);
|
|
||||||
}
|
|
||||||
if (callback) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return xhr.send(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
runScripts = function() {
|
|
||||||
var coffees, execute, index, length, s, scripts;
|
|
||||||
scripts = document.getElementsByTagName('script');
|
|
||||||
coffees = (function() {
|
|
||||||
var _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = scripts.length; _i < _len; _i++) {
|
|
||||||
s = scripts[_i];
|
|
||||||
if (s.type === 'text/coffeescript') {
|
|
||||||
_results.push(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
index = 0;
|
|
||||||
length = coffees.length;
|
|
||||||
(execute = function() {
|
|
||||||
var script;
|
|
||||||
script = coffees[index++];
|
|
||||||
if ((script != null ? script.type : void 0) === 'text/coffeescript') {
|
|
||||||
if (script.src) {
|
|
||||||
return CoffeeScript.load(script.src, execute);
|
|
||||||
} else {
|
|
||||||
CoffeeScript.run(script.innerHTML);
|
|
||||||
return execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (window.addEventListener) {
|
|
||||||
addEventListener('DOMContentLoaded', runScripts, false);
|
|
||||||
} else {
|
|
||||||
attachEvent('onload', runScripts);
|
|
||||||
}
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,111 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
|
|
||||||
|
|
||||||
fs = require('fs');
|
|
||||||
|
|
||||||
path = require('path');
|
|
||||||
|
|
||||||
helpers = require('./helpers');
|
|
||||||
|
|
||||||
optparse = require('./optparse');
|
|
||||||
|
|
||||||
CoffeeScript = require('./coffee-script');
|
|
||||||
|
|
||||||
tasks = {};
|
|
||||||
|
|
||||||
options = {};
|
|
||||||
|
|
||||||
switches = [];
|
|
||||||
|
|
||||||
oparse = null;
|
|
||||||
|
|
||||||
helpers.extend(global, {
|
|
||||||
task: function(name, description, action) {
|
|
||||||
var _ref;
|
|
||||||
if (!action) {
|
|
||||||
_ref = [description, action], action = _ref[0], description = _ref[1];
|
|
||||||
}
|
|
||||||
return tasks[name] = {
|
|
||||||
name: name,
|
|
||||||
description: description,
|
|
||||||
action: action
|
|
||||||
};
|
|
||||||
},
|
|
||||||
option: function(letter, flag, description) {
|
|
||||||
return switches.push([letter, flag, description]);
|
|
||||||
},
|
|
||||||
invoke: function(name) {
|
|
||||||
if (!tasks[name]) {
|
|
||||||
missingTask(name);
|
|
||||||
}
|
|
||||||
return tasks[name].action(options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
exports.run = function() {
|
|
||||||
var arg, args, _i, _len, _ref, _results;
|
|
||||||
global.__originalDirname = fs.realpathSync('.');
|
|
||||||
process.chdir(cakefileDirectory(__originalDirname));
|
|
||||||
args = process.argv.slice(2);
|
|
||||||
CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
|
|
||||||
filename: 'Cakefile'
|
|
||||||
});
|
|
||||||
oparse = new optparse.OptionParser(switches);
|
|
||||||
if (!args.length) {
|
|
||||||
return printTasks();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
options = oparse.parse(args);
|
|
||||||
} catch (e) {
|
|
||||||
return fatalError("" + e);
|
|
||||||
}
|
|
||||||
_ref = options["arguments"];
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
arg = _ref[_i];
|
|
||||||
_results.push(invoke(arg));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
printTasks = function() {
|
|
||||||
var cakefilePath, desc, name, relative, spaces, task;
|
|
||||||
relative = path.relative || path.resolve;
|
|
||||||
cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile');
|
|
||||||
console.log("" + cakefilePath + " defines the following tasks:\n");
|
|
||||||
for (name in tasks) {
|
|
||||||
task = tasks[name];
|
|
||||||
spaces = 20 - name.length;
|
|
||||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
|
||||||
desc = task.description ? "# " + task.description : '';
|
|
||||||
console.log("cake " + name + spaces + " " + desc);
|
|
||||||
}
|
|
||||||
if (switches.length) {
|
|
||||||
return console.log(oparse.help());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fatalError = function(message) {
|
|
||||||
console.error(message + '\n');
|
|
||||||
console.log('To see a list of all tasks/options, run "cake"');
|
|
||||||
return process.exit(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
missingTask = function(task) {
|
|
||||||
return fatalError("No such task: " + task);
|
|
||||||
};
|
|
||||||
|
|
||||||
cakefileDirectory = function(dir) {
|
|
||||||
var parent;
|
|
||||||
if (path.existsSync(path.join(dir, 'Cakefile'))) {
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
parent = path.normalize(path.join(dir, '..'));
|
|
||||||
if (parent !== dir) {
|
|
||||||
return cakefileDirectory(parent);
|
|
||||||
}
|
|
||||||
throw new Error("Cakefile not found in " + (process.cwd()));
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,167 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref,
|
|
||||||
__hasProp = {}.hasOwnProperty;
|
|
||||||
|
|
||||||
fs = require('fs');
|
|
||||||
|
|
||||||
path = require('path');
|
|
||||||
|
|
||||||
_ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED;
|
|
||||||
|
|
||||||
parser = require('./parser').parser;
|
|
||||||
|
|
||||||
vm = require('vm');
|
|
||||||
|
|
||||||
if (require.extensions) {
|
|
||||||
require.extensions['.coffee'] = function(module, filename) {
|
|
||||||
var content;
|
|
||||||
content = compile(fs.readFileSync(filename, 'utf8'), {
|
|
||||||
filename: filename
|
|
||||||
});
|
|
||||||
return module._compile(content, filename);
|
|
||||||
};
|
|
||||||
} else if (require.registerExtension) {
|
|
||||||
require.registerExtension('.coffee', function(content) {
|
|
||||||
return compile(content);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.VERSION = '1.3.3';
|
|
||||||
|
|
||||||
exports.RESERVED = RESERVED;
|
|
||||||
|
|
||||||
exports.helpers = require('./helpers');
|
|
||||||
|
|
||||||
exports.compile = compile = function(code, options) {
|
|
||||||
var header, js, merge;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
merge = exports.helpers.merge;
|
|
||||||
try {
|
|
||||||
js = (parser.parse(lexer.tokenize(code))).compile(options);
|
|
||||||
if (!options.header) {
|
|
||||||
return js;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (options.filename) {
|
|
||||||
err.message = "In " + options.filename + ", " + err.message;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
header = "Generated by CoffeeScript " + this.VERSION;
|
|
||||||
return "// " + header + "\n" + js;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.tokens = function(code, options) {
|
|
||||||
return lexer.tokenize(code, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.nodes = function(source, options) {
|
|
||||||
if (typeof source === 'string') {
|
|
||||||
return parser.parse(lexer.tokenize(source, options));
|
|
||||||
} else {
|
|
||||||
return parser.parse(source);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.run = function(code, options) {
|
|
||||||
var mainModule;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
mainModule = require.main;
|
|
||||||
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
|
|
||||||
mainModule.moduleCache && (mainModule.moduleCache = {});
|
|
||||||
mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename)));
|
|
||||||
if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) {
|
|
||||||
return mainModule._compile(compile(code, options), mainModule.filename);
|
|
||||||
} else {
|
|
||||||
return mainModule._compile(code, mainModule.filename);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports["eval"] = function(code, options) {
|
|
||||||
var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref1, _ref2, _require;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
if (!(code = code.trim())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Script = vm.Script;
|
|
||||||
if (Script) {
|
|
||||||
if (options.sandbox != null) {
|
|
||||||
if (options.sandbox instanceof Script.createContext().constructor) {
|
|
||||||
sandbox = options.sandbox;
|
|
||||||
} else {
|
|
||||||
sandbox = Script.createContext();
|
|
||||||
_ref1 = options.sandbox;
|
|
||||||
for (k in _ref1) {
|
|
||||||
if (!__hasProp.call(_ref1, k)) continue;
|
|
||||||
v = _ref1[k];
|
|
||||||
sandbox[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
|
|
||||||
} else {
|
|
||||||
sandbox = global;
|
|
||||||
}
|
|
||||||
sandbox.__filename = options.filename || 'eval';
|
|
||||||
sandbox.__dirname = path.dirname(sandbox.__filename);
|
|
||||||
if (!(sandbox !== global || sandbox.module || sandbox.require)) {
|
|
||||||
Module = require('module');
|
|
||||||
sandbox.module = _module = new Module(options.modulename || 'eval');
|
|
||||||
sandbox.require = _require = function(path) {
|
|
||||||
return Module._load(path, _module, true);
|
|
||||||
};
|
|
||||||
_module.filename = sandbox.__filename;
|
|
||||||
_ref2 = Object.getOwnPropertyNames(require);
|
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
||||||
r = _ref2[_i];
|
|
||||||
if (r !== 'paths') {
|
|
||||||
_require[r] = require[r];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
|
|
||||||
_require.resolve = function(request) {
|
|
||||||
return Module._resolveFilename(request, _module);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = {};
|
|
||||||
for (k in options) {
|
|
||||||
if (!__hasProp.call(options, k)) continue;
|
|
||||||
v = options[k];
|
|
||||||
o[k] = v;
|
|
||||||
}
|
|
||||||
o.bare = true;
|
|
||||||
js = compile(code, o);
|
|
||||||
if (sandbox === global) {
|
|
||||||
return vm.runInThisContext(js);
|
|
||||||
} else {
|
|
||||||
return vm.runInContext(js, sandbox);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lexer = new Lexer;
|
|
||||||
|
|
||||||
parser.lexer = {
|
|
||||||
lex: function() {
|
|
||||||
var tag, _ref1;
|
|
||||||
_ref1 = this.tokens[this.pos++] || [''], tag = _ref1[0], this.yytext = _ref1[1], this.yylineno = _ref1[2];
|
|
||||||
return tag;
|
|
||||||
},
|
|
||||||
setInput: function(tokens) {
|
|
||||||
this.tokens = tokens;
|
|
||||||
return this.pos = 0;
|
|
||||||
},
|
|
||||||
upcomingInput: function() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
parser.yy = require('./nodes');
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,500 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref;
|
|
||||||
|
|
||||||
fs = require('fs');
|
|
||||||
|
|
||||||
path = require('path');
|
|
||||||
|
|
||||||
helpers = require('./helpers');
|
|
||||||
|
|
||||||
optparse = require('./optparse');
|
|
||||||
|
|
||||||
CoffeeScript = require('./coffee-script');
|
|
||||||
|
|
||||||
_ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
|
|
||||||
|
|
||||||
EventEmitter = require('events').EventEmitter;
|
|
||||||
|
|
||||||
helpers.extend(CoffeeScript, new EventEmitter);
|
|
||||||
|
|
||||||
printLine = function(line) {
|
|
||||||
return process.stdout.write(line + '\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
printWarn = function(line) {
|
|
||||||
return process.stderr.write(line + '\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
hidden = function(file) {
|
|
||||||
return /^\.|~$/.test(file);
|
|
||||||
};
|
|
||||||
|
|
||||||
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
|
|
||||||
|
|
||||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
|
||||||
|
|
||||||
opts = {};
|
|
||||||
|
|
||||||
sources = [];
|
|
||||||
|
|
||||||
sourceCode = [];
|
|
||||||
|
|
||||||
notSources = {};
|
|
||||||
|
|
||||||
watchers = {};
|
|
||||||
|
|
||||||
optionParser = null;
|
|
||||||
|
|
||||||
exports.run = function() {
|
|
||||||
var literals, source, _i, _len, _results;
|
|
||||||
parseOptions();
|
|
||||||
if (opts.nodejs) {
|
|
||||||
return forkNode();
|
|
||||||
}
|
|
||||||
if (opts.help) {
|
|
||||||
return usage();
|
|
||||||
}
|
|
||||||
if (opts.version) {
|
|
||||||
return version();
|
|
||||||
}
|
|
||||||
if (opts.require) {
|
|
||||||
loadRequires();
|
|
||||||
}
|
|
||||||
if (opts.interactive) {
|
|
||||||
return require('./repl');
|
|
||||||
}
|
|
||||||
if (opts.watch && !fs.watch) {
|
|
||||||
return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
|
|
||||||
}
|
|
||||||
if (opts.stdio) {
|
|
||||||
return compileStdio();
|
|
||||||
}
|
|
||||||
if (opts["eval"]) {
|
|
||||||
return compileScript(null, sources[0]);
|
|
||||||
}
|
|
||||||
if (!sources.length) {
|
|
||||||
return require('./repl');
|
|
||||||
}
|
|
||||||
literals = opts.run ? sources.splice(1) : [];
|
|
||||||
process.argv = process.argv.slice(0, 2).concat(literals);
|
|
||||||
process.argv[0] = 'coffee';
|
|
||||||
process.execPath = require.main.filename;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = sources.length; _i < _len; _i++) {
|
|
||||||
source = sources[_i];
|
|
||||||
_results.push(compilePath(source, true, path.normalize(source)));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
compilePath = function(source, topLevel, base) {
|
|
||||||
return fs.stat(source, function(err, stats) {
|
|
||||||
if (err && err.code !== 'ENOENT') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if ((err != null ? err.code : void 0) === 'ENOENT') {
|
|
||||||
if (topLevel && source.slice(-7) !== '.coffee') {
|
|
||||||
source = sources[sources.indexOf(source)] = "" + source + ".coffee";
|
|
||||||
return compilePath(source, topLevel, base);
|
|
||||||
}
|
|
||||||
if (topLevel) {
|
|
||||||
console.error("File not found: " + source);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (stats.isDirectory()) {
|
|
||||||
if (opts.watch) {
|
|
||||||
watchDir(source, base);
|
|
||||||
}
|
|
||||||
return fs.readdir(source, function(err, files) {
|
|
||||||
var file, index, _ref1, _ref2;
|
|
||||||
if (err && err.code !== 'ENOENT') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if ((err != null ? err.code : void 0) === 'ENOENT') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index = sources.indexOf(source);
|
|
||||||
files = files.filter(function(file) {
|
|
||||||
return !hidden(file);
|
|
||||||
});
|
|
||||||
[].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
|
|
||||||
var _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = files.length; _i < _len; _i++) {
|
|
||||||
file = files[_i];
|
|
||||||
_results.push(path.join(source, file));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})())), _ref1;
|
|
||||||
[].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
|
|
||||||
return null;
|
|
||||||
}))), _ref2;
|
|
||||||
return files.forEach(function(file) {
|
|
||||||
return compilePath(path.join(source, file), false, base);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else if (topLevel || path.extname(source) === '.coffee') {
|
|
||||||
if (opts.watch) {
|
|
||||||
watch(source, base);
|
|
||||||
}
|
|
||||||
return fs.readFile(source, function(err, code) {
|
|
||||||
if (err && err.code !== 'ENOENT') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if ((err != null ? err.code : void 0) === 'ENOENT') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return compileScript(source, code.toString(), base);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
notSources[source] = true;
|
|
||||||
return removeSource(source, base);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
compileScript = function(file, input, base) {
|
|
||||||
var o, options, t, task;
|
|
||||||
o = opts;
|
|
||||||
options = compileOptions(file);
|
|
||||||
try {
|
|
||||||
t = task = {
|
|
||||||
file: file,
|
|
||||||
input: input,
|
|
||||||
options: options
|
|
||||||
};
|
|
||||||
CoffeeScript.emit('compile', task);
|
|
||||||
if (o.tokens) {
|
|
||||||
return printTokens(CoffeeScript.tokens(t.input));
|
|
||||||
} else if (o.nodes) {
|
|
||||||
return printLine(CoffeeScript.nodes(t.input).toString().trim());
|
|
||||||
} else if (o.run) {
|
|
||||||
return CoffeeScript.run(t.input, t.options);
|
|
||||||
} else if (o.join && t.file !== o.join) {
|
|
||||||
sourceCode[sources.indexOf(t.file)] = t.input;
|
|
||||||
return compileJoin();
|
|
||||||
} else {
|
|
||||||
t.output = CoffeeScript.compile(t.input, t.options);
|
|
||||||
CoffeeScript.emit('success', task);
|
|
||||||
if (o.print) {
|
|
||||||
return printLine(t.output.trim());
|
|
||||||
} else if (o.compile) {
|
|
||||||
return writeJs(t.file, t.output, base);
|
|
||||||
} else if (o.lint) {
|
|
||||||
return lint(t.file, t.output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
CoffeeScript.emit('failure', err, task);
|
|
||||||
if (CoffeeScript.listeners('failure').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (o.watch) {
|
|
||||||
return printLine(err.message + '\x07');
|
|
||||||
}
|
|
||||||
printWarn(err instanceof Error && err.stack || ("ERROR: " + err));
|
|
||||||
return process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
compileStdio = function() {
|
|
||||||
var code, stdin;
|
|
||||||
code = '';
|
|
||||||
stdin = process.openStdin();
|
|
||||||
stdin.on('data', function(buffer) {
|
|
||||||
if (buffer) {
|
|
||||||
return code += buffer.toString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return stdin.on('end', function() {
|
|
||||||
return compileScript(null, code);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
joinTimeout = null;
|
|
||||||
|
|
||||||
compileJoin = function() {
|
|
||||||
if (!opts.join) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!sourceCode.some(function(code) {
|
|
||||||
return code === null;
|
|
||||||
})) {
|
|
||||||
clearTimeout(joinTimeout);
|
|
||||||
return joinTimeout = wait(100, function() {
|
|
||||||
return compileScript(opts.join, sourceCode.join('\n'), opts.join);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
loadRequires = function() {
|
|
||||||
var realFilename, req, _i, _len, _ref1;
|
|
||||||
realFilename = module.filename;
|
|
||||||
module.filename = '.';
|
|
||||||
_ref1 = opts.require;
|
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
||||||
req = _ref1[_i];
|
|
||||||
require(req);
|
|
||||||
}
|
|
||||||
return module.filename = realFilename;
|
|
||||||
};
|
|
||||||
|
|
||||||
watch = function(source, base) {
|
|
||||||
var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
|
|
||||||
prevStats = null;
|
|
||||||
compileTimeout = null;
|
|
||||||
watchErr = function(e) {
|
|
||||||
if (e.code === 'ENOENT') {
|
|
||||||
if (sources.indexOf(source) === -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
rewatch();
|
|
||||||
return compile();
|
|
||||||
} catch (e) {
|
|
||||||
removeSource(source, base, true);
|
|
||||||
return compileJoin();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
compile = function() {
|
|
||||||
clearTimeout(compileTimeout);
|
|
||||||
return compileTimeout = wait(25, function() {
|
|
||||||
return fs.stat(source, function(err, stats) {
|
|
||||||
if (err) {
|
|
||||||
return watchErr(err);
|
|
||||||
}
|
|
||||||
if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) {
|
|
||||||
return rewatch();
|
|
||||||
}
|
|
||||||
prevStats = stats;
|
|
||||||
return fs.readFile(source, function(err, code) {
|
|
||||||
if (err) {
|
|
||||||
return watchErr(err);
|
|
||||||
}
|
|
||||||
compileScript(source, code.toString(), base);
|
|
||||||
return rewatch();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
watcher = fs.watch(source, compile);
|
|
||||||
} catch (e) {
|
|
||||||
watchErr(e);
|
|
||||||
}
|
|
||||||
return rewatch = function() {
|
|
||||||
if (watcher != null) {
|
|
||||||
watcher.close();
|
|
||||||
}
|
|
||||||
return watcher = fs.watch(source, compile);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
watchDir = function(source, base) {
|
|
||||||
var readdirTimeout, watcher;
|
|
||||||
readdirTimeout = null;
|
|
||||||
try {
|
|
||||||
return watcher = fs.watch(source, function() {
|
|
||||||
clearTimeout(readdirTimeout);
|
|
||||||
return readdirTimeout = wait(25, function() {
|
|
||||||
return fs.readdir(source, function(err, files) {
|
|
||||||
var file, _i, _len, _results;
|
|
||||||
if (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
watcher.close();
|
|
||||||
return unwatchDir(source, base);
|
|
||||||
}
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = files.length; _i < _len; _i++) {
|
|
||||||
file = files[_i];
|
|
||||||
if (!(!hidden(file) && !notSources[file])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
file = path.join(source, file);
|
|
||||||
if (sources.some(function(s) {
|
|
||||||
return s.indexOf(file) >= 0;
|
|
||||||
})) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sources.push(file);
|
|
||||||
sourceCode.push(null);
|
|
||||||
_results.push(compilePath(file, false, base));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
if (e.code !== 'ENOENT') {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
unwatchDir = function(source, base) {
|
|
||||||
var file, prevSources, toRemove, _i, _len;
|
|
||||||
prevSources = sources.slice(0);
|
|
||||||
toRemove = (function() {
|
|
||||||
var _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = sources.length; _i < _len; _i++) {
|
|
||||||
file = sources[_i];
|
|
||||||
if (file.indexOf(source) >= 0) {
|
|
||||||
_results.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
|
|
||||||
file = toRemove[_i];
|
|
||||||
removeSource(file, base, true);
|
|
||||||
}
|
|
||||||
if (!sources.some(function(s, i) {
|
|
||||||
return prevSources[i] !== s;
|
|
||||||
})) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return compileJoin();
|
|
||||||
};
|
|
||||||
|
|
||||||
removeSource = function(source, base, removeJs) {
|
|
||||||
var index, jsPath;
|
|
||||||
index = sources.indexOf(source);
|
|
||||||
sources.splice(index, 1);
|
|
||||||
sourceCode.splice(index, 1);
|
|
||||||
if (removeJs && !opts.join) {
|
|
||||||
jsPath = outputPath(source, base);
|
|
||||||
return path.exists(jsPath, function(exists) {
|
|
||||||
if (exists) {
|
|
||||||
return fs.unlink(jsPath, function(err) {
|
|
||||||
if (err && err.code !== 'ENOENT') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return timeLog("removed " + source);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
outputPath = function(source, base) {
|
|
||||||
var baseDir, dir, filename, srcDir;
|
|
||||||
filename = path.basename(source, path.extname(source)) + '.js';
|
|
||||||
srcDir = path.dirname(source);
|
|
||||||
baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
|
|
||||||
dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
|
|
||||||
return path.join(dir, filename);
|
|
||||||
};
|
|
||||||
|
|
||||||
writeJs = function(source, js, base) {
|
|
||||||
var compile, jsDir, jsPath;
|
|
||||||
jsPath = outputPath(source, base);
|
|
||||||
jsDir = path.dirname(jsPath);
|
|
||||||
compile = function() {
|
|
||||||
if (js.length <= 0) {
|
|
||||||
js = ' ';
|
|
||||||
}
|
|
||||||
return fs.writeFile(jsPath, js, function(err) {
|
|
||||||
if (err) {
|
|
||||||
return printLine(err.message);
|
|
||||||
} else if (opts.compile && opts.watch) {
|
|
||||||
return timeLog("compiled " + source);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return path.exists(jsDir, function(exists) {
|
|
||||||
if (exists) {
|
|
||||||
return compile();
|
|
||||||
} else {
|
|
||||||
return exec("mkdir -p " + jsDir, compile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
wait = function(milliseconds, func) {
|
|
||||||
return setTimeout(func, milliseconds);
|
|
||||||
};
|
|
||||||
|
|
||||||
timeLog = function(message) {
|
|
||||||
return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
|
|
||||||
};
|
|
||||||
|
|
||||||
lint = function(file, js) {
|
|
||||||
var conf, jsl, printIt;
|
|
||||||
printIt = function(buffer) {
|
|
||||||
return printLine(file + ':\t' + buffer.toString().trim());
|
|
||||||
};
|
|
||||||
conf = __dirname + '/../../extras/jsl.conf';
|
|
||||||
jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
|
|
||||||
jsl.stdout.on('data', printIt);
|
|
||||||
jsl.stderr.on('data', printIt);
|
|
||||||
jsl.stdin.write(js);
|
|
||||||
return jsl.stdin.end();
|
|
||||||
};
|
|
||||||
|
|
||||||
printTokens = function(tokens) {
|
|
||||||
var strings, tag, token, value;
|
|
||||||
strings = (function() {
|
|
||||||
var _i, _len, _ref1, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
|
|
||||||
token = tokens[_i];
|
|
||||||
_ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1];
|
|
||||||
_results.push("[" + tag + " " + value + "]");
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
return printLine(strings.join(' '));
|
|
||||||
};
|
|
||||||
|
|
||||||
parseOptions = function() {
|
|
||||||
var i, o, source, _i, _len;
|
|
||||||
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
|
|
||||||
o = opts = optionParser.parse(process.argv.slice(2));
|
|
||||||
o.compile || (o.compile = !!o.output);
|
|
||||||
o.run = !(o.compile || o.print || o.lint);
|
|
||||||
o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
|
|
||||||
sources = o["arguments"];
|
|
||||||
for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
|
|
||||||
source = sources[i];
|
|
||||||
sourceCode[i] = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
compileOptions = function(filename) {
|
|
||||||
return {
|
|
||||||
filename: filename,
|
|
||||||
bare: opts.bare,
|
|
||||||
header: opts.compile
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
forkNode = function() {
|
|
||||||
var args, nodeArgs;
|
|
||||||
nodeArgs = opts.nodejs.split(/\s+/);
|
|
||||||
args = process.argv.slice(1);
|
|
||||||
args.splice(args.indexOf('--nodejs'), 2);
|
|
||||||
return spawn(process.execPath, nodeArgs.concat(args), {
|
|
||||||
cwd: process.cwd(),
|
|
||||||
env: process.env,
|
|
||||||
customFds: [0, 1, 2]
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
usage = function() {
|
|
||||||
return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
|
|
||||||
};
|
|
||||||
|
|
||||||
version = function() {
|
|
||||||
return printLine("CoffeeScript version " + CoffeeScript.VERSION);
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,606 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
|
|
||||||
|
|
||||||
Parser = require('jison').Parser;
|
|
||||||
|
|
||||||
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
|
|
||||||
|
|
||||||
o = function(patternString, action, options) {
|
|
||||||
var match;
|
|
||||||
patternString = patternString.replace(/\s{2,}/g, ' ');
|
|
||||||
if (!action) {
|
|
||||||
return [patternString, '$$ = $1;', options];
|
|
||||||
}
|
|
||||||
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
|
|
||||||
action = action.replace(/\bnew /g, '$&yy.');
|
|
||||||
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
|
|
||||||
return [patternString, "$$ = " + action + ";", options];
|
|
||||||
};
|
|
||||||
|
|
||||||
grammar = {
|
|
||||||
Root: [
|
|
||||||
o('', function() {
|
|
||||||
return new Block;
|
|
||||||
}), o('Body'), o('Block TERMINATOR')
|
|
||||||
],
|
|
||||||
Body: [
|
|
||||||
o('Line', function() {
|
|
||||||
return Block.wrap([$1]);
|
|
||||||
}), o('Body TERMINATOR Line', function() {
|
|
||||||
return $1.push($3);
|
|
||||||
}), o('Body TERMINATOR')
|
|
||||||
],
|
|
||||||
Line: [o('Expression'), o('Statement')],
|
|
||||||
Statement: [
|
|
||||||
o('Return'), o('Comment'), o('STATEMENT', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')],
|
|
||||||
Block: [
|
|
||||||
o('INDENT OUTDENT', function() {
|
|
||||||
return new Block;
|
|
||||||
}), o('INDENT Body OUTDENT', function() {
|
|
||||||
return $2;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Identifier: [
|
|
||||||
o('IDENTIFIER', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
AlphaNumeric: [
|
|
||||||
o('NUMBER', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
}), o('STRING', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Literal: [
|
|
||||||
o('AlphaNumeric'), o('JS', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
}), o('REGEX', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
}), o('DEBUGGER', function() {
|
|
||||||
return new Literal($1);
|
|
||||||
}), o('UNDEFINED', function() {
|
|
||||||
return new Undefined;
|
|
||||||
}), o('NULL', function() {
|
|
||||||
return new Null;
|
|
||||||
}), o('BOOL', function() {
|
|
||||||
return new Bool($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Assign: [
|
|
||||||
o('Assignable = Expression', function() {
|
|
||||||
return new Assign($1, $3);
|
|
||||||
}), o('Assignable = TERMINATOR Expression', function() {
|
|
||||||
return new Assign($1, $4);
|
|
||||||
}), o('Assignable = INDENT Expression OUTDENT', function() {
|
|
||||||
return new Assign($1, $4);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
AssignObj: [
|
|
||||||
o('ObjAssignable', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('ObjAssignable : Expression', function() {
|
|
||||||
return new Assign(new Value($1), $3, 'object');
|
|
||||||
}), o('ObjAssignable :\
|
|
||||||
INDENT Expression OUTDENT', function() {
|
|
||||||
return new Assign(new Value($1), $4, 'object');
|
|
||||||
}), o('Comment')
|
|
||||||
],
|
|
||||||
ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
|
|
||||||
Return: [
|
|
||||||
o('RETURN Expression', function() {
|
|
||||||
return new Return($2);
|
|
||||||
}), o('RETURN', function() {
|
|
||||||
return new Return;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Comment: [
|
|
||||||
o('HERECOMMENT', function() {
|
|
||||||
return new Comment($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Code: [
|
|
||||||
o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
|
|
||||||
return new Code($2, $5, $4);
|
|
||||||
}), o('FuncGlyph Block', function() {
|
|
||||||
return new Code([], $2, $1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
FuncGlyph: [
|
|
||||||
o('->', function() {
|
|
||||||
return 'func';
|
|
||||||
}), o('=>', function() {
|
|
||||||
return 'boundfunc';
|
|
||||||
})
|
|
||||||
],
|
|
||||||
OptComma: [o(''), o(',')],
|
|
||||||
ParamList: [
|
|
||||||
o('', function() {
|
|
||||||
return [];
|
|
||||||
}), o('Param', function() {
|
|
||||||
return [$1];
|
|
||||||
}), o('ParamList , Param', function() {
|
|
||||||
return $1.concat($3);
|
|
||||||
}), o('ParamList OptComma TERMINATOR Param', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
}), o('ParamList OptComma INDENT ParamList OptComma OUTDENT', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Param: [
|
|
||||||
o('ParamVar', function() {
|
|
||||||
return new Param($1);
|
|
||||||
}), o('ParamVar ...', function() {
|
|
||||||
return new Param($1, null, true);
|
|
||||||
}), o('ParamVar = Expression', function() {
|
|
||||||
return new Param($1, $3);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
|
|
||||||
Splat: [
|
|
||||||
o('Expression ...', function() {
|
|
||||||
return new Splat($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
SimpleAssignable: [
|
|
||||||
o('Identifier', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('Value Accessor', function() {
|
|
||||||
return $1.add($2);
|
|
||||||
}), o('Invocation Accessor', function() {
|
|
||||||
return new Value($1, [].concat($2));
|
|
||||||
}), o('ThisProperty')
|
|
||||||
],
|
|
||||||
Assignable: [
|
|
||||||
o('SimpleAssignable'), o('Array', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('Object', function() {
|
|
||||||
return new Value($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Value: [
|
|
||||||
o('Assignable'), o('Literal', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('Parenthetical', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('Range', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('This')
|
|
||||||
],
|
|
||||||
Accessor: [
|
|
||||||
o('. Identifier', function() {
|
|
||||||
return new Access($2);
|
|
||||||
}), o('?. Identifier', function() {
|
|
||||||
return new Access($2, 'soak');
|
|
||||||
}), o(':: Identifier', function() {
|
|
||||||
return [new Access(new Literal('prototype')), new Access($2)];
|
|
||||||
}), o('::', function() {
|
|
||||||
return new Access(new Literal('prototype'));
|
|
||||||
}), o('Index')
|
|
||||||
],
|
|
||||||
Index: [
|
|
||||||
o('INDEX_START IndexValue INDEX_END', function() {
|
|
||||||
return $2;
|
|
||||||
}), o('INDEX_SOAK Index', function() {
|
|
||||||
return extend($2, {
|
|
||||||
soak: true
|
|
||||||
});
|
|
||||||
})
|
|
||||||
],
|
|
||||||
IndexValue: [
|
|
||||||
o('Expression', function() {
|
|
||||||
return new Index($1);
|
|
||||||
}), o('Slice', function() {
|
|
||||||
return new Slice($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Object: [
|
|
||||||
o('{ AssignList OptComma }', function() {
|
|
||||||
return new Obj($2, $1.generated);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
AssignList: [
|
|
||||||
o('', function() {
|
|
||||||
return [];
|
|
||||||
}), o('AssignObj', function() {
|
|
||||||
return [$1];
|
|
||||||
}), o('AssignList , AssignObj', function() {
|
|
||||||
return $1.concat($3);
|
|
||||||
}), o('AssignList OptComma TERMINATOR AssignObj', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
}), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Class: [
|
|
||||||
o('CLASS', function() {
|
|
||||||
return new Class;
|
|
||||||
}), o('CLASS Block', function() {
|
|
||||||
return new Class(null, null, $2);
|
|
||||||
}), o('CLASS EXTENDS Expression', function() {
|
|
||||||
return new Class(null, $3);
|
|
||||||
}), o('CLASS EXTENDS Expression Block', function() {
|
|
||||||
return new Class(null, $3, $4);
|
|
||||||
}), o('CLASS SimpleAssignable', function() {
|
|
||||||
return new Class($2);
|
|
||||||
}), o('CLASS SimpleAssignable Block', function() {
|
|
||||||
return new Class($2, null, $3);
|
|
||||||
}), o('CLASS SimpleAssignable EXTENDS Expression', function() {
|
|
||||||
return new Class($2, $4);
|
|
||||||
}), o('CLASS SimpleAssignable EXTENDS Expression Block', function() {
|
|
||||||
return new Class($2, $4, $5);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Invocation: [
|
|
||||||
o('Value OptFuncExist Arguments', function() {
|
|
||||||
return new Call($1, $3, $2);
|
|
||||||
}), o('Invocation OptFuncExist Arguments', function() {
|
|
||||||
return new Call($1, $3, $2);
|
|
||||||
}), o('SUPER', function() {
|
|
||||||
return new Call('super', [new Splat(new Literal('arguments'))]);
|
|
||||||
}), o('SUPER Arguments', function() {
|
|
||||||
return new Call('super', $2);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
OptFuncExist: [
|
|
||||||
o('', function() {
|
|
||||||
return false;
|
|
||||||
}), o('FUNC_EXIST', function() {
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Arguments: [
|
|
||||||
o('CALL_START CALL_END', function() {
|
|
||||||
return [];
|
|
||||||
}), o('CALL_START ArgList OptComma CALL_END', function() {
|
|
||||||
return $2;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
This: [
|
|
||||||
o('THIS', function() {
|
|
||||||
return new Value(new Literal('this'));
|
|
||||||
}), o('@', function() {
|
|
||||||
return new Value(new Literal('this'));
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ThisProperty: [
|
|
||||||
o('@ Identifier', function() {
|
|
||||||
return new Value(new Literal('this'), [new Access($2)], 'this');
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Array: [
|
|
||||||
o('[ ]', function() {
|
|
||||||
return new Arr([]);
|
|
||||||
}), o('[ ArgList OptComma ]', function() {
|
|
||||||
return new Arr($2);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
RangeDots: [
|
|
||||||
o('..', function() {
|
|
||||||
return 'inclusive';
|
|
||||||
}), o('...', function() {
|
|
||||||
return 'exclusive';
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Range: [
|
|
||||||
o('[ Expression RangeDots Expression ]', function() {
|
|
||||||
return new Range($2, $4, $3);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Slice: [
|
|
||||||
o('Expression RangeDots Expression', function() {
|
|
||||||
return new Range($1, $3, $2);
|
|
||||||
}), o('Expression RangeDots', function() {
|
|
||||||
return new Range($1, null, $2);
|
|
||||||
}), o('RangeDots Expression', function() {
|
|
||||||
return new Range(null, $2, $1);
|
|
||||||
}), o('RangeDots', function() {
|
|
||||||
return new Range(null, null, $1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ArgList: [
|
|
||||||
o('Arg', function() {
|
|
||||||
return [$1];
|
|
||||||
}), o('ArgList , Arg', function() {
|
|
||||||
return $1.concat($3);
|
|
||||||
}), o('ArgList OptComma TERMINATOR Arg', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
}), o('INDENT ArgList OptComma OUTDENT', function() {
|
|
||||||
return $2;
|
|
||||||
}), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() {
|
|
||||||
return $1.concat($4);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Arg: [o('Expression'), o('Splat')],
|
|
||||||
SimpleArgs: [
|
|
||||||
o('Expression'), o('SimpleArgs , Expression', function() {
|
|
||||||
return [].concat($1, $3);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Try: [
|
|
||||||
o('TRY Block', function() {
|
|
||||||
return new Try($2);
|
|
||||||
}), o('TRY Block Catch', function() {
|
|
||||||
return new Try($2, $3[0], $3[1]);
|
|
||||||
}), o('TRY Block FINALLY Block', function() {
|
|
||||||
return new Try($2, null, null, $4);
|
|
||||||
}), o('TRY Block Catch FINALLY Block', function() {
|
|
||||||
return new Try($2, $3[0], $3[1], $5);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Catch: [
|
|
||||||
o('CATCH Identifier Block', function() {
|
|
||||||
return [$2, $3];
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Throw: [
|
|
||||||
o('THROW Expression', function() {
|
|
||||||
return new Throw($2);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Parenthetical: [
|
|
||||||
o('( Body )', function() {
|
|
||||||
return new Parens($2);
|
|
||||||
}), o('( INDENT Body OUTDENT )', function() {
|
|
||||||
return new Parens($3);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
WhileSource: [
|
|
||||||
o('WHILE Expression', function() {
|
|
||||||
return new While($2);
|
|
||||||
}), o('WHILE Expression WHEN Expression', function() {
|
|
||||||
return new While($2, {
|
|
||||||
guard: $4
|
|
||||||
});
|
|
||||||
}), o('UNTIL Expression', function() {
|
|
||||||
return new While($2, {
|
|
||||||
invert: true
|
|
||||||
});
|
|
||||||
}), o('UNTIL Expression WHEN Expression', function() {
|
|
||||||
return new While($2, {
|
|
||||||
invert: true,
|
|
||||||
guard: $4
|
|
||||||
});
|
|
||||||
})
|
|
||||||
],
|
|
||||||
While: [
|
|
||||||
o('WhileSource Block', function() {
|
|
||||||
return $1.addBody($2);
|
|
||||||
}), o('Statement WhileSource', function() {
|
|
||||||
return $2.addBody(Block.wrap([$1]));
|
|
||||||
}), o('Expression WhileSource', function() {
|
|
||||||
return $2.addBody(Block.wrap([$1]));
|
|
||||||
}), o('Loop', function() {
|
|
||||||
return $1;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Loop: [
|
|
||||||
o('LOOP Block', function() {
|
|
||||||
return new While(new Literal('true')).addBody($2);
|
|
||||||
}), o('LOOP Expression', function() {
|
|
||||||
return new While(new Literal('true')).addBody(Block.wrap([$2]));
|
|
||||||
})
|
|
||||||
],
|
|
||||||
For: [
|
|
||||||
o('Statement ForBody', function() {
|
|
||||||
return new For($1, $2);
|
|
||||||
}), o('Expression ForBody', function() {
|
|
||||||
return new For($1, $2);
|
|
||||||
}), o('ForBody Block', function() {
|
|
||||||
return new For($2, $1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ForBody: [
|
|
||||||
o('FOR Range', function() {
|
|
||||||
return {
|
|
||||||
source: new Value($2)
|
|
||||||
};
|
|
||||||
}), o('ForStart ForSource', function() {
|
|
||||||
$2.own = $1.own;
|
|
||||||
$2.name = $1[0];
|
|
||||||
$2.index = $1[1];
|
|
||||||
return $2;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ForStart: [
|
|
||||||
o('FOR ForVariables', function() {
|
|
||||||
return $2;
|
|
||||||
}), o('FOR OWN ForVariables', function() {
|
|
||||||
$3.own = true;
|
|
||||||
return $3;
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ForValue: [
|
|
||||||
o('Identifier'), o('ThisProperty'), o('Array', function() {
|
|
||||||
return new Value($1);
|
|
||||||
}), o('Object', function() {
|
|
||||||
return new Value($1);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ForVariables: [
|
|
||||||
o('ForValue', function() {
|
|
||||||
return [$1];
|
|
||||||
}), o('ForValue , ForValue', function() {
|
|
||||||
return [$1, $3];
|
|
||||||
})
|
|
||||||
],
|
|
||||||
ForSource: [
|
|
||||||
o('FORIN Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2
|
|
||||||
};
|
|
||||||
}), o('FOROF Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
object: true
|
|
||||||
};
|
|
||||||
}), o('FORIN Expression WHEN Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
guard: $4
|
|
||||||
};
|
|
||||||
}), o('FOROF Expression WHEN Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
guard: $4,
|
|
||||||
object: true
|
|
||||||
};
|
|
||||||
}), o('FORIN Expression BY Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
step: $4
|
|
||||||
};
|
|
||||||
}), o('FORIN Expression WHEN Expression BY Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
guard: $4,
|
|
||||||
step: $6
|
|
||||||
};
|
|
||||||
}), o('FORIN Expression BY Expression WHEN Expression', function() {
|
|
||||||
return {
|
|
||||||
source: $2,
|
|
||||||
step: $4,
|
|
||||||
guard: $6
|
|
||||||
};
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Switch: [
|
|
||||||
o('SWITCH Expression INDENT Whens OUTDENT', function() {
|
|
||||||
return new Switch($2, $4);
|
|
||||||
}), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
|
|
||||||
return new Switch($2, $4, $6);
|
|
||||||
}), o('SWITCH INDENT Whens OUTDENT', function() {
|
|
||||||
return new Switch(null, $3);
|
|
||||||
}), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
|
|
||||||
return new Switch(null, $3, $5);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Whens: [
|
|
||||||
o('When'), o('Whens When', function() {
|
|
||||||
return $1.concat($2);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
When: [
|
|
||||||
o('LEADING_WHEN SimpleArgs Block', function() {
|
|
||||||
return [[$2, $3]];
|
|
||||||
}), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() {
|
|
||||||
return [[$2, $3]];
|
|
||||||
})
|
|
||||||
],
|
|
||||||
IfBlock: [
|
|
||||||
o('IF Expression Block', function() {
|
|
||||||
return new If($2, $3, {
|
|
||||||
type: $1
|
|
||||||
});
|
|
||||||
}), o('IfBlock ELSE IF Expression Block', function() {
|
|
||||||
return $1.addElse(new If($4, $5, {
|
|
||||||
type: $3
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
],
|
|
||||||
If: [
|
|
||||||
o('IfBlock'), o('IfBlock ELSE Block', function() {
|
|
||||||
return $1.addElse($3);
|
|
||||||
}), o('Statement POST_IF Expression', function() {
|
|
||||||
return new If($3, Block.wrap([$1]), {
|
|
||||||
type: $2,
|
|
||||||
statement: true
|
|
||||||
});
|
|
||||||
}), o('Expression POST_IF Expression', function() {
|
|
||||||
return new If($3, Block.wrap([$1]), {
|
|
||||||
type: $2,
|
|
||||||
statement: true
|
|
||||||
});
|
|
||||||
})
|
|
||||||
],
|
|
||||||
Operation: [
|
|
||||||
o('UNARY Expression', function() {
|
|
||||||
return new Op($1, $2);
|
|
||||||
}), o('- Expression', (function() {
|
|
||||||
return new Op('-', $2);
|
|
||||||
}), {
|
|
||||||
prec: 'UNARY'
|
|
||||||
}), o('+ Expression', (function() {
|
|
||||||
return new Op('+', $2);
|
|
||||||
}), {
|
|
||||||
prec: 'UNARY'
|
|
||||||
}), o('-- SimpleAssignable', function() {
|
|
||||||
return new Op('--', $2);
|
|
||||||
}), o('++ SimpleAssignable', function() {
|
|
||||||
return new Op('++', $2);
|
|
||||||
}), o('SimpleAssignable --', function() {
|
|
||||||
return new Op('--', $1, null, true);
|
|
||||||
}), o('SimpleAssignable ++', function() {
|
|
||||||
return new Op('++', $1, null, true);
|
|
||||||
}), o('Expression ?', function() {
|
|
||||||
return new Existence($1);
|
|
||||||
}), o('Expression + Expression', function() {
|
|
||||||
return new Op('+', $1, $3);
|
|
||||||
}), o('Expression - Expression', function() {
|
|
||||||
return new Op('-', $1, $3);
|
|
||||||
}), o('Expression MATH Expression', function() {
|
|
||||||
return new Op($2, $1, $3);
|
|
||||||
}), o('Expression SHIFT Expression', function() {
|
|
||||||
return new Op($2, $1, $3);
|
|
||||||
}), o('Expression COMPARE Expression', function() {
|
|
||||||
return new Op($2, $1, $3);
|
|
||||||
}), o('Expression LOGIC Expression', function() {
|
|
||||||
return new Op($2, $1, $3);
|
|
||||||
}), o('Expression RELATION Expression', function() {
|
|
||||||
if ($2.charAt(0) === '!') {
|
|
||||||
return new Op($2.slice(1), $1, $3).invert();
|
|
||||||
} else {
|
|
||||||
return new Op($2, $1, $3);
|
|
||||||
}
|
|
||||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
|
||||||
Expression', function() {
|
|
||||||
return new Assign($1, $3, $2);
|
|
||||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
|
||||||
INDENT Expression OUTDENT', function() {
|
|
||||||
return new Assign($1, $4, $2);
|
|
||||||
}), o('SimpleAssignable EXTENDS Expression', function() {
|
|
||||||
return new Extends($1, $3);
|
|
||||||
})
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
|
|
||||||
|
|
||||||
tokens = [];
|
|
||||||
|
|
||||||
for (name in grammar) {
|
|
||||||
alternatives = grammar[name];
|
|
||||||
grammar[name] = (function() {
|
|
||||||
var _i, _j, _len, _len1, _ref, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
|
|
||||||
alt = alternatives[_i];
|
|
||||||
_ref = alt[0].split(' ');
|
|
||||||
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
|
||||||
token = _ref[_j];
|
|
||||||
if (!grammar[token]) {
|
|
||||||
tokens.push(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name === 'Root') {
|
|
||||||
alt[1] = "return " + alt[1];
|
|
||||||
}
|
|
||||||
_results.push(alt);
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.parser = new Parser({
|
|
||||||
tokens: tokens.join(' '),
|
|
||||||
bnf: grammar,
|
|
||||||
operators: operators.reverse(),
|
|
||||||
startSymbol: 'Root'
|
|
||||||
});
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,77 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var extend, flatten;
|
|
||||||
|
|
||||||
exports.starts = function(string, literal, start) {
|
|
||||||
return literal === string.substr(start, literal.length);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.ends = function(string, literal, back) {
|
|
||||||
var len;
|
|
||||||
len = literal.length;
|
|
||||||
return literal === string.substr(string.length - len - (back || 0), len);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.compact = function(array) {
|
|
||||||
var item, _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
|
||||||
item = array[_i];
|
|
||||||
if (item) {
|
|
||||||
_results.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.count = function(string, substr) {
|
|
||||||
var num, pos;
|
|
||||||
num = pos = 0;
|
|
||||||
if (!substr.length) {
|
|
||||||
return 1 / 0;
|
|
||||||
}
|
|
||||||
while (pos = 1 + string.indexOf(substr, pos)) {
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.merge = function(options, overrides) {
|
|
||||||
return extend(extend({}, options), overrides);
|
|
||||||
};
|
|
||||||
|
|
||||||
extend = exports.extend = function(object, properties) {
|
|
||||||
var key, val;
|
|
||||||
for (key in properties) {
|
|
||||||
val = properties[key];
|
|
||||||
object[key] = val;
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.flatten = flatten = function(array) {
|
|
||||||
var element, flattened, _i, _len;
|
|
||||||
flattened = [];
|
|
||||||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
|
||||||
element = array[_i];
|
|
||||||
if (element instanceof Array) {
|
|
||||||
flattened = flattened.concat(flatten(element));
|
|
||||||
} else {
|
|
||||||
flattened.push(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flattened;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.del = function(obj, key) {
|
|
||||||
var val;
|
|
||||||
val = obj[key];
|
|
||||||
delete obj[key];
|
|
||||||
return val;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.last = function(array, back) {
|
|
||||||
return array[array.length - (back || 0) - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,11 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var key, val, _ref;
|
|
||||||
|
|
||||||
_ref = require('./coffee-script');
|
|
||||||
for (key in _ref) {
|
|
||||||
val = _ref[key];
|
|
||||||
exports[key] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,788 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1,
|
|
||||||
__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; };
|
|
||||||
|
|
||||||
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
|
||||||
|
|
||||||
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last;
|
|
||||||
|
|
||||||
exports.Lexer = Lexer = (function() {
|
|
||||||
|
|
||||||
function Lexer() {}
|
|
||||||
|
|
||||||
Lexer.prototype.tokenize = function(code, opts) {
|
|
||||||
var i, tag;
|
|
||||||
if (opts == null) {
|
|
||||||
opts = {};
|
|
||||||
}
|
|
||||||
if (WHITESPACE.test(code)) {
|
|
||||||
code = "\n" + code;
|
|
||||||
}
|
|
||||||
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
|
|
||||||
this.code = code;
|
|
||||||
this.line = opts.line || 0;
|
|
||||||
this.indent = 0;
|
|
||||||
this.indebt = 0;
|
|
||||||
this.outdebt = 0;
|
|
||||||
this.indents = [];
|
|
||||||
this.ends = [];
|
|
||||||
this.tokens = [];
|
|
||||||
i = 0;
|
|
||||||
while (this.chunk = code.slice(i)) {
|
|
||||||
i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
|
||||||
}
|
|
||||||
this.closeIndentation();
|
|
||||||
if (tag = this.ends.pop()) {
|
|
||||||
this.error("missing " + tag);
|
|
||||||
}
|
|
||||||
if (opts.rewrite === false) {
|
|
||||||
return this.tokens;
|
|
||||||
}
|
|
||||||
return (new Rewriter).rewrite(this.tokens);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.identifierToken = function() {
|
|
||||||
var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
|
|
||||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
input = match[0], id = match[1], colon = match[2];
|
|
||||||
if (id === 'own' && this.tag() === 'FOR') {
|
|
||||||
this.token('OWN', id);
|
|
||||||
return id.length;
|
|
||||||
}
|
|
||||||
forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@');
|
|
||||||
tag = 'IDENTIFIER';
|
|
||||||
if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
|
|
||||||
tag = id.toUpperCase();
|
|
||||||
if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
|
|
||||||
tag = 'LEADING_WHEN';
|
|
||||||
} else if (tag === 'FOR') {
|
|
||||||
this.seenFor = true;
|
|
||||||
} else if (tag === 'UNLESS') {
|
|
||||||
tag = 'IF';
|
|
||||||
} else if (__indexOf.call(UNARY, tag) >= 0) {
|
|
||||||
tag = 'UNARY';
|
|
||||||
} else if (__indexOf.call(RELATION, tag) >= 0) {
|
|
||||||
if (tag !== 'INSTANCEOF' && this.seenFor) {
|
|
||||||
tag = 'FOR' + tag;
|
|
||||||
this.seenFor = false;
|
|
||||||
} else {
|
|
||||||
tag = 'RELATION';
|
|
||||||
if (this.value() === '!') {
|
|
||||||
this.tokens.pop();
|
|
||||||
id = '!' + id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
|
|
||||||
if (forcedIdentifier) {
|
|
||||||
tag = 'IDENTIFIER';
|
|
||||||
id = new String(id);
|
|
||||||
id.reserved = true;
|
|
||||||
} else if (__indexOf.call(RESERVED, id) >= 0) {
|
|
||||||
this.error("reserved word \"" + id + "\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!forcedIdentifier) {
|
|
||||||
if (__indexOf.call(COFFEE_ALIASES, id) >= 0) {
|
|
||||||
id = COFFEE_ALIAS_MAP[id];
|
|
||||||
}
|
|
||||||
tag = (function() {
|
|
||||||
switch (id) {
|
|
||||||
case '!':
|
|
||||||
return 'UNARY';
|
|
||||||
case '==':
|
|
||||||
case '!=':
|
|
||||||
return 'COMPARE';
|
|
||||||
case '&&':
|
|
||||||
case '||':
|
|
||||||
return 'LOGIC';
|
|
||||||
case 'true':
|
|
||||||
case 'false':
|
|
||||||
return 'BOOL';
|
|
||||||
case 'break':
|
|
||||||
case 'continue':
|
|
||||||
return 'STATEMENT';
|
|
||||||
default:
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
this.token(tag, id);
|
|
||||||
if (colon) {
|
|
||||||
this.token(':', ':');
|
|
||||||
}
|
|
||||||
return input.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.numberToken = function() {
|
|
||||||
var binaryLiteral, lexedLength, match, number, octalLiteral;
|
|
||||||
if (!(match = NUMBER.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
number = match[0];
|
|
||||||
if (/^0[BOX]/.test(number)) {
|
|
||||||
this.error("radix prefix '" + number + "' must be lowercase");
|
|
||||||
} else if (/E/.test(number) && !/^0x/.test(number)) {
|
|
||||||
this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'");
|
|
||||||
} else if (/^0\d*[89]/.test(number)) {
|
|
||||||
this.error("decimal literal '" + number + "' must not be prefixed with '0'");
|
|
||||||
} else if (/^0\d+/.test(number)) {
|
|
||||||
this.error("octal literal '" + number + "' must be prefixed with '0o'");
|
|
||||||
}
|
|
||||||
lexedLength = number.length;
|
|
||||||
if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
|
|
||||||
number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16);
|
|
||||||
}
|
|
||||||
if (binaryLiteral = /^0b([01]+)/.exec(number)) {
|
|
||||||
number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
|
|
||||||
}
|
|
||||||
this.token('NUMBER', number);
|
|
||||||
return lexedLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.stringToken = function() {
|
|
||||||
var match, octalEsc, string;
|
|
||||||
switch (this.chunk.charAt(0)) {
|
|
||||||
case "'":
|
|
||||||
if (!(match = SIMPLESTR.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
if (!(string = this.balancedString(this.chunk, '"'))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (0 < string.indexOf('#{', 1)) {
|
|
||||||
this.interpolateString(string.slice(1, -1));
|
|
||||||
} else {
|
|
||||||
this.token('STRING', this.escapeLines(string));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
|
|
||||||
this.error("octal escape sequences " + string + " are not allowed");
|
|
||||||
}
|
|
||||||
this.line += count(string, '\n');
|
|
||||||
return string.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.heredocToken = function() {
|
|
||||||
var doc, heredoc, match, quote;
|
|
||||||
if (!(match = HEREDOC.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
heredoc = match[0];
|
|
||||||
quote = heredoc.charAt(0);
|
|
||||||
doc = this.sanitizeHeredoc(match[2], {
|
|
||||||
quote: quote,
|
|
||||||
indent: null
|
|
||||||
});
|
|
||||||
if (quote === '"' && 0 <= doc.indexOf('#{')) {
|
|
||||||
this.interpolateString(doc, {
|
|
||||||
heredoc: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.token('STRING', this.makeString(doc, quote, true));
|
|
||||||
}
|
|
||||||
this.line += count(heredoc, '\n');
|
|
||||||
return heredoc.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.commentToken = function() {
|
|
||||||
var comment, here, match;
|
|
||||||
if (!(match = this.chunk.match(COMMENT))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
comment = match[0], here = match[1];
|
|
||||||
if (here) {
|
|
||||||
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
|
|
||||||
herecomment: true,
|
|
||||||
indent: Array(this.indent + 1).join(' ')
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
this.line += count(comment, '\n');
|
|
||||||
return comment.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.jsToken = function() {
|
|
||||||
var match, script;
|
|
||||||
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
this.token('JS', (script = match[0]).slice(1, -1));
|
|
||||||
return script.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.regexToken = function() {
|
|
||||||
var flags, length, match, prev, regex, _ref2, _ref3;
|
|
||||||
if (this.chunk.charAt(0) !== '/') {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (match = HEREGEX.exec(this.chunk)) {
|
|
||||||
length = this.heregexToken(match);
|
|
||||||
this.line += count(match[0], '\n');
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
prev = last(this.tokens);
|
|
||||||
if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!(match = REGEX.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
|
|
||||||
if (regex.slice(0, 2) === '/*') {
|
|
||||||
this.error('regular expressions cannot begin with `*`');
|
|
||||||
}
|
|
||||||
if (regex === '//') {
|
|
||||||
regex = '/(?:)/';
|
|
||||||
}
|
|
||||||
this.token('REGEX', "" + regex + flags);
|
|
||||||
return match.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.heregexToken = function(match) {
|
|
||||||
var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
|
|
||||||
heregex = match[0], body = match[1], flags = match[2];
|
|
||||||
if (0 > body.indexOf('#{')) {
|
|
||||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
|
||||||
if (re.match(/^\*/)) {
|
|
||||||
this.error('regular expressions cannot begin with `*`');
|
|
||||||
}
|
|
||||||
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
|
|
||||||
return heregex.length;
|
|
||||||
}
|
|
||||||
this.token('IDENTIFIER', 'RegExp');
|
|
||||||
this.tokens.push(['CALL_START', '(']);
|
|
||||||
tokens = [];
|
|
||||||
_ref2 = this.interpolateString(body, {
|
|
||||||
regex: true
|
|
||||||
});
|
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
||||||
_ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
|
|
||||||
if (tag === 'TOKENS') {
|
|
||||||
tokens.push.apply(tokens, value);
|
|
||||||
} else {
|
|
||||||
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
value = value.replace(/\\/g, '\\\\');
|
|
||||||
tokens.push(['STRING', this.makeString(value, '"', true)]);
|
|
||||||
}
|
|
||||||
tokens.push(['+', '+']);
|
|
||||||
}
|
|
||||||
tokens.pop();
|
|
||||||
if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
|
|
||||||
this.tokens.push(['STRING', '""'], ['+', '+']);
|
|
||||||
}
|
|
||||||
(_ref5 = this.tokens).push.apply(_ref5, tokens);
|
|
||||||
if (flags) {
|
|
||||||
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
|
|
||||||
}
|
|
||||||
this.token(')', ')');
|
|
||||||
return heregex.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.lineToken = function() {
|
|
||||||
var diff, indent, match, noNewlines, prev, size;
|
|
||||||
if (!(match = MULTI_DENT.exec(this.chunk))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
indent = match[0];
|
|
||||||
this.line += count(indent, '\n');
|
|
||||||
this.seenFor = false;
|
|
||||||
prev = last(this.tokens, 1);
|
|
||||||
size = indent.length - 1 - indent.lastIndexOf('\n');
|
|
||||||
noNewlines = this.unfinished();
|
|
||||||
if (size - this.indebt === this.indent) {
|
|
||||||
if (noNewlines) {
|
|
||||||
this.suppressNewlines();
|
|
||||||
} else {
|
|
||||||
this.newlineToken();
|
|
||||||
}
|
|
||||||
return indent.length;
|
|
||||||
}
|
|
||||||
if (size > this.indent) {
|
|
||||||
if (noNewlines) {
|
|
||||||
this.indebt = size - this.indent;
|
|
||||||
this.suppressNewlines();
|
|
||||||
return indent.length;
|
|
||||||
}
|
|
||||||
diff = size - this.indent + this.outdebt;
|
|
||||||
this.token('INDENT', diff);
|
|
||||||
this.indents.push(diff);
|
|
||||||
this.ends.push('OUTDENT');
|
|
||||||
this.outdebt = this.indebt = 0;
|
|
||||||
} else {
|
|
||||||
this.indebt = 0;
|
|
||||||
this.outdentToken(this.indent - size, noNewlines);
|
|
||||||
}
|
|
||||||
this.indent = size;
|
|
||||||
return indent.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.outdentToken = function(moveOut, noNewlines) {
|
|
||||||
var dent, len;
|
|
||||||
while (moveOut > 0) {
|
|
||||||
len = this.indents.length - 1;
|
|
||||||
if (this.indents[len] === void 0) {
|
|
||||||
moveOut = 0;
|
|
||||||
} else if (this.indents[len] === this.outdebt) {
|
|
||||||
moveOut -= this.outdebt;
|
|
||||||
this.outdebt = 0;
|
|
||||||
} else if (this.indents[len] < this.outdebt) {
|
|
||||||
this.outdebt -= this.indents[len];
|
|
||||||
moveOut -= this.indents[len];
|
|
||||||
} else {
|
|
||||||
dent = this.indents.pop() - this.outdebt;
|
|
||||||
moveOut -= dent;
|
|
||||||
this.outdebt = 0;
|
|
||||||
this.pair('OUTDENT');
|
|
||||||
this.token('OUTDENT', dent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dent) {
|
|
||||||
this.outdebt -= moveOut;
|
|
||||||
}
|
|
||||||
while (this.value() === ';') {
|
|
||||||
this.tokens.pop();
|
|
||||||
}
|
|
||||||
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
|
|
||||||
this.token('TERMINATOR', '\n');
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.whitespaceToken = function() {
|
|
||||||
var match, nline, prev;
|
|
||||||
if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
prev = last(this.tokens);
|
|
||||||
if (prev) {
|
|
||||||
prev[match ? 'spaced' : 'newLine'] = true;
|
|
||||||
}
|
|
||||||
if (match) {
|
|
||||||
return match[0].length;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.newlineToken = function() {
|
|
||||||
while (this.value() === ';') {
|
|
||||||
this.tokens.pop();
|
|
||||||
}
|
|
||||||
if (this.tag() !== 'TERMINATOR') {
|
|
||||||
this.token('TERMINATOR', '\n');
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.suppressNewlines = function() {
|
|
||||||
if (this.value() === '\\') {
|
|
||||||
this.tokens.pop();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.literalToken = function() {
|
|
||||||
var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
|
|
||||||
if (match = OPERATOR.exec(this.chunk)) {
|
|
||||||
value = match[0];
|
|
||||||
if (CODE.test(value)) {
|
|
||||||
this.tagParameters();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = this.chunk.charAt(0);
|
|
||||||
}
|
|
||||||
tag = value;
|
|
||||||
prev = last(this.tokens);
|
|
||||||
if (value === '=' && prev) {
|
|
||||||
if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
|
|
||||||
this.error("reserved word \"" + (this.value()) + "\" can't be assigned");
|
|
||||||
}
|
|
||||||
if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
|
|
||||||
prev[0] = 'COMPOUND_ASSIGN';
|
|
||||||
prev[1] += '=';
|
|
||||||
return value.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value === ';') {
|
|
||||||
this.seenFor = false;
|
|
||||||
tag = 'TERMINATOR';
|
|
||||||
} else if (__indexOf.call(MATH, value) >= 0) {
|
|
||||||
tag = 'MATH';
|
|
||||||
} else if (__indexOf.call(COMPARE, value) >= 0) {
|
|
||||||
tag = 'COMPARE';
|
|
||||||
} else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
|
|
||||||
tag = 'COMPOUND_ASSIGN';
|
|
||||||
} else if (__indexOf.call(UNARY, value) >= 0) {
|
|
||||||
tag = 'UNARY';
|
|
||||||
} else if (__indexOf.call(SHIFT, value) >= 0) {
|
|
||||||
tag = 'SHIFT';
|
|
||||||
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
|
|
||||||
tag = 'LOGIC';
|
|
||||||
} else if (prev && !prev.spaced) {
|
|
||||||
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
|
|
||||||
if (prev[0] === '?') {
|
|
||||||
prev[0] = 'FUNC_EXIST';
|
|
||||||
}
|
|
||||||
tag = 'CALL_START';
|
|
||||||
} else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
|
|
||||||
tag = 'INDEX_START';
|
|
||||||
switch (prev[0]) {
|
|
||||||
case '?':
|
|
||||||
prev[0] = 'INDEX_SOAK';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (value) {
|
|
||||||
case '(':
|
|
||||||
case '{':
|
|
||||||
case '[':
|
|
||||||
this.ends.push(INVERSES[value]);
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
case '}':
|
|
||||||
case ']':
|
|
||||||
this.pair(value);
|
|
||||||
}
|
|
||||||
this.token(tag, value);
|
|
||||||
return value.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
|
||||||
var attempt, herecomment, indent, match, _ref2;
|
|
||||||
indent = options.indent, herecomment = options.herecomment;
|
|
||||||
if (herecomment) {
|
|
||||||
if (HEREDOC_ILLEGAL.test(doc)) {
|
|
||||||
this.error("block comment cannot contain \"*/\", starting");
|
|
||||||
}
|
|
||||||
if (doc.indexOf('\n') <= 0) {
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (match = HEREDOC_INDENT.exec(doc)) {
|
|
||||||
attempt = match[1];
|
|
||||||
if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
|
|
||||||
indent = attempt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (indent) {
|
|
||||||
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
|
|
||||||
}
|
|
||||||
if (!herecomment) {
|
|
||||||
doc = doc.replace(/^\n/, '');
|
|
||||||
}
|
|
||||||
return doc;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.tagParameters = function() {
|
|
||||||
var i, stack, tok, tokens;
|
|
||||||
if (this.tag() !== ')') {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
stack = [];
|
|
||||||
tokens = this.tokens;
|
|
||||||
i = tokens.length;
|
|
||||||
tokens[--i][0] = 'PARAM_END';
|
|
||||||
while (tok = tokens[--i]) {
|
|
||||||
switch (tok[0]) {
|
|
||||||
case ')':
|
|
||||||
stack.push(tok);
|
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
case 'CALL_START':
|
|
||||||
if (stack.length) {
|
|
||||||
stack.pop();
|
|
||||||
} else if (tok[0] === '(') {
|
|
||||||
tok[0] = 'PARAM_START';
|
|
||||||
return this;
|
|
||||||
} else {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.closeIndentation = function() {
|
|
||||||
return this.outdentToken(this.indent);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.balancedString = function(str, end) {
|
|
||||||
var continueCount, i, letter, match, prev, stack, _i, _ref2;
|
|
||||||
continueCount = 0;
|
|
||||||
stack = [end];
|
|
||||||
for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
|
|
||||||
if (continueCount) {
|
|
||||||
--continueCount;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (letter = str.charAt(i)) {
|
|
||||||
case '\\':
|
|
||||||
++continueCount;
|
|
||||||
continue;
|
|
||||||
case end:
|
|
||||||
stack.pop();
|
|
||||||
if (!stack.length) {
|
|
||||||
return str.slice(0, i + 1 || 9e9);
|
|
||||||
}
|
|
||||||
end = stack[stack.length - 1];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (end === '}' && (letter === '"' || letter === "'")) {
|
|
||||||
stack.push(end = letter);
|
|
||||||
} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
|
|
||||||
continueCount += match[0].length - 1;
|
|
||||||
} else if (end === '}' && letter === '{') {
|
|
||||||
stack.push(end = '}');
|
|
||||||
} else if (end === '"' && prev === '#' && letter === '{') {
|
|
||||||
stack.push(end = '}');
|
|
||||||
}
|
|
||||||
prev = letter;
|
|
||||||
}
|
|
||||||
return this.error("missing " + (stack.pop()) + ", starting");
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.interpolateString = function(str, options) {
|
|
||||||
var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
heredoc = options.heredoc, regex = options.regex;
|
|
||||||
tokens = [];
|
|
||||||
pi = 0;
|
|
||||||
i = -1;
|
|
||||||
while (letter = str.charAt(i += 1)) {
|
|
||||||
if (letter === '\\') {
|
|
||||||
i += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pi < i) {
|
|
||||||
tokens.push(['NEOSTRING', str.slice(pi, i)]);
|
|
||||||
}
|
|
||||||
inner = expr.slice(1, -1);
|
|
||||||
if (inner.length) {
|
|
||||||
nested = new Lexer().tokenize(inner, {
|
|
||||||
line: this.line,
|
|
||||||
rewrite: false
|
|
||||||
});
|
|
||||||
nested.pop();
|
|
||||||
if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
|
|
||||||
nested.shift();
|
|
||||||
}
|
|
||||||
if (len = nested.length) {
|
|
||||||
if (len > 1) {
|
|
||||||
nested.unshift(['(', '(', this.line]);
|
|
||||||
nested.push([')', ')', this.line]);
|
|
||||||
}
|
|
||||||
tokens.push(['TOKENS', nested]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i += expr.length;
|
|
||||||
pi = i + 1;
|
|
||||||
}
|
|
||||||
if ((i > pi && pi < str.length)) {
|
|
||||||
tokens.push(['NEOSTRING', str.slice(pi)]);
|
|
||||||
}
|
|
||||||
if (regex) {
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
if (!tokens.length) {
|
|
||||||
return this.token('STRING', '""');
|
|
||||||
}
|
|
||||||
if (tokens[0][0] !== 'NEOSTRING') {
|
|
||||||
tokens.unshift(['', '']);
|
|
||||||
}
|
|
||||||
if (interpolated = tokens.length > 1) {
|
|
||||||
this.token('(', '(');
|
|
||||||
}
|
|
||||||
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
|
|
||||||
_ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
|
|
||||||
if (i) {
|
|
||||||
this.token('+', '+');
|
|
||||||
}
|
|
||||||
if (tag === 'TOKENS') {
|
|
||||||
(_ref4 = this.tokens).push.apply(_ref4, value);
|
|
||||||
} else {
|
|
||||||
this.token('STRING', this.makeString(value, '"', heredoc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (interpolated) {
|
|
||||||
this.token(')', ')');
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.pair = function(tag) {
|
|
||||||
var size, wanted;
|
|
||||||
if (tag !== (wanted = last(this.ends))) {
|
|
||||||
if ('OUTDENT' !== wanted) {
|
|
||||||
this.error("unmatched " + tag);
|
|
||||||
}
|
|
||||||
this.indent -= size = last(this.indents);
|
|
||||||
this.outdentToken(size, true);
|
|
||||||
return this.pair(tag);
|
|
||||||
}
|
|
||||||
return this.ends.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.token = function(tag, value) {
|
|
||||||
return this.tokens.push([tag, value, this.line]);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.tag = function(index, tag) {
|
|
||||||
var tok;
|
|
||||||
return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.value = function(index, val) {
|
|
||||||
var tok;
|
|
||||||
return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.unfinished = function() {
|
|
||||||
var _ref2;
|
|
||||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
|
||||||
return str.replace(MULTILINER, heredoc ? '\\n' : '');
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.makeString = function(body, quote, heredoc) {
|
|
||||||
if (!body) {
|
|
||||||
return quote + quote;
|
|
||||||
}
|
|
||||||
body = body.replace(/\\([\s\S])/g, function(match, contents) {
|
|
||||||
if (contents === '\n' || contents === quote) {
|
|
||||||
return contents;
|
|
||||||
} else {
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
body = body.replace(RegExp("" + quote, "g"), '\\$&');
|
|
||||||
return quote + this.escapeLines(body, heredoc) + quote;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lexer.prototype.error = function(message) {
|
|
||||||
throw SyntaxError("" + message + " on line " + (this.line + 1));
|
|
||||||
};
|
|
||||||
|
|
||||||
return Lexer;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
|
|
||||||
|
|
||||||
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
|
|
||||||
|
|
||||||
COFFEE_ALIAS_MAP = {
|
|
||||||
and: '&&',
|
|
||||||
or: '||',
|
|
||||||
is: '==',
|
|
||||||
isnt: '!=',
|
|
||||||
not: '!',
|
|
||||||
yes: 'true',
|
|
||||||
no: 'false',
|
|
||||||
on: 'true',
|
|
||||||
off: 'false'
|
|
||||||
};
|
|
||||||
|
|
||||||
COFFEE_ALIASES = (function() {
|
|
||||||
var _results;
|
|
||||||
_results = [];
|
|
||||||
for (key in COFFEE_ALIAS_MAP) {
|
|
||||||
_results.push(key);
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
|
|
||||||
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
|
|
||||||
|
|
||||||
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield'];
|
|
||||||
|
|
||||||
STRICT_PROSCRIBED = ['arguments', 'eval'];
|
|
||||||
|
|
||||||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
|
|
||||||
|
|
||||||
exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED);
|
|
||||||
|
|
||||||
exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED;
|
|
||||||
|
|
||||||
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
|
|
||||||
|
|
||||||
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
|
|
||||||
|
|
||||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
|
|
||||||
|
|
||||||
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
|
|
||||||
|
|
||||||
WHITESPACE = /^[^\n\S]+/;
|
|
||||||
|
|
||||||
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;
|
|
||||||
|
|
||||||
CODE = /^[-=]>/;
|
|
||||||
|
|
||||||
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
|
|
||||||
|
|
||||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
|
|
||||||
|
|
||||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
|
||||||
|
|
||||||
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
|
|
||||||
|
|
||||||
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
|
|
||||||
|
|
||||||
HEREGEX_OMIT = /\s+(?:#.*)?/g;
|
|
||||||
|
|
||||||
MULTILINER = /\n/g;
|
|
||||||
|
|
||||||
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
|
|
||||||
|
|
||||||
HEREDOC_ILLEGAL = /\*\//;
|
|
||||||
|
|
||||||
LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
|
|
||||||
|
|
||||||
TRAILING_SPACES = /\s+$/;
|
|
||||||
|
|
||||||
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
|
|
||||||
|
|
||||||
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
|
|
||||||
|
|
||||||
LOGIC = ['&&', '||', '&', '|', '^'];
|
|
||||||
|
|
||||||
SHIFT = ['<<', '>>', '>>>'];
|
|
||||||
|
|
||||||
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
|
|
||||||
|
|
||||||
MATH = ['*', '/', '%'];
|
|
||||||
|
|
||||||
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
|
||||||
|
|
||||||
BOOL = ['TRUE', 'FALSE'];
|
|
||||||
|
|
||||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']'];
|
|
||||||
|
|
||||||
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
|
|
||||||
|
|
||||||
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
|
|
||||||
|
|
||||||
INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED');
|
|
||||||
|
|
||||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
|
||||||
|
|
||||||
}).call(this);
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,138 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
|
||||||
|
|
||||||
exports.OptionParser = OptionParser = (function() {
|
|
||||||
|
|
||||||
function OptionParser(rules, banner) {
|
|
||||||
this.banner = banner;
|
|
||||||
this.rules = buildRules(rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionParser.prototype.parse = function(args) {
|
|
||||||
var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, seenNonOptionArg, skippingArgument, value, _i, _j, _len, _len1, _ref;
|
|
||||||
options = {
|
|
||||||
"arguments": []
|
|
||||||
};
|
|
||||||
skippingArgument = false;
|
|
||||||
originalArgs = args;
|
|
||||||
args = normalizeArguments(args);
|
|
||||||
for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
|
|
||||||
arg = args[i];
|
|
||||||
if (skippingArgument) {
|
|
||||||
skippingArgument = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (arg === '--') {
|
|
||||||
pos = originalArgs.indexOf('--');
|
|
||||||
options["arguments"] = options["arguments"].concat(originalArgs.slice(pos + 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
|
|
||||||
seenNonOptionArg = options["arguments"].length > 0;
|
|
||||||
if (!seenNonOptionArg) {
|
|
||||||
matchedRule = false;
|
|
||||||
_ref = this.rules;
|
|
||||||
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
|
||||||
rule = _ref[_j];
|
|
||||||
if (rule.shortFlag === arg || rule.longFlag === arg) {
|
|
||||||
value = true;
|
|
||||||
if (rule.hasArgument) {
|
|
||||||
skippingArgument = true;
|
|
||||||
value = args[i + 1];
|
|
||||||
}
|
|
||||||
options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
|
|
||||||
matchedRule = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isOption && !matchedRule) {
|
|
||||||
throw new Error("unrecognized option: " + arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (seenNonOptionArg || !isOption) {
|
|
||||||
options["arguments"].push(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionParser.prototype.help = function() {
|
|
||||||
var letPart, lines, rule, spaces, _i, _len, _ref;
|
|
||||||
lines = [];
|
|
||||||
if (this.banner) {
|
|
||||||
lines.unshift("" + this.banner + "\n");
|
|
||||||
}
|
|
||||||
_ref = this.rules;
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
rule = _ref[_i];
|
|
||||||
spaces = 15 - rule.longFlag.length;
|
|
||||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
|
||||||
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
|
||||||
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
|
|
||||||
}
|
|
||||||
return "\n" + (lines.join('\n')) + "\n";
|
|
||||||
};
|
|
||||||
|
|
||||||
return OptionParser;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
LONG_FLAG = /^(--\w[\w\-]*)/;
|
|
||||||
|
|
||||||
SHORT_FLAG = /^(-\w)$/;
|
|
||||||
|
|
||||||
MULTI_FLAG = /^-(\w{2,})/;
|
|
||||||
|
|
||||||
OPTIONAL = /\[(\w+(\*?))\]/;
|
|
||||||
|
|
||||||
buildRules = function(rules) {
|
|
||||||
var tuple, _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = rules.length; _i < _len; _i++) {
|
|
||||||
tuple = rules[_i];
|
|
||||||
if (tuple.length < 3) {
|
|
||||||
tuple.unshift(null);
|
|
||||||
}
|
|
||||||
_results.push(buildRule.apply(null, tuple));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
buildRule = function(shortFlag, longFlag, description, options) {
|
|
||||||
var match;
|
|
||||||
if (options == null) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
match = longFlag.match(OPTIONAL);
|
|
||||||
longFlag = longFlag.match(LONG_FLAG)[1];
|
|
||||||
return {
|
|
||||||
name: longFlag.substr(2),
|
|
||||||
shortFlag: shortFlag,
|
|
||||||
longFlag: longFlag,
|
|
||||||
description: description,
|
|
||||||
hasArgument: !!(match && match[1]),
|
|
||||||
isList: !!(match && match[2])
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
normalizeArguments = function(args) {
|
|
||||||
var arg, l, match, result, _i, _j, _len, _len1, _ref;
|
|
||||||
args = args.slice(0);
|
|
||||||
result = [];
|
|
||||||
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
|
||||||
arg = args[_i];
|
|
||||||
if (match = arg.match(MULTI_FLAG)) {
|
|
||||||
_ref = match[1].split('');
|
|
||||||
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
|
||||||
l = _ref[_j];
|
|
||||||
result.push('-' + l);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.push(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(this);
|
|
File diff suppressed because one or more lines are too long
|
@ -1,261 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var ACCESSOR, CoffeeScript, Module, REPL_PROMPT, REPL_PROMPT_CONTINUATION, REPL_PROMPT_MULTILINE, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, inspect, multilineMode, pipedInput, readline, repl, run, stdin, stdout;
|
|
||||||
|
|
||||||
stdin = process.openStdin();
|
|
||||||
|
|
||||||
stdout = process.stdout;
|
|
||||||
|
|
||||||
CoffeeScript = require('./coffee-script');
|
|
||||||
|
|
||||||
readline = require('readline');
|
|
||||||
|
|
||||||
inspect = require('util').inspect;
|
|
||||||
|
|
||||||
Script = require('vm').Script;
|
|
||||||
|
|
||||||
Module = require('module');
|
|
||||||
|
|
||||||
REPL_PROMPT = 'coffee> ';
|
|
||||||
|
|
||||||
REPL_PROMPT_MULTILINE = '------> ';
|
|
||||||
|
|
||||||
REPL_PROMPT_CONTINUATION = '......> ';
|
|
||||||
|
|
||||||
enableColours = false;
|
|
||||||
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
enableColours = !process.env.NODE_DISABLE_COLORS;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = function(err) {
|
|
||||||
return stdout.write((err.stack || err.toString()) + '\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/;
|
|
||||||
|
|
||||||
SIMPLEVAR = /(\w+)$/i;
|
|
||||||
|
|
||||||
autocomplete = function(text) {
|
|
||||||
return completeAttribute(text) || completeVariable(text) || [[], text];
|
|
||||||
};
|
|
||||||
|
|
||||||
completeAttribute = function(text) {
|
|
||||||
var all, completions, key, match, obj, possibilities, prefix, val;
|
|
||||||
if (match = text.match(ACCESSOR)) {
|
|
||||||
all = match[0], obj = match[1], prefix = match[2];
|
|
||||||
try {
|
|
||||||
val = Script.runInThisContext(obj);
|
|
||||||
} catch (error) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
val = Object(val);
|
|
||||||
possibilities = Object.getOwnPropertyNames(val);
|
|
||||||
for (key in val) {
|
|
||||||
if (~possibilities.indexOf(val)) {
|
|
||||||
possibilities.push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
completions = getCompletions(prefix, possibilities);
|
|
||||||
return [completions, prefix];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
completeVariable = function(text) {
|
|
||||||
var completions, free, keywords, possibilities, r, vars, _ref;
|
|
||||||
free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0;
|
|
||||||
if (text === "") {
|
|
||||||
free = "";
|
|
||||||
}
|
|
||||||
if (free != null) {
|
|
||||||
vars = Script.runInThisContext('Object.getOwnPropertyNames(Object(this))');
|
|
||||||
keywords = (function() {
|
|
||||||
var _i, _len, _ref1, _results;
|
|
||||||
_ref1 = CoffeeScript.RESERVED;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
||||||
r = _ref1[_i];
|
|
||||||
if (r.slice(0, 2) !== '__') {
|
|
||||||
_results.push(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
})();
|
|
||||||
possibilities = vars.concat(keywords);
|
|
||||||
completions = getCompletions(free, possibilities);
|
|
||||||
return [completions, free];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
getCompletions = function(prefix, candidates) {
|
|
||||||
var el, _i, _len, _results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = candidates.length; _i < _len; _i++) {
|
|
||||||
el = candidates[_i];
|
|
||||||
if (el.indexOf(prefix) === 0) {
|
|
||||||
_results.push(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
process.on('uncaughtException', error);
|
|
||||||
|
|
||||||
backlog = '';
|
|
||||||
|
|
||||||
run = function(buffer) {
|
|
||||||
var code, returnValue, _;
|
|
||||||
buffer = buffer.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, "$1$2$3");
|
|
||||||
buffer = buffer.replace(/[\r\n]+$/, "");
|
|
||||||
if (multilineMode) {
|
|
||||||
backlog += "" + buffer + "\n";
|
|
||||||
repl.setPrompt(REPL_PROMPT_CONTINUATION);
|
|
||||||
repl.prompt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!buffer.toString().trim() && !backlog) {
|
|
||||||
repl.prompt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
code = backlog += buffer;
|
|
||||||
if (code[code.length - 1] === '\\') {
|
|
||||||
backlog = "" + backlog.slice(0, -1) + "\n";
|
|
||||||
repl.setPrompt(REPL_PROMPT_CONTINUATION);
|
|
||||||
repl.prompt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
repl.setPrompt(REPL_PROMPT);
|
|
||||||
backlog = '';
|
|
||||||
try {
|
|
||||||
_ = global._;
|
|
||||||
returnValue = CoffeeScript["eval"]("_=(" + code + "\n)", {
|
|
||||||
filename: 'repl',
|
|
||||||
modulename: 'repl'
|
|
||||||
});
|
|
||||||
if (returnValue === void 0) {
|
|
||||||
global._ = _;
|
|
||||||
}
|
|
||||||
repl.output.write("" + (inspect(returnValue, false, 2, enableColours)) + "\n");
|
|
||||||
} catch (err) {
|
|
||||||
error(err);
|
|
||||||
}
|
|
||||||
return repl.prompt();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (stdin.readable) {
|
|
||||||
pipedInput = '';
|
|
||||||
repl = {
|
|
||||||
prompt: function() {
|
|
||||||
return stdout.write(this._prompt);
|
|
||||||
},
|
|
||||||
setPrompt: function(p) {
|
|
||||||
return this._prompt = p;
|
|
||||||
},
|
|
||||||
input: stdin,
|
|
||||||
output: stdout,
|
|
||||||
on: function() {}
|
|
||||||
};
|
|
||||||
stdin.on('data', function(chunk) {
|
|
||||||
var line, lines, _i, _len, _ref;
|
|
||||||
pipedInput += chunk;
|
|
||||||
if (!/\n/.test(pipedInput)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lines = pipedInput.split("\n");
|
|
||||||
pipedInput = lines[lines.length - 1];
|
|
||||||
_ref = lines.slice(0, -1);
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
line = _ref[_i];
|
|
||||||
if (!(line)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stdout.write("" + line + "\n");
|
|
||||||
run(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stdin.on('end', function() {
|
|
||||||
var line, _i, _len, _ref;
|
|
||||||
_ref = pipedInput.trim().split("\n");
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
line = _ref[_i];
|
|
||||||
if (!(line)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stdout.write("" + line + "\n");
|
|
||||||
run(line);
|
|
||||||
}
|
|
||||||
stdout.write('\n');
|
|
||||||
return process.exit(0);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (readline.createInterface.length < 3) {
|
|
||||||
repl = readline.createInterface(stdin, autocomplete);
|
|
||||||
stdin.on('data', function(buffer) {
|
|
||||||
return repl.write(buffer);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
repl = readline.createInterface(stdin, stdout, autocomplete);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
multilineMode = false;
|
|
||||||
|
|
||||||
repl.input.on('keypress', function(char, key) {
|
|
||||||
var cursorPos, newPrompt;
|
|
||||||
if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cursorPos = repl.cursor;
|
|
||||||
repl.output.cursorTo(0);
|
|
||||||
repl.output.clearLine(1);
|
|
||||||
multilineMode = !multilineMode;
|
|
||||||
if (!multilineMode && backlog) {
|
|
||||||
repl._line();
|
|
||||||
}
|
|
||||||
backlog = '';
|
|
||||||
repl.setPrompt((newPrompt = multilineMode ? REPL_PROMPT_MULTILINE : REPL_PROMPT));
|
|
||||||
repl.prompt();
|
|
||||||
return repl.output.cursorTo(newPrompt.length + (repl.cursor = cursorPos));
|
|
||||||
});
|
|
||||||
|
|
||||||
repl.input.on('keypress', function(char, key) {
|
|
||||||
if (!(multilineMode && repl.line)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'd')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
multilineMode = false;
|
|
||||||
return repl._line();
|
|
||||||
});
|
|
||||||
|
|
||||||
repl.on('attemptClose', function() {
|
|
||||||
if (multilineMode) {
|
|
||||||
multilineMode = false;
|
|
||||||
repl.output.cursorTo(0);
|
|
||||||
repl.output.clearLine(1);
|
|
||||||
repl._onLine(repl.line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (backlog) {
|
|
||||||
backlog = '';
|
|
||||||
repl.output.write('\n');
|
|
||||||
repl.setPrompt(REPL_PROMPT);
|
|
||||||
return repl.prompt();
|
|
||||||
} else {
|
|
||||||
return repl.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
repl.on('close', function() {
|
|
||||||
repl.output.write('\n');
|
|
||||||
return repl.input.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
repl.on('line', run);
|
|
||||||
|
|
||||||
repl.setPrompt(REPL_PROMPT);
|
|
||||||
|
|
||||||
repl.prompt();
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,349 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref,
|
|
||||||
__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; },
|
|
||||||
__slice = [].slice;
|
|
||||||
|
|
||||||
exports.Rewriter = (function() {
|
|
||||||
|
|
||||||
function Rewriter() {}
|
|
||||||
|
|
||||||
Rewriter.prototype.rewrite = function(tokens) {
|
|
||||||
this.tokens = tokens;
|
|
||||||
this.removeLeadingNewlines();
|
|
||||||
this.removeMidExpressionNewlines();
|
|
||||||
this.closeOpenCalls();
|
|
||||||
this.closeOpenIndexes();
|
|
||||||
this.addImplicitIndentation();
|
|
||||||
this.tagPostfixConditionals();
|
|
||||||
this.addImplicitBraces();
|
|
||||||
this.addImplicitParentheses();
|
|
||||||
return this.tokens;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.scanTokens = function(block) {
|
|
||||||
var i, token, tokens;
|
|
||||||
tokens = this.tokens;
|
|
||||||
i = 0;
|
|
||||||
while (token = tokens[i]) {
|
|
||||||
i += block.call(this, token, i, tokens);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.detectEnd = function(i, condition, action) {
|
|
||||||
var levels, token, tokens, _ref, _ref1;
|
|
||||||
tokens = this.tokens;
|
|
||||||
levels = 0;
|
|
||||||
while (token = tokens[i]) {
|
|
||||||
if (levels === 0 && condition.call(this, token, i)) {
|
|
||||||
return action.call(this, token, i);
|
|
||||||
}
|
|
||||||
if (!token || levels < 0) {
|
|
||||||
return action.call(this, token, i - 1);
|
|
||||||
}
|
|
||||||
if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
|
||||||
levels += 1;
|
|
||||||
} else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) {
|
|
||||||
levels -= 1;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
return i - 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.removeLeadingNewlines = function() {
|
|
||||||
var i, tag, _i, _len, _ref;
|
|
||||||
_ref = this.tokens;
|
|
||||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
|
||||||
tag = _ref[i][0];
|
|
||||||
if (tag !== 'TERMINATOR') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i) {
|
|
||||||
return this.tokens.splice(0, i);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.removeMidExpressionNewlines = function() {
|
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
|
||||||
var _ref;
|
|
||||||
if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
tokens.splice(i, 1);
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.closeOpenCalls = function() {
|
|
||||||
var action, condition;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var _ref;
|
|
||||||
return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')';
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END';
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i) {
|
|
||||||
if (token[0] === 'CALL_START') {
|
|
||||||
this.detectEnd(i + 1, condition, action);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.closeOpenIndexes = function() {
|
|
||||||
var action, condition;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = token[0]) === ']' || _ref === 'INDEX_END';
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
return token[0] = 'INDEX_END';
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i) {
|
|
||||||
if (token[0] === 'INDEX_START') {
|
|
||||||
this.detectEnd(i + 1, condition, action);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.addImplicitBraces = function() {
|
|
||||||
var action, condition, sameLine, stack, start, startIndent, startIndex, startsLine;
|
|
||||||
stack = [];
|
|
||||||
start = null;
|
|
||||||
startsLine = null;
|
|
||||||
sameLine = true;
|
|
||||||
startIndent = 0;
|
|
||||||
startIndex = 0;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var one, tag, three, two, _ref, _ref1;
|
|
||||||
_ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2];
|
|
||||||
if ('HERECOMMENT' === (one != null ? one[0] : void 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tag = token[0];
|
|
||||||
if (__indexOf.call(LINEBREAKS, tag) >= 0) {
|
|
||||||
sameLine = false;
|
|
||||||
}
|
|
||||||
return (((tag === 'TERMINATOR' || tag === 'OUTDENT') || (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine && !(i - startIndex === 1))) && ((!startsLine && this.tag(i - 1) !== ',') || !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':'))) || (tag === ',' && one && ((_ref1 = one[0]) !== 'IDENTIFIER' && _ref1 !== 'NUMBER' && _ref1 !== 'STRING' && _ref1 !== '@' && _ref1 !== 'TERMINATOR' && _ref1 !== 'OUTDENT'));
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
var tok;
|
|
||||||
tok = this.generate('}', '}', token[2]);
|
|
||||||
return this.tokens.splice(i, 0, tok);
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
|
||||||
var ago, idx, prevTag, tag, tok, value, _ref, _ref1;
|
|
||||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
|
||||||
stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
|
|
||||||
start = stack.pop();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref1 = stack[stack.length - 1]) != null ? _ref1[0] : void 0) !== '{'))) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
sameLine = true;
|
|
||||||
startIndex = i + 1;
|
|
||||||
stack.push(['{']);
|
|
||||||
idx = ago === '@' ? i - 2 : i - 1;
|
|
||||||
while (this.tag(idx - 2) === 'HERECOMMENT') {
|
|
||||||
idx -= 2;
|
|
||||||
}
|
|
||||||
prevTag = this.tag(idx - 1);
|
|
||||||
startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0);
|
|
||||||
value = new String('{');
|
|
||||||
value.generated = true;
|
|
||||||
tok = this.generate('{', value, token[2]);
|
|
||||||
tokens.splice(idx, 0, tok);
|
|
||||||
this.detectEnd(i + 2, condition, action);
|
|
||||||
return 2;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.addImplicitParentheses = function() {
|
|
||||||
var action, condition, noCall, seenControl, seenSingle;
|
|
||||||
noCall = seenSingle = seenControl = false;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var post, tag, _ref, _ref1;
|
|
||||||
tag = token[0];
|
|
||||||
if (!seenSingle && token.fromThen) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>' || tag === 'CLASS') {
|
|
||||||
seenSingle = true;
|
|
||||||
}
|
|
||||||
if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY' || tag === '=') {
|
|
||||||
seenControl = true;
|
|
||||||
}
|
|
||||||
if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
return this.tokens.splice(i, 0, this.generate('CALL_END', ')', token[2]));
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
|
||||||
var callObject, current, next, prev, tag, _ref, _ref1, _ref2;
|
|
||||||
tag = token[0];
|
|
||||||
if (tag === 'CLASS' || tag === 'IF' || tag === 'FOR' || tag === 'WHILE') {
|
|
||||||
noCall = true;
|
|
||||||
}
|
|
||||||
_ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2];
|
|
||||||
callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref1 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref1) >= 0);
|
|
||||||
seenSingle = false;
|
|
||||||
seenControl = false;
|
|
||||||
if (__indexOf.call(LINEBREAKS, tag) >= 0) {
|
|
||||||
noCall = false;
|
|
||||||
}
|
|
||||||
if (prev && !prev.spaced && tag === '?') {
|
|
||||||
token.call = true;
|
|
||||||
}
|
|
||||||
if (token.fromThen) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
tokens.splice(i, 0, this.generate('CALL_START', '(', token[2]));
|
|
||||||
this.detectEnd(i + 1, condition, action);
|
|
||||||
if (prev[0] === '?') {
|
|
||||||
prev[0] = 'FUNC_EXIST';
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.addImplicitIndentation = function() {
|
|
||||||
var action, condition, indent, outdent, starter;
|
|
||||||
starter = indent = outdent = null;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var _ref;
|
|
||||||
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN'));
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
|
||||||
var tag, _ref, _ref1;
|
|
||||||
tag = token[0];
|
|
||||||
if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
|
|
||||||
tokens.splice(i, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
|
|
||||||
tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token))));
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
|
|
||||||
tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token))));
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
|
|
||||||
starter = tag;
|
|
||||||
_ref1 = this.indentation(token, true), indent = _ref1[0], outdent = _ref1[1];
|
|
||||||
if (starter === 'THEN') {
|
|
||||||
indent.fromThen = true;
|
|
||||||
}
|
|
||||||
tokens.splice(i + 1, 0, indent);
|
|
||||||
this.detectEnd(i + 2, condition, action);
|
|
||||||
if (tag === 'THEN') {
|
|
||||||
tokens.splice(i, 1);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.tagPostfixConditionals = function() {
|
|
||||||
var action, condition, original;
|
|
||||||
original = null;
|
|
||||||
condition = function(token, i) {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT';
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) {
|
|
||||||
return original[0] = 'POST_' + original[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return this.scanTokens(function(token, i) {
|
|
||||||
if (token[0] !== 'IF') {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
original = token;
|
|
||||||
this.detectEnd(i + 1, condition, action);
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.indentation = function(token, implicit) {
|
|
||||||
var indent, outdent;
|
|
||||||
if (implicit == null) {
|
|
||||||
implicit = false;
|
|
||||||
}
|
|
||||||
indent = ['INDENT', 2, token[2]];
|
|
||||||
outdent = ['OUTDENT', 2, token[2]];
|
|
||||||
if (implicit) {
|
|
||||||
indent.generated = outdent.generated = true;
|
|
||||||
}
|
|
||||||
return [indent, outdent];
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.generate = function(tag, value, line) {
|
|
||||||
var tok;
|
|
||||||
tok = [tag, value, line];
|
|
||||||
tok.generated = true;
|
|
||||||
return tok;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rewriter.prototype.tag = function(i) {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
return Rewriter;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']];
|
|
||||||
|
|
||||||
exports.INVERSES = INVERSES = {};
|
|
||||||
|
|
||||||
EXPRESSION_START = [];
|
|
||||||
|
|
||||||
EXPRESSION_END = [];
|
|
||||||
|
|
||||||
for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
|
|
||||||
_ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1];
|
|
||||||
EXPRESSION_START.push(INVERSES[rite] = left);
|
|
||||||
EXPRESSION_END.push(INVERSES[left] = rite);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
|
||||||
|
|
||||||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
|
||||||
|
|
||||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
|
||||||
|
|
||||||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
|
||||||
|
|
||||||
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
|
||||||
|
|
||||||
IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
|
|
||||||
|
|
||||||
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
|
||||||
|
|
||||||
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
|
|
||||||
|
|
||||||
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,146 +0,0 @@
|
||||||
// Generated by CoffeeScript 1.3.3
|
|
||||||
(function() {
|
|
||||||
var Scope, extend, last, _ref;
|
|
||||||
|
|
||||||
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
|
|
||||||
|
|
||||||
exports.Scope = Scope = (function() {
|
|
||||||
|
|
||||||
Scope.root = null;
|
|
||||||
|
|
||||||
function Scope(parent, expressions, method) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.expressions = expressions;
|
|
||||||
this.method = method;
|
|
||||||
this.variables = [
|
|
||||||
{
|
|
||||||
name: 'arguments',
|
|
||||||
type: 'arguments'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
this.positions = {};
|
|
||||||
if (!this.parent) {
|
|
||||||
Scope.root = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope.prototype.add = function(name, type, immediate) {
|
|
||||||
if (this.shared && !immediate) {
|
|
||||||
return this.parent.add(name, type, immediate);
|
|
||||||
}
|
|
||||||
if (Object.prototype.hasOwnProperty.call(this.positions, name)) {
|
|
||||||
return this.variables[this.positions[name]].type = type;
|
|
||||||
} else {
|
|
||||||
return this.positions[name] = this.variables.push({
|
|
||||||
name: name,
|
|
||||||
type: type
|
|
||||||
}) - 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.namedMethod = function() {
|
|
||||||
if (this.method.name || !this.parent) {
|
|
||||||
return this.method;
|
|
||||||
}
|
|
||||||
return this.parent.namedMethod();
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.find = function(name) {
|
|
||||||
if (this.check(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this.add(name, 'var');
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.parameter = function(name) {
|
|
||||||
if (this.shared && this.parent.check(name, true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return this.add(name, 'param');
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.check = function(name) {
|
|
||||||
var _ref1;
|
|
||||||
return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0));
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.temporary = function(name, index) {
|
|
||||||
if (name.length > 1) {
|
|
||||||
return '_' + name + (index > 1 ? index - 1 : '');
|
|
||||||
} else {
|
|
||||||
return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.type = function(name) {
|
|
||||||
var v, _i, _len, _ref1;
|
|
||||||
_ref1 = this.variables;
|
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
||||||
v = _ref1[_i];
|
|
||||||
if (v.name === name) {
|
|
||||||
return v.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.freeVariable = function(name, reserve) {
|
|
||||||
var index, temp;
|
|
||||||
if (reserve == null) {
|
|
||||||
reserve = true;
|
|
||||||
}
|
|
||||||
index = 0;
|
|
||||||
while (this.check((temp = this.temporary(name, index)))) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
if (reserve) {
|
|
||||||
this.add(temp, 'var', true);
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.assign = function(name, value) {
|
|
||||||
this.add(name, {
|
|
||||||
value: value,
|
|
||||||
assigned: true
|
|
||||||
}, true);
|
|
||||||
return this.hasAssignments = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.hasDeclarations = function() {
|
|
||||||
return !!this.declaredVariables().length;
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.declaredVariables = function() {
|
|
||||||
var realVars, tempVars, v, _i, _len, _ref1;
|
|
||||||
realVars = [];
|
|
||||||
tempVars = [];
|
|
||||||
_ref1 = this.variables;
|
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
||||||
v = _ref1[_i];
|
|
||||||
if (v.type === 'var') {
|
|
||||||
(v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return realVars.sort().concat(tempVars.sort());
|
|
||||||
};
|
|
||||||
|
|
||||||
Scope.prototype.assignedVariables = function() {
|
|
||||||
var v, _i, _len, _ref1, _results;
|
|
||||||
_ref1 = this.variables;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
||||||
v = _ref1[_i];
|
|
||||||
if (v.type.assigned) {
|
|
||||||
_results.push("" + v.name + " = " + v.type.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
|
|
||||||
return Scope;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
}).call(this);
|
|
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
"name": "coffee-script",
|
|
||||||
"description": "Unfancy JavaScript",
|
|
||||||
"keywords": ["javascript", "language", "coffeescript", "compiler"],
|
|
||||||
"author": "Jeremy Ashkenas",
|
|
||||||
"version": "1.3.3",
|
|
||||||
"licenses": [{
|
|
||||||
"type": "MIT",
|
|
||||||
"url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
|
|
||||||
}],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4.0"
|
|
||||||
},
|
|
||||||
"directories" : {
|
|
||||||
"lib" : "./lib/coffee-script"
|
|
||||||
},
|
|
||||||
"main" : "./lib/coffee-script/coffee-script",
|
|
||||||
"bin": {
|
|
||||||
"coffee": "./bin/coffee",
|
|
||||||
"cake": "./bin/cake"
|
|
||||||
},
|
|
||||||
"homepage": "http://coffeescript.org",
|
|
||||||
"bugs": "https://github.com/jashkenas/coffee-script/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git://github.com/jashkenas/coffee-script.git"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"uglify-js": ">=1.0.0",
|
|
||||||
"jison": ">=0.2.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -65,7 +65,7 @@ static const struct QCommandLineConfigEntry flags[] =
|
||||||
{ QCommandLine::Option, '\0', "proxy-auth", "Provides authentication information for the proxy, e.g. ''-proxy-auth=username:password'", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "proxy-auth", "Provides authentication information for the proxy, e.g. ''-proxy-auth=username:password'", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "proxy-type", "Specifies the proxy type, 'http' (default), 'none' (disable completely), or 'socks5'", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "proxy-type", "Specifies the proxy type, 'http' (default), 'none' (disable completely), or 'socks5'", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "script-encoding", "Sets the encoding used for the starting script, default is 'utf8'", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "script-encoding", "Sets the encoding used for the starting script, default is 'utf8'", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "script-language", "Sets the script language instead of detecting it: 'javascript', 'coffeescript'", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "script-language", "Sets the script language instead of detecting it: 'javascript'", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "web-security", "Enables web security, 'true' (default) or 'false'", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "web-security", "Enables web security, 'true' (default) or 'false'", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "ssl-protocol", "Sets the SSL protocol (supported protocols: 'SSLv3' (default), 'SSLv2', 'TLSv1', 'any')", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "ssl-protocol", "Sets the SSL protocol (supported protocols: 'SSLv3' (default), 'SSLv2', 'TLSv1', 'any')", QCommandLine::Optional },
|
||||||
{ QCommandLine::Option, '\0', "ssl-certificates-path", "Sets the location for custom CA certificates (if none set, uses system default)", QCommandLine::Optional },
|
{ QCommandLine::Option, '\0', "ssl-certificates-path", "Sets the location for custom CA certificates (if none set, uses system default)", QCommandLine::Optional },
|
||||||
|
|
|
@ -40,8 +40,6 @@
|
||||||
#define HTTP_HEADER_CONTENT_LENGTH "content-length"
|
#define HTTP_HEADER_CONTENT_LENGTH "content-length"
|
||||||
#define HTTP_HEADER_CONTENT_TYPE "content-type"
|
#define HTTP_HEADER_CONTENT_TYPE "content-type"
|
||||||
|
|
||||||
#define COFFEE_SCRIPT_EXTENSION ".coffee"
|
|
||||||
|
|
||||||
#define JS_ELEMENT_CLICK "(function (el) { " \
|
#define JS_ELEMENT_CLICK "(function (el) { " \
|
||||||
"var ev = document.createEvent('MouseEvents');" \
|
"var ev = document.createEvent('MouseEvents');" \
|
||||||
"ev.initEvent(\"click\", true, true);" \
|
"ev.initEvent(\"click\", true, true);" \
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of the PhantomJS project from Ofi Labs.
|
|
||||||
|
|
||||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the <organization> nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "csconverter.h"
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QWebFrame>
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "terminal.h"
|
|
||||||
|
|
||||||
static CSConverter *csconverter_instance = 0;
|
|
||||||
|
|
||||||
CSConverter *CSConverter::instance()
|
|
||||||
{
|
|
||||||
if (!csconverter_instance)
|
|
||||||
csconverter_instance = new CSConverter();
|
|
||||||
|
|
||||||
return csconverter_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSConverter::CSConverter()
|
|
||||||
: QObject(QCoreApplication::instance())
|
|
||||||
{
|
|
||||||
m_webPage.mainFrame()->evaluateJavaScript(
|
|
||||||
Utils::readResourceFileUtf8(":/coffee-script/extras/coffee-script.js"),
|
|
||||||
QString("phantomjs://coffee-script/extras/coffee-script.js")
|
|
||||||
);
|
|
||||||
m_webPage.mainFrame()->addToJavaScriptWindowObject("converter", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant CSConverter::convert(const QString &script)
|
|
||||||
{
|
|
||||||
setProperty("source", script);
|
|
||||||
QVariant result = m_webPage.mainFrame()->evaluateJavaScript(
|
|
||||||
"try {" \
|
|
||||||
" [true, this.CoffeeScript.compile(converter.source)];" \
|
|
||||||
"} catch (error) {" \
|
|
||||||
" [false, error.message];" \
|
|
||||||
"}",
|
|
||||||
QString()
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of the PhantomJS project from Ofi Labs.
|
|
||||||
|
|
||||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the <organization> nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CSCONVERTER_H
|
|
||||||
#define CSCONVERTER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QtWebKitWidgets/QWebPage>
|
|
||||||
|
|
||||||
class CSConverter: public QObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static CSConverter *instance();
|
|
||||||
QVariant convert(const QString &script);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CSConverter();
|
|
||||||
QWebPage m_webPage;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CSCONVERTER_H
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
require.stub('vm');
|
|
||||||
require.stub('path');
|
|
||||||
require.stub('fs', {
|
|
||||||
readFileSync: function(path, encoding) {
|
|
||||||
return fs.read(path);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = require('../coffee-script');
|
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
#include "csconverter.h"
|
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@ RESOURCES = phantomjs.qrc \
|
||||||
|
|
||||||
QTPLUGIN += qphantom
|
QTPLUGIN += qphantom
|
||||||
|
|
||||||
HEADERS += csconverter.h \
|
HEADERS += \
|
||||||
phantom.h \
|
phantom.h \
|
||||||
callback.h \
|
callback.h \
|
||||||
webpage.h \
|
webpage.h \
|
||||||
|
@ -33,7 +33,6 @@ SOURCES += phantom.cpp \
|
||||||
webpage.cpp \
|
webpage.cpp \
|
||||||
webserver.cpp \
|
webserver.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
csconverter.cpp \
|
|
||||||
utils.cpp \
|
utils.cpp \
|
||||||
networkaccessmanager.cpp \
|
networkaccessmanager.cpp \
|
||||||
cookiejar.cpp \
|
cookiejar.cpp \
|
||||||
|
|
|
@ -9,25 +9,7 @@
|
||||||
<file>modules/fs.js</file>
|
<file>modules/fs.js</file>
|
||||||
<file>modules/system.js</file>
|
<file>modules/system.js</file>
|
||||||
<file>modules/child_process.js</file>
|
<file>modules/child_process.js</file>
|
||||||
<file>modules/_coffee-script.js</file>
|
|
||||||
<file>modules/cookiejar.js</file>
|
<file>modules/cookiejar.js</file>
|
||||||
<file>repl.js</file>
|
<file>repl.js</file>
|
||||||
|
|
||||||
<file>coffee-script/package.json</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/coffee-script.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/optparse.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/command.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/scope.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/parser.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/browser.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/nodes.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/grammar.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/lexer.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/repl.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/cake.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/helpers.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/rewriter.js</file>
|
|
||||||
<file>coffee-script/lib/coffee-script/index.js</file>
|
|
||||||
<file>coffee-script/extras/coffee-script.js</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -95,11 +95,6 @@ bool Utils::exceptionHandler(const char* dump_path, const char* minidump_id, voi
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QVariant Utils::coffee2js(const QString &script)
|
|
||||||
{
|
|
||||||
return CSConverter::instance()->convert(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::injectJsInFrame(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript)
|
bool Utils::injectJsInFrame(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript)
|
||||||
{
|
{
|
||||||
return injectJsInFrame(jsFilePath, QString(), Encoding::UTF8, libraryPath, targetFrame, startingScript);
|
return injectJsInFrame(jsFilePath, QString(), Encoding::UTF8, libraryPath, targetFrame, startingScript);
|
||||||
|
@ -168,7 +163,6 @@ QString Utils::jsFromScriptFile(const QString& scriptPath, const QString& script
|
||||||
QFile jsFile(scriptPath);
|
QFile jsFile(scriptPath);
|
||||||
if (jsFile.exists() && jsFile.open(QFile::ReadOnly)) {
|
if (jsFile.exists() && jsFile.open(QFile::ReadOnly)) {
|
||||||
QString scriptBody = enc.decode(jsFile.readAll());
|
QString scriptBody = enc.decode(jsFile.readAll());
|
||||||
bool hasCoffeeExtension = jsFile.fileName().endsWith(COFFEE_SCRIPT_EXTENSION);
|
|
||||||
jsFile.close();
|
jsFile.close();
|
||||||
|
|
||||||
// Remove CLI script heading
|
// Remove CLI script heading
|
||||||
|
@ -178,17 +172,7 @@ QString Utils::jsFromScriptFile(const QString& scriptPath, const QString& script
|
||||||
scriptBody.remove(0, len);
|
scriptBody.remove(0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the language is set to coffeescript, or the language is not set and the file ends in .coffee, make coffee.
|
// If a language is specified and is not "javascript", reject it.
|
||||||
if (scriptLanguage == "coffeescript" || (scriptLanguage.isNull() && hasCoffeeExtension)) {
|
|
||||||
QVariant result = Utils::coffee2js(scriptBody);
|
|
||||||
if (result.toStringList().at(0) == "false") {
|
|
||||||
return QString();
|
|
||||||
} else {
|
|
||||||
return result.toStringList().at(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a language is specified and is not "coffeescript" or "javascript", reject it.
|
|
||||||
if (scriptLanguage != "javascript" && !scriptLanguage.isNull()) {
|
if (scriptLanguage != "javascript" && !scriptLanguage.isNull()) {
|
||||||
QString errMessage = QString("Unsupported language: %1").arg(scriptLanguage);
|
QString errMessage = QString("Unsupported language: %1").arg(scriptLanguage);
|
||||||
Terminal::instance()->cerr(errMessage);
|
Terminal::instance()->cerr(errMessage);
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <QtWebKitWidgets/QWebFrame>
|
#include <QtWebKitWidgets/QWebFrame>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include "csconverter.h"
|
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
|
@ -57,7 +56,6 @@ public:
|
||||||
#else
|
#else
|
||||||
static bool exceptionHandler(const char* dump_path, const char* minidump_id, void* context, bool succeeded);
|
static bool exceptionHandler(const char* dump_path, const char* minidump_id, void* context, bool succeeded);
|
||||||
#endif
|
#endif
|
||||||
static QVariant coffee2js(const QString &script);
|
|
||||||
static bool injectJsInFrame(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
static bool injectJsInFrame(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
||||||
static bool injectJsInFrame(const QString &jsFilePath, const QString &jsFileLanguage, const Encoding &jsFileEnc, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
static bool injectJsInFrame(const QString &jsFilePath, const QString &jsFileLanguage, const Encoding &jsFileEnc, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
||||||
static QString readResourceFileUtf8(const QString &resourceFilePath);
|
static QString readResourceFileUtf8(const QString &resourceFilePath);
|
||||||
|
|
Loading…
Reference in New Issue