mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 09:58:32 +02:00
Merge branch 'master' into dev
This commit is contained in:
commit
957640f163
@ -33,7 +33,7 @@
|
|||||||
"@excalidraw/excalidraw": "0.13.0",
|
"@excalidraw/excalidraw": "0.13.0",
|
||||||
"archiver": "5.3.1",
|
"archiver": "5.3.1",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"axios": "1.2.1",
|
"axios": "1.2.2",
|
||||||
"better-sqlite3": "7.4.5",
|
"better-sqlite3": "7.4.5",
|
||||||
"chokidar": "3.5.3",
|
"chokidar": "3.5.3",
|
||||||
"cls-hooked": "4.2.2",
|
"cls-hooked": "4.2.2",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
import NoteContextAwareWidget from "../note_context_aware_widget.js";
|
||||||
|
|
||||||
const TPL = `<button class="button-widget no-print" data-toggle="tooltip">
|
const TPL = `<button class="button-widget bx"
|
||||||
<span class="bx"></span>
|
data-toggle="tooltip"
|
||||||
</button>`;
|
title=""></button>`;
|
||||||
|
|
||||||
export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
@ -22,7 +22,6 @@ export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
this.$widget = $(TPL);
|
||||||
this.$iconSpan = this.$widget.find("span");
|
|
||||||
|
|
||||||
if (this.settings.onContextMenu) {
|
if (this.settings.onContextMenu) {
|
||||||
this.$widget.on("contextmenu", e => {
|
this.$widget.on("contextmenu", e => {
|
||||||
@ -52,9 +51,9 @@ export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refreshIcon() {
|
refreshIcon() {
|
||||||
for (const className of this.$iconSpan[0].classList) {
|
for (const className of this.$widget[0].classList) {
|
||||||
if (className.startsWith("bx-")) {
|
if (className.startsWith("bx-")) {
|
||||||
this.$iconSpan.removeClass(className);
|
this.$widget.removeClass(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +61,7 @@ export default class AbstractButtonWidget extends NoteContextAwareWidget {
|
|||||||
? this.settings.icon()
|
? this.settings.icon()
|
||||||
: this.settings.icon;
|
: this.settings.icon;
|
||||||
|
|
||||||
this.$iconSpan.addClass(icon);
|
this.$widget.addClass(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
initialRenderCompleteEvent() {
|
initialRenderCompleteEvent() {
|
||||||
|
@ -39,12 +39,10 @@ export default class EditButton extends OnClickButtonWidget {
|
|||||||
// make the edit button stand out on the first display, otherwise
|
// make the edit button stand out on the first display, otherwise
|
||||||
// it's difficult to notice that the note is readonly
|
// it's difficult to notice that the note is readonly
|
||||||
if (this.isVisible() && !wasVisible) {
|
if (this.isVisible() && !wasVisible) {
|
||||||
this.$iconSpan.addClass("bx-tada");
|
this.$widget.addClass("bx-tada bx-lg");
|
||||||
this.$widget.css("transform", "scale(2)");
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$iconSpan.removeClass("bx-tada bx-lg");
|
this.$widget.removeClass("bx-tada bx-lg");
|
||||||
this.$widget.css("transform", "scale(1)");
|
|
||||||
}, 1700);
|
}, 1700);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,12 @@ const TPL = `
|
|||||||
background-position: 50% 45%;
|
background-position: 50% 45%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.global-menu-button:hover {
|
.global-menu-button:hover {
|
||||||
background-image: url("${window.glob.assetPath}/images/icon-color.png");
|
background-image: url("${window.glob.assetPath}/images/icon-color.png");
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.global-menu-button-update-available {
|
.global-menu-button-update-available {
|
||||||
|
@ -28,7 +28,8 @@ function sanitize(dirtyHtml) {
|
|||||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
|
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
|
||||||
'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div',
|
'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div',
|
||||||
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'section', 'img',
|
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'section', 'img',
|
||||||
'figure', 'figcaption', 'span', 'label', 'input'
|
'figure', 'figcaption', 'span', 'label', 'input',
|
||||||
|
'en-media' // for ENEX import
|
||||||
],
|
],
|
||||||
allowedAttributes: {
|
allowedAttributes: {
|
||||||
'a': [ 'href', 'class', 'data-note-path' ],
|
'a': [ 'href', 'class', 'data-note-path' ],
|
||||||
@ -41,6 +42,7 @@ function sanitize(dirtyHtml) {
|
|||||||
'code': [ 'class' ],
|
'code': [ 'class' ],
|
||||||
'ul': [ 'class' ],
|
'ul': [ 'class' ],
|
||||||
'table': [ 'class' ],
|
'table': [ 'class' ],
|
||||||
|
'en-media': [ 'hash' ]
|
||||||
},
|
},
|
||||||
allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'evernote'],
|
allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'data', 'evernote'],
|
||||||
transformTags,
|
transformTags,
|
||||||
|
@ -24,6 +24,7 @@ class SearchContext {
|
|||||||
this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch;
|
this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch;
|
||||||
this.highlightedTokens = [];
|
this.highlightedTokens = [];
|
||||||
this.originalQuery = "";
|
this.originalQuery = "";
|
||||||
|
this.fulltextQuery = ""; // complete fulltext part
|
||||||
// if true, becca does not have (up-to-date) information needed to process the query
|
// if true, becca does not have (up-to-date) information needed to process the query
|
||||||
// and some extra data needs to be loaded before executing
|
// and some extra data needs to be loaded before executing
|
||||||
this.dbLoadNeeded = false;
|
this.dbLoadNeeded = false;
|
||||||
|
@ -17,18 +17,22 @@ class SearchResult {
|
|||||||
return this.notePathArray[this.notePathArray.length - 1];
|
return this.notePathArray[this.notePathArray.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
computeScore(tokens) {
|
computeScore(fulltextQuery, tokens) {
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
|
|
||||||
|
const note = becca.notes[this.noteId];
|
||||||
|
|
||||||
|
if (note.title.toLowerCase() === fulltextQuery) {
|
||||||
|
this.score += 100; // high reward for exact match #3470
|
||||||
|
}
|
||||||
|
|
||||||
|
// notes with matches on its own note title as opposed to ancestors or descendants
|
||||||
|
this.addScoreForStrings(tokens, note.title, 1.5);
|
||||||
|
|
||||||
// matches in attributes don't get extra points and thus are implicitly valued less than note path matches
|
// matches in attributes don't get extra points and thus are implicitly valued less than note path matches
|
||||||
|
|
||||||
this.addScoreForStrings(tokens, this.notePathTitle, 1);
|
this.addScoreForStrings(tokens, this.notePathTitle, 1);
|
||||||
|
|
||||||
// add one more time for note title alone (already contained in the notePathTitle),
|
|
||||||
// thus preferring notes with matches on its own note title as opposed to ancestors or descendants
|
|
||||||
const note = becca.notes[this.noteId];
|
|
||||||
this.addScoreForStrings(tokens, note.title, 1.5);
|
|
||||||
|
|
||||||
if (note.isInHiddenSubtree()) {
|
if (note.isInHiddenSubtree()) {
|
||||||
this.score = this.score / 2;
|
this.score = this.score / 2;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
function lex(str) {
|
function lex(str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
|
||||||
|
let fulltextQuery = "";
|
||||||
const fulltextTokens = [];
|
const fulltextTokens = [];
|
||||||
const expressionTokens = [];
|
const expressionTokens = [];
|
||||||
|
|
||||||
@ -37,6 +38,8 @@ function lex(str) {
|
|||||||
expressionTokens.push(rec);
|
expressionTokens.push(rec);
|
||||||
} else {
|
} else {
|
||||||
fulltextTokens.push(rec);
|
fulltextTokens.push(rec);
|
||||||
|
|
||||||
|
fulltextQuery = str.substr(0, endIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentWord = '';
|
currentWord = '';
|
||||||
@ -129,7 +132,10 @@ function lex(str) {
|
|||||||
|
|
||||||
finishWord(str.length - 1);
|
finishWord(str.length - 1);
|
||||||
|
|
||||||
|
fulltextQuery = fulltextQuery.trim();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
fulltextQuery,
|
||||||
fulltextTokens,
|
fulltextTokens,
|
||||||
expressionTokens
|
expressionTokens
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ function findResultsWithExpression(expression, searchContext) {
|
|||||||
.filter(note => !!note);
|
.filter(note => !!note);
|
||||||
|
|
||||||
for (const res of searchResults) {
|
for (const res of searchResults) {
|
||||||
res.computeScore(searchContext.highlightedTokens);
|
res.computeScore(searchContext.fulltextQuery, searchContext.highlightedTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noteSet.sorted) {
|
if (!noteSet.sorted) {
|
||||||
@ -195,7 +195,9 @@ function findResultsWithExpression(expression, searchContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseQueryToExpression(query, searchContext) {
|
function parseQueryToExpression(query, searchContext) {
|
||||||
const {fulltextTokens, expressionTokens} = lex(query);
|
const {fulltextQuery, fulltextTokens, expressionTokens} = lex(query);
|
||||||
|
searchContext.fulltextQuery = fulltextQuery;
|
||||||
|
|
||||||
let structuredExpressionTokens;
|
let structuredExpressionTokens;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -291,6 +291,10 @@ function deferred() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeDiacritic(str) {
|
function removeDiacritic(str) {
|
||||||
|
if (!str) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return str.normalize("NFD").replace(/\p{Diacritic}/gu, "");
|
return str.normalize("NFD").replace(/\p{Diacritic}/gu, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user