是否可以序列化Ace Session对象?

时间:2013-12-05 09:22:26

标签: javascript ace-editor

我想序列化并存储Ace Session对象,所以我可以打开一个“文件”并恢复所有内容,值,选择,光标位置,模式等。

我已经尝试JSON.stringify(session),但它会抛出一个循环错误。

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

最简单的版本是

var session = editor.session
state = {}
state.value = session.getValue();
state.selection = session.selection.toJSON()
state.options = session.getOptions()
state.mode = session.getMode().$id
state.folds = session.getAllFolds().map(function(fold) {
    return {
        start       : fold.start,
        end         : fold.end,
        placeholder : fold.placeholder
    };
});
state.scrollTop = session.getScrollTop()
state.scrollLeft = session.getScrollLeft()

JSON.stringify(state)

并恢复

session.setValue(state.value)
session.selection.fromJSON(state.selection)
session.setOptions(state.options)
session.setMode(state.mode)
try {
    state.folds.forEach(function(fold){
        session.addFold(fold.placeholder, 
            Range.fromPoints(fold.start, fold.end));
    });
} catch(e) {}
session.setScrollTop(state.scrollTop)
session.setScrollTop(state.scrollLeft)

这并不包括恢复无法管理,这是可行的,但有点棘手。您可以尝试解决此问题https://github.com/ajaxorg/ace/issues/1452

答案 1 :(得分:0)

我的解决方案来自3个方面:

将会话序列化代码移动到单独的模块:

editor-session.js:

var ace = require('brace');
var Range = ace.acequire('ace/range').Range;

var filterHistory = function(deltas) {
    return deltas.filter(function (d) {
        return d.group != "fold";
    });
};

/** @param {AceAjax.Editor} editor */
function sessionToJson(editor)
{
    return {
        content: editor.getSession().getValue(),
        selection: editor.getSelection().toJSON(),
        options: editor.getOptions(),
        mode: editor.session.getMode().$id,
        scrollTop: editor.session.getScrollTop(),
        scrollLeft: editor.session.getScrollLeft(),
        history: {
            undo: editor.session.getUndoManager().$undoStack.map(filterHistory),
            redo: editor.session.getUndoManager().$undoStack.map(filterHistory)
        },
        folds: editor.session.getAllFolds().map(function(fold) {
            return {
                start       : fold.start,
                end         : fold.end,
                placeholder : fold.placeholder
            };
        })
    }
}

/** @param {AceAjax.Editor} editor */
function jsonToSession(editor, state)
{
    editor.session.setValue(state.content);
    editor.selection.fromJSON(state.selection);
    editor.session.setOptions(state.options);
    editor.session.setMode(state.mode);
    editor.session.setScrollTop(state.scrollTop);
    editor.session.setScrollLeft(state.scrollLeft);
    editor.session.$undoManager.$undoStack = state.history.undo;
    editor.session.$undoManager.$redoStack = state.history.redo;
    try {
        state.folds.forEach(function(fold) {
            editor.session.addFold(fold.placeholder, Range.fromPoints(fold.start, fold.end));
        });
    } catch(e) {console.log('Fold exception: ' + e)}
}

module.exports.sessionToJson = sessionToJson;
module.exports.jsonToSession = jsonToSession;

浏览器端JS:由browserify处理

var ace = require('brace');
var state = require('./editor-session');
var editor = ace.edit('web-editor');

...

function saveEditorSession() {
    localStorage.setItem('editorSession', JSON.stringify(state.sessionToJson(editor)));
}

editor.getSession().on("change", function () {
    textarea.value = editor.getSession().getValue();
    // Save editor session to localStorage
    saveEditorSession();
    // Send editor content to backend
    ajax.saveContent(textarea.value, function (response) { });
});

editor.getSession().selection.on('changeSelection', saveEditorSession);
editor.getSession().selection.on('changeCursor', saveEditorSession);
editor.getSession().on('changeFold', saveEditorSession);
editor.getSession().on('changeScrollLeft', saveEditorSession);
editor.getSession().on('changeScrollTop', saveEditorSession);