diff --git a/libraries/codemirror/addon/lint/eslint.js b/libraries/codemirror/addon/lint/eslint.js index ce04f0bc4..321ddd3ba 100644 --- a/libraries/codemirror/addon/lint/eslint.js +++ b/libraries/codemirror/addon/lint/eslint.js @@ -28,7 +28,9 @@ } async function validatorJavaScript(text, options) { - if (glob.getActiveNote() == null || glob.getActiveNote().mime === 'application/json') { + if (glob.isMobile() + || glob.getActiveNote() == null + || glob.getActiveNote().mime === 'application/json') { // eslint doesn't seem to validate pure JSON well return []; } diff --git a/src/public/javascripts/desktop.js b/src/public/javascripts/desktop.js index bfc694839..43d41ea72 100644 --- a/src/public/javascripts/desktop.js +++ b/src/public/javascripts/desktop.js @@ -42,6 +42,9 @@ import macInit from './services/mac_init.js'; import cssLoader from './services/css_loader.js'; import dateNoteService from './services/date_notes.js'; +window.glob.isDesktop = utils.isDesktop; +window.glob.isMobile = utils.isMobile; + // required for CKEditor image upload plugin window.glob.getActiveNode = treeService.getActiveNode; window.glob.getHeaders = server.getHeaders; diff --git a/src/public/javascripts/mobile.js b/src/public/javascripts/mobile.js index d6b2ba226..7ff4ad57a 100644 --- a/src/public/javascripts/mobile.js +++ b/src/public/javascripts/mobile.js @@ -8,6 +8,9 @@ import treeChangesService from "./services/branches.js"; import utils from "./services/utils.js"; import treeUtils from "./services/tree_utils.js"; +window.glob.isDesktop = utils.isDesktop; +window.glob.isMobile = utils.isMobile; + const $leftPane = $("#left-pane"); const $tree = $("#tree"); const $detail = $("#detail"); @@ -42,6 +45,13 @@ async function showTree() { source: tree, scrollParent: $tree, minExpandLevel: 2, // root can't be collapsed + click: (event, data) => { + if (data.targetType !== 'expander' && data.node.isActive()) { + $tree.fancytree('getTree').reactivate(true); + + return false; + } + }, activate: async (event, data) => { const node = data.node; @@ -97,10 +107,10 @@ $detail.on("click", ".note-menu-button", async e => { treeService.createNote(node, node.data.noteId, 'into'); } else if (cmd === "delete") { - treeChangesService.deleteNodes([node]); - - // move to the tree - togglePanes(); + if (await treeChangesService.deleteNodes([node])) { + // move to the tree + togglePanes(); + } } else { throw new Error("Unrecognized command " + cmd); diff --git a/src/public/javascripts/services/branches.js b/src/public/javascripts/services/branches.js index a761f5b3a..36bf50778 100644 --- a/src/public/javascripts/services/branches.js +++ b/src/public/javascripts/services/branches.js @@ -82,7 +82,7 @@ async function deleteNodes(nodes) { nodes = await filterRootNote(nodes); if (nodes.length === 0 || !confirm('Are you sure you want to delete select note(s) and all the sub-notes?')) { - return; + return false; } for (const node of nodes) { @@ -123,6 +123,8 @@ async function deleteNodes(nodes) { } infoService.showMessage("Note(s) has been deleted."); + + return true; } async function moveNodeUpInHierarchy(node) { diff --git a/src/public/javascripts/services/note_autocomplete.js b/src/public/javascripts/services/note_autocomplete.js index 4da90e381..7dced1bf4 100644 --- a/src/public/javascripts/services/note_autocomplete.js +++ b/src/public/javascripts/services/note_autocomplete.js @@ -1,6 +1,6 @@ import server from "./server.js"; import noteDetailService from "./note_detail.js"; -import treeService from './tree.js'; +import utils from './utils.js'; // this key needs to have this value so it's hit by the tooltip const SELECTED_PATH_KEY = "data-note-path"; @@ -21,84 +21,94 @@ async function autocompleteSource(term, cb) { } function clearText($el) { + if (utils.isMobile()) { + return; + } + $el.setSelectedPath(""); $el.autocomplete("val", "").change(); } function showRecentNotes($el) { + if (utils.isMobile()) { + return; + } + $el.setSelectedPath(""); $el.autocomplete("val", ""); $el.focus(); } function initNoteAutocomplete($el, options) { - if (!$el.hasClass("note-autocomplete-input")) { - options = options || {}; - - $el.addClass("note-autocomplete-input"); - - const $clearTextButton = $("") - .addClass("input-group-text input-clearer-button jam jam-close") - .prop("title", "Clear text field"); - - const $showRecentNotesButton = $("") - .addClass("input-group-text show-recent-notes-button jam jam-clock") - .prop("title", "Show recent notes"); - - const $goToSelectedNoteButton = $("") - .addClass("input-group-text go-to-selected-note-button jam jam-arrow-right") - .attr("data-action", "note"); - - const $sideButtons = $("
") - .addClass("input-group-append") - .append($clearTextButton) - .append($showRecentNotesButton); - - if (!options.hideGoToSelectedNoteButton) { - $sideButtons.append($goToSelectedNoteButton); - } - - $el.after($sideButtons); - - $clearTextButton.click(() => clearText($el)); - - $showRecentNotesButton.click(e => { - showRecentNotes($el); - - // this will cause the click not give focus to the "show recent notes" button - // this is important because otherwise input will lose focus immediatelly and not show the results - return false; - }); - - $el.autocomplete({ - appendTo: document.querySelector('body'), - hint: false, - autoselect: true, - openOnFocus: true, - minLength: 0, - tabAutocomplete: false - }, [ - { - source: autocompleteSource, - displayKey: 'title', - templates: { - suggestion: function(suggestion) { - return suggestion.highlighted; - } - }, - // we can't cache identical searches because notes can be created / renamed, new recent notes can be added - cache: false - } - ]); - - $el.on('autocomplete:selected', (event, suggestion) => $el.setSelectedPath(suggestion.path)); - $el.on('autocomplete:closed', () => { - if (!$el.val().trim()) { - clearText($el); - } - }); + if ($el.hasClass("note-autocomplete-input") || utils.isMobile()) { + return $el; } + options = options || {}; + + $el.addClass("note-autocomplete-input"); + + const $clearTextButton = $("") + .addClass("input-group-text input-clearer-button jam jam-close") + .prop("title", "Clear text field"); + + const $showRecentNotesButton = $("") + .addClass("input-group-text show-recent-notes-button jam jam-clock") + .prop("title", "Show recent notes"); + + const $goToSelectedNoteButton = $("") + .addClass("input-group-text go-to-selected-note-button jam jam-arrow-right") + .attr("data-action", "note"); + + const $sideButtons = $("
") + .addClass("input-group-append") + .append($clearTextButton) + .append($showRecentNotesButton); + + if (!options.hideGoToSelectedNoteButton) { + $sideButtons.append($goToSelectedNoteButton); + } + + $el.after($sideButtons); + + $clearTextButton.click(() => clearText($el)); + + $showRecentNotesButton.click(e => { + showRecentNotes($el); + + // this will cause the click not give focus to the "show recent notes" button + // this is important because otherwise input will lose focus immediatelly and not show the results + return false; + }); + + $el.autocomplete({ + appendTo: document.querySelector('body'), + hint: false, + autoselect: true, + openOnFocus: true, + minLength: 0, + tabAutocomplete: false + }, [ + { + source: autocompleteSource, + displayKey: 'title', + templates: { + suggestion: function(suggestion) { + return suggestion.highlighted; + } + }, + // we can't cache identical searches because notes can be created / renamed, new recent notes can be added + cache: false + } + ]); + + $el.on('autocomplete:selected', (event, suggestion) => $el.setSelectedPath(suggestion.path)); + $el.on('autocomplete:closed', () => { + if (!$el.val().trim()) { + clearText($el); + } + }); + return $el; } diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index 4a8f45b65..2221dfec9 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -75,7 +75,10 @@ class TabContext { treeService.setNoteTitle(this.noteId, title); }); - this.$noteTitle.bind('keydown', 'return', () => this.getComponent().focus()); + if (utils.isDesktop()) { + // keyboard plugin is not loaded in mobile + this.$noteTitle.bind('keydown', 'return', () => this.getComponent().focus()); + } this.$protectButton = this.$tabContent.find(".protect-button"); this.$protectButton.click(protectedSessionService.protectNoteAndSendToServer); diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index 417e1d88f..58efee20b 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -649,9 +649,8 @@ async function createNote(node, parentNoteId, target, extraOptions = {}) { if (!node.getChildren() && node.isFolder()) { await node.setExpanded(); } - else { - node.addChildren(newNode); - } + + node.addChildren(newNode); await node.getLastChild().setActive(true);