added webpack

This commit is contained in:
zadam 2020-04-12 14:22:51 +02:00
parent 3c311cd2a4
commit 339f212e4c
28 changed files with 1774 additions and 244 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.DS_Store .DS_Store
node_modules/ node_modules/
dist/ dist/
src/public/dist/
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
*.db *.db

View File

@ -1,4 +1,4 @@
FROM node:12.16.1-alpine FROM node:12.16.2-alpine
# Create app directory # Create app directory
WORKDIR /usr/src/app WORKDIR /usr/src/app

View File

@ -12,6 +12,8 @@ echo "Copying required linux-x64 binaries"
rm -r $SRC_DIR/node_modules/sqlite3/lib/binding/* rm -r $SRC_DIR/node_modules/sqlite3/lib/binding/*
rm -r $SRC_DIR/node_modules/pngquant-bin/vendor/* rm -r $SRC_DIR/node_modules/pngquant-bin/vendor/*
rm -r $SRC_DIR/src/public/dist/*.mobile.*
cp -r bin/deps/linux-x64/sqlite/* $SRC_DIR/node_modules/sqlite3/lib/binding/ cp -r bin/deps/linux-x64/sqlite/* $SRC_DIR/node_modules/sqlite3/lib/binding/
cp bin/deps/linux-x64/image/pngquant $SRC_DIR/node_modules/pngquant-bin/vendor/ cp bin/deps/linux-x64/image/pngquant $SRC_DIR/node_modules/pngquant-bin/vendor/

View File

@ -19,6 +19,8 @@ cp bin/deps/mac-x64/image/cjpeg $SRC_DIR/node_modules/mozjpeg/vendor/
cp bin/deps/mac-x64/image/pngquant $SRC_DIR/node_modules/pngquant-bin/vendor/ cp bin/deps/mac-x64/image/pngquant $SRC_DIR/node_modules/pngquant-bin/vendor/
cp bin/deps/mac-x64/image/gifsicle $SRC_DIR/node_modules/giflossy/vendor/ cp bin/deps/mac-x64/image/gifsicle $SRC_DIR/node_modules/giflossy/vendor/
rm -r $SRC_DIR/src/public/dist/*.mobile.*
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=x64 --overwrite --icon=images/app-icons/mac/icon.icns ./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=darwin --arch=x64 --overwrite --icon=images/app-icons/mac/icon.icns
BUILD_DIR=./dist/trilium-mac-x64 BUILD_DIR=./dist/trilium-mac-x64

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
PKG_DIR=dist/trilium-linux-x64-server PKG_DIR=dist/trilium-linux-x64-server
NODE_VERSION=12.16.1 NODE_VERSION=12.16.2
if [ "$1" != "DONTCOPY" ] if [ "$1" != "DONTCOPY" ]
then then

View File

@ -19,6 +19,8 @@ cp bin/deps/win-x64/image/cjpeg.exe $SRC_DIR/node_modules/mozjpeg/vendor/
cp bin/deps/win-x64/image/pngquant.exe $SRC_DIR/node_modules/pngquant-bin/vendor/ cp bin/deps/win-x64/image/pngquant.exe $SRC_DIR/node_modules/pngquant-bin/vendor/
cp bin/deps/win-x64/image/gifsicle.exe $SRC_DIR/node_modules/giflossy/vendor/ cp bin/deps/win-x64/image/gifsicle.exe $SRC_DIR/node_modules/giflossy/vendor/
rm -r $SRC_DIR/src/public/dist/*.mobile.*
./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=images/app-icons/win/icon.ico ./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=win32 --arch=x64 --overwrite --icon=images/app-icons/win/icon.ico
BUILD_DIR=./dist/trilium-windows-x64 BUILD_DIR=./dist/trilium-windows-x64

View File

@ -22,8 +22,14 @@ cp -r README.md $DIR/
cp -r LICENSE $DIR/ cp -r LICENSE $DIR/
cp -r config-sample.ini $DIR/ cp -r config-sample.ini $DIR/
cp -r electron.js $DIR/ cp -r electron.js $DIR/
cp webpack-* $DIR/
# run in subshell (so we return to original dir) # run in subshell (so we return to original dir)
(cd $DIR && npm install --only=prod) (cd $DIR && npm install --only=prod && npm run webpack)
find $DIR/libraries -name "*.map" -type f -delete find $DIR/libraries -name "*.map" -type f -delete
rm -r $DIR/src/public/javascripts
sed -i -e 's/javascripts\/desktop.js/dist\/desktop.js/g' $DIR/src/views/desktop.ejs
sed -i -e 's/javascripts\/mobile.js/dist\/mobile.js/g' $DIR/src/views/mobile.ejs

1609
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,8 @@
"start-electron": "TRILIUM_ENV=dev electron .", "start-electron": "TRILIUM_ENV=dev electron .",
"build-backend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js", "build-backend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/backend_api src/entities/*.js src/services/backend_script_api.js",
"build-frontend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/javascripts/entities/*.js src/public/javascripts/services/frontend_script_api.js", "build-frontend-docs": "./node_modules/.bin/jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/javascripts/entities/*.js src/public/javascripts/services/frontend_script_api.js",
"build-docs": "npm run build-backend-docs && npm run build-frontend-docs" "build-docs": "npm run build-backend-docs && npm run build-frontend-docs",
"webpack": "npx webpack -c webpack-desktop.config.js && npx webpack -c webpack-mobile.config.js"
}, },
"dependencies": { "dependencies": {
"async-mutex": "0.2.1", "async-mutex": "0.2.1",
@ -82,7 +83,9 @@
"electron-packager": "14.2.1", "electron-packager": "14.2.1",
"electron-rebuild": "1.10.1", "electron-rebuild": "1.10.1",
"jsdoc": "3.6.4", "jsdoc": "3.6.4",
"lorem-ipsum": "2.0.3" "lorem-ipsum": "2.0.3",
"webpack": "5.0.0-beta.14",
"webpack-cli": "4.0.0-beta.8"
}, },
"optionalDependencies": { "optionalDependencies": {
"electron-installer-debian": "2.0.1" "electron-installer-debian": "2.0.1"

View File

@ -45,6 +45,7 @@ app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public')));
app.use('/libraries', express.static(path.join(__dirname, '..', 'libraries'))); app.use('/libraries', express.static(path.join(__dirname, '..', 'libraries')));
app.use('/images', express.static(path.join(__dirname, '..', 'images'))); app.use('/images', express.static(path.join(__dirname, '..', 'images')));
app.use('/dist', express.static(path.join(__dirname, '..', 'dist')));
const sessionParser = session({ const sessionParser = session({
secret: sessionSecret, secret: sessionSecret,
resave: false, // true forces the session to be saved back to the session store, even if the session was never modified during the request. resave: false, // true forces the session to be saved back to the session store, even if the session was never modified during the request.

View File

@ -1,80 +1,17 @@
import treeCache from './services/tree_cache.js';
import options from "./services/options.js";
import appContext from "./services/app_context.js"; import appContext from "./services/app_context.js";
import glob from './services/glob.js';
import link from './services/link.js';
import ws from './services/ws.js';
import noteType from './widgets/note_type.js';
import protectedSessionService from './services/protected_session.js';
import protectedSessionHolder from './services/protected_session_holder.js';
import FrontendScriptApi from './services/frontend_script_api.js';
import ScriptContext from './services/script_context.js';
import sync from './services/sync.js';
import treeService from './services/tree.js';
import branchService from './services/branches.js';
import utils from './services/utils.js'; import utils from './services/utils.js';
import server from './services/server.js';
import Entrypoints from './services/entrypoints.js';
import noteTooltipService from './services/note_tooltip.js'; import noteTooltipService from './services/note_tooltip.js';
import bundle from "./services/bundle.js"; import bundleService from "./services/bundle.js";
import libraryLoader from "./services/library_loader.js";
import hoistedNoteService from './services/hoisted_note.js';
import noteTypeService from './widgets/note_type.js';
import linkService from './services/link.js';
import noteAutocompleteService from './services/note_autocomplete.js'; import noteAutocompleteService from './services/note_autocomplete.js';
import macInit from './services/mac_init.js'; import macInit from './services/mac_init.js';
import dateNoteService from './services/date_notes.js';
import importService from './services/import.js';
import keyboardActionService from "./services/keyboard_actions.js";
import splitService from "./services/split.js";
import noteContentRenderer from "./services/note_content_renderer.js";
import FlexContainer from "./widgets/flex_container.js";
import GlobalMenuWidget from "./widgets/global_menu.js";
import TabRowWidget from "./widgets/tab_row.js";
import TitleBarButtonsWidget from "./widgets/title_bar_buttons.js";
import StandardTopWidget from "./widgets/standard_top_widget.js";
import SidePaneContainer from "./widgets/side_pane_container.js";
import GlobalButtonsWidget from "./widgets/global_buttons.js";
import SearchBoxWidget from "./widgets/search_box.js";
import SearchResultsWidget from "./widgets/search_results.js";
import NoteTreeWidget from "./widgets/note_tree.js";
import TabCachingWidget from "./widgets/tab_caching_widget.js";
import NotePathsWidget from "./widgets/note_paths.js";
import NoteTitleWidget from "./widgets/note_title.js";
import RunScriptButtonsWidget from "./widgets/run_script_buttons.js";
import ProtectedNoteSwitchWidget from "./widgets/protected_note_switch.js";
import NoteTypeWidget from "./widgets/note_type.js";
import NoteActionsWidget from "./widgets/note_actions.js";
import PromotedAttributesWidget from "./widgets/promoted_attributes.js";
import NoteDetailWidget from "./widgets/note_detail.js";
import NoteInfoWidget from "./widgets/note_info.js";
import CalendarWidget from "./widgets/calendar.js";
import AttributesWidget from "./widgets/attributes.js";
import LinkMapWidget from "./widgets/link_map.js";
import NoteRevisionsWidget from "./widgets/note_revisions.js";
import SimilarNotesWidget from "./widgets/similar_notes.js";
import WhatLinksHereWidget from "./widgets/what_links_here.js";
import SidePaneToggles from "./widgets/side_pane_toggles.js";
import EmptyTypeWidget from "./widgets/type_widgets/empty.js";
import TextTypeWidget from "./widgets/type_widgets/editable_text.js";
import CodeTypeWidget from "./widgets/type_widgets/code.js";
import FileTypeWidget from "./widgets/type_widgets/file.js";
import ImageTypeWidget from "./widgets/type_widgets/image.js";
import SearchTypeWidget from "./widgets/type_widgets/search.js";
import RenderTypeWidget from "./widgets/type_widgets/render.js";
import RelationMapTypeWidget from "./widgets/type_widgets/relation_map.js";
import ProtectedSessionTypeWidget from "./widgets/type_widgets/protected_session.js";
import BookTypeWidget from "./widgets/type_widgets/book.js";
import contextMenu from "./services/context_menu.js"; import contextMenu from "./services/context_menu.js";
import DesktopLayout from "./widgets/desktop_layout.js"; import DesktopLayout from "./widgets/desktop_layout.js";
import bundleService from "./services/bundle.js"; import glob from "./services/glob.js";
import NoteShort from "./entities/note_short.js"
import NoteCompletement from "./entities/note_complement.js" glob.setupGlobs();
import Branch from "./entities/branch.js"
import Attribute from "./entities/attribute.js"
if (utils.isElectron()) { if (utils.isElectron()) {
require('electron').ipcRenderer.on('globalShortcut', async function(event, actionName) { utils.dynamicRequire('electron').ipcRenderer.on('globalShortcut', async function(event, actionName) {
appContext.triggerCommand(actionName); appContext.triggerCommand(actionName);
}); });
} }
@ -97,7 +34,7 @@ noteTooltipService.setupGlobalTooltip();
noteAutocompleteService.init(); noteAutocompleteService.init();
if (utils.isElectron()) { if (utils.isElectron()) {
const electron = require('electron'); const electron = utils.dynamicRequire('electron');
const {webContents} = electron.remote.getCurrentWindow(); const {webContents} = electron.remote.getCurrentWindow();
webContents.on('context-menu', (event, params) => { webContents.on('context-menu', (event, params) => {

View File

@ -34,7 +34,7 @@ export async function importMarkdownInline() {
} }
if (utils.isElectron()) { if (utils.isElectron()) {
const {clipboard} = require('electron'); const {clipboard} = utils.dynamicRequire('electron');
const text = clipboard.readText(); const text = clipboard.readText();
convertMarkdownToHtml(text); convertMarkdownToHtml(text);

View File

@ -1,80 +1,8 @@
import treeCache from './services/tree_cache.js';
import options from "./services/options.js";
import appContext from "./services/app_context.js"; import appContext from "./services/app_context.js";
import glob from './services/glob.js';
import noteContentRenderer from "./services/note_content_renderer.js";
import FlexContainer from "./widgets/flex_container.js";
import EmptyTypeWidget from "./widgets/type_widgets/empty.js";
import AbstractTextTypeWidget from "./widgets/type_widgets/abstract_text_type_widget.js";
import EditableTextTypeWidget from "./widgets/type_widgets/editable_text.js";
import ReadonlyTextTypeWidget from "./widgets/type_widgets/read_only_text.js";
import DeletedTypeWidget from "./widgets/type_widgets/deleted.js";
import CodeTypeWidget from "./widgets/type_widgets/code.js";
import FileTypeWidget from "./widgets/type_widgets/file.js";
import ImageTypeWidget from "./widgets/type_widgets/image.js";
import SearchTypeWidget from "./widgets/type_widgets/search.js";
import RenderTypeWidget from "./widgets/type_widgets/render.js";
import RelationMapTypeWidget from "./widgets/type_widgets/relation_map.js";
import ProtectedSessionTypeWidget from "./widgets/type_widgets/protected_session.js";
import BookTypeWidget from "./widgets/type_widgets/book.js";
import MobileLayout from "./widgets/mobile_layout.js"; import MobileLayout from "./widgets/mobile_layout.js";
import utils from "./services/utils.js"; import glob from "./services/glob.js";
import link from './services/link.js';
import ws from './services/ws.js'; glob.setupGlobs();
import noteType from './widgets/note_type.js';
import protectedSessionService from './services/protected_session.js';
import protectedSessionHolder from './services/protected_session_holder.js';
import treeService from './services/tree.js';
import branchService from './services/branches.js';
import server from './services/server.js';
import Entrypoints from './services/entrypoints.js';
import noteTooltipService from './services/note_tooltip.js';
import bundle from "./services/bundle.js";
import libraryLoader from "./services/library_loader.js";
import hoistedNoteService from './services/hoisted_note.js';
import noteTypeService from './widgets/note_type.js';
import linkService from './services/link.js';
import dateNoteService from './services/date_notes.js';
import importService from './services/import.js';
import keyboardActionService from "./services/keyboard_actions.js";
import splitService from "./services/split.js";
import GlobalMenuWidget from "./widgets/global_menu.js";
import TabRowWidget from "./widgets/tab_row.js";
import NoteTreeWidget from "./widgets/note_tree.js";
import treeBuilderService from "./services/tree_builder.js";
import spacedUpdateService from "./services/spaced_update.js";
import toastService from "./services/toast.js";
import BasicWidget from "./widgets/basic_widget.js";
import TabAwareWidget from "./widgets/tab_aware_widget.js";
import TabCachingWidget from "./widgets/tab_caching_widget.js";
import NoteTitleWidget from "./widgets/note_title.js";
import PromotedAttributesWidget from "./widgets/promoted_attributes.js";
import NoteDetailWidget from "./widgets/note_detail.js";
import bundleService from "./services/bundle.js";
import dialogCommandExecutor from "./services/dialog_command_executor.js";
import mainTreeExecutor from "./services/main_tree_executors.js";
import zoom from "./services/zoom.js";
import tabManager from "./services/tab_manager.js";
import tabContext from "./services/tab_context.js";
import Component from "./widgets/component.js";
import mimeTypes from "./services/mime_types.js";
import screenContainer from "./widgets/screen_container.js";
import clipboard from "./services/clipboard.js";
import renderService from "./services/render.js";
import NoteShort from "./entities/note_short.js"
import NoteCompletement from "./entities/note_complement.js"
import Branch from "./entities/branch.js"
import Attribute from "./entities/attribute.js"
import mutex from "./services/mutex.js"
import noteCreateService from "./services/note_create.js"
import closeDetailWidget from "./widgets/close_detail_button.js"
import mobileDetailMenu from "./widgets/mobile_detail_menu.js"
import mobileGlobalButtons from "./widgets/mobile_global_buttons.js"
import mobileScreenSwitcher from "./widgets/mobile_screen_switcher.js";
import frontendScriptApi from "./services/frontend_script_api.js";
import CollapsibleWidget from "./widgets/collapsible_widget.js";
import LoadResults from "./services/load_results.js";
import syncService from "./services/sync.js";
appContext.setLayout(new MobileLayout()); appContext.setLayout(new MobileLayout());
appContext.start(); appContext.start();

View File

@ -1,8 +1,6 @@
import utils from "./utils.js"; import utils from "./utils.js";
import treeService from "./tree.js";
import dateNoteService from "./date_notes.js"; import dateNoteService from "./date_notes.js";
import hoistedNoteService from "./hoisted_note.js"; import hoistedNoteService from "./hoisted_note.js";
import treeCache from "./tree_cache.js";
import server from "./server.js"; import server from "./server.js";
import appContext from "./app_context.js"; import appContext from "./app_context.js";
import Component from "../widgets/component.js"; import Component from "../widgets/component.js";
@ -36,7 +34,7 @@ export default class Entrypoints extends Component {
openDevToolsCommand() { openDevToolsCommand() {
if (utils.isElectron()) { if (utils.isElectron()) {
require('electron').remote.getCurrentWindow().toggleDevTools(); utils.dynamicRequire('electron').remote.getCurrentWindow().toggleDevTools();
} }
} }
@ -45,8 +43,8 @@ export default class Entrypoints extends Component {
return; return;
} }
const {remote} = require('electron'); const {remote} = utils.dynamicRequire('electron');
const {FindInPage} = require('electron-find'); const {FindInPage} = utils.dynamicRequire('electron-find');
const findInPage = new FindInPage(remote.getCurrentWebContents(), { const findInPage = new FindInPage(remote.getCurrentWebContents(), {
offsetTop: 10, offsetTop: 10,
offsetRight: 10, offsetRight: 10,
@ -98,7 +96,7 @@ export default class Entrypoints extends Component {
toggleFullscreenCommand() { toggleFullscreenCommand() {
if (utils.isElectron()) { if (utils.isElectron()) {
const win = require('electron').remote.getCurrentWindow(); const win = utils.dynamicRequire('electron').remote.getCurrentWindow();
if (win.isFullScreenable()) { if (win.isFullScreenable()) {
win.setFullScreen(!win.isFullScreen()); win.setFullScreen(!win.isFullScreen());
@ -139,7 +137,7 @@ export default class Entrypoints extends Component {
backInNoteHistoryCommand() { backInNoteHistoryCommand() {
if (utils.isElectron()) { if (utils.isElectron()) {
// standard JS version does not work completely correctly in electron // standard JS version does not work completely correctly in electron
const webContents = require('electron').remote.getCurrentWebContents(); const webContents = utils.dynamicRequire('electron').remote.getCurrentWebContents();
const activeIndex = parseInt(webContents.getActiveIndex()); const activeIndex = parseInt(webContents.getActiveIndex());
webContents.goToIndex(activeIndex - 1); webContents.goToIndex(activeIndex - 1);
@ -152,7 +150,7 @@ export default class Entrypoints extends Component {
forwardInNoteHistoryCommand() { forwardInNoteHistoryCommand() {
if (utils.isElectron()) { if (utils.isElectron()) {
// standard JS version does not work completely correctly in electron // standard JS version does not work completely correctly in electron
const webContents = require('electron').remote.getCurrentWebContents(); const webContents = utils.dynamicRequire('electron').remote.getCurrentWebContents();
const activeIndex = parseInt(webContents.getActiveIndex()); const activeIndex = parseInt(webContents.getActiveIndex());
webContents.goToIndex(activeIndex + 1); webContents.goToIndex(activeIndex + 1);

View File

@ -6,87 +6,89 @@ import ws from "./ws.js";
import protectedSessionHolder from "./protected_session_holder.js"; import protectedSessionHolder from "./protected_session_holder.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
window.glob.PROFILING_LOG = false; function setupGlobs() {
window.glob.PROFILING_LOG = false;
window.glob.isDesktop = utils.isDesktop; window.glob.isDesktop = utils.isDesktop;
window.glob.isMobile = utils.isMobile; window.glob.isMobile = utils.isMobile;
window.glob.getComponentByEl = el => appContext.getComponentByEl(el); window.glob.getComponentByEl = el => appContext.getComponentByEl(el);
window.glob.getHeaders = server.getHeaders; window.glob.getHeaders = server.getHeaders;
// required for ESLint plugin and CKEditor // required for ESLint plugin and CKEditor
window.glob.getActiveTabNote = () => appContext.tabManager.getActiveTabNote(); window.glob.getActiveTabNote = () => appContext.tabManager.getActiveTabNote();
window.glob.requireLibrary = libraryLoader.requireLibrary; window.glob.requireLibrary = libraryLoader.requireLibrary;
window.glob.ESLINT = libraryLoader.ESLINT; window.glob.ESLINT = libraryLoader.ESLINT;
window.glob.appContext = appContext; // for debugging window.glob.appContext = appContext; // for debugging
window.glob.treeCache = treeCache; window.glob.treeCache = treeCache;
// for CKEditor integration (button on block toolbar) // for CKEditor integration (button on block toolbar)
window.glob.importMarkdownInline = async () => { window.glob.importMarkdownInline = async () => {
const dialog = await import("./dialogs/markdown_import.js"); const dialog = await import("../dialogs/markdown_import.js");
dialog.importMarkdownInline(); dialog.importMarkdownInline();
}; };
window.glob.SEARCH_HELP_TEXT = ` window.glob.SEARCH_HELP_TEXT = `
<strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="Search">complete help on search</button> <strong>Search tips</strong> - also see <button class="btn btn-sm" type="button" data-help-page="Search">complete help on search</button>
<p> <p>
<ul> <ul>
<li>Just enter any text for full text search</li> <li>Just enter any text for full text search</li>
<li><code>@abc</code> - returns notes with label abc</li> <li><code>@abc</code> - returns notes with label abc</li>
<li><code>@year=2019</code> - matches notes with label <code>year</code> having value <code>2019</code></li> <li><code>@year=2019</code> - matches notes with label <code>year</code> having value <code>2019</code></li>
<li><code>@rock @pop</code> - matches notes which have both <code>rock</code> and <code>pop</code> labels</li> <li><code>@rock @pop</code> - matches notes which have both <code>rock</code> and <code>pop</code> labels</li>
<li><code>@rock or @pop</code> - only one of the labels must be present</li> <li><code>@rock or @pop</code> - only one of the labels must be present</li>
<li><code>@year&lt;=2000</code> - numerical comparison (also &gt;, &gt;=, &lt;).</li> <li><code>@year&lt;=2000</code> - numerical comparison (also &gt;, &gt;=, &lt;).</li>
<li><code>@dateCreated>=MONTH-1</code> - notes created in the last month</li> <li><code>@dateCreated>=MONTH-1</code> - notes created in the last month</li>
<li><code>=handler</code> - will execute script defined in <code>handler</code> relation to get results</li> <li><code>=handler</code> - will execute script defined in <code>handler</code> relation to get results</li>
</ul> </ul>
</p>`; </p>`;
window.onerror = function (msg, url, lineNo, columnNo, error) { window.onerror = function (msg, url, lineNo, columnNo, error) {
const string = msg.toLowerCase(); const string = msg.toLowerCase();
let message = "Uncaught error: "; let message = "Uncaught error: ";
if (string.includes("Cannot read property 'defaultView' of undefined")) { if (string.includes("Cannot read property 'defaultView' of undefined")) {
// ignore this specific error which is very common but we don't know where it comes from // ignore this specific error which is very common but we don't know where it comes from
// and it seems to be harmless // and it seems to be harmless
return true; return true;
} } else if (string.includes("script error")) {
else if (string.includes("script error")) { message += 'No details available';
message += 'No details available'; } else {
} message += [
else { 'Message: ' + msg,
message += [ 'URL: ' + url,
'Message: ' + msg, 'Line: ' + lineNo,
'URL: ' + url, 'Column: ' + columnNo,
'Line: ' + lineNo, 'Error object: ' + JSON.stringify(error)
'Column: ' + columnNo, ].join(' - ');
'Error object: ' + JSON.stringify(error) }
].join(' - ');
ws.logError(message);
return false;
};
protectedSessionHolder.setProtectedSessionId(null);
for (const appCssNoteId of glob.appCssNoteIds || []) {
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`);
} }
ws.logError(message); const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/";
return false; $(document).on("click", "button[data-help-page]", e => {
}; const $button = $(e.target);
protectedSessionHolder.setProtectedSessionId(null); window.open(wikiBaseUrl + $button.attr("data-help-page"), '_blank');
});
for (const appCssNoteId of glob.appCssNoteIds || []) { $("body").on("click", "a.external", function () {
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`); window.open($(this).attr("href"), '_blank');
});
} }
const wikiBaseUrl = "https://github.com/zadam/trilium/wiki/"; export default {
setupGlobs
$(document).on("click", "button[data-help-page]", e => { }
const $button = $(e.target);
window.open(wikiBaseUrl + $button.attr("data-help-page"), '_blank');
});
$("body").on("click", "a.external", function () {
window.open($(this).attr("href"), '_blank');
});
export default {}

View File

@ -35,7 +35,7 @@ async function getRenderedContent(note) {
$downloadButton.on('click', () => utils.download(getFileUrl())); $downloadButton.on('click', () => utils.download(getFileUrl()));
$openButton.on('click', () => { $openButton.on('click', () => {
if (utils.isElectron()) { if (utils.isElectron()) {
const open = require("open"); const open = utils.dynamicRequire("open");
open(getFileUrl(), {url: true}); open(getFileUrl(), {url: true});
} }

View File

@ -52,7 +52,7 @@ async function call(method, url, data, headers = {}) {
const start = Date.now(); const start = Date.now();
if (utils.isElectron()) { if (utils.isElectron()) {
const ipc = require('electron').ipcRenderer; const ipc = utils.dynamicRequire('electron').ipcRenderer;
const requestId = i++; const requestId = i++;
resp = await new Promise((resolve, reject) => { resp = await new Promise((resolve, reject) => {
@ -135,7 +135,7 @@ function ajax(url, method, data, headers) {
} }
if (utils.isElectron()) { if (utils.isElectron()) {
const ipc = require('electron').ipcRenderer; const ipc = utils.dynamicRequire('electron').ipcRenderer;
ipc.on('server-response', (event, arg) => { ipc.on('server-response', (event, arg) => {
if (REQUEST_LOGGING_ENABLED) { if (REQUEST_LOGGING_ENABLED) {

View File

@ -137,7 +137,7 @@ ws.subscribeToMessages(message => {
appContext.tabManager.activateOrOpenNote(message.noteId); appContext.tabManager.activateOrOpenNote(message.noteId);
if (utils.isElectron()) { if (utils.isElectron()) {
const currentWindow = require("electron").remote.getCurrentWindow(); const currentWindow = utils.dynamicRequire("electron").remote.getCurrentWindow();
currentWindow.show(); currentWindow.show();
} }

View File

@ -99,7 +99,7 @@ function download(url) {
url += '?' + Date.now(); // don't use cache url += '?' + Date.now(); // don't use cache
if (isElectron()) { if (isElectron()) {
const remote = require('electron').remote; const remote = utils.dynamicRequire('electron').remote;
remote.getCurrentWebContents().downloadURL(url); remote.getCurrentWebContents().downloadURL(url);
} }
@ -270,7 +270,7 @@ function isHtmlEmpty(html) {
async function clearBrowserCache() { async function clearBrowserCache() {
if (isElectron()) { if (isElectron()) {
const win = require('electron').remote.getCurrentWindow(); const win = utils.dynamicRequire('electron').remote.getCurrentWindow();
await win.webContents.session.clearCache(); await win.webContents.session.clearCache();
} }
} }
@ -300,6 +300,15 @@ function isCKEditorInitialized() {
return !!(window && window.cutToNote); return !!(window && window.cutToNote);
} }
function dynamicRequire(moduleName) {
if (typeof __non_webpack_require__ !== 'undefined') {
return __non_webpack_require__(moduleName);
}
else {
return require(moduleName);
}
}
export default { export default {
reloadApp, reloadApp,
parseDate, parseDate,
@ -337,5 +346,6 @@ export default {
getUrlForDownload, getUrlForDownload,
normalizeShortcut, normalizeShortcut,
copySelectionToClipboard, copySelectionToClipboard,
isCKEditorInitialized isCKEditorInitialized,
dynamicRequire
}; };

View File

@ -1,5 +1,6 @@
import options from "./options.js"; import options from "./options.js";
import Component from "../widgets/component.js"; import Component from "../widgets/component.js";
import utils from "../services/utils.js";
const MIN_ZOOM = 0.5; const MIN_ZOOM = 0.5;
const MAX_ZOOM = 2.0; const MAX_ZOOM = 2.0;
@ -14,7 +15,7 @@ export default class ZoomService extends Component {
setZoomFactor(zoomFactor) { setZoomFactor(zoomFactor) {
zoomFactor = parseFloat(zoomFactor); zoomFactor = parseFloat(zoomFactor);
const webFrame = require('electron').webFrame; const webFrame = utils.dynamicRequire('electron').webFrame;
webFrame.setZoomFactor(zoomFactor); webFrame.setZoomFactor(zoomFactor);
} }
@ -30,7 +31,7 @@ export default class ZoomService extends Component {
} }
getCurrentZoom() { getCurrentZoom() {
return require('electron').webFrame.getZoomFactor(); return utils.dynamicRequire('electron').webFrame.getZoomFactor();
} }
zoomOutEvent() { zoomOutEvent() {

View File

@ -133,7 +133,7 @@ async function checkOutstandingSyncs() {
const { stats, initialized } = await $.get('api/sync/stats'); const { stats, initialized } = await $.get('api/sync/stats');
if (initialized) { if (initialized) {
const remote = require('electron').remote; const remote = utils.dynamicRequire('electron').remote;
remote.app.relaunch(); remote.app.relaunch();
remote.app.exit(0); remote.app.exit(0);
} }

View File

@ -40,7 +40,7 @@ export default class HistoryNavigationWidget extends BasicWidget {
this.$forwardInHistory = this.$widget.find("[data-trigger-command='forwardInNoteHistory']"); this.$forwardInHistory = this.$widget.find("[data-trigger-command='forwardInNoteHistory']");
this.$forwardInHistory.on('contextmenu', contextMenuHandler); this.$forwardInHistory.on('contextmenu', contextMenuHandler);
const electron = require('electron'); const electron = utils.dynamicRequire('electron');
this.webContents = electron.remote.getCurrentWindow().webContents; this.webContents = electron.remote.getCurrentWindow().webContents;
// without this the history is preserved across frontend reloads // without this the history is preserved across frontend reloads

File diff suppressed because one or more lines are too long

View File

@ -30,13 +30,13 @@ export default class TitleBarButtonsWidget extends BasicWidget {
$minimizeBtn.on('click', () => { $minimizeBtn.on('click', () => {
$minimizeBtn.trigger('blur'); $minimizeBtn.trigger('blur');
const {remote} = require('electron'); const {remote} = utils.dynamicRequire('electron');
remote.BrowserWindow.getFocusedWindow().minimize(); remote.BrowserWindow.getFocusedWindow().minimize();
}); });
$maximizeBtn.on('click', () => { $maximizeBtn.on('click', () => {
$maximizeBtn.trigger('blur'); $maximizeBtn.trigger('blur');
const {remote} = require('electron'); const {remote} = utils.dynamicRequire('electron');
const focusedWindow = remote.BrowserWindow.getFocusedWindow(); const focusedWindow = remote.BrowserWindow.getFocusedWindow();
if (focusedWindow.isMaximized()) { if (focusedWindow.isMaximized()) {
@ -48,7 +48,7 @@ export default class TitleBarButtonsWidget extends BasicWidget {
$closeBtn.on('click', () => { $closeBtn.on('click', () => {
$closeBtn.trigger('blur'); $closeBtn.trigger('blur');
const {remote} = require('electron'); const {remote} = utils.dynamicRequire('electron');
remote.BrowserWindow.getFocusedWindow().close(); remote.BrowserWindow.getFocusedWindow().close();
}); });

View File

@ -122,7 +122,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
this.textEditor.model.document.on('change:data', () => this.spacedUpdate.scheduleUpdate()); this.textEditor.model.document.on('change:data', () => this.spacedUpdate.scheduleUpdate());
if (glob.isDev && ENABLE_INSPECTOR) { if (glob.isDev && ENABLE_INSPECTOR) {
await import('../../../libraries/ckeditor/inspector.js'); await import(/* webpackIgnore: true */'../../../libraries/ckeditor/inspector.js');
CKEditorInspector.attach(this.textEditor); CKEditorInspector.attach(this.textEditor);
} }
} }

View File

@ -55,7 +55,7 @@ export default class FileTypeWidget extends TypeWidget {
this.$openButton.on('click', () => { this.$openButton.on('click', () => {
if (utils.isElectron()) { if (utils.isElectron()) {
const open = require("open"); const open = utils.dynamicRequire("open");
open(this.getFileUrl(), {url: true}); open(this.getFileUrl(), {url: true});
} }

14
webpack-desktop.config.js Normal file
View File

@ -0,0 +1,14 @@
const path = require('path');
module.exports = {
mode: 'production',
entry: {
mobile: './src/public/javascripts/desktop.js',
},
output: {
publicPath: 'dist/',
path: path.resolve(__dirname, 'src/public/dist'),
filename: 'desktop.js'
},
devtool: 'source-map'
};

14
webpack-mobile.config.js Normal file
View File

@ -0,0 +1,14 @@
const path = require('path');
module.exports = {
mode: 'production',
entry: {
mobile: './src/public/javascripts/mobile.js',
},
output: {
publicPath: '/dist/',
path: path.resolve(__dirname, 'src/public/dist'),
filename: 'mobile.js'
},
devtool: 'source-map'
};