From bb8fd2b054e09190e6642231f70e85e554808e02 Mon Sep 17 00:00:00 2001 From: contributor Date: Wed, 3 May 2023 16:19:28 +0300 Subject: [PATCH 1/6] zip export - set note title as document.title --- src/services/export/zip.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/services/export/zip.js b/src/services/export/zip.js index c58afca9f..6bbd1b6ed 100644 --- a/src/services/export/zip.js +++ b/src/services/export/zip.js @@ -248,6 +248,7 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) if (noteMeta.format === 'html') { if (!content.substr(0, 100).toLowerCase().includes(" element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809 content = ` @@ -256,10 +257,11 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) + ${htmlTitle}
-

${utils.escapeHtml(title)}

+

${htmlTitle}

${content}
From 22587ee6b5f016646023647a341431edaf727c48 Mon Sep 17 00:00:00 2001 From: Nriver <6752679+Nriver@users.noreply.github.com> Date: Thu, 4 May 2023 14:57:33 +0800 Subject: [PATCH 2/6] customize search engine --- src/public/app/desktop.js | 21 +++++- .../widgets/type_widgets/content_widget.js | 2 + .../options/other/search_engine.js | 73 +++++++++++++++++++ src/routes/api/options.js | 4 +- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/public/app/widgets/type_widgets/options/other/search_engine.js diff --git a/src/public/app/desktop.js b/src/public/app/desktop.js index e83f4477e..7b0da9e35 100644 --- a/src/public/app/desktop.js +++ b/src/public/app/desktop.js @@ -8,6 +8,7 @@ import contextMenu from "./menus/context_menu.js"; import DesktopLayout from "./layouts/desktop_layout.js"; import glob from "./services/glob.js"; import zoomService from './components/zoom.js'; +import options from "./services/options.js"; bundleService.getWidgetBundlesByParent().then(widgetBundles => { appContext.setLayout(new DesktopLayout(widgetBundles)); @@ -115,11 +116,27 @@ if (utils.isElectron()) { ? (`${params.selectionText.substr(0, 13)}…`) : params.selectionText; + // Read the search engine from the options and fallback to DuckDuckGo if the option is not set. + const customSearchEngineName = options.get("customSearchEngineName"); + const customSearchEngineUrl = options.get("customSearchEngineUrl"); + let searchEngineName; + let searchEngineUrl; + if (customSearchEngineName && customSearchEngineUrl) { + searchEngineName = customSearchEngineName; + searchEngineUrl = customSearchEngineUrl; + } else { + searchEngineName = "Duckduckgo"; + searchEngineUrl = "https://duckduckgo.com/?q={keyword}"; + } + + // Replace the placeholder with the real search keyword. + let searchUrl = searchEngineUrl.replace("{keyword}", encodeURIComponent(params.selectionText)); + items.push({ enabled: editFlags.canPaste, - title: `Search for "${shortenedSelection}" with DuckDuckGo`, + title: `Search for "${shortenedSelection}" with ${searchEngineName}`, uiIcon: "bx bx-search-alt", - handler: () => electron.shell.openExternal(`https://duckduckgo.com/?q=${encodeURIComponent(params.selectionText)}`) + handler: () => electron.shell.openExternal(searchUrl) }); } diff --git a/src/public/app/widgets/type_widgets/content_widget.js b/src/public/app/widgets/type_widgets/content_widget.js index d81fe550a..967c996e5 100644 --- a/src/public/app/widgets/type_widgets/content_widget.js +++ b/src/public/app/widgets/type_widgets/content_widget.js @@ -18,6 +18,7 @@ import PasswordOptions from "./options/password.js"; import EtapiOptions from "./options/etapi.js"; import BackupOptions from "./options/backup.js"; import SyncOptions from "./options/sync.js"; +import SearchEngineOptions from "./options/other/search_engine.js"; import TrayOptions from "./options/other/tray.js"; import NoteErasureTimeoutOptions from "./options/other/note_erasure_timeout.js"; import NoteRevisionsSnapshotIntervalOptions from "./options/other/note_revisions_snapshot_interval.js"; @@ -75,6 +76,7 @@ const CONTENT_WIDGETS = { _optionsBackup: [ BackupOptions ], _optionsSync: [ SyncOptions ], _optionsOther: [ + SearchEngineOptions, TrayOptions, NoteErasureTimeoutOptions, NoteRevisionsSnapshotIntervalOptions, diff --git a/src/public/app/widgets/type_widgets/options/other/search_engine.js b/src/public/app/widgets/type_widgets/options/other/search_engine.js new file mode 100644 index 000000000..fcbc7b5c2 --- /dev/null +++ b/src/public/app/widgets/type_widgets/options/other/search_engine.js @@ -0,0 +1,73 @@ +import OptionsWidget from "../options_widget.js"; + +const TPL = ` +
+ + +

Search Engine

+ +

Custom search engine requires both a name and a URL to be set. If either of these is not set, DuckDuckGo will be used as the default search engine.

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
`; + +const SEARCH_ENGINES = { + "Bing": "https://www.bing.com/search?q={keyword}", + "Baidu": "https://www.baidu.com/s?wd={keyword}", + "Duckduckgo": "https://duckduckgo.com/?q={keyword}", + "Google": "https://www.google.com/search?q={keyword}", +} + +export default class SearchEngineOptions extends OptionsWidget { + doRender() { + this.$widget = $(TPL); + + this.$form = this.$widget.find(".sync-setup-form"); + this.$predefinedSearchEngineSelect = this.$widget.find(".predefined-search-engine-select"); + this.$customSearchEngineName = this.$widget.find(".custom-search-engine-name"); + this.$customSearchEngineUrl = this.$widget.find(".custom-search-engine-url"); + + this.$predefinedSearchEngineSelect.on('change', () => { + const predefinedSearchEngine = this.$predefinedSearchEngineSelect.val(); + this.$customSearchEngineName[0].value = predefinedSearchEngine; + this.$customSearchEngineUrl[0].value = SEARCH_ENGINES[predefinedSearchEngine]; + }); + + this.$form.on('submit', () => { + this.updateMultipleOptions({ + 'customSearchEngineName': this.$customSearchEngineName.val(), + 'customSearchEngineUrl': this.$customSearchEngineUrl.val() + }); + }); + } + + async optionsLoaded(options) { + this.$predefinedSearchEngineSelect.val(""); + this.$customSearchEngineName[0].value = options.customSearchEngineName; + this.$customSearchEngineUrl[0].value = options.customSearchEngineUrl; + } +} diff --git a/src/routes/api/options.js b/src/routes/api/options.js index 855672e9a..e98b1795f 100644 --- a/src/routes/api/options.js +++ b/src/routes/api/options.js @@ -61,7 +61,9 @@ const ALLOWED_OPTIONS = new Set([ 'downloadImagesAutomatically', 'minTocHeadings', 'checkForUpdates', - 'disableTray' + 'disableTray', + 'customSearchEngineName', + 'customSearchEngineUrl', ]); function getOptions() { From 8ce499e9581a397f061accf104b4528906782115 Mon Sep 17 00:00:00 2001 From: Nriver <6752679+Nriver@users.noreply.github.com> Date: Thu, 4 May 2023 16:20:09 +0800 Subject: [PATCH 3/6] add runtime check for search engine options --- .../app/widgets/type_widgets/options/other/search_engine.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/public/app/widgets/type_widgets/options/other/search_engine.js b/src/public/app/widgets/type_widgets/options/other/search_engine.js index fcbc7b5c2..081aa0aa8 100644 --- a/src/public/app/widgets/type_widgets/options/other/search_engine.js +++ b/src/public/app/widgets/type_widgets/options/other/search_engine.js @@ -1,4 +1,5 @@ import OptionsWidget from "../options_widget.js"; +import utils from "../../../../services/utils.js"; const TPL = `
@@ -43,6 +44,10 @@ const SEARCH_ENGINES = { } export default class SearchEngineOptions extends OptionsWidget { + isEnabled() { + return super.isEnabled() && utils.isElectron(); + } + doRender() { this.$widget = $(TPL); From 61616f708f96f368894549c4b1c07f584c0bd230 Mon Sep 17 00:00:00 2001 From: Nriver <6752679+Nriver@users.noreply.github.com> Date: Thu, 4 May 2023 18:01:51 +0800 Subject: [PATCH 4/6] add default options for search engine options --- src/services/options_init.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/options_init.js b/src/services/options_init.js index fd66718f8..1ce5bbd5d 100644 --- a/src/services/options_init.js +++ b/src/services/options_init.js @@ -89,6 +89,8 @@ const defaultOptions = [ { name: 'minTocHeadings', value: '5', isSynced: true }, { name: 'checkForUpdates', value: 'true', isSynced: true }, { name: 'disableTray', value: 'false', isSynced: false }, + { name: 'customSearchEngineName', value: 'Duckduckgo', isSynced: false }, + { name: 'customSearchEngineUrl', value: 'https://duckduckgo.com/?q={keyword}', isSynced: false }, ]; function initStartupOptions() { From 386e8dd32eb08f767bba02fe8da61d1753068a03 Mon Sep 17 00:00:00 2001 From: contributor Date: Thu, 4 May 2023 19:56:02 +0300 Subject: [PATCH 5/6] zip import - remove html tags added by Trilium --- src/services/export/zip.js | 4 ++-- src/services/import/zip.js | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/services/export/zip.js b/src/services/export/zip.js index 6bbd1b6ed..d31927d19 100644 --- a/src/services/export/zip.js +++ b/src/services/export/zip.js @@ -257,11 +257,11 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) - ${htmlTitle} + ${htmlTitle}
-

${htmlTitle}

+

${htmlTitle}

${content}
diff --git a/src/services/import/zip.js b/src/services/import/zip.js index abe3b58a9..74a942113 100644 --- a/src/services/import/zip.js +++ b/src/services/import/zip.js @@ -240,6 +240,8 @@ async function importZip(taskContext, fileBuffer, importRootNote) { return /^(?:[a-z]+:)?\/\//i.test(url); } + content = removeTrilumTags(content); + content = content.replace(/

([^<]*)<\/h1>/gi, (match, text) => { if (noteTitle.trim() === text.trim()) { return ""; // remove whole H1 tag @@ -325,6 +327,18 @@ async function importZip(taskContext, fileBuffer, importRootNote) { return content; } + function removeTrilumTags(content) { + const tagsToRemove = [ + '

([^<]*)<\/h1>', + '([^<]*)<\/title>' + ] + for (const tag of tagsToRemove) { + let re = new RegExp(tag, "gi"); + content = content.replace(re, ''); + } + return content; + } + function processNoteContent(noteMeta, type, mime, content, noteTitle, filePath) { if (noteMeta?.format === 'markdown' || (!noteMeta && taskContext.data.textImportedAsText && ['text/markdown', 'text/x-markdown'].includes(mime))) { From bb9631476e5d22db78a5d8390aece8670c7ea415 Mon Sep 17 00:00:00 2001 From: contributor <foss.contributor@gmail.com> Date: Wed, 3 May 2023 18:49:46 +0300 Subject: [PATCH 6/6] bump metaFile format version --- src/services/export/zip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/export/zip.js b/src/services/export/zip.js index d31927d19..1bc73f768 100644 --- a/src/services/export/zip.js +++ b/src/services/export/zip.js @@ -417,7 +417,7 @@ ${markdownContent}`; const rootMeta = getNoteMeta(branch, { notePath: [] }, existingFileNames); const metaFile = { - formatVersion: 1, + formatVersion: 2, appVersion: packageInfo.version, files: [ rootMeta ] };