mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	refactored all mentions of "history" to "revision"
This commit is contained in:
		
							parent
							
								
									a69d8737ce
								
							
						
					
					
						commit
						47eb1e3e02
					
				@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					UPDATE options SET name = 'note_revision_snapshot_time_interval' WHERE name = 'history_snapshot_time_interval';
 | 
				
			||||||
@ -1,72 +0,0 @@
 | 
				
			|||||||
import noteDetailService from '../services/note_detail.js';
 | 
					 | 
				
			||||||
import utils from '../services/utils.js';
 | 
					 | 
				
			||||||
import server from '../services/server.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const $dialog = $("#note-history-dialog");
 | 
					 | 
				
			||||||
const $list = $("#note-history-list");
 | 
					 | 
				
			||||||
const $content = $("#note-history-content");
 | 
					 | 
				
			||||||
const $title = $("#note-history-title");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let historyItems = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function showCurrentNoteHistory() {
 | 
					 | 
				
			||||||
    await showNoteHistoryDialog(noteDetailService.getCurrentNoteId());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function showNoteHistoryDialog(noteId, noteRevisionId) {
 | 
					 | 
				
			||||||
    glob.activeDialog = $dialog;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $dialog.dialog({
 | 
					 | 
				
			||||||
        modal: true,
 | 
					 | 
				
			||||||
        width: 800,
 | 
					 | 
				
			||||||
        height: 700
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $list.empty();
 | 
					 | 
				
			||||||
    $content.empty();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    historyItems = await server.get('notes-history/' + noteId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (const item of historyItems) {
 | 
					 | 
				
			||||||
        const dateModified = utils.parseDate(item.dateModifiedFrom);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $list.append($('<option>', {
 | 
					 | 
				
			||||||
            value: item.noteRevisionId,
 | 
					 | 
				
			||||||
            text: utils.formatDateTime(dateModified)
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (historyItems.length > 0) {
 | 
					 | 
				
			||||||
        if (!noteRevisionId) {
 | 
					 | 
				
			||||||
            noteRevisionId = $list.find("option:first").val();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $list.val(noteRevisionId).trigger('change');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
        $title.text("No history for this note yet...");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$list.on('change', () => {
 | 
					 | 
				
			||||||
    const optVal = $list.find(":selected").val();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const historyItem = historyItems.find(r => r.noteRevisionId === optVal);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $title.html(historyItem.title);
 | 
					 | 
				
			||||||
    $content.html(historyItem.content);
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$(document).on('click', "a[action='note-history']", event => {
 | 
					 | 
				
			||||||
    const linkEl = $(event.target);
 | 
					 | 
				
			||||||
    const noteId = linkEl.attr('note-path');
 | 
					 | 
				
			||||||
    const noteRevisionId = linkEl.attr('note-history-id');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showNoteHistoryDialog(noteId, noteRevisionId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
    showCurrentNoteHistory
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
							
								
								
									
										72
									
								
								src/public/javascripts/dialogs/note_revisions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/public/javascripts/dialogs/note_revisions.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					import noteDetailService from '../services/note_detail.js';
 | 
				
			||||||
 | 
					import utils from '../services/utils.js';
 | 
				
			||||||
 | 
					import server from '../services/server.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const $dialog = $("#note-revisions-dialog");
 | 
				
			||||||
 | 
					const $list = $("#note-revision-list");
 | 
				
			||||||
 | 
					const $content = $("#note-revision-content");
 | 
				
			||||||
 | 
					const $title = $("#note-revision-title");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let revisionItems = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function showCurrentNoteRevisions() {
 | 
				
			||||||
 | 
					    await showNoteRevisionsDialog(noteDetailService.getCurrentNoteId());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function showNoteRevisionsDialog(noteId, noteRevisionId) {
 | 
				
			||||||
 | 
					    glob.activeDialog = $dialog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $dialog.dialog({
 | 
				
			||||||
 | 
					        modal: true,
 | 
				
			||||||
 | 
					        width: 800,
 | 
				
			||||||
 | 
					        height: 700
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $list.empty();
 | 
				
			||||||
 | 
					    $content.empty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    revisionItems = await server.get('notes-revisions/' + noteId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const item of revisionItems) {
 | 
				
			||||||
 | 
					        const dateModified = utils.parseDate(item.dateModifiedFrom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list.append($('<option>', {
 | 
				
			||||||
 | 
					            value: item.noteRevisionId,
 | 
				
			||||||
 | 
					            text: utils.formatDateTime(dateModified)
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (revisionItems.length > 0) {
 | 
				
			||||||
 | 
					        if (!noteRevisionId) {
 | 
				
			||||||
 | 
					            noteRevisionId = $list.find("option:first").val();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list.val(noteRevisionId).trigger('change');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        $title.text("No revisions for this note yet...");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$list.on('change', () => {
 | 
				
			||||||
 | 
					    const optVal = $list.find(":selected").val();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const revisionItem = revisionItems.find(r => r.noteRevisionId === optVal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $title.html(revisionItem.title);
 | 
				
			||||||
 | 
					    $content.html(revisionItem.content);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(document).on('click', "a[action='note-revision']", event => {
 | 
				
			||||||
 | 
					    const linkEl = $(event.target);
 | 
				
			||||||
 | 
					    const noteId = linkEl.attr('note-path');
 | 
				
			||||||
 | 
					    const noteRevisionId = linkEl.attr('note-revision-id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showNoteRevisionsDialog(noteId, noteRevisionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    showCurrentNoteRevisions
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -30,9 +30,9 @@ async function showDialog() {
 | 
				
			|||||||
            const revLink = $("<a>", {
 | 
					            const revLink = $("<a>", {
 | 
				
			||||||
                href: 'javascript:',
 | 
					                href: 'javascript:',
 | 
				
			||||||
                text: 'rev'
 | 
					                text: 'rev'
 | 
				
			||||||
            }).attr('action', 'note-history')
 | 
					            }).attr('action', 'note-revision')
 | 
				
			||||||
                .attr('note-path', change.noteId)
 | 
					                .attr('note-path', change.noteId)
 | 
				
			||||||
                .attr('note-history-id', change.noteRevisionId);
 | 
					                .attr('note-revision-id', change.noteRevisionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let noteLink;
 | 
					            let noteLink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -117,9 +117,9 @@ addModule((function() {
 | 
				
			|||||||
})());
 | 
					})());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
addModule((function () {
 | 
					addModule((function () {
 | 
				
			||||||
    const $form = $("#history-snapshot-time-interval-form");
 | 
					    const $form = $("#note-revision-snapshot-time-interval-form");
 | 
				
			||||||
    const $timeInterval = $("#history-snapshot-time-interval-in-seconds");
 | 
					    const $timeInterval = $("#note-revision-snapshot-time-interval-in-seconds");
 | 
				
			||||||
    const settingName = 'history_snapshot_time_interval';
 | 
					    const settingName = 'note_revision_snapshot_time_interval';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function settingsLoaded(settings) {
 | 
					    function settingsLoaded(settings) {
 | 
				
			||||||
        $timeInterval.val(settings[settingName]);
 | 
					        $timeInterval.val(settings[settingName]);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
"use strict";
 | 
					import server from './services/server.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(document).ready(() => {
 | 
					$(document).ready(() => {
 | 
				
			||||||
    server.get('migration').then(result => {
 | 
					    server.get('migration').then(result => {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/public/javascripts/services/bootstrap.js
									
									
									
									
										vendored
									
									
								
							@ -1,7 +1,7 @@
 | 
				
			|||||||
import addLinkDialog from '../dialogs/add_link.js';
 | 
					import addLinkDialog from '../dialogs/add_link.js';
 | 
				
			||||||
import jumpToNoteDialog from '../dialogs/jump_to_note.js';
 | 
					import jumpToNoteDialog from '../dialogs/jump_to_note.js';
 | 
				
			||||||
import labelsDialog from '../dialogs/labels.js';
 | 
					import labelsDialog from '../dialogs/labels.js';
 | 
				
			||||||
import noteRevisionsDialog from '../dialogs/note_history.js';
 | 
					import noteRevisionsDialog from '../dialogs/note_revisions.js';
 | 
				
			||||||
import noteSourceDialog from '../dialogs/note_source.js';
 | 
					import noteSourceDialog from '../dialogs/note_source.js';
 | 
				
			||||||
import recentChangesDialog from '../dialogs/recent_changes.js';
 | 
					import recentChangesDialog from '../dialogs/recent_changes.js';
 | 
				
			||||||
import recentNotesDialog from '../dialogs/recent_notes.js';
 | 
					import recentNotesDialog from '../dialogs/recent_notes.js';
 | 
				
			||||||
@ -43,7 +43,7 @@ utils.bindShortcut('ctrl+l', addLinkDialog.showDialog);
 | 
				
			|||||||
$("#jump-to-note-button").click(jumpToNoteDialog.showDialog);
 | 
					$("#jump-to-note-button").click(jumpToNoteDialog.showDialog);
 | 
				
			||||||
utils.bindShortcut('ctrl+j', jumpToNoteDialog.showDialog);
 | 
					utils.bindShortcut('ctrl+j', jumpToNoteDialog.showDialog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$("#show-history-button").click(noteRevisionsDialog.showCurrentNoteHistory);
 | 
					$("#show-note-revisions-button").click(noteRevisionsDialog.showCurrentNoteRevisions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$("#show-source-button").click(noteSourceDialog.showDialog);
 | 
					$("#show-source-button").click(noteSourceDialog.showDialog);
 | 
				
			||||||
utils.bindShortcut('ctrl+u', noteSourceDialog.showDialog);
 | 
					utils.bindShortcut('ctrl+u', noteSourceDialog.showDialog);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
import linkService from './link.js';
 | 
					//import messagingService from './messaging.js';
 | 
				
			||||||
import messagingService from './messaging.js';
 | 
					//import ScriptContext from './script_context.js';
 | 
				
			||||||
import ScriptContext from './script_context.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function reloadApp() {
 | 
					function reloadApp() {
 | 
				
			||||||
    window.location.reload(true);
 | 
					    window.location.reload(true);
 | 
				
			||||||
@ -189,7 +188,7 @@ async function requireScript(url) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
async function requireCss(url) {
 | 
					async function requireCss(url) {
 | 
				
			||||||
    const css = Array
 | 
					    const css = Array
 | 
				
			||||||
        .from(document.querySelectorAll('linkService'))
 | 
					        .from(document.querySelectorAll('link'))
 | 
				
			||||||
        .map(scr => scr.href);
 | 
					        .map(scr => scr.href);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!css.includes(url)) {
 | 
					    if (!css.includes(url)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -10,10 +10,10 @@ const wrap = require('express-promise-wrap').wrap;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
					router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			||||||
    const noteId = req.params.noteId;
 | 
					    const noteId = req.params.noteId;
 | 
				
			||||||
    const history = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
 | 
					    const revisions = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
 | 
				
			||||||
    protected_session.decryptNoteHistoryRows(req, history);
 | 
					    protected_session.decryptNoteRevisions(req, revisions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.send(history);
 | 
					    res.send(revisions);
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
					router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			||||||
@ -22,7 +22,7 @@ router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			|||||||
    await sql.doInTransaction(async () => {
 | 
					    await sql.doInTransaction(async () => {
 | 
				
			||||||
        await sql.replace("note_revisions", req.body);
 | 
					        await sql.replace("note_revisions", req.body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await sync_table.addNoteHistorySync(req.body.noteRevisionId, sourceId);
 | 
					        await sync_table.addNoteRevisionSync(req.body.noteRevisionId, sourceId);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.send();
 | 
					    res.send();
 | 
				
			||||||
@ -8,7 +8,7 @@ const auth = require('../../services/auth');
 | 
				
			|||||||
const wrap = require('express-promise-wrap').wrap;
 | 
					const wrap = require('express-promise-wrap').wrap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// options allowed to be updated directly in settings dialog
 | 
					// options allowed to be updated directly in settings dialog
 | 
				
			||||||
const ALLOWED_OPTIONS = ['protected_session_timeout', 'history_snapshot_time_interval'];
 | 
					const ALLOWED_OPTIONS = ['protected_session_timeout', 'note_revision_snapshot_time_interval'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get('/all', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
					router.get('/all', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			||||||
    const settings = await sql.getMap("SELECT name, value FROM options");
 | 
					    const settings = await sql.getMap("SELECT name, value FROM options");
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ router.post('/force-note-sync/:noteId', auth.checkApiAuth, wrap(async (req, res,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
 | 
					        for (const noteRevisionId of await sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
 | 
				
			||||||
            await sync_table.addNoteHistorySync(noteRevisionId);
 | 
					            await sync_table.addNoteRevisionsSync(noteRevisionId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -169,7 +169,7 @@ router.put('/branches', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			|||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.put('/note_revisions', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
					router.put('/note_revisions', auth.checkApiAuth, wrap(async (req, res, next) => {
 | 
				
			||||||
    await syncUpdate.updateNoteHistory(req.body.entity, req.body.sourceId);
 | 
					    await syncUpdate.updateNoteRevision(req.body.entity, req.body.sourceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.send({});
 | 
					    res.send({});
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ const treeApiRoute = require('./api/tree');
 | 
				
			|||||||
const notesApiRoute = require('./api/notes');
 | 
					const notesApiRoute = require('./api/notes');
 | 
				
			||||||
const treeChangesApiRoute = require('./api/tree_changes');
 | 
					const treeChangesApiRoute = require('./api/tree_changes');
 | 
				
			||||||
const cloningApiRoute = require('./api/cloning');
 | 
					const cloningApiRoute = require('./api/cloning');
 | 
				
			||||||
const noteHistoryApiRoute = require('./api/note_history');
 | 
					const noteRevisionsApiRoute = require('./api/note_revisions');
 | 
				
			||||||
const recentChangesApiRoute = require('./api/recent_changes');
 | 
					const recentChangesApiRoute = require('./api/recent_changes');
 | 
				
			||||||
const settingsApiRoute = require('./api/settings');
 | 
					const settingsApiRoute = require('./api/settings');
 | 
				
			||||||
const passwordApiRoute = require('./api/password');
 | 
					const passwordApiRoute = require('./api/password');
 | 
				
			||||||
@ -44,7 +44,7 @@ function register(app) {
 | 
				
			|||||||
    app.use('/api/tree', treeChangesApiRoute);
 | 
					    app.use('/api/tree', treeChangesApiRoute);
 | 
				
			||||||
    app.use('/api/notes', cloningApiRoute);
 | 
					    app.use('/api/notes', cloningApiRoute);
 | 
				
			||||||
    app.use('/api', labelsRoute);
 | 
					    app.use('/api', labelsRoute);
 | 
				
			||||||
    app.use('/api/notes-history', noteHistoryApiRoute);
 | 
					    app.use('/api/notes-revisions', noteRevisionsApiRoute);
 | 
				
			||||||
    app.use('/api/recent-changes', recentChangesApiRoute);
 | 
					    app.use('/api/recent-changes', recentChangesApiRoute);
 | 
				
			||||||
    app.use('/api/settings', settingsApiRoute);
 | 
					    app.use('/api/settings', settingsApiRoute);
 | 
				
			||||||
    app.use('/api/password', passwordApiRoute);
 | 
					    app.use('/api/password', passwordApiRoute);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
const build = require('./build');
 | 
					const build = require('./build');
 | 
				
			||||||
const packageJson = require('../../package');
 | 
					const packageJson = require('../../package');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_DB_VERSION = 80;
 | 
					const APP_DB_VERSION = 81;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    app_version: packageJson.version,
 | 
					    app_version: packageJson.version,
 | 
				
			||||||
 | 
				
			|||||||
@ -161,7 +161,7 @@ async function runAllChecks() {
 | 
				
			|||||||
            note_revisions LEFT JOIN notes USING(noteId) 
 | 
					            note_revisions LEFT JOIN notes USING(noteId) 
 | 
				
			||||||
          WHERE 
 | 
					          WHERE 
 | 
				
			||||||
            notes.noteId IS NULL`,
 | 
					            notes.noteId IS NULL`,
 | 
				
			||||||
        "Missing notes records for following note history ID > note ID", errorList);
 | 
					        "Missing notes records for following note revision ID > note ID", errorList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await runCheck(`
 | 
					    await runCheck(`
 | 
				
			||||||
          SELECT 
 | 
					          SELECT 
 | 
				
			||||||
 | 
				
			|||||||
@ -154,32 +154,32 @@ async function protectNote(note, dataKey, protect, sourceId) {
 | 
				
			|||||||
        await sync_table.addNoteSync(note.noteId, sourceId);
 | 
					        await sync_table.addNoteSync(note.noteId, sourceId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await protectNoteHistory(note.noteId, dataKey, protect, sourceId);
 | 
					    await protectNoteRevisions(note.noteId, dataKey, protect, sourceId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function protectNoteHistory(noteId, dataKey, protect, sourceId) {
 | 
					async function protectNoteRevisions(noteId, dataKey, protect, sourceId) {
 | 
				
			||||||
    const historyToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
 | 
					    const revisionsToChange = await sql.getRows("SELECT * FROM note_revisions WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const history of historyToChange) {
 | 
					    for (const revision of revisionsToChange) {
 | 
				
			||||||
        if (protect) {
 | 
					        if (protect) {
 | 
				
			||||||
            protected_session.encryptNoteHistoryRow(dataKey, history);
 | 
					            protected_session.encryptNoteRevision(dataKey, revision);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            history.isProtected = true;
 | 
					            revision.isProtected = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            protected_session.decryptNoteHistoryRow(dataKey, history);
 | 
					            protected_session.decryptNoteRevision(dataKey, revision);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            history.isProtected = false;
 | 
					            revision.isProtected = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await sql.execute("UPDATE note_revisions SET title = ?, content = ?, isProtected = ? WHERE noteRevisionId = ?",
 | 
					        await sql.execute("UPDATE note_revisions SET title = ?, content = ?, isProtected = ? WHERE noteRevisionId = ?",
 | 
				
			||||||
            [history.title, history.content, history.isProtected, history.noteRevisionId]);
 | 
					            [revision.title, revision.content, revision.isProtected, revision.noteRevisionId]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await sync_table.addNoteHistorySync(history.noteRevisionId, sourceId);
 | 
					        await sync_table.addNoteRevisionSync(revision.noteRevisionId, sourceId);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
 | 
					async function saveNoteRevision(noteId, dataKey, sourceId, nowStr) {
 | 
				
			||||||
    const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
 | 
					    const oldNote = await sql.getRow("SELECT * FROM notes WHERE noteId = ?", [noteId]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (oldNote.type === 'file') {
 | 
					    if (oldNote.type === 'file') {
 | 
				
			||||||
@ -200,12 +200,12 @@ async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
 | 
				
			|||||||
        // title and text should be decrypted now
 | 
					        // title and text should be decrypted now
 | 
				
			||||||
        title: oldNote.title,
 | 
					        title: oldNote.title,
 | 
				
			||||||
        content: oldNote.content,
 | 
					        content: oldNote.content,
 | 
				
			||||||
        isProtected: 0, // will be fixed in the protectNoteHistory() call
 | 
					        isProtected: 0, // will be fixed in the protectNoteRevisions() call
 | 
				
			||||||
        dateModifiedFrom: oldNote.dateModified,
 | 
					        dateModifiedFrom: oldNote.dateModified,
 | 
				
			||||||
        dateModifiedTo: nowStr
 | 
					        dateModifiedTo: nowStr
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await sync_table.addNoteHistorySync(newNoteRevisionId, sourceId);
 | 
					    await sync_table.addNoteRevisionSync(newNoteRevisionId, sourceId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function saveNoteImages(noteId, noteText, sourceId) {
 | 
					async function saveNoteImages(noteId, noteText, sourceId) {
 | 
				
			||||||
@ -279,26 +279,26 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
 | 
				
			|||||||
    const now = new Date();
 | 
					    const now = new Date();
 | 
				
			||||||
    const nowStr = utils.nowDate();
 | 
					    const nowStr = utils.nowDate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const historySnapshotTimeInterval = parseInt(await options.getOption('history_snapshot_time_interval'));
 | 
					    const noteRevisionSnapshotTimeInterval = parseInt(await options.getOption('note_revision_snapshot_time_interval'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000));
 | 
					    const revisionCutoff = utils.dateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const existingnoteRevisionId = await sql.getValue(
 | 
					    const existingnoteRevisionId = await sql.getValue(
 | 
				
			||||||
        "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, historyCutoff]);
 | 
					        "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, revisionCutoff]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await sql.doInTransaction(async () => {
 | 
					    await sql.doInTransaction(async () => {
 | 
				
			||||||
        const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.detail.dateCreated).getTime();
 | 
					        const msSinceDateCreated = now.getTime() - utils.parseDateTime(newNote.detail.dateCreated).getTime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (labelsMap.disable_versioning !== 'true'
 | 
					        if (labelsMap.disable_versioning !== 'true'
 | 
				
			||||||
            && !existingnoteRevisionId
 | 
					            && !existingnoteRevisionId
 | 
				
			||||||
            && msSinceDateCreated >= historySnapshotTimeInterval * 1000) {
 | 
					            && msSinceDateCreated >= noteRevisionSnapshotTimeInterval * 1000) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await saveNoteHistory(noteId, dataKey, sourceId, nowStr);
 | 
					            await saveNoteRevision(noteId, dataKey, sourceId, nowStr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await saveNoteImages(noteId, newNote.detail.content, sourceId);
 | 
					        await saveNoteImages(noteId, newNote.detail.content, sourceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await protectNoteHistory(noteId, dataKey, newNote.detail.isProtected);
 | 
					        await protectNoteRevisions(noteId, dataKey, newNote.detail.isProtected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
 | 
					        await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
 | 
				
			||||||
            newNote.detail.title,
 | 
					            newNote.detail.title,
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ async function initOptions(startNotePath) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    await createOption('start_note_path', startNotePath, false);
 | 
					    await createOption('start_note_path', startNotePath, false);
 | 
				
			||||||
    await createOption('protected_session_timeout', 600, true);
 | 
					    await createOption('protected_session_timeout', 600, true);
 | 
				
			||||||
    await createOption('history_snapshot_time_interval', 600, true);
 | 
					    await createOption('note_revision_snapshot_time_interval', 600, true);
 | 
				
			||||||
    await createOption('last_backup_date', utils.nowDate(), false);
 | 
					    await createOption('last_backup_date', utils.nowDate(), false);
 | 
				
			||||||
    await createOption('db_version', app_info.db_version, false);
 | 
					    await createOption('db_version', app_info.db_version, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -75,7 +75,7 @@ function decryptNotes(dataKey, notes) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function decryptNoteHistoryRow(dataKey, hist) {
 | 
					function decryptNoteRevision(dataKey, hist) {
 | 
				
			||||||
    dataKey = getDataKey(dataKey);
 | 
					    dataKey = getDataKey(dataKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!hist.isProtected) {
 | 
					    if (!hist.isProtected) {
 | 
				
			||||||
@ -91,11 +91,11 @@ function decryptNoteHistoryRow(dataKey, hist) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function decryptNoteHistoryRows(dataKey, historyRows) {
 | 
					function decryptNoteRevisions(dataKey, noteRevisions) {
 | 
				
			||||||
    dataKey = getDataKey(dataKey);
 | 
					    dataKey = getDataKey(dataKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const hist of historyRows) {
 | 
					    for (const revision of noteRevisions) {
 | 
				
			||||||
        decryptNoteHistoryRow(dataKey, hist);
 | 
					        decryptNoteRevision(dataKey, revision);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -106,11 +106,11 @@ function encryptNote(dataKey, note) {
 | 
				
			|||||||
    note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content);
 | 
					    note.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(note.noteId), note.content);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function encryptNoteHistoryRow(dataKey, history) {
 | 
					function encryptNoteRevision(dataKey, revision) {
 | 
				
			||||||
    dataKey = getDataKey(dataKey);
 | 
					    dataKey = getDataKey(dataKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    history.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.noteRevisionId), history.title);
 | 
					    revision.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(revision.noteRevisionId), revision.title);
 | 
				
			||||||
    history.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(history.noteRevisionId), history.content);
 | 
					    revision.content = data_encryption.encrypt(dataKey, data_encryption.noteContentIv(revision.noteRevisionId), revision.content);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
@ -120,8 +120,8 @@ module.exports = {
 | 
				
			|||||||
    isProtectedSessionAvailable,
 | 
					    isProtectedSessionAvailable,
 | 
				
			||||||
    decryptNote,
 | 
					    decryptNote,
 | 
				
			||||||
    decryptNotes,
 | 
					    decryptNotes,
 | 
				
			||||||
    decryptNoteHistoryRow,
 | 
					    decryptNoteRevision,
 | 
				
			||||||
    decryptNoteHistoryRows,
 | 
					    decryptNoteRevisions,
 | 
				
			||||||
    encryptNote,
 | 
					    encryptNote,
 | 
				
			||||||
    encryptNoteHistoryRow
 | 
					    encryptNoteRevision
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -129,7 +129,7 @@ async function pullSync(syncContext) {
 | 
				
			|||||||
            await syncUpdate.updateBranch(resp, syncContext.sourceId);
 | 
					            await syncUpdate.updateBranch(resp, syncContext.sourceId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (sync.entityName === 'note_revisions') {
 | 
					        else if (sync.entityName === 'note_revisions') {
 | 
				
			||||||
            await syncUpdate.updateNoteHistory(resp, syncContext.sourceId);
 | 
					            await syncUpdate.updateNoteRevision(resp, syncContext.sourceId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (sync.entityName === 'note_reordering') {
 | 
					        else if (sync.entityName === 'note_reordering') {
 | 
				
			||||||
            await syncUpdate.updateNoteReordering(resp, syncContext.sourceId);
 | 
					            await syncUpdate.updateNoteReordering(resp, syncContext.sourceId);
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ async function addNoteReorderingSync(parentNoteId, sourceId) {
 | 
				
			|||||||
    await addEntitySync("note_reordering", parentNoteId, sourceId)
 | 
					    await addEntitySync("note_reordering", parentNoteId, sourceId)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function addNoteHistorySync(noteRevisionId, sourceId) {
 | 
					async function addNoteRevisionSync(noteRevisionId, sourceId) {
 | 
				
			||||||
    await addEntitySync("note_revisions", noteRevisionId, sourceId);
 | 
					    await addEntitySync("note_revisions", noteRevisionId, sourceId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -104,7 +104,7 @@ module.exports = {
 | 
				
			|||||||
    addNoteSync,
 | 
					    addNoteSync,
 | 
				
			||||||
    addBranchSync,
 | 
					    addBranchSync,
 | 
				
			||||||
    addNoteReorderingSync,
 | 
					    addNoteReorderingSync,
 | 
				
			||||||
    addNoteHistorySync,
 | 
					    addNoteRevisionSync,
 | 
				
			||||||
    addOptionsSync,
 | 
					    addOptionsSync,
 | 
				
			||||||
    addRecentNoteSync,
 | 
					    addRecentNoteSync,
 | 
				
			||||||
    addImageSync,
 | 
					    addImageSync,
 | 
				
			||||||
 | 
				
			|||||||
@ -42,18 +42,18 @@ async function updateBranch(entity, sourceId) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function updateNoteHistory(entity, sourceId) {
 | 
					async function updateNoteRevision(entity, sourceId) {
 | 
				
			||||||
    const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]);
 | 
					    const orig = await sql.getRowOrNull("SELECT * FROM note_revisions WHERE noteRevisionId = ?", [entity.noteRevisionId]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await sql.doInTransaction(async () => {
 | 
					    await sql.doInTransaction(async () => {
 | 
				
			||||||
        // we update note history even if date modified to is the same because the only thing which might have changed
 | 
					        // we update note revision even if date modified to is the same because the only thing which might have changed
 | 
				
			||||||
        // is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
 | 
					        // is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
 | 
				
			||||||
        if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
 | 
					        if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
 | 
				
			||||||
            await sql.replace('note_revisions', entity);
 | 
					            await sql.replace('note_revisions', entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await sync_table.addNoteHistorySync(entity.noteRevisionId, sourceId);
 | 
					            await sync_table.addNoteRevisionSync(entity.noteRevisionId, sourceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            log.info("Update/sync note history " + entity.noteRevisionId);
 | 
					            log.info("Update/sync note revision " + entity.noteRevisionId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -161,7 +161,7 @@ async function updateApiToken(entity, sourceId) {
 | 
				
			|||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    updateNote,
 | 
					    updateNote,
 | 
				
			||||||
    updateBranch,
 | 
					    updateBranch,
 | 
				
			||||||
    updateNoteHistory,
 | 
					    updateNoteRevision,
 | 
				
			||||||
    updateNoteReordering,
 | 
					    updateNoteReordering,
 | 
				
			||||||
    updateOptions,
 | 
					    updateOptions,
 | 
				
			||||||
    updateRecentNotes,
 | 
					    updateRecentNotes,
 | 
				
			||||||
 | 
				
			|||||||
@ -123,7 +123,7 @@
 | 
				
			|||||||
              <span class="caret"></span>
 | 
					              <span class="caret"></span>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
            <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dLabel">
 | 
					            <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dLabel">
 | 
				
			||||||
              <li><a id="show-history-button"><kbd>Alt+H</kbd> History</a></li>
 | 
					              <li><a id="show-note-revisions-button">Note revisions</a></li>
 | 
				
			||||||
              <li><a class="show-labels-button"><kbd>Alt+L</kbd> Labels</a></li>
 | 
					              <li><a class="show-labels-button"><kbd>Alt+L</kbd> Labels</a></li>
 | 
				
			||||||
              <li><a id="show-source-button"><kbd>Ctrl+U</kbd> HTML source</a></li>
 | 
					              <li><a id="show-source-button"><kbd>Ctrl+U</kbd> HTML source</a></li>
 | 
				
			||||||
              <li><a id="upload-attachment-button">Upload attachment</a></li>
 | 
					              <li><a id="upload-attachment-button">Upload attachment</a></li>
 | 
				
			||||||
@ -277,7 +277,7 @@
 | 
				
			|||||||
        <ul>
 | 
					        <ul>
 | 
				
			||||||
          <li><a href="#change-password">Change password</a></li>
 | 
					          <li><a href="#change-password">Change password</a></li>
 | 
				
			||||||
          <li><a href="#protected-session-timeout">Protected session</a></li>
 | 
					          <li><a href="#protected-session-timeout">Protected session</a></li>
 | 
				
			||||||
          <li><a href="#history-snapshot-time-interval">History snapshots</a></li>
 | 
					          <li><a href="#note-revision-snapshot-time-interval">Note revisions</a></li>
 | 
				
			||||||
          <li><a href="#advanced">Advanced</a></li>
 | 
					          <li><a href="#advanced">Advanced</a></li>
 | 
				
			||||||
          <li><a href="#about">About Trilium</a></li>
 | 
					          <li><a href="#about">About Trilium</a></li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
@ -314,13 +314,13 @@
 | 
				
			|||||||
            <button class="btn btn-sm">Save</button>
 | 
					            <button class="btn btn-sm">Save</button>
 | 
				
			||||||
          </form>
 | 
					          </form>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div id="history-snapshot-time-interval">
 | 
					        <div id="note-revision-snapshot-time-interval">
 | 
				
			||||||
          <p>History snapshot time interval is time in seconds after which new history record will be created for the note.</p>
 | 
					          <p>Note revision snapshot time interval is time in seconds after which new note revision will be created for the note.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <form id="history-snapshot-time-interval-form">
 | 
					          <form id="note-revision-snapshot-time-interval-form">
 | 
				
			||||||
            <div class="form-group">
 | 
					            <div class="form-group">
 | 
				
			||||||
              <label for="history-snapshot-time-interval-in-seconds">History snapshot time interval (in seconds)</label>
 | 
					              <label for="note-revision-snapshot-time-interval-in-seconds">Note revision snapshot time interval (in seconds)</label>
 | 
				
			||||||
              <input class="form-control" id="history-snapshot-time-interval-in-seconds" type="number">
 | 
					              <input class="form-control" id="note-revision-snapshot-time-interval-in-seconds" type="number">
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <button class="btn btn-sm">Save</button>
 | 
					            <button class="btn btn-sm">Save</button>
 | 
				
			||||||
@ -346,7 +346,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          <p>This will remove all image data of images not used in any current version of note from the database (metadata will remain).
 | 
					          <p>This will remove all image data of images not used in any current version of note from the database (metadata will remain).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            This means that some images can disappear from note history.</p>
 | 
					            This means that some images can disappear from note revisions.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <button id="cleanup-unused-images-button" class="btn btn-warning btn-sm">Permanently cleanup unused images</button>
 | 
					          <button id="cleanup-unused-images-button" class="btn btn-warning btn-sm">Permanently cleanup unused images</button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -389,15 +389,15 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div id="note-history-dialog" title="Note history" style="display: none;">
 | 
					    <div id="note-revisions-dialog" title="Note revisions" style="display: none;">
 | 
				
			||||||
      <div style="display: flex;">
 | 
					      <div style="display: flex;">
 | 
				
			||||||
        <select id="note-history-list" size="25" style="width: 150px; height: 630px;">
 | 
					        <select id="note-revision-list" size="25" style="width: 150px; height: 630px;">
 | 
				
			||||||
        </select>
 | 
					        </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div id="note-history-content-wrapper" style="flex-grow: 1; margin-left: 20px;">
 | 
					        <div id="note-revision-content-wrapper" style="flex-grow: 1; margin-left: 20px;">
 | 
				
			||||||
          <h3 id="note-history-title" style="margin: 3px;"></h3>
 | 
					          <h3 id="note-revision-title" style="margin: 3px;"></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div id="note-history-content" style="height: 600px; width: 600px; overflow: auto;"></div>
 | 
					          <div id="note-revision-content" style="height: 600px; width: 600px; overflow: auto;"></div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -67,8 +67,6 @@
 | 
				
			|||||||
    <link href="libraries/bootstrap/css/bootstrap.css" rel="stylesheet">
 | 
					    <link href="libraries/bootstrap/css/bootstrap.css" rel="stylesheet">
 | 
				
			||||||
    <script src="libraries/bootstrap/js/bootstrap.js"></script>
 | 
					    <script src="libraries/bootstrap/js/bootstrap.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <script src="javascripts/migration.js"></script>
 | 
					    <script src="javascripts/migration.js" type="module"></script>
 | 
				
			||||||
    <script src="javascripts/utils.js"></script>
 | 
					 | 
				
			||||||
    <script src="javascripts/server.js"></script>
 | 
					 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user