Is it possible to serialize an Ace Session object?

夙愿已清 提交于 2019-12-21 20:28:26

问题


I'd like to serialize and store Ace Session objects, so I can open a "File" and restore everything, value, selection, cursor position, mode, etc.

I've tried JSON.stringify(session) and it throws a circular error.

Any ideas?


回答1:


the simplest version would be

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)

and to restore

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)

this doesn't cover restoring undomanager which is doable but a little trickier. you can try to bump this issue https://github.com/ajaxorg/ace/issues/1452




回答2:


My solution combined from 3 sources:

  • https://stackoverflow.com/a/20404474/630169
  • https://stackoverflow.com/a/28260919/630169
  • https://stackoverflow.com/a/34311510/630169

Moved session serialization code to a separate module:

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;

Browser side JS: processed by 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);


来源:https://stackoverflow.com/questions/20395991/is-it-possible-to-serialize-an-ace-session-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!