diff --git a/core/fse--class.js b/core/fse--class.js deleted file mode 100644 index ed8bfa76..00000000 --- a/core/fse--class.js +++ /dev/null @@ -1,325 +0,0 @@ -/* jslint node: true */ -'use strict'; - -var ViewController = require('./view_controller.js').ViewController; -var ansi = require('./ansi_term.js'); -var theme = require('./theme.js'); -var MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView; -var Message = require('./message.js'); - -var async = require('async'); -var events = require('events'); -var assert = require('assert'); -var _ = require('lodash'); - -module.exports = FullScreenEditor; - -function FullScreenEditor(options) { - events.EventEmitter.call(this); - - assert(_.isObject(options.client)); - assert(_.isObject(options.art)); - assert(_.isString(options.editorType)); - - var self = this; - - // - // options.callingMenu : menu that created us - // options.client - // options.art{} : name -> artAsset - // options.font : optional - // options.editorMode (view|edit|quote) | (editMenu|) - // - // options.editorType : email | area - this.callingMenu = options.callingMenu; - this.client = options.client; - this.art = options.art; - this.font = options.font; - this.editorType = options.editorType; - - this.mciData = {}; - - this.editorMode = 'edit'; // view | edit | editMenu | - - this.initViewControllers(); - - this.getFooterName = function(editorMode) { - editorMode = editorMode || this.editorMode; - return 'footer' + _.capitalize(editorMode); // e.g.. 'footerEditMenu' - }; - - this.getFormId = function(name) { - return { - header : 0, - body : 1, - footerEdit : 2, - footerEditMenu : 3, - footerView : 4, - - help : 50, - }[name]; - }; - - this.isViewMode = function() { - return 'view' === this.editorMode; - }; - - this.redrawFooter = function(options, cb) { - async.waterfall( - [ - function moveToFooterPosition(callback) { - // - // Calculate footer staring position - // - // row = (header height + body height) - // - // Header: mciData.body.height - // Body : We must find this in the config / theme - // - // :TODO: don't hard code this -- allow footer height to be part of theme/etc. - self.client.term.rawWrite(ansi.goto(23, 1)); - callback(null); - }, - function clearFooterArea(callback) { - if(options.clear) { - self.client.term.rawWrite(ansi.reset() + ansi.deleteLine(3)); - } - callback(null); - }, - function displayFooterArt(callback) { - var footerArt = self.art[options.footerName]; - - theme.displayThemedAsset( - footerArt, - self.client, - { font : self.font }, - function displayed(err, artData) { - callback(err, artData); - } - ); - } - ], - function complete(err, artData) { - cb(err, artData); - } - ); - }; - - this.redrawAll = function(options, cb) { - var artComponents = [ 'header', 'body' ]; - var art = self.art; - - self.client.term.rawWrite(ansi.resetScreen()); - - async.series( - [ - function displayHeaderAndBody(callback) { - async.eachSeries( artComponents, function dispArt(n, next) { - theme.displayThemedAsset( - art[n], - self.client, - { font : self.font }, - function displayed(err, artData) { - if(options.initMci) { - self.mciData[n] = artData; - } - next(err); - } - ); - }, function complete(err) { - callback(err); - }); - }, - function displayFooter(callback) { - // we have to treat the footer special - var footerName = self.getFooterName(); - self.redrawFooter( { clear : false, footerName : footerName }, function footerDisplayed(err, artData) { - if(options.initMci) { - self.mciData[footerName] = artData; - } - callback(err); - }); - }, - function refreshViews(callback) { - if(options.refreshViews) { - artComponents.push(self.getFooterName()); - - artComponents.forEach(function artComp(n) { - self.viewControllers[n].redrawAll(); - }); - } - callback(null); - } - ], - function complete(err) { - cb(err); - } - ); - }; - - this.createInitialViews = function(cb) { - - var menuLoadOpts = { callingMenu : self.callingMenu }; - - async.series( - [ - function header(callback) { - menuLoadOpts.formId = self.getFormId('header'); - menuLoadOpts.mciMap = self.mciData.header.mciMap; - - self.addViewController( - 'header', - new ViewController( { client : self.client, formId : menuLoadOpts.formId } ) - ).loadFromMenuConfig(menuLoadOpts, function headerReady(err) { - callback(err); - }); - }, - function body(callback) { - menuLoadOpts.formId = self.getFormId('body'); - menuLoadOpts.mciMap = self.mciData.body.mciMap; - - self.addViewController( - 'body', - new ViewController( { client : self.client, formId : menuLoadOpts.formId } ) - ).loadFromMenuConfig(menuLoadOpts, function bodyReady(err) { - callback(err); - }); - }, - function footer(callback) { - var footerName = self.getFooterName(); - - menuLoadOpts.formId = self.getFormId(footerName); - menuLoadOpts.mciMap = self.mciData[footerName].mciMap; - - self.addViewController( - footerName, - new ViewController( { client : self.client, formId : menuLoadOpts.formId } ) - ).loadFromMenuConfig(menuLoadOpts, function footerReady(err) { - callback(err); - }); - }, - function prepare(callback) { - var header = self.viewControllers.header; - var from = header.getView(1); - from.acceptsFocus = false; - from.setText(self.client.user.username); - - callback(null); - }, - function setInitialFocus(callback) { - self.viewControllers.body.setFocus(false); - self.viewControllers.header.switchFocus(2); - callback(null); - } - ], - function complete(err) { - cb(err); - } - ); - }; - - this.switchFooter = function(cb) { - var footerName = self.getFooterName(); - - self.redrawFooter( { footerName : footerName, clear : true }, function artDisplayed(err, artData) { - if(err) { - cb(err); - return; - } - - var formId = self.getFormId(footerName); - - if(_.isUndefined(self.viewControllers[footerName])) { - console.log(artData) - var menuLoadOpts = { - callingMenu : self.callingMenu, - formId : formId, - mciMap : artData.mciMap - }; - - self.addViewController( - footerName, - new ViewController( { client : self.client, formId : formId } ) - ).loadFromMenuConfig(menuLoadOpts, function footerReady(err) { - cb(err); - }); - } else { - self.viewControllers[footerName].redrawAll(); - cb(null); - } - }); - }; -} - -require('util').inherits(FullScreenEditor, events.EventEmitter); -require('./mod_mixins.js').ViewControllerManagement.call(FullScreenEditor.prototype); - -FullScreenEditor.prototype.enter = function() { - - var self = this; - - async.series( - [ - function drawScreen(callback) { - self.redrawAll( { initMci : true }, function allDrawn(err) { - callback(err); - }); - }, - function createViews(callback) { - self.createInitialViews(function viewsCreated(err) { - callback(err); - }); - }, - ], - function complete(err) { - if(err) { - self.emit('error', err); - } - } - ); -}; - -FullScreenEditor.prototype.leave = function() { - -}; - -FullScreenEditor.prototype.submitHandler = function(formData, extraArgs) { - var self = this; - - // :TODO: Use key map from config for this stuff - - if(formData.id === self.getFormId('header')) { - // :TODO: we need to validate the "to" here - self.viewControllers.header.setFocus(false); - self.viewControllers.body.switchFocus(1); - } else if(formData.id === self.getFormId('body') && formData.key && 'escape' === formData.key.name) { - if(!self.isViewMode()) { - self.editorMode = 'edit' === self.editorMode ? 'editMenu' : 'edit'; - - self.switchFooter(function next(err) { - if(err) { - // :TODO:... what now? - console.log(err) - } else { - switch(self.editorMode) { - case 'edit' : - if(!_.isUndefined(self.viewControllers.footerEditMenu)) { - self.viewControllers.footerEditMenu.setFocus(false); - } - self.viewControllers.body.switchFocus(1); - self.observeEditEvents(); - break; - - case 'editMenu' : - self.viewControllers.body.setFocus(false); - self.viewControllers.footerEditMenu.switchFocus(1); - break; - - default : throw new Error('Unexpected mode'); - } - - } - }); - } - } -}; \ No newline at end of file diff --git a/core/text_buffer.js b/core/text_buffer.js deleted file mode 100644 index 202ad313..00000000 --- a/core/text_buffer.js +++ /dev/null @@ -1,192 +0,0 @@ - -var _ = require('lodash'); - -exports.TextBuffer = TextBuffer; - -/* -* gap buffer of objects -* Single buffer for actual/render -* Preserve original line endings if possible -* object has text -* standard whitespace are just objects -* tabs are special objects -* hard line feeds are recorded -* cursor always at currentSpan / object - - -*/ - -function TextBuferFragment(options) { - if(_.isString(options)) { - this.text = options; - } else { - this.text = options.text || ''; - } - - var self = this; - - this.isTab = function() { - return '\t' === self.text; - }; - - this.isWhitespace = function() { - return self.text.match(/\s+/g) ? true : false; - }; - - Object.defineProperty(this, 'length', { - enumerable : true, - get : function() { - return this.text.length; - }, - }); -} - -function TextBuffer(options) { - - this.gapSize = options.gapSize || 64; - this.buffer = new Array(this.gapSize); - this.gapStart = 0; - this.gapEnd = this.gapSize; - this.spliceArgs = new Array(this.gapSize + 2); - - - var self = this; - - Object.defineProperty(this, 'length', { - enumerable : true, - get : function() { - return this.buffer.length - (this.gapEnd - this.gapSize); - }, - }); - - this.adjustGap = function(index) { - var gapSize = (self.gapEnd - self.gapStart); - var delta; - var i; - - if(index < self.gapStart) { - delta = self.gapStart - index; - - for(i = delta - 1; i >= 0; --i) { - self.buffer[self.gapEnd - delta + i] = self.buffer[index + i]; - } - - self.gapStart -= delta; - self.gapEnd -= delta; - } else if(index > self.gapStart) { - delta = index - self.gapStart; - - for(i = 0; i < delta; ++i) { - self.buffer[self.gapStart + i] = self.buffer[self.gapEnd + i]; - } - - self.gapStart += delta; - self.gapEnd += delta; - } - }; -} - -TextBuffer.prototype.get = function(index) { - if(index >= this.length) { - return undefined; - } - - if(index >= this.gapStart) { - index += (this.gapEnd - this.gapStart); - } - - return this.buffer[index]; -}; - -TextBuffer.prototype.insertFragment = function(index, fragment) { - if(index < 0) { - throw new RangeError('Index must be >= 0'); - } - -/* - if(index > this.length) { - console.log(this.gapStart) - console.log(this.gapEnd) - throw new RangeError('Index must be <= length'); - }*/ - - if(this.gapStart === this.gapEnd) { - this.spliceArgs[0] = index; - this.spliceArgs[1] = 0; - - Array.prototype.splice.apply(this.buffer, this.spliceArgs); - - this.gapStart = index; - this.gapEnd = index + this.gapSize; - } else { - this.adjustGap(index); - } - - this.buffer[this.gapStart++] = fragment; -}; - -TextBuffer.prototype.insertText = function(index, text) { - // - // Create fragments from text. Each fragment is: - // * A series of whitespace(s) - // * A tab - // * Printable characters - // - // A fragment may also have various flags set - // for eol markers. These are always normalized - // to a single *nix style \n - // - if(0 === text.length) { - return; - } - - var re = /\r\n|\n|\r|\t|\s+/g; - var m; - var i = index; - var from; - do { - from = re.lastIndex + (_.isObject(m) ? m[0].length - 1 : 0); - m = re.exec(text); - if(null !== m) { - - this.insertFragment(i++, new TextBuferFragment({ - text : text.substring(from, re.lastIndex) - })); - - switch(m[0].charAt(0)) { - case '\t' : - for(var j = 0; j < m[0].length; ++j) { - this.insertFragment(i++, new TextBuferFragment({ - text : m[0].charAt(j) - })); - } - break; - - case '\r' : - case '\n' : - var count = m[0].split(/\r\n|\n|\r/g).length; - for(var j = 0; j < count; ++j) { - this.insertFragment(i++, new TextBuferFragment({ - text : '\n' // always normalized - })); - } - break; - - case ' ' : - this.insertFragment(i++, new TextBuferFragment({ - text : m[0], - })); - break; - } - } - } while(0 !== re.lastIndex); -}; - -// :TODO: getArray() should take range -TextBuffer.prototype.getArray = function() { - return this.buffer.slice(0, this.gapStart).concat(this.buffer.slice(this.gapEnd)); -}; - -TextBuffer.prototype.getText = function(range) { - -}; \ No newline at end of file diff --git a/mods/msg_area_post.js b/mods/msg_area_post.js deleted file mode 100644 index 827d1dec..00000000 --- a/mods/msg_area_post.js +++ /dev/null @@ -1,59 +0,0 @@ -/* jslint node: true */ -'use strict'; - -var MenuModule = require('../core/menu_module.js').MenuModule; -var FullScreenEditor = require('../core/fse--class.js'); // :TODO: fix this -//var theme = require('../core/theme.js'); - -var async = require('async'); -var assert = require('assert'); -var _ = require('lodash'); - -exports.getModule = MessageAreaPostModule; - -exports.moduleInfo = { - name : 'Message Area Post', - desc : 'Module posting a new message to an area', - author : 'NuSkooler', -}; - -function MessageAreaPostModule(options) { - MenuModule.call(this, options); - - var self = this; - - - this.initSequence = function() { - self.fse = new FullScreenEditor( { - callingMenu : this, - client : this.client, - // :TODO: should pass in full config? want access to keymap/etc. as well - art : this.menuConfig.config.fseArt, - font : this.menuConfig.font, - editorType : 'area', - editorMode : 'edit', - }); - - self.fse.on('error', function fseError(err) { - console.log('fse error: ' + err) - }); - - self.fse.enter(); - }; - - this.menuMethods = { - // :TODO: is there a cleaner way to achieve this? - fseSubmitProxy : function(formData, extraArgs) { - self.fse.submitHandler(formData, extraArgs); - } - }; -} - -require('util').inherits(MessageAreaPostModule, MenuModule); - -/* -MessageAreaPostModule.prototype.mciReady = function(mciData, cb) { - this.standardMCIReadyHandler(mciData, cb); -}; -*/ -