mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
findwidget in read only notes WIP
This commit is contained in:
parent
37cb5f5e9a
commit
f250b72563
7
libraries/jquery.mark.es6.min.js
vendored
Normal file
7
libraries/jquery.mark.es6.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -16,7 +16,7 @@ async function convertMarkdownToHtml(text) {
|
||||
|
||||
const result = writer.render(parsed);
|
||||
|
||||
appContext.triggerCommand('executeInTextEditor', {
|
||||
appContext.triggerCommand('executeWithTextEditor', {
|
||||
callback: textEditor => {
|
||||
const viewFragment = textEditor.data.processor.toView(result);
|
||||
const modelFragment = textEditor.data.toModel(viewFragment);
|
||||
|
@ -61,10 +61,13 @@ const EXCALIDRAW = {
|
||||
"node_modules/react/umd/react.production.min.js",
|
||||
"node_modules/react-dom/umd/react-dom.production.min.js",
|
||||
"node_modules/@excalidraw/excalidraw/dist/excalidraw.production.min.js",
|
||||
],
|
||||
// css: [
|
||||
// "stylesheets/somestyle.css"
|
||||
// ]
|
||||
]
|
||||
};
|
||||
|
||||
const MARKJS = {
|
||||
js: [
|
||||
"libraries/jquery.mark.es6.min.js"
|
||||
]
|
||||
};
|
||||
|
||||
async function requireLibrary(library) {
|
||||
@ -118,5 +121,6 @@ export default {
|
||||
WHEEL_ZOOM,
|
||||
FORCE_GRAPH,
|
||||
MERMAID,
|
||||
EXCALIDRAW
|
||||
EXCALIDRAW,
|
||||
MARKJS
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ class NoteContext extends Component {
|
||||
}
|
||||
|
||||
async getTextEditor(callback) {
|
||||
return new Promise(resolve => appContext.triggerCommand('executeInTextEditor', {
|
||||
return new Promise(resolve => appContext.triggerCommand('executeWithTextEditor', {
|
||||
callback,
|
||||
resolve,
|
||||
ntxId: this.ntxId
|
||||
@ -236,7 +236,14 @@ class NoteContext extends Component {
|
||||
}
|
||||
|
||||
async getCodeEditor() {
|
||||
return new Promise(resolve => appContext.triggerCommand('executeInCodeEditor', {
|
||||
return new Promise(resolve => appContext.triggerCommand('executeWithCodeEditor', {
|
||||
resolve,
|
||||
ntxId: this.ntxId
|
||||
}));
|
||||
}
|
||||
|
||||
async getContentElement() {
|
||||
return new Promise(resolve => appContext.triggerCommand('executeWithContentElement', {
|
||||
resolve,
|
||||
ntxId: this.ntxId
|
||||
}));
|
||||
|
@ -365,6 +365,10 @@ function sleep(time_ms) {
|
||||
});
|
||||
}
|
||||
|
||||
function escapeRegExp(str) {
|
||||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
||||
}
|
||||
|
||||
export default {
|
||||
reloadFrontendApp,
|
||||
parseDate,
|
||||
@ -410,4 +414,5 @@ export default {
|
||||
filterAttributeName,
|
||||
isValidAttributeName,
|
||||
sleep,
|
||||
escapeRegExp
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import FindInText from "./find_in_text.js";
|
||||
import FindInCode from "./find_in_code.js";
|
||||
import FindInHtml from "./find_in_html.js";
|
||||
|
||||
const findWidgetDelayMillis = 200;
|
||||
const waitForEnter = (findWidgetDelayMillis < 0);
|
||||
@ -86,6 +87,13 @@ export default class FindWidget extends NoteContextAwareWidget {
|
||||
|
||||
this.textHandler = new FindInText(this);
|
||||
this.codeHandler = new FindInCode(this);
|
||||
this.htmlHandler = new FindInHtml(this);
|
||||
}
|
||||
|
||||
async noteSwitched() {
|
||||
await super.noteSwitched();
|
||||
|
||||
await this.closeSearch();
|
||||
}
|
||||
|
||||
doRender() {
|
||||
@ -125,6 +133,42 @@ export default class FindWidget extends NoteContextAwareWidget {
|
||||
return this.$widget;
|
||||
}
|
||||
|
||||
async findInTextEvent() {
|
||||
if (!this.isActiveNoteContext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!['text', 'code'].includes(this.note.type) || !this.$findBox.is(":hidden")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readOnly = await this.noteContext.isReadOnly();
|
||||
|
||||
if (readOnly) {
|
||||
this.handler = this.htmlHandler;
|
||||
} else {
|
||||
this.handler = this.note.type === "code"
|
||||
? this.codeHandler
|
||||
: this.textHandler;
|
||||
}
|
||||
|
||||
this.$findBox.show();
|
||||
this.$input.focus();
|
||||
this.$totalFound.text(0);
|
||||
this.$currentFound.text(0);
|
||||
|
||||
const searchTerm = await this.handler.getInitialSearchTerm();
|
||||
|
||||
this.$input.val(searchTerm || "");
|
||||
|
||||
// Directly perform the search if there's some text to
|
||||
// find, without delaying or waiting for enter
|
||||
if (searchTerm !== "") {
|
||||
this.$input.select();
|
||||
await this.performFind();
|
||||
}
|
||||
}
|
||||
|
||||
startSearch() {
|
||||
// XXX This should clear the previous search immediately in all cases
|
||||
// (the search is stale when waitforenter but also while the
|
||||
@ -172,35 +216,6 @@ export default class FindWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
}
|
||||
|
||||
async findInTextEvent() {
|
||||
if (!this.isActiveNoteContext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only writeable text and code supported
|
||||
const readOnly = await this.noteContext.isReadOnly();
|
||||
|
||||
if (readOnly || !['text', 'code'].includes(this.note.type) || !this.$findBox.is(":hidden")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$findBox.show();
|
||||
this.$input.focus();
|
||||
this.$totalFound.text(0);
|
||||
this.$currentFound.text(0);
|
||||
|
||||
const searchTerm = await this.handler.getInitialSearchTerm();
|
||||
|
||||
this.$input.val(searchTerm || "");
|
||||
|
||||
// Directly perform the search if there's some text to
|
||||
// find, without delaying or waiting for enter
|
||||
if (searchTerm !== "") {
|
||||
this.$input.select();
|
||||
await this.performFind();
|
||||
}
|
||||
}
|
||||
|
||||
/** Perform the find and highlight the find results. */
|
||||
async performFind() {
|
||||
const searchTerm = this.$input.val();
|
||||
@ -216,6 +231,7 @@ export default class FindWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
async closeSearch() {
|
||||
if (this.$findBox.is(":visible")) {
|
||||
this.$findBox.hide();
|
||||
|
||||
// Restore any state, if there's a current occurrence clear markers
|
||||
@ -229,20 +245,9 @@ export default class FindWidget extends NoteContextAwareWidget {
|
||||
|
||||
this.searchTerm = null;
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.isNoteContentReloaded(this.noteId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return super.isEnabled() && ['text', 'code'].includes(this.note.type);
|
||||
}
|
||||
|
||||
get handler() {
|
||||
return this.note.type === "code"
|
||||
? this.codeHandler
|
||||
: this.textHandler;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
// ck-find-result and ck-find-result_selected are the styles ck-editor
|
||||
// uses for highlighting matches, use the same one on CodeMirror
|
||||
// for consistency
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
const FIND_RESULT_SELECTED_CSS_CLASSNAME = "ck-find-result_selected";
|
||||
const FIND_RESULT_CSS_CLASSNAME = "ck-find-result";
|
||||
|
||||
const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
export default class FindInCode {
|
||||
constructor(parent) {
|
||||
/** @property {FindWidget} */
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ export default class FindInCode {
|
||||
}
|
||||
|
||||
if (searchTerm !== "") {
|
||||
searchTerm = escapeRegExp(searchTerm);
|
||||
searchTerm = utils.escapeRegExp(searchTerm);
|
||||
|
||||
// Find and highlight matches
|
||||
// Find and highlight matches
|
||||
|
36
src/public/app/widgets/find_in_html.js
Normal file
36
src/public/app/widgets/find_in_html.js
Normal file
@ -0,0 +1,36 @@
|
||||
// ck-find-result and ck-find-result_selected are the styles ck-editor
|
||||
// uses for highlighting matches, use the same one on CodeMirror
|
||||
// for consistency
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
const FIND_RESULT_SELECTED_CSS_CLASSNAME = "ck-find-result_selected";
|
||||
const FIND_RESULT_CSS_CLASSNAME = "ck-find-result";
|
||||
|
||||
export default class FindInHtml {
|
||||
constructor(parent) {
|
||||
/** @property {FindWidget} */
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
async getInitialSearchTerm() {
|
||||
return ""; // FIXME
|
||||
}
|
||||
|
||||
async performFind(searchTerm, matchCase, wholeWord) {
|
||||
await libraryLoader.requireLibrary(libraryLoader.MARKJS);
|
||||
|
||||
const $content = await this.parent.noteContext.getContentElement();
|
||||
|
||||
$content.markRegExp(new RegExp(utils.escapeRegExp(searchTerm), "gi"));
|
||||
}
|
||||
|
||||
async findNext(direction, currentFound, nextFound) {
|
||||
}
|
||||
|
||||
async cleanup(totalFound, currentFound) {
|
||||
}
|
||||
|
||||
async close() {
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
export default class FindInText {
|
||||
constructor(parent) {
|
||||
/** @property {FindWidget} */
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ export default class EditableCodeTypeWidget extends TypeWidget {
|
||||
}
|
||||
}
|
||||
|
||||
async executeInCodeEditorEvent({resolve, ntxId}) {
|
||||
async executeWithCodeEditorEvent({resolve, ntxId}) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
return !selection.isCollapsed;
|
||||
}
|
||||
|
||||
async executeInTextEditorEvent({callback, resolve, ntxId}) {
|
||||
async executeWithTextEditorEvent({callback, resolve, ntxId}) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
}
|
||||
|
@ -30,4 +30,14 @@ export default class ReadOnlyCodeTypeWidget extends TypeWidget {
|
||||
|
||||
this.$content.text(noteComplement.content);
|
||||
}
|
||||
|
||||
async executeWithContentElementEvent({resolve, ntxId}) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.initialized;
|
||||
|
||||
resolve(this.$content);
|
||||
}
|
||||
}
|
||||
|
@ -114,4 +114,14 @@ export default class ReadOnlyTextTypeWidget extends AbstractTextTypeWidget {
|
||||
async refreshIncludedNoteEvent({noteId}) {
|
||||
this.refreshIncludedNote(this.$content, noteId);
|
||||
}
|
||||
|
||||
async executeWithContentElementEvent({resolve, ntxId}) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.initialized;
|
||||
|
||||
resolve(this.$content);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user