Fix JS errors in loading editor
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
extends ../layout
|
||||
|
||||
block scripts
|
||||
//- Only use the native bootstrap on the editor page,
|
||||
//- since we use the Angular-based bootstrap elsewhere.
|
||||
script(src=jsPath+'libs/bootstrap-3.1.1.js')
|
||||
|
||||
block content
|
||||
#loadingScreen
|
||||
h3 Loading...
|
||||
@@ -37,15 +42,15 @@ block content
|
||||
window.csrfToken = "!{csrfToken}";
|
||||
window.requirejs = {
|
||||
"paths" : {
|
||||
"underscore": "libs/underscore",
|
||||
"underscore": "libs/underscore-1.3.3",
|
||||
"mathjax": "https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML",
|
||||
"moment": "libs/moment"
|
||||
"moment": "libs/moment-2.4.0"
|
||||
},
|
||||
"urlArgs" : "fingerprint=#{fingerprint(jsPath + 'ide.js')}",
|
||||
"waitSeconds": 0,
|
||||
"shim": {
|
||||
"libs/backbone": {
|
||||
deps: ["libs/underscore"]
|
||||
deps: ["libs/underscore-1.3.3"]
|
||||
},
|
||||
"libs/pdfListView/PdfListView": {
|
||||
deps: ["libs/pdf"]
|
||||
@@ -62,7 +67,7 @@ block content
|
||||
- locals.supressDefaultJs = true
|
||||
- var fingerprintedPath = fingerprint(jsPath+'libs/pdf.worker.js')
|
||||
- var pdfJsWorkerPath = jsPath+'libs/pdf.worker.js?fingerprint='+fingerprintedPath
|
||||
script
|
||||
script(type='text/javascript').
|
||||
window.sharelatex.pdfJsWorkerPath = "#{pdfJsWorkerPath}"
|
||||
|
||||
script(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require [
|
||||
"libs/mustache"
|
||||
"./main"
|
||||
"libs/underscore"
|
||||
"underscore"
|
||||
], (m)->
|
||||
$(document).ready ->
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define [
|
||||
"editor/ShareJsDoc"
|
||||
"libs/backbone"
|
||||
"libs/underscore"
|
||||
"underscore"
|
||||
], (ShareJsDoc) ->
|
||||
class Document
|
||||
@getDocument: (ide, doc_id) ->
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
define [
|
||||
"libs/bootstrap"
|
||||
"libs/mustache"
|
||||
"libs/backbone"
|
||||
"libs/mustache"
|
||||
], () ->
|
||||
FileViewManager = Backbone.View.extend
|
||||
template: $("#fileViewTemplate").html()
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
require [
|
||||
"libs/jquery.validate"
|
||||
"libs/fineuploader"
|
||||
"libs/bootstrap"
|
||||
], ()->
|
||||
|
||||
$().ready ->
|
||||
url = document.location.toString();
|
||||
if (url.match('#'))
|
||||
$('.nav-tabs a[href=#'+url.split('#')[1]+']').tab('show')
|
||||
$('.nav-tabs a').on 'shown', (e)->
|
||||
window.location.hash = e.target.hash
|
||||
|
||||
shortRegisterFormRules =
|
||||
rules:
|
||||
redir:
|
||||
required:false
|
||||
email:
|
||||
required: true
|
||||
email: true
|
||||
password:
|
||||
required: true
|
||||
|
||||
errorElement: 'div'
|
||||
submitHandler: (form)->
|
||||
formData = $(form).serialize()
|
||||
$.ajax
|
||||
url: "/register",
|
||||
type:'POST',
|
||||
data: formData,
|
||||
success: (data)->
|
||||
if data.message?
|
||||
new Message data.message
|
||||
ga('send', 'event', 'register', 'failure', data.message)
|
||||
else
|
||||
ga('send', 'event', 'register', 'success')
|
||||
window.location = data.redir || "/project"
|
||||
|
||||
|
||||
|
||||
$('#registerFormShort').validate shortRegisterFormRules
|
||||
|
||||
$("#registerFormShort").show()
|
||||
|
||||
passwordFormInited = false
|
||||
$('a#changePassword').click (event)->
|
||||
event.preventDefault()
|
||||
$modal = $ '#changePasswordModal'
|
||||
$modal.modal
|
||||
backdrop:true
|
||||
show:true
|
||||
keyboard:true
|
||||
|
||||
if !passwordFormInited
|
||||
passwordFormInited = true
|
||||
$modal.find('.cancel').click (e)->
|
||||
$modal.modal('hide')
|
||||
|
||||
$modal.find('form#changePasswordForm').submit (e)->
|
||||
e.preventDefault()
|
||||
formData = $('form#changePasswordForm').serialize()
|
||||
$.ajax
|
||||
url: "/user/password/update"
|
||||
type:'POST'
|
||||
data: formData
|
||||
success: (data)->
|
||||
if(data.message)
|
||||
new Message data.message
|
||||
$modal.modal('hide')
|
||||
|
||||
$('form#loginForm').submit (event)->
|
||||
event.preventDefault()
|
||||
formData = $(this).serialize()
|
||||
$.ajax
|
||||
url: "/login"
|
||||
type:'POST'
|
||||
data: formData
|
||||
error: (data)->
|
||||
if data.responseText
|
||||
message = JSON.parse(data.responseText).message
|
||||
new Message message
|
||||
success: (data)->
|
||||
if data.message
|
||||
new Message data.message
|
||||
ga('send', 'event', 'login', 'failure', data.message)
|
||||
else if data.redir
|
||||
window.location.href = data.redir
|
||||
ga('send', 'event', 'login', 'success')
|
||||
else
|
||||
ga('send', 'event', 'login', 'success')
|
||||
window.location.href = '/project'
|
||||
|
||||
$('form#passwordReset').submit (event)->
|
||||
event.preventDefault()
|
||||
formData = $(this).serialize()
|
||||
$.ajax
|
||||
url: "/user/password/reset"
|
||||
type:'POST'
|
||||
data: formData
|
||||
success: (data)->
|
||||
new Message text:"You have been sent an email to complete your password reset."
|
||||
error:(data)->
|
||||
message = JSON.parse(data?.responseText)?.message
|
||||
new Message type:"error", text: message || "Something went wrong processing your request."
|
||||
|
||||
|
||||
$('form#setPasswordReset').validate
|
||||
rules:
|
||||
password:
|
||||
required: true
|
||||
messages:
|
||||
password: "Password is required"
|
||||
errorElement: 'div'
|
||||
submitHandler: (form)->
|
||||
event.preventDefault()
|
||||
formData = $(form).serialize()
|
||||
$.ajax
|
||||
url: "/user/password/set"
|
||||
type:'POST'
|
||||
data: formData
|
||||
success: (data)->
|
||||
new Message text:"Your password has been reset. <a href='/login'>Login here</a>."
|
||||
error:(data)->
|
||||
new Message type:"error", text:"Something went wrong processing your request."
|
||||
|
||||
|
||||
$('a#deleteUserAccount').click (e)->
|
||||
redirect = ->
|
||||
window.location.href = '/'
|
||||
|
||||
|
||||
$modal = $('#deleteUserAccountModal')
|
||||
$modal.modal
|
||||
backdrop:true
|
||||
show:true
|
||||
keyboard:true
|
||||
|
||||
$modal.find('.cancel').click (e)->
|
||||
$modal.modal('hide')
|
||||
|
||||
$confirm = $modal.find('.btn-danger')
|
||||
|
||||
$modal.on 'hide', ->
|
||||
$confirm.off 'click'
|
||||
|
||||
$confirm.click (e) =>
|
||||
e.preventDefault()
|
||||
val = $modal.find(".inputmodal").val()
|
||||
if val == "Delete"
|
||||
$modal.modal('hide')
|
||||
$.ajax
|
||||
url: '/user'
|
||||
type: 'DELETE'
|
||||
data:
|
||||
_csrf: $(@).data("csrf")
|
||||
success: (data)->
|
||||
new Message {title:"Deleted", text:" : Your account has been deleted"}
|
||||
setTimeout redirect, 10000
|
||||
else
|
||||
$modal.find(".inputmodal").val("")
|
||||
alert "You did not type 'Delete', please try again"
|
||||
|
||||
|
||||
$('a#unsubscribeFromNewsletter').click (e)->
|
||||
$.ajax
|
||||
url: '/user/newsletter/unsubscribe'
|
||||
type: 'DELETE'
|
||||
data:
|
||||
_csrf: $(@).data("csrf")
|
||||
success: (data)->
|
||||
new Message {title:"Unsubscribed", text:" : You have been unsubscribed from the newsletter"}
|
||||
|
||||
$('form#userSettings').validate
|
||||
rules:
|
||||
email:
|
||||
required: true
|
||||
email: true
|
||||
highlight: (element, errorClass, validClas)->
|
||||
$(element).parents("div[class='clearfix']").addClass("error")
|
||||
|
||||
unhighlight: (element, errorClass, validClass)->
|
||||
$(element).parents(".error").removeClass("error")
|
||||
errorElement: 'div'
|
||||
submitHandler: (form)->
|
||||
formData = $(form).serialize()
|
||||
$.ajax
|
||||
url: '/user/settings'
|
||||
type: 'POST'
|
||||
data: formData
|
||||
success: (data)->
|
||||
if data.message
|
||||
displayMessage data
|
||||
else
|
||||
new Message {text:"Your settings have been saved"}
|
||||
error:(data)->
|
||||
message = JSON.parse(data?.responseText)?.message
|
||||
new Message type:"error", text: message || "Something went wrong processing your request."
|
||||
|
||||
|
||||
|
||||
class Message
|
||||
constructor: (message)->
|
||||
aClose = $('<a></a>').addClass('close').attr('href','#').html('×')
|
||||
pTitle = $('<strong></strong>').text(message.title)
|
||||
pText = $('<span></span>').html(' '+message.text)
|
||||
div = $('<div></div>')
|
||||
.addClass('alert')
|
||||
.append(aClose)
|
||||
.append(pTitle)
|
||||
.append(pText)
|
||||
if message.type == "error"
|
||||
div.addClass("alert-danger")
|
||||
else
|
||||
div.addClass("alert-info")
|
||||
|
||||
$('.messageArea').last().append(div)
|
||||
|
||||
$(aClose).click (event) ->
|
||||
$(div).remove()
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
define ["libs/backbone"], () ->
|
||||
FileDiff = Backbone.Model.extend
|
||||
url: -> "/project/#{window.userSettings.project_id}/version/#{@get("version_id")}/file/#{@get("path")}"
|
||||
|
||||
sync: (method, model, options) ->
|
||||
throw "FileDiffs can only be read" unless method == "read"
|
||||
options ||= {}
|
||||
params =
|
||||
url: @url()
|
||||
type: "GET"
|
||||
$.ajax(_.extend(params, options))
|
||||
|
||||
parse: (response) ->
|
||||
content : response
|
||||
@@ -1,64 +0,0 @@
|
||||
define [
|
||||
"libs/mustache"
|
||||
"libs/backbone"
|
||||
], ()->
|
||||
|
||||
FileDiffView = Backbone.View.extend
|
||||
className: "fileDiffView"
|
||||
|
||||
template: $("#fileDiffTemplate").html()
|
||||
|
||||
events:
|
||||
"click .nav .raw" : "loadRawFile"
|
||||
|
||||
render: ->
|
||||
$(@el).html Mustache.to_html(@template, @modelView())
|
||||
return this
|
||||
|
||||
modelView: ->
|
||||
fileView = @model.toJSON()
|
||||
fileView.id = @model.cid
|
||||
fileView.url = @model.url()
|
||||
fileView.headerClass = "updated"
|
||||
fileView.deleted = false
|
||||
|
||||
if fileView.sections? and fileView.sections.length > 0
|
||||
fileView.diff = true
|
||||
for section in fileView.sections
|
||||
currentOldLine = section.old_start_line
|
||||
currentNewLine = section.new_start_line
|
||||
for line in section.lines
|
||||
line.old_number = currentOldLine
|
||||
line.new_number = currentNewLine
|
||||
if line.type == "added"
|
||||
currentNewLine += 1
|
||||
line.added = true
|
||||
if line.type == "removed"
|
||||
currentOldLine += 1
|
||||
line.removed = true
|
||||
if line.type == "unchanged"
|
||||
currentNewLine += 1
|
||||
currentOldLine += 1
|
||||
line.unchanged = true
|
||||
|
||||
if fileView.type == "renamed"
|
||||
fileView.moved = true
|
||||
fileView.newPath = fileView.path
|
||||
fileView.path = fileView.oldPath
|
||||
|
||||
if fileView.type == "created"
|
||||
fileView.headerClass = "created"
|
||||
|
||||
if fileView.type == "deleted"
|
||||
fileView.headerClass = "deleted"
|
||||
fileView.deleted = true
|
||||
|
||||
return fileView
|
||||
|
||||
loadRawFile: ->
|
||||
unless @loadedRawFile
|
||||
view = this
|
||||
@model.fetch
|
||||
success: (model) ->
|
||||
view.$(".rawFileContent").text(model.get("content"))
|
||||
@loadedRawFile = true
|
||||
@@ -1,65 +0,0 @@
|
||||
define [
|
||||
"history/VersionListView"
|
||||
"history/VersionList"
|
||||
"history/HistoryView"
|
||||
"account/AccountManager"
|
||||
"libs/backbone"
|
||||
], (VersionListView, VersionList, HistoryView, AccountManager) ->
|
||||
HistoryManager = class
|
||||
templates:
|
||||
historyPanel: $("#historyPanelTemplate").html()
|
||||
|
||||
constructor: (ide, options) ->
|
||||
@ide = ide
|
||||
@ide.on "afterJoinProject", (project) =>
|
||||
if !@inited
|
||||
@inited = true
|
||||
@project = project
|
||||
@historyPanel = $(@templates.historyPanel)
|
||||
@ide.tabManager.addTab
|
||||
id: "history"
|
||||
name: "History"
|
||||
content: @historyPanel
|
||||
after: "code"
|
||||
onShown: () => @showHistoryArea()
|
||||
lock: true
|
||||
@view = new HistoryView
|
||||
el : @historyPanel
|
||||
manager : this
|
||||
@view.render()
|
||||
@versionList = new VersionList
|
||||
@versionListView = new VersionListView(
|
||||
collection : @versionList,
|
||||
el : @view.$("#versionListArea")
|
||||
)
|
||||
|
||||
showHistoryArea: ->
|
||||
if @project.get("features").versioning
|
||||
@view.setHistoryAreaToDisplayHistory()
|
||||
@versionList.fetchNewVersions()
|
||||
@versionListView.loadUntilFull()
|
||||
else
|
||||
@view.setHistoryAreaToDisplayEnableVersioning()
|
||||
|
||||
enableVersioning: ->
|
||||
ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "history")
|
||||
AccountManager.askToUpgrade @ide,
|
||||
onUpgrade: () =>
|
||||
ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "history")
|
||||
@showHistoryArea()
|
||||
|
||||
takeSnapshot: (message, callback = (error) ->) ->
|
||||
$.ajax
|
||||
type : "POST"
|
||||
url : "/project/#{@project.id}/snapshot"
|
||||
data :
|
||||
message: message
|
||||
_csrf: csrfToken
|
||||
dataType: "json"
|
||||
success : (data, status, xhr) =>
|
||||
@versionList.fetchNewVersions()
|
||||
callback()
|
||||
error : (data, status, xhr) =>
|
||||
callback(new Error("takeSnapshot returned with error: #{status}"))
|
||||
|
||||
return HistoryManager
|
||||
@@ -1,39 +0,0 @@
|
||||
define [
|
||||
"utils/Modal"
|
||||
"libs/backbone"
|
||||
], (Modal) ->
|
||||
HistoryView = Backbone.View.extend
|
||||
template : $("#revisionAreaTemplate").html()
|
||||
|
||||
events :
|
||||
"click #enableVersioning" : "enableVersioning"
|
||||
"click #take-snapshot" : "takeSnapshot"
|
||||
|
||||
render : ->
|
||||
@$el.html(@template)
|
||||
return this
|
||||
|
||||
setHistoryAreaToDisplayHistory: ->
|
||||
@$("#historyAreaWrapper").show()
|
||||
@$("#enableVersioningMessage").hide()
|
||||
|
||||
setHistoryAreaToDisplayEnableVersioning: ->
|
||||
@$("#historyAreaWrapper").hide()
|
||||
@$("#enableVersioningMessage").show()
|
||||
|
||||
enableVersioning: -> @options.manager.enableVersioning()
|
||||
|
||||
takeSnapshot: ->
|
||||
Modal.createModal
|
||||
title: "Snapshot comment"
|
||||
message: $("#snapshotCommentTemplate").html()
|
||||
buttons: [{
|
||||
text: "Cancel"
|
||||
},{
|
||||
text: "Take Snapshot"
|
||||
class: "btn-primary"
|
||||
callback: () =>
|
||||
@options.manager.takeSnapshot(
|
||||
$("#snapshotComment").val()
|
||||
)
|
||||
}]
|
||||
@@ -1,10 +0,0 @@
|
||||
define [
|
||||
"libs/backbone"
|
||||
], ()->
|
||||
Version = Backbone.Model.extend
|
||||
url: -> "/project/" + window.userSettings.project_id + "/version/" + @id
|
||||
parse: (json) ->
|
||||
if json.version
|
||||
json = json.version
|
||||
json.message = json.message.split("\n")[0]
|
||||
return json
|
||||
@@ -1,28 +0,0 @@
|
||||
define [
|
||||
"./util"
|
||||
"history/FileDiff"
|
||||
"history/FileDiffView"
|
||||
"libs/mustache"
|
||||
"libs/backbone"
|
||||
], (util, FileDiff, FileDiffView)->
|
||||
VersionView = Backbone.View.extend
|
||||
template : $("#diffTemplate").html()
|
||||
|
||||
render: ->
|
||||
html = Mustache.to_html(@template, @modelView())
|
||||
@$el = $("#diffViewArea")
|
||||
|
||||
@$el.empty()
|
||||
@$el.append html
|
||||
|
||||
for fileDiff in @model.get("file_diffs")
|
||||
model = new FileDiff(_.extend(fileDiff, version_id: @model.get("id")))
|
||||
view = new FileDiffView model: model
|
||||
@$el.append view.render().el
|
||||
|
||||
return this
|
||||
|
||||
modelView: ->
|
||||
modelView = @model.toJSON()
|
||||
modelView.date = util.formatDate(modelView.date)
|
||||
return modelView
|
||||
@@ -1,48 +0,0 @@
|
||||
define [
|
||||
"history/Version"
|
||||
"libs/backbone"
|
||||
], (Version)->
|
||||
VersionList = Backbone.Collection.extend
|
||||
model: Version
|
||||
batchSize: 50
|
||||
|
||||
url: () ->
|
||||
url = "/project/#{window.userSettings.project_id}/version?limit=#{@batchSize}"
|
||||
if @models.length > 0
|
||||
last = @models[@models.length - 1]
|
||||
url += "&before=#{last.get("id")}"
|
||||
return url
|
||||
|
||||
parse: (json) ->
|
||||
for version in json.versions
|
||||
version.date = new Date(version.date)
|
||||
return json.versions
|
||||
|
||||
comparator: (version) -> - Date.parse(version.get("date"))
|
||||
|
||||
fetchNextBatch: (options = {}) ->
|
||||
options.add = true
|
||||
@fetch options
|
||||
|
||||
fetchNewVersions: (options = {}) ->
|
||||
options.url = "/project/#{window.userSettings.project_id}/version?limit=5"
|
||||
options.add = true
|
||||
unless options.timeout?
|
||||
options.timeout = 10000 #milliseconds
|
||||
|
||||
# Keep requesting the beginning of the version list
|
||||
# until we've added some more versions or reached the
|
||||
# timeout limit.
|
||||
currentVersionCount = @models.length
|
||||
continueLoading = () =>
|
||||
unless @models.length > currentVersionCount
|
||||
unless options.timeout <= 0
|
||||
runAgain = () =>
|
||||
options.timeout = options.timeout - 1000
|
||||
@fetchNewVersions(options)
|
||||
setTimeout(runAgain, 1000)
|
||||
options.success = continueLoading
|
||||
options.error = continueLoading
|
||||
@fetch options
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
define [
|
||||
"./util"
|
||||
"history/VersionDetailView"
|
||||
"libs/mustache"
|
||||
"libs/backbone"
|
||||
], (util, VersionDetailView)->
|
||||
VersionListView = Backbone.View.extend
|
||||
template: $("#versionListTemplate").html()
|
||||
|
||||
events:
|
||||
"scroll" : "loadUntilFull"
|
||||
|
||||
initialize: ->
|
||||
@itemViews = []
|
||||
@atEndOfCollection = false
|
||||
|
||||
self = this
|
||||
@collection.on "add", (model) ->
|
||||
self.addItem model
|
||||
@collection.on "reset", (collection) ->
|
||||
self.addItem model for model in collection.models
|
||||
|
||||
@render()
|
||||
@hideLoading()
|
||||
|
||||
render: ->
|
||||
@$el.html Mustache.to_html @template
|
||||
@$el.css
|
||||
overflow: "scroll"
|
||||
this
|
||||
|
||||
addItem: (model) ->
|
||||
view = new VersionListItemView(model : model)
|
||||
@itemViews.push view
|
||||
index = @collection.indexOf(model)
|
||||
elementAtIndex = @$("#version-list").children()[index]
|
||||
view.$el.insertBefore(elementAtIndex)
|
||||
|
||||
listShorterThanContainer: ->
|
||||
@$el.height() > @$("#version-list").height()
|
||||
|
||||
atEndOfListView: ->
|
||||
@$el.scrollTop() + @$el.height() >= @$("#version-list").height() - 30
|
||||
|
||||
loadUntilFull: (e, callback) ->
|
||||
if (@listShorterThanContainer() or @atEndOfListView()) and not @atEndOfCollection and not @loading
|
||||
@showLoading()
|
||||
@hideEmptyMessage()
|
||||
@collection.fetchNextBatch
|
||||
error: =>
|
||||
@hideLoading()
|
||||
@atEndOfCollection = true
|
||||
@showEmptyMessageIfCollectionEmpty()
|
||||
callback() if callback?
|
||||
success: =>
|
||||
@hideLoading()
|
||||
@loadUntilFull(e, callback)
|
||||
else
|
||||
callback() if callback?
|
||||
|
||||
showEmptyMessageIfCollectionEmpty: ()->
|
||||
if @collection.isEmpty()
|
||||
@$(".empty-message").show()
|
||||
else
|
||||
@$(".empty-message").hide()
|
||||
|
||||
hideEmptyMessage: () ->
|
||||
@$(".empty-message").hide()
|
||||
|
||||
showLoading: ->
|
||||
@loading = true
|
||||
@$(".loading").show()
|
||||
|
||||
hideLoading: ->
|
||||
@loading = false
|
||||
@$(".loading").hide()
|
||||
|
||||
VersionListItemView = Backbone.View.extend
|
||||
tagName: "li"
|
||||
|
||||
events:
|
||||
"click a": "showVersionDetail"
|
||||
|
||||
template : $("#versionListItemTemplate").html()
|
||||
|
||||
initialize: ->
|
||||
@render()
|
||||
|
||||
render: ->
|
||||
@$el.html Mustache.to_html(@template, @modelView())
|
||||
return this
|
||||
|
||||
modelView: ->
|
||||
modelView = @model.toJSON()
|
||||
modelView.date = util.formatDate(modelView.date)
|
||||
return modelView
|
||||
|
||||
showVersionDetail: ->
|
||||
$("#versionListArea .active").removeClass "active"
|
||||
@$el.addClass "active"
|
||||
@model.fetch success: (model) ->
|
||||
view = new VersionDetailView(model: model)
|
||||
view.render()
|
||||
|
||||
return VersionListView
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
define ->
|
||||
formatDate = (date) ->
|
||||
date = new Date(date) unless date instanceof Date
|
||||
delta = (new Date() - date) / 1000.0
|
||||
seconds = 1
|
||||
minutes = 60*seconds
|
||||
hours = 60*minutes
|
||||
days = 24*hours
|
||||
if (delta < 30*seconds)
|
||||
"just now"
|
||||
else if (delta < 2*minutes)
|
||||
"a minute ago"
|
||||
else if (delta < 1*hours)
|
||||
Math.floor(delta / minutes) + " minutes ago"
|
||||
else if (delta < 2*hours)
|
||||
"an hour ago"
|
||||
else if (delta < 1*days)
|
||||
Math.floor(delta / hours) + " hours ago"
|
||||
else
|
||||
hours = date.getHours()
|
||||
hours = "0" + hours if hours < 10
|
||||
minutes = date.getMinutes()
|
||||
minutes = "0" + minutes if minutes < 10
|
||||
hours + ":" + minutes + " " + date.toLocaleDateString()
|
||||
|
||||
return {
|
||||
formatDate : formatDate
|
||||
}
|
||||
@@ -32,7 +32,6 @@ define [
|
||||
"libs/jquery.color"
|
||||
"libs/jquery-layout"
|
||||
"libs/backbone"
|
||||
"main"
|
||||
], (
|
||||
ConnectionManager,
|
||||
HistoryManager,
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
require [
|
||||
"./slides"
|
||||
"./forms"
|
||||
"./gui"
|
||||
"./home"
|
||||
"./event_tracking"
|
||||
], ()->
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ define [
|
||||
"pdf/NativePdfView"
|
||||
"libs/backbone"
|
||||
"libs/mustache"
|
||||
"libs/bootstrap"
|
||||
"libs/jquery.storage"
|
||||
], (PdfjsView, NativePdfView) ->
|
||||
LatexErrorView = Backbone.View.extend
|
||||
|
||||
@@ -4,7 +4,7 @@ define [
|
||||
"pdf/SyncButtonsView"
|
||||
"libs/latex-log-parser"
|
||||
"libs/jquery.storage"
|
||||
"libs/underscore"
|
||||
"underscore"
|
||||
"libs/backbone"
|
||||
], (Modal, CompiledView, SyncButtonsView, LogParser) ->
|
||||
class PdfManager
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
require [
|
||||
"libs/jquery.slides.min"
|
||||
], () ->
|
||||
$('#slides').slidesjs({
|
||||
width: 940,
|
||||
height: 100,
|
||||
play: {
|
||||
active: false,
|
||||
auto: true,
|
||||
interval: 5000
|
||||
},
|
||||
navigation: {
|
||||
active: false
|
||||
},
|
||||
pagination: {
|
||||
active: false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
define [
|
||||
"libs/underscore"
|
||||
"libs/typeahead"
|
||||
"libs/mustache"
|
||||
], () ->
|
||||
class TagManager
|
||||
template: $('#tagTemplate').html()
|
||||
|
||||
constructor: () ->
|
||||
@getTags (error, @allTags) =>
|
||||
@_initDeleteTagButtons()
|
||||
@_initAddTagButtons()
|
||||
$("form.search").on "submit", (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
deleteTagFromProject: (project_id, tagName) ->
|
||||
$.post "/project/#{project_id}/tag", { deletedTag: tagName, _csrf: window.csrfToken }
|
||||
$(".tag-label[data-project-id=#{project_id}][data-tag='#{tagName}']").remove()
|
||||
|
||||
getTags: (callback = (err, tags) ->) ->
|
||||
$.getJSON "/tag", (tags) =>
|
||||
tags = _.sortBy tags, (tag) =>
|
||||
return -tag.project_ids.length
|
||||
callback null, tags
|
||||
|
||||
getCurrentTagsForProject: (project_id) ->
|
||||
currentTags = opts.$newTagLocation.parents('.project-tags').find('.tag-label')
|
||||
_.map currentTags, (currentTag)->
|
||||
$(currentTag).text().trim()
|
||||
|
||||
createTagForProject: (project_id, tagName)->
|
||||
existingTag = null
|
||||
for tag in @allTags
|
||||
if tag.name.toLowerCase() == tagName.toLowerCase()
|
||||
existingTag = tag
|
||||
break
|
||||
|
||||
if !existingTag?
|
||||
existingTag =
|
||||
name: tagName
|
||||
project_ids: []
|
||||
@allTags.push existingTag
|
||||
|
||||
if project_id not in existingTag.project_ids
|
||||
existingTag.project_ids.push project_id
|
||||
$.post "/project/#{project_id}/tag", {tag: tagName, _csrf: window.csrfToken}
|
||||
el = $ Mustache.to_html @template, project_id: project_id, tagName: tagName
|
||||
el.insertBefore $(".project-tags[data-project-id=#{project_id}] .new-tags")
|
||||
@_initDeleteTagButton(el)
|
||||
|
||||
_initAddTagButtons: () ->
|
||||
tagManager = @
|
||||
$('.addTagButton').on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
project_id = $(@).data("project-id")
|
||||
tagManager._showTagInputForm(project_id)
|
||||
|
||||
_initDeleteTagButtons: () ->
|
||||
$(".tag-label").each (index, tag) =>
|
||||
@_initDeleteTagButton($(tag))
|
||||
|
||||
_initDeleteTagButton: ($tag) ->
|
||||
tagManager = @
|
||||
$tag.find('.delete-tag').on 'click', (e)->
|
||||
tagName = $(@).data("tag")
|
||||
project_id = $(@).data("project-id")
|
||||
tagManager.deleteTagFromProject(project_id, tagName)
|
||||
|
||||
_showTagInputForm: (project_id) ->
|
||||
$("input.tags-input[data-project-id=#{project_id}]").show()
|
||||
$(".addTagButton[data-project-id=#{project_id}]").hide()
|
||||
@._initTagInput(project_id)
|
||||
|
||||
_hideTagInputForm: (project_id) ->
|
||||
@_tearDownTagInput(project_id)
|
||||
$("input.tags-input[data-project-id=#{project_id}]").hide()
|
||||
$(".addTagButton[data-project-id=#{project_id}]").show()
|
||||
|
||||
_initTagInput: (project_id) ->
|
||||
input = $("input.tags-input[data-project-id=#{project_id}]")
|
||||
|
||||
typeahead = for tag in @allTags
|
||||
{ value: $("<div/>").text(tag.name).html() }
|
||||
input.typeahead(local: typeahead)
|
||||
input.focus()
|
||||
|
||||
input.on "typeahead:selected", (e) =>
|
||||
tagName = input.val()
|
||||
@createTagForProject project_id, tagName
|
||||
input.val("")
|
||||
|
||||
input.on 'keypress', (e) =>
|
||||
if(e.keyCode == 13)
|
||||
tagName = input.val()
|
||||
|
||||
if tagName.length > 0
|
||||
@createTagForProject project_id, tagName
|
||||
input.val("")
|
||||
|
||||
input.on "blur", (e) =>
|
||||
# Give the typeahead element a chance to be selected
|
||||
setTimeout () =>
|
||||
@_hideTagInputForm(project_id)
|
||||
, 100
|
||||
|
||||
_tearDownTagInput: (project_id) ->
|
||||
input = $("input.tags-input[data-project-id=#{project_id}]")
|
||||
input.typeahead("destroy")
|
||||
input.off()
|
||||
|
||||
|
||||
window.tagManager = new TagManager()
|
||||
@@ -1,7 +1,6 @@
|
||||
define [
|
||||
"libs/backbone"
|
||||
"libs/mustache"
|
||||
"libs/bootstrap"
|
||||
], () ->
|
||||
Modal = Backbone.View.extend {
|
||||
templates:
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Generated by CoffeeScript 1.3.3
|
||||
(function() {
|
||||
|
||||
require(['jquery'], function($) {
|
||||
var RevisionHistory;
|
||||
return module.exports = RevisionHistory = new Class({
|
||||
constructor: function(data) {
|
||||
this.tableTemplate = _.template($('#revisionHistoryRowTemplate'));
|
||||
return this.tableRow = $(this.template({
|
||||
date: new Date(),
|
||||
filesChangeCount: 4
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
Reference in New Issue
Block a user