Можно ли сериализовать объект Ace Session?

Я хотел бы сериализовать и сохранить объекты Ace Session, чтобы я мог открыть "Файл" и восстановить все, значение, выбор, положение курсора, режим и т. Д.

я пробовал JSON.stringify(session) и это бросает круговую ошибку.

Есть идеи?

2 ответа

Решение

Самая простая версия будет

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)

это не распространяется на восстановление undomanager, что выполнимо, но немного сложнее. Вы можете попытаться устранить эту проблему https://github.com/ajaxorg/ace/issues/1452

Мое решение объединено из 3 источников:

Код сериализации сеанса перенесен в отдельный модуль:

редактор 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);
Другие вопросы по тегам