Merge branch 'master' into dev

This commit is contained in:
zadam 2023-01-02 22:53:03 +01:00
commit 957640f163
10 changed files with 38 additions and 22 deletions

View File

@ -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",

View File

@ -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() {

View File

@ -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);
} }
} }

View File

@ -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 {

View File

@ -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,

View File

@ -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;

View File

@ -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;
} }

View File

@ -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
} }

View File

@ -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 {

View File

@ -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, "");
} }