function prepareForExport(doc, settings = settings) { let states = JSON.parse(JSON.stringify(doc.states)); states.forEach(state => { delete state.mouseOffsetX; delete state.mouseOffsetY; delete state.activeTime; delete state.isActive; }); let _connections = JSON.parse(JSON.stringify(doc.connections)).map((conn, index) => { conn.type = doc.connections[index].constructor.name; return conn; }); _connections = _connections.map(conn => { switch(conn.type) { case 'Connection': conn.stateA = conn.stateA.id; conn.stateB = conn.stateB.id; break; case 'StartConnection': conn.state = conn.state.id; break; case 'SelfConnection': conn.state = conn.state.id; break; } return conn; }); const _doc = JSON.parse(JSON.stringify(doc)); _doc.states = states; _doc.connections = _connections; delete _doc.unsaved; delete _doc.lastSavedHash; delete _doc.element; const _settings = JSON.parse(JSON.stringify(settings)); delete _settings.colors.getColor; return { document: _doc, settings: _settings, }; } function exportToJson(doc, _settings = settings) { return JSON.stringify(prepareForExport(doc, _settings)); } function parseFromJson(json) { const data = JSON.parse(json); const doc = Object.assign(new FSMDocument(''), data.document); doc.states = doc.states.map(state => Object.assign(new State(0, 0), state)); doc.connections = doc.connections.map(connection => { switch(connection.type) { case 'Connection': connection = Object.assign(new Connection(null, null), connection); connection.stateA = doc.states.find(state => state.id === connection.stateA); connection.stateB = doc.states.find(state => state.id === connection.stateB); break; case 'SelfConnection': connection = Object.assign(new SelfConnection(null), connection); connection.state = doc.states.find(state => state.id === connection.state); break; case 'StartConnection': connection = Object.assign(new StartConnection(), connection); connection.state = doc.states.find(state => state.id === connection.state); break; } delete connection.type; return connection; }); doc.lastSavedHash = doc.hashCode(); return { document: doc, settings, }; } function importFromJson(json) { const doc = parseFromJson(json); addDocument(doc.document); switchDocument(doc.document); } function exportToFile() { if(activeDocument === null) { return; } const document = documents[activeDocument]; const name = `${new Date(document.createdAt).toLocaleDateString()} - ${document.name || 'Unbenannt'}.fsm`; const json = exportToJson(document); downloadFile(name, json, 'application/json'); } function downloadFile(name, content, type) { const element = document.createElement('a'); element.setAttribute('href', `data:${type};base64,${btoa(content)}`); element.setAttribute('download', name); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } function saveToLocalStorage() { if(activeDocument === null) { return; } const newDoc = documents[activeDocument]; const data = getLocalStorageEntries(); const index = data.findIndex(entry => entry.document.id === newDoc.id); if(index !== -1) { data[index] = { document: newDoc, settings, }; } else { data.push({ document: newDoc, settings, }); } const newData = data.map(entry => prepareForExport(entry.document, entry.settings)); localStorage.setItem('documents', JSON.stringify(newData)); } function getLocalStorageEntries() { const entries = JSON.parse(localStorage.getItem('documents')); return !!entries ? entries.map(entry => parseFromJson(JSON.stringify(entry))) : []; } function openFromLocalStorage(id) { const entry = getLocalStorageEntries().find(entry => entry.document.id === id); addDocument(entry.document); switchDocument(entry.document); }