noide
Version:
Web Editor built on hapi and nes websockets using browserify, superviews.js, bootstrap and the ACE editor.
215 lines (194 loc) • 5.19 kB
JavaScript
var page = require('page')
var Fso = require('./fso')
var Session = require('./session')
var observable = require('./observable')
var storageKey = 'noide'
// The current active file
var current
// The map of files
var files = null
// The map of recent files
var recent = new Map()
// The map of sessions
var sessions = new Map()
var noide = {
get current () {
return current
},
set current (value) {
current = value
this.emitChangeCurrent({
detail: current
})
},
load: function (payload) {
this.cwd = payload.cwd
files = new Map(payload.watched.map(function (item) {
return [item.relativePath, new Fso(item)]
}))
var storage = window.localStorage.getItem(storageKey)
storage = storage ? JSON.parse(storage) : {}
var file, i
if (storage.recent) {
for (i = 0; i < storage.recent.length; i++) {
file = files.get(storage.recent[i])
if (file) {
recent.set(file, false)
}
}
}
if (storage.expanded) {
for (i = 0; i < storage.expanded.length; i++) {
file = files.get(storage.expanded[i])
if (file && file.isDirectory) {
file.expanded = true
}
}
}
},
saveState: function (files) {
var storage = {
recent: this.recent.map(function (item) {
return item.relativePath
}),
expanded: this.files.filter(function (item) {
return item.expanded
}).map(function (item) {
return item.relativePath
})
}
window.localStorage.setItem(storageKey, JSON.stringify(storage))
},
get files () {
return Array.from(files.values())
},
get sessions () {
return Array.from(sessions.values())
},
get recent () {
return Array.from(recent.keys())
},
get dirty () {
return this.sessions.filter(function (item) {
return item.isDirty
})
},
addFile: function (data) {
var file = new Fso(data)
files.set(file.relativePath, file)
this.emitAddFile(file)
return file
},
getFile: function (path) {
return files.get(path)
},
hasFile: function (path) {
return files.has(path)
},
hasRecent: function (file) {
return recent.has(file)
},
addRecent: function (file) {
recent.set(file, true)
this.emitAddRecent(file)
},
getSession: function (file) {
return sessions.get(file)
},
getRecent: function (file) {
return recent.get(file)
},
hasSession: function (file) {
return sessions.has(file)
},
addSession: function (file, contents) {
var session = new Session(file, contents)
sessions.set(file, session)
return session
},
markSessionClean: function (session) {
session.markClean()
this.emitChangeSessionDirty(session)
},
onInput: function () {
var file = noide.current
var session = this.getSession(file)
if (session) {
var isClean = session.isClean
if (isClean && session.isDirty) {
session.isDirty = false
this.emitChangeSessionDirty(session)
} else if (!isClean && !session.isDirty) {
session.isDirty = true
this.emitChangeSessionDirty(session)
}
}
},
removeFile: function (file) {
// Remove from files
if (this.hasFile(file.relativePath)) {
files.delete(file.relativePath)
this.emitRemoveFile(file)
}
// Remove session
if (this.hasSession(file)) {
sessions.delete(file)
}
// Remove from recent files
if (this.hasRecent(file)) {
recent.delete(file)
this.emitRemoveRecent(file)
}
// If it's the current file getting removed,
// navigate back to the previous session/file
if (current === file) {
if (sessions.size) {
// Open the first session
page('/file?path=' + this.sessions[0].file.relativePath)
} else if (recent.size) {
// Open the first recent file
page('/file?path=' + this.recent[0].relativePath)
} else {
page('/')
}
}
},
closeFile: function (file) {
var session = this.getSession(file)
var close = session && session.isDirty
? window.confirm('There are unsaved changes to this file. Are you sure?')
: true
if (close) {
// Remove from recent files
recent.delete(file)
this.emitRemoveRecent(file)
if (session) {
// Remove session
sessions.delete(file)
// If it's the current file getting closed,
// navigate back to the previous session/file
if (current === file) {
if (sessions.size) {
// Open the first session
page('/file?path=' + this.sessions[0].file.relativePath)
} else if (recent.size) {
// Open the first recent file
page('/file?path=' + this.recent[0].relativePath)
} else {
page('/')
}
}
}
}
}
}
window.noide = noide
module.exports = observable(noide, {
'Change': 'change',
'AddFile': 'addfile',
'RemoveFile': 'removefile',
'AddRecent': 'addRecent',
'RemoveRecent': 'removerecent',
'ChangeCurrent': 'changecurrent',
'ChangeSessionDirty': 'changesessiondirty'
})