# Triggers # # status: # - success CodeSync.Document = Backbone.Model.extend callbackDelay: 150 initialize: (@attributes,options)-> if localKey = @attributes.localStorageKey @attributes.contents ||= localStorage.getItem(localKey) Backbone.Model::initialize.apply(@, arguments) _.bindAll @, "onContentChange" @on "change:contents", @onContentChange @on "change:name", ()=> @set("mode", @determineMode()) @set("display", @nameWithoutExtension() ) @on "change:mode", ()=> @set('extension', @determineExtension(), silent: true) url: ()-> CodeSync.get("assetCompilationEndpoint") saveToDisk: ()-> if @isSaveable() @sendToServer(true, "saveToDisk") saveToLocalStorage: (path)-> if path? localStorage.setItem(path, @get("contents")) loadSourceFromDisk: (callback)-> $.ajax url: "#{ @url() }?path=#{ @get('path') }" type: "GET" success: (response={})=> if response.success is true and response.contents? @set("contents", response.contents, silent: true) callback(@) toJSON: ()-> name: @nameWithoutExtension() path: @get('path') extension: @get('extension') || @determineExtension() contents: @toContent() nameWithoutExtension: ()-> extension = @get('extension') || @determineExtension() (@get("name") || "untitled").replace(extension,'') toMode: ()-> mode = @get("mode") || @determineMode() modeModel = CodeSync.Modes.getMode(mode) toCodeMirrorMode: ()-> @toMode()?.get("codeMirrorMode") toCodeMirrorDocument: ()-> CodeMirror.Doc @toContent(), @toCodeMirrorMode(), 0 toCodeMirrorOptions: ()-> @toMode().get("codeMirrorOptions") toContent: ()-> "#{ @get("contents") || @toMode()?.get("defaultContent") || " " }" onContentChange: ()-> localKey = @get("localStorageKey") localKey = if localKey? && _.isFunction(localKey) then localKey.call(@) else localKey localStorage.setItem(localKey, @get("contents")) @sendToServer(false, "onContentChange") sendToServer: (allowSaveToDisk=false, reason="")-> allowSaveToDisk = false unless @isSaveable() data = if allowSaveToDisk is true then @toJSON() else _(@toJSON()).pick('name','extension','contents') CodeSync.log("Sending Data To #{ CodeSync.get("assetCompilationEndpoint") }", data) $.ajax type: "POST" url: CodeSync.get("assetCompilationEndpoint") data: JSON.stringify(data) error: (response)=> CodeSync.log("Document Process Error", arguments) success: (response)=> CodeSync.log("Document Process Response", response) if response.success is true @trigger "status", type: "success", message: @successMessage(reason), compiled: response.compiled if response.success is true and response.compiled? @set("compiled", response.compiled) if response.success is false and response.error? @set("error", response.error?.message) @trigger "status", type: "error", message: response.error?.message loadInPage: (options={})-> if @type() is "stylesheet" helpers.processStyleContent.call(@, @get('compiled')) else if (@type() is "script" or @type() is "template") helpers.processScriptContent.call(@, @get('compiled')) if options.complete _.delay(options.complete, (options.delay||@callbackDelay)) # Determines how we will handle the compiled assets when loading in the page type: ()-> switch @get("mode") when "css","sass","scss","less" "stylesheet" when "coffeescript","javascript" "script" when "skim","mustache","jst","haml","eco" "template" missingFileName: ()-> name = (@get('path') || @get('name')) !name? || name.length is 0 # If this is an adHoc document that is not being saved to disk, or rather # pulled from an existing asset on disk, then we will need to create an extension # that is appropriate for the CodeMirror mode, for the purposes of on the fly compilation determineExtension: ()-> filename = @get("path") || @get("name") if extension = CodeSync.Document.getExtensionFor(filename) return extension if @get("mode")? return CodeSync.Modes.guessExtensionFor( @get('mode') || CodeSync.get("defaultFileType") ) # Determine a CodeMirror mode setting appropriate for the file extension determineMode: -> path = @get("path") || @get("name") || @get("extension") CodeSync.Modes.guessModeFor(path) successMessage: (reason)-> if @type() is "template" "Success. Template will be available as JST[\"#{ @nameWithoutExtension() }\"]" isSticky: ()-> @get("sticky")? is true isSaveable: ()-> @get("path")?.length > 0 && !@get("doNotSave") CodeSync.Document.getFileNameFrom = (string="")-> string.split('/').pop() CodeSync.Document.getExtensionFor = (string="")-> filename = CodeSync.Document.getFileNameFrom(string) [fname,rest...] = filename.split('.') if val = rest.length > 0 && rest.join('.') ".#{ val }" CodeSync.Documents = Backbone.Collection.extend model: CodeSync.Document initialize: (models,options)-> Backbone.Collection::initialize.apply(@, arguments) if client = CodeSync.Client.get() && client?.socket? client.subscribeWith (notification)-> console.log "Documents", notification nextId: ()-> @models.length + 1 findByPath: (path)-> documentModel = @detect (documentModel)-> documentModel.get('path')?.match(path) findOrCreateForPath: (path="", callback)-> if documentModel = @findByPath(path) callback?(documentModel) else name = CodeSync.Document.getFileNameFrom(path) extension = CodeSync.Document.getExtensionFor(name) display = name.replace(extension,'') id = @nextId() documentModel = new CodeSync.Document({name,extension,display,path,id}) documentModel.loadSourceFromDisk ()=> callback?(documentModel) helpers = processStyleContent: (content)-> $('head style[data-codesync-document]').remove() $('head').append "" processScriptContent: (code)-> doc = @ evalRunner = (code)-> try eval(code) catch e doc.trigger "status", type: "error", message: "JS Error: #{ e.message }", sticky: true throw(e) evalRunner.call(window, code)