Find file
Fetching contributors…
Cannot retrieve contributors at this time
197 lines (178 sloc) 7.24 KB
# Extension module.
# Encapsulates for all session/state loading saving logic.
# TODO(amasad): Graceful localStorage degradation to cookies.
$ = jQuery
PUSHSTATE_SUPPORTED = 'pushState' of history
twitter: ->
text = 'Check out my REPL session - '
related = 'replit'
url = window.location.href
uri = $.param {
<a href="{uri}" target="_blank"></a>
facebook: ->
<a href="javascript:var d=document,f='',l=d.location,e=encodeURIComponent,p='.php?src=bm&v=4&i=1315186262&u='+e(l.href)+'&t='+e(d.title);1;try{if (!/^(.*\.)?facebook\.[^.]*$/.test(;share_internal_bookmarklet(p)}catch(z) {a=function() {if (!'r'+p,'sharer','toolbar=0,status=0,resizable=1,width=626,height=436'))l.href=f+p};if (/Firefox/.test(navigator.userAgent))setTimeout(a,0);else{a()}}void(0)"></a>
# Unofficial!
gplus: ->
text = 'Check out my REPL session - ' + window.location.href
text = encodeURI text
<a href="{text}&login=1&pli=1&hideloc=1" target="_blank"></a>
$.extend REPLIT,
eval_history: []
pushState: (text) ->
window.history.pushState null, null, "/#{text}"
REPLIT.setHash 0, text
# Resets application to its initial state (handler for language_loaded event).
reset_state = (e, lang_name) ->
localStorage.setItem 'lang_name', lang_name
@session = {}
@session.eval_history = []
REPLIT.pushState ''
$ ->
# If there exists a REPLIT_DATA variable, then we are in a saved session.
# Load the language specified by the incoming session data.
REPLIT.current_lang_name = REPLIT_DATA.language
REPLIT.OpenPage 'workspace', ->
REPLIT.LoadLanguage REPLIT_DATA.language, ->
# Set the editor text.
REPLIT.editor.getSession().setValue REPLIT_DATA.editor_text if not REPLIT.ISMOBILE
# Get the session data. = REPLIT_DATA.session_id
REPLIT.session.rid = REPLIT_DATA.revision_id
REPLIT.session.saved_eval_history = REPLIT_DATA.eval_history
# Show the replay button.
# Delete the incoming session data from the server since we have
# extracted everything we neeed.
delete window['REPLIT_DATA']
# On each language load after this one reset the state.
REPLIT.$this.bind 'language_loaded', reset_state
# We are not in a saved session.
# Safely bind the reset state function.
REPLIT.$this.bind 'language_loaded', reset_state
lang_name = localStorage.getItem('lang_name')
if lang_name?
REPLIT.loading_saved_lang = true
# We have a saved local settings for language to load. Delay this until
# the Analytics modules has set its hook so it can catch language loading.
$ ->
REPLIT.current_lang_name = lang_name
REPLIT.OpenPage 'workspace', ->
REPLIT.LoadLanguage lang_name
# This is the first visit; show language overlay.
$('#languages-back').bind 'click.language_modal', (e) ->
return false
$('#content-languages .language-group li').bind 'click.language_modal', (e) ->
REPLIT.Modal false
REPLIT.$this.bind 'language_loaded.language_modal', (e) ->
$('#languages-back').unbind 'click.language_modal'
REPLIT.OpenPage 'languages'
REPLIT.Modal true
# Click handler for the replay button.
$('#replay-button').click (e) ->
# Get the history comming from the server.
history = REPLIT.session.saved_eval_history
locked = false
locked_queue = []
index = -1
# Executes a command from history and waits for the result to continue
# with the next command.
handler = ->
if not locked
if history[index]?
# Set the prompt text to the command in question.
REPLIT.jqconsole.SetPromptText history[index]
# Remove multiline handler from jqconsole to ensure it doesn't
# continue to the next line.
_multiline = REPLIT.jqconsole.multiline_callback
REPLIT.jqconsole.multiline_callback = undefined
# Simulate an enter button on jqconsole.
# Reassign the multiline handler.
REPLIT.jqconsole.multiline_callback = _multiline
# There is no more commands; unbind the handler.
REPLIT.$this.unbind 'result', handler
REPLIT.$this.unbind 'error', handler
# We are done with the eval history from the server; delete it.
delete REPLIT.session['saved_eval_history']
locked_queue.push handler
input_lock = ->
locked = true
input_unlock = ->
locked = false
fn = locked_queue.shift()
setTimeout fn, 100 if fn?
REPLIT.$this.bind 'result', handler
REPLIT.$this.bind 'error', handler
REPLIT.$this.bind 'input', input_unlock
REPLIT.$this.bind 'input_request', input_lock
# Initiate the first handler to start executing history commands.
# This button can only be clicked once. Now hide it.
saveSession = (e) ->
# Can't save if we haven't selected a language yet.
if not REPLIT.current_lang? then return
# Get the post data to save.
post_data =
language: REPLIT.current_lang.system_name
editor_text: REPLIT.editor.getSession().getValue() if not REPLIT.ISMOBILE
eval_history: JSON.stringify REPLIT.session.eval_history
# If we are already REPLing on a saved session, get its id. = if
# Do the actual save request.
$.post '/save', post_data, (data) ->
{session_id, revision_id} = data
$savebox = $('#save-box')
# Update URL.
if revision_id > 0
REPLIT.pushState session_id + '/' + revision_id
REPLIT.pushState session_id
# Update IDs. = session_id
REPLIT.session.rid = revision_id
# Render social share links.
$savebox.find('li.twitter a').replaceWith SHARE_TEMPLATE.twitter()
$savebox.find('li.facebook a').replaceWith SHARE_TEMPLATE.facebook()
$savebox.find('li.gplus a').replaceWith SHARE_TEMPLATE.gplus()
$savebox.find('input').val window.location.href
$ (e) ->
return e.stopPropagation()
$('body').bind 'click.closesave', ->
# Disable share button for a little while.
setTimeout bindSaveButton, WAIT_BETWEEN_SAVES
bindSaveButton = -> $('#button-save').click saveSession
unbindSaveButton = -> $('#button-save').unbind 'click'
$('#save-box input').click -> $(this).select()
# When any command is evaled, save it in the eval_history array of the session
# object, in order to send it to the server on save.
REPLIT.$this.bind 'eval', (e, command) ->
REPLIT.session.eval_history.push command