moved all sources to src directory

This commit is contained in:
azivner
2018-01-28 22:18:14 -05:00
parent 669d189ab7
commit 52ad7f64b4
468 changed files with 18 additions and 17 deletions

View File

@@ -0,0 +1,137 @@
"use strict";
const addLink = (function() {
const dialogEl = $("#add-link-dialog");
const formEl = $("#add-link-form");
const autoCompleteEl = $("#note-autocomplete");
const linkTitleEl = $("#link-title");
const clonePrefixEl = $("#clone-prefix");
const linkTitleFormGroup = $("#add-link-title-form-group");
const prefixFormGroup = $("#add-link-prefix-form-group");
const linkTypeEls = $("input[name='add-link-type']");
const linkTypeHtmlEl = linkTypeEls.filter('input[value="html"]');
function setLinkType(linkType) {
linkTypeEls.each(function () {
$(this).prop('checked', $(this).val() === linkType);
});
linkTypeChanged();
}
function showDialog() {
glob.activeDialog = dialogEl;
if (noteEditor.getCurrentNoteType() === 'text') {
linkTypeHtmlEl.prop('disabled', false);
setLinkType('html');
}
else {
linkTypeHtmlEl.prop('disabled', true);
setLinkType('selected-to-current');
}
dialogEl.dialog({
modal: true,
width: 700
});
autoCompleteEl.val('').focus();
clonePrefixEl.val('');
linkTitleEl.val('');
function setDefaultLinkTitle(noteId) {
const noteTitle = noteTree.getNoteTitle(noteId);
linkTitleEl.val(noteTitle);
}
autoCompleteEl.autocomplete({
source: noteTree.getAutocompleteItems(),
minLength: 0,
change: () => {
const val = autoCompleteEl.val();
const notePath = link.getNodePathFromLabel(val);
if (!notePath) {
return;
}
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
if (noteId) {
setDefaultLinkTitle(noteId);
}
},
// this is called when user goes through autocomplete list with keyboard
// at this point the item isn't selected yet so we use supplied ui.item to see WHERE the cursor is
focus: (event, ui) => {
const notePath = link.getNodePathFromLabel(ui.item.value);
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
setDefaultLinkTitle(noteId);
}
});
}
formEl.submit(() => {
const value = autoCompleteEl.val();
const notePath = link.getNodePathFromLabel(value);
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
if (notePath) {
const linkType = $("input[name='add-link-type']:checked").val();
if (linkType === 'html') {
const linkTitle = linkTitleEl.val();
dialogEl.dialog("close");
link.addLinkToEditor(linkTitle, '#' + notePath);
}
else if (linkType === 'selected-to-current') {
const prefix = clonePrefixEl.val();
cloning.cloneNoteTo(noteId, noteEditor.getCurrentNoteId(), prefix);
dialogEl.dialog("close");
}
else if (linkType === 'current-to-selected') {
const prefix = clonePrefixEl.val();
cloning.cloneNoteTo(noteEditor.getCurrentNoteId(), noteId, prefix);
dialogEl.dialog("close");
}
}
return false;
});
function linkTypeChanged() {
const value = linkTypeEls.filter(":checked").val();
if (value === 'html') {
linkTitleFormGroup.show();
prefixFormGroup.hide();
}
else {
linkTitleFormGroup.hide();
prefixFormGroup.show();
}
}
linkTypeEls.change(linkTypeChanged);
$(document).bind('keydown', 'ctrl+l', e => {
showDialog();
e.preventDefault();
});
return {
showDialog
};
})();

View File

@@ -0,0 +1,62 @@
"use strict";
const attributesDialog = (function() {
const dialogEl = $("#attributes-dialog");
const attributesModel = new AttributesModel();
function AttributesModel() {
const self = this;
this.attributes = ko.observableArray();
this.loadAttributes = async function() {
const noteId = noteEditor.getCurrentNoteId();
const attributes = await server.get('notes/' + noteId + '/attributes');
this.attributes(attributes);
};
this.addNewRow = function() {
self.attributes.push({
attributeId: '',
name: '',
value: ''
});
};
this.save = async function() {
const noteId = noteEditor.getCurrentNoteId();
const attributes = await server.put('notes/' + noteId + '/attributes', this.attributes());
self.attributes(attributes);
showMessage("Attributes have been saved.");
};
}
async function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800,
height: 700
});
attributesModel.loadAttributes();
}
$(document).bind('keydown', 'alt+a', e => {
showDialog();
e.preventDefault();
});
ko.applyBindings(attributesModel, document.getElementById('attributes-dialog'));
return {
showDialog
};
})();

View File

@@ -0,0 +1,45 @@
"use strict";
const editTreePrefix = (function() {
const dialogEl = $("#edit-tree-prefix-dialog");
const formEl = $("#edit-tree-prefix-form");
const treePrefixInputEl = $("#tree-prefix-input");
const noteTitleEl = $('#tree-prefix-note-title');
let noteTreeId;
async function showDialog() {
glob.activeDialog = dialogEl;
await dialogEl.dialog({
modal: true,
width: 500
});
const currentNode = noteTree.getCurrentNode();
noteTreeId = currentNode.data.noteTreeId;
treePrefixInputEl.val(currentNode.data.prefix).focus();
const noteTitle = noteTree.getNoteTitle(currentNode.data.noteId);
noteTitleEl.html(noteTitle);
}
formEl.submit(() => {
const prefix = treePrefixInputEl.val();
server.put('tree/' + noteTreeId + '/set-prefix', {
prefix: prefix
}).then(() => noteTree.setPrefix(noteTreeId, prefix));
dialogEl.dialog("close");
return false;
});
return {
showDialog
};
})();

View File

@@ -0,0 +1,38 @@
"use strict";
const eventLog = (function() {
const dialogEl = $("#event-log-dialog");
const listEl = $("#event-log-list");
async function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800,
height: 700
});
const result = await server.get('event-log');
listEl.html('');
for (const event of result) {
const dateTime = formatDateTime(parseDate(event.dateAdded));
if (event.noteId) {
const noteLink = link.createNoteLink(event.noteId).prop('outerHTML');
event.comment = event.comment.replace('<note>', noteLink);
}
const eventEl = $('<li>').html(dateTime + " - " + event.comment);
listEl.append(eventEl);
}
}
return {
showDialog
};
})();

View File

@@ -0,0 +1,56 @@
"use strict";
const jumpToNote = (function() {
const dialogEl = $("#jump-to-note-dialog");
const autoCompleteEl = $("#jump-to-note-autocomplete");
const formEl = $("#jump-to-note-form");
async function showDialog() {
glob.activeDialog = dialogEl;
autoCompleteEl.val('');
dialogEl.dialog({
modal: true,
width: 800
});
await autoCompleteEl.autocomplete({
source: await stopWatch("building autocomplete", noteTree.getAutocompleteItems),
minLength: 0
});
}
function getSelectedNotePath() {
const val = autoCompleteEl.val();
return link.getNodePathFromLabel(val);
}
function goToNote() {
const notePath = getSelectedNotePath();
if (notePath) {
noteTree.activateNode(notePath);
dialogEl.dialog('close');
}
}
$(document).bind('keydown', 'ctrl+j', e => {
showDialog();
e.preventDefault();
});
formEl.submit(() => {
const action = dialogEl.find("button:focus").val();
goToNote();
return false;
});
return {
showDialog
};
})();

View File

@@ -0,0 +1,78 @@
"use strict";
const noteHistory = (function() {
const dialogEl = $("#note-history-dialog");
const listEl = $("#note-history-list");
const contentEl = $("#note-history-content");
const titleEl = $("#note-history-title");
let historyItems = [];
async function showCurrentNoteHistory() {
await showNoteHistoryDialog(noteEditor.getCurrentNoteId());
}
async function showNoteHistoryDialog(noteId, noteRevisionId) {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800,
height: 700
});
listEl.empty();
contentEl.empty();
historyItems = await server.get('notes-history/' + noteId);
for (const item of historyItems) {
const dateModified = parseDate(item.dateModifiedFrom);
listEl.append($('<option>', {
value: item.noteRevisionId,
text: formatDateTime(dateModified)
}));
}
if (historyItems.length > 0) {
if (!noteRevisionId) {
noteRevisionId = listEl.find("option:first").val();
}
listEl.val(noteRevisionId).trigger('change');
}
else {
titleEl.text("No history for this note yet...");
}
}
$(document).bind('keydown', 'alt+h', e => {
showCurrentNoteHistory();
e.preventDefault();
});
listEl.on('change', () => {
const optVal = listEl.find(":selected").val();
const historyItem = historyItems.find(r => r.noteRevisionId === optVal);
titleEl.html(historyItem.title);
contentEl.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;
});
return {
showCurrentNoteHistory
};
})();

View File

@@ -0,0 +1,57 @@
"use strict";
const noteSource = (function() {
const dialogEl = $("#note-source-dialog");
const noteSourceEl = $("#note-source");
function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800,
height: 500
});
const noteText = noteEditor.getCurrentNote().detail.content;
noteSourceEl.text(formatHtml(noteText));
}
function formatHtml(str) {
const div = document.createElement('div');
div.innerHTML = str.trim();
return formatNode(div, 0).innerHTML.trim();
}
function formatNode(node, level) {
const indentBefore = new Array(level++ + 1).join(' ');
const indentAfter = new Array(level - 1).join(' ');
let textNode;
for (let i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
formatNode(node.children[i], level);
if (node.lastElementChild === node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}
return node;
}
$(document).bind('keydown', 'ctrl+u', e => {
showDialog();
e.preventDefault();
});
return {
showDialog
};
})();

View File

@@ -0,0 +1,89 @@
"use strict";
const recentChanges = (function() {
const dialogEl = $("#recent-changes-dialog");
async function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800,
height: 700
});
const result = await server.get('recent-changes/');
dialogEl.html('');
const groupedByDate = groupByDate(result);
for (const [dateDay, dayChanges] of groupedByDate) {
const changesListEl = $('<ul>');
const dayEl = $('<div>').append($('<b>').html(formatDate(dateDay))).append(changesListEl);
for (const change of dayChanges) {
const formattedTime = formatTime(parseDate(change.dateModifiedTo));
const revLink = $("<a>", {
href: 'javascript:',
text: 'rev'
}).attr('action', 'note-history')
.attr('note-path', change.noteId)
.attr('note-history-id', change.noteRevisionId);
let noteLink;
if (change.current_isDeleted) {
noteLink = change.current_title;
}
else {
noteLink = link.createNoteLink(change.noteId, change.title);
}
changesListEl.append($('<li>')
.append(formattedTime + ' - ')
.append(noteLink)
.append(' (').append(revLink).append(')'));
}
dialogEl.append(dayEl);
}
}
function groupByDate(result) {
const groupedByDate = new Map();
const dayCache = {};
for (const row of result) {
let dateDay = parseDate(row.dateModifiedTo);
dateDay.setHours(0);
dateDay.setMinutes(0);
dateDay.setSeconds(0);
dateDay.setMilliseconds(0);
// this stupidity is to make sure that we always use the same day object because Map uses only
// reference equality
if (dayCache[dateDay]) {
dateDay = dayCache[dateDay];
}
else {
dayCache[dateDay] = dateDay;
}
if (!groupedByDate.has(dateDay)) {
groupedByDate.set(dateDay, []);
}
groupedByDate.get(dateDay).push(row);
}
return groupedByDate;
}
$(document).bind('keydown', 'alt+r', showDialog);
return {
showDialog
};
})();

View File

@@ -0,0 +1,146 @@
"use strict";
const recentNotes = (function() {
const dialogEl = $("#recent-notes-dialog");
const selectBoxEl = $('#recent-notes-select-box');
const jumpToButtonEl = $('#recent-notes-jump-to');
const addLinkButtonEl = $('#recent-notes-add-link');
const addCurrentAsChildEl = $("#recent-notes-add-current-as-child");
const addRecentAsChildEl = $("#recent-notes-add-recent-as-child");
const noteDetailEl = $('#note-detail');
// list of recent note paths
let list = [];
async function reload() {
const result = await server.get('recent-notes');
list = result.map(r => r.notePath);
}
function addRecentNote(noteTreeId, notePath) {
setTimeout(async () => {
// we include the note into recent list only if the user stayed on the note at least 5 seconds
if (notePath && notePath === noteTree.getCurrentNotePath()) {
const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath));
list = result.map(r => r.notePath);
}
}, 1500);
}
function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: 800
});
selectBoxEl.find('option').remove();
// remove the current note
const recNotes = list.filter(note => note !== noteTree.getCurrentNotePath());
$.each(recNotes, (key, valueNotePath) => {
const noteTitle = noteTree.getNotePathTitle(valueNotePath);
const option = $("<option></option>")
.attr("value", valueNotePath)
.text(noteTitle);
// select the first one (most recent one) by default
if (key === 0) {
option.attr("selected", "selected");
}
selectBoxEl.append(option);
});
}
function getSelectedNotePath() {
return selectBoxEl.find("option:selected").val();
}
function getSelectedNoteId() {
const notePath = getSelectedNotePath();
return treeUtils.getNoteIdFromNotePath(notePath);
}
function setActiveNoteBasedOnRecentNotes() {
const notePath = getSelectedNotePath();
noteTree.activateNode(notePath);
dialogEl.dialog('close');
}
function addLinkBasedOnRecentNotes() {
const notePath = getSelectedNotePath();
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
const linkTitle = noteTree.getNoteTitle(noteId);
dialogEl.dialog("close");
link.addLinkToEditor(linkTitle, '#' + notePath);
}
async function addCurrentAsChild() {
await cloning.cloneNoteTo(noteEditor.getCurrentNoteId(), getSelectedNoteId());
dialogEl.dialog("close");
}
async function addRecentAsChild() {
await cloning.cloneNoteTo(getSelectedNoteId(), noteEditor.getCurrentNoteId());
dialogEl.dialog("close");
}
selectBoxEl.keydown(e => {
const key = e.which;
// to get keycodes use http://keycode.info/
if (key === 13)// the enter key code
{
setActiveNoteBasedOnRecentNotes();
}
else if (key === 76 /* l */) {
addLinkBasedOnRecentNotes();
}
else if (key === 67 /* c */) {
addCurrentAsChild();
}
else if (key === 82 /* r */) {
addRecentAsChild()
}
else {
return; // avoid prevent default
}
e.preventDefault();
});
reload();
$(document).bind('keydown', 'ctrl+e', e => {
showDialog();
e.preventDefault();
});
selectBoxEl.dblclick(e => {
setActiveNoteBasedOnRecentNotes();
});
jumpToButtonEl.click(setActiveNoteBasedOnRecentNotes);
addLinkButtonEl.click(addLinkBasedOnRecentNotes);
addCurrentAsChildEl.click(addCurrentAsChild);
addRecentAsChildEl.click(addRecentAsChild);
return {
showDialog,
addRecentNote,
reload
};
})();

View File

@@ -0,0 +1,205 @@
"use strict";
const settings = (function() {
const dialogEl = $("#settings-dialog");
const tabsEl = $("#settings-tabs");
const settingModules = [];
function addModule(module) {
settingModules.push(module);
}
async function showDialog() {
glob.activeDialog = dialogEl;
const settings = await server.get('settings');
dialogEl.dialog({
modal: true,
width: 900
});
tabsEl.tabs();
for (const module of settingModules) {
if (module.settingsLoaded) {
module.settingsLoaded(settings);
}
}
}
async function saveSettings(settingName, settingValue) {
await server.post('settings', {
name: settingName,
value: settingValue
});
showMessage("Settings change have been saved.");
}
return {
showDialog,
saveSettings,
addModule
};
})();
settings.addModule((function() {
const formEl = $("#change-password-form");
const oldPasswordEl = $("#old-password");
const newPassword1El = $("#new-password1");
const newPassword2El = $("#new-password2");
function settingsLoaded(settings) {
}
formEl.submit(() => {
const oldPassword = oldPasswordEl.val();
const newPassword1 = newPassword1El.val();
const newPassword2 = newPassword2El.val();
oldPasswordEl.val('');
newPassword1El.val('');
newPassword2El.val('');
if (newPassword1 !== newPassword2) {
alert("New passwords are not the same.");
return false;
}
server.post('password/change', {
'current_password': oldPassword,
'new_password': newPassword1
}).then(result => {
if (result.success) {
alert("Password has been changed. Trilium will be reloaded after you press OK.");
// password changed so current protected session is invalid and needs to be cleared
protected_session.resetProtectedSession();
}
else {
showError(result.message);
}
});
return false;
});
return {
settingsLoaded
};
})());
settings.addModule((function() {
const formEl = $("#protected-session-timeout-form");
const protectedSessionTimeoutEl = $("#protected-session-timeout-in-seconds");
const settingName = 'protected_session_timeout';
function settingsLoaded(settings) {
protectedSessionTimeoutEl.val(settings[settingName]);
}
formEl.submit(() => {
const protectedSessionTimeout = protectedSessionTimeoutEl.val();
settings.saveSettings(settingName, protectedSessionTimeout).then(() => {
protected_session.setProtectedSessionTimeout(protectedSessionTimeout);
});
return false;
});
return {
settingsLoaded
};
})());
settings.addModule((function () {
const formEl = $("#history-snapshot-time-interval-form");
const timeIntervalEl = $("#history-snapshot-time-interval-in-seconds");
const settingName = 'history_snapshot_time_interval';
function settingsLoaded(settings) {
timeIntervalEl.val(settings[settingName]);
}
formEl.submit(() => {
settings.saveSettings(settingName, timeIntervalEl.val());
return false;
});
return {
settingsLoaded
};
})());
settings.addModule((async function () {
const appVersionEl = $("#app-version");
const dbVersionEl = $("#db-version");
const buildDateEl = $("#build-date");
const buildRevisionEl = $("#build-revision");
const appInfo = await server.get('app-info');
appVersionEl.html(appInfo.app_version);
dbVersionEl.html(appInfo.db_version);
buildDateEl.html(appInfo.build_date);
buildRevisionEl.html(appInfo.build_revision);
buildRevisionEl.attr('href', 'https://github.com/zadam/trilium/commit/' + appInfo.build_revision);
return {};
})());
settings.addModule((async function () {
const forceFullSyncButton = $("#force-full-sync-button");
const fillSyncRowsButton = $("#fill-sync-rows-button");
const anonymizeButton = $("#anonymize-button");
const cleanupSoftDeletedButton = $("#cleanup-soft-deleted-items-button");
const cleanupUnusedImagesButton = $("#cleanup-unused-images-button");
const vacuumDatabaseButton = $("#vacuum-database-button");
forceFullSyncButton.click(async () => {
await server.post('sync/force-full-sync');
showMessage("Full sync triggered");
});
fillSyncRowsButton.click(async () => {
await server.post('sync/fill-sync-rows');
showMessage("Sync rows filled successfully");
});
anonymizeButton.click(async () => {
await server.post('anonymization/anonymize');
showMessage("Created anonymized database");
});
cleanupSoftDeletedButton.click(async () => {
if (confirm("Do you really want to clean up soft-deleted items?")) {
await server.post('cleanup/cleanup-soft-deleted-items');
showMessage("Soft deleted items have been cleaned up");
}
});
cleanupUnusedImagesButton.click(async () => {
if (confirm("Do you really want to clean up unused images?")) {
await server.post('cleanup/cleanup-unused-images');
showMessage("Unused images have been cleaned up");
}
});
vacuumDatabaseButton.click(async () => {
await server.post('cleanup/vacuum-database');
showMessage("Database has been vacuumed");
});
return {};
})());

View File

@@ -0,0 +1,71 @@
"use strict";
const sqlConsole = (function() {
const dialogEl = $("#sql-console-dialog");
const queryEl = $('#sql-console-query');
const executeButton = $('#sql-console-execute');
const resultHeadEl = $('#sql-console-results thead');
const resultBodyEl = $('#sql-console-results tbody');
function showDialog() {
glob.activeDialog = dialogEl;
dialogEl.dialog({
modal: true,
width: $(window).width(),
height: $(window).height()
});
}
async function execute() {
const sqlQuery = queryEl.val();
const result = await server.post("sql/execute", {
query: sqlQuery
});
if (!result.success) {
showError(result.error);
return;
}
else {
showMessage("Query was executed successfully.");
}
const rows = result.rows;
resultHeadEl.empty();
resultBodyEl.empty();
if (rows.length > 0) {
const result = rows[0];
const rowEl = $("<tr>");
for (const key in result) {
rowEl.append($("<th>").html(key));
}
resultHeadEl.append(rowEl);
}
for (const result of rows) {
const rowEl = $("<tr>");
for (const key in result) {
rowEl.append($("<td>").html(result[key]));
}
resultBodyEl.append(rowEl);
}
}
$(document).bind('keydown', 'alt+o', showDialog);
queryEl.bind('keydown', 'ctrl+return', execute);
executeButton.click(execute);
return {
showDialog
};
})();