use trilium version number in asset paths to avoid caching issues WIP

pull/255/head
zadam 2022-10-26 23:50:54 +07:00
parent 441a59305b
commit b499640db8
28 changed files with 124 additions and 83 deletions

@ -2,7 +2,7 @@ image:
file: .gitpod.dockerfile file: .gitpod.dockerfile
tasks: tasks:
- before: nvm install 16.15.0 && nvm use 16.15.0 - before: nvm install 16.18.0 && nvm use 16.18.0
init: npm install init: npm install
command: npm run start-server command: npm run start-server

@ -1,5 +1,5 @@
# !!! Don't try to build this Dockerfile directly, run it through bin/build-docker.sh script !!! # !!! Don't try to build this Dockerfile directly, run it through bin/build-docker.sh script !!!
FROM node:16.15.0-alpine FROM node:16.18.0-alpine
# Create app directory # Create app directory
WORKDIR /usr/src/app WORKDIR /usr/src/app

@ -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=16.15.0 NODE_VERSION=16.18.0
if [ "$1" != "DONTCOPY" ] if [ "$1" != "DONTCOPY" ]
then then

@ -5,7 +5,7 @@ if [[ $# -eq 0 ]] ; then
exit 1 exit 1
fi fi
n exec 16.15.0 npm run webpack n exec 16.18.0 npm run webpack
DIR=$1 DIR=$1
@ -30,7 +30,7 @@ cp -r electron.js $DIR/
cp webpack-* $DIR/ cp webpack-* $DIR/
# run in subshell (so we return to original dir) # run in subshell (so we return to original dir)
(cd $DIR && n exec 16.15.0 npm install --only=prod) (cd $DIR && n exec 16.18.0 npm install --only=prod)
# cleanup of useless files in dependencies # cleanup of useless files in dependencies
rm -r $DIR/node_modules/image-q/demo rm -r $DIR/node_modules/image-q/demo

@ -6,7 +6,7 @@ It is meant as a last resort solution when the standard mean to access your data
## Installation ## Installation
This tool requires node.js, testing has been done on 16.15.0, but it will probably work on other versions as well. This tool requires node.js, testing has been done on 16.18.0, but it will probably work on other versions as well.
``` ```
npm install npm install

4
package-lock.json generated

@ -1,12 +1,12 @@
{ {
"name": "trilium", "name": "trilium",
"version": "0.56.0-beta", "version": "0.56.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "trilium", "name": "trilium",
"version": "0.56.0-beta", "version": "0.56.1",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"dependencies": { "dependencies": {

@ -4,7 +4,7 @@ const Branch = require('../../src/becca/entities/branch');
const SearchContext = require('../../src/services/search/search_context'); const SearchContext = require('../../src/services/search/search_context');
const dateUtils = require('../../src/services/date_utils'); const dateUtils = require('../../src/services/date_utils');
const becca = require('../../src/becca/becca'); const becca = require('../../src/becca/becca');
const {NoteBuilder, findNoteByTitle, note} = require('./note_cache_mocking'); const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
describe("Search", () => { describe("Search", () => {
let rootNote; let rootNote;

@ -1,4 +1,4 @@
const {note} = require('./note_cache_mocking'); const {note} = require('./becca_mocking.js');
const ValueExtractor = require('../../src/services/search/value_extractor'); const ValueExtractor = require('../../src/services/search/value_extractor');
const becca = require('../../src/becca/becca'); const becca = require('../../src/becca/becca');
const SearchContext = require("../../src/services/search/search_context"); const SearchContext = require("../../src/services/search/search_context");

@ -10,6 +10,7 @@ const FileStore = require('session-file-store')(session);
const sessionSecret = require('./services/session_secret'); const sessionSecret = require('./services/session_secret');
const dataDir = require('./services/data_dir'); const dataDir = require('./services/data_dir');
const utils = require('./services/utils'); const utils = require('./services/utils');
const assetPath = require('./services/asset_path');
require('./services/handlers'); require('./services/handlers');
require('./becca/becca_loader'); require('./becca/becca_loader');
@ -34,14 +35,19 @@ app.use(express.json({limit: '500mb'}));
app.use(express.raw({limit: '500mb'})); app.use(express.raw({limit: '500mb'}));
app.use(express.urlencoded({extended: false})); app.use(express.urlencoded({extended: false}));
app.use(cookieParser()); app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public/root')));
app.use('/libraries', express.static(path.join(__dirname, '..', 'libraries'))); app.use(`/${assetPath}/app`, express.static(path.join(__dirname, 'public/app')));
app.use(`/${assetPath}/app-dist`, express.static(path.join(__dirname, 'public/app-dist')));
app.use(`/${assetPath}/fonts`, express.static(path.join(__dirname, 'public/fonts')));
app.use(`/${assetPath}/stylesheets`, express.static(path.join(__dirname, 'public/stylesheets')));
app.use(`/${assetPath}/libraries`, express.static(path.join(__dirname, '..', 'libraries')));
// excalidraw-view mode in shared notes // excalidraw-view mode in shared notes
app.use('/node_modules/react/umd/react.production.min.js', express.static(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js'))); app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js')));
app.use('/node_modules/react-dom/umd/react-dom.production.min.js', express.static(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js'))); app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js')));
// expose whole dist folder since complete assets are needed in edit and share // expose whole dist folder since complete assets are needed in edit and share
app.use('/node_modules/@excalidraw/excalidraw/dist/', express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/'))); app.use(`/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
app.use('/images', express.static(path.join(__dirname, '..', 'images'))); app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
app.use(`/${assetPath}/images`, express.static(path.join(__dirname, '..', 'images')));
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.

@ -64,7 +64,7 @@ function setupGlobs() {
}; };
for (const appCssNoteId of glob.appCssNoteIds || []) { for (const appCssNoteId of glob.appCssNoteIds || []) {
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`); libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`, false);
} }
utils.initHelpButtons($(window)); utils.initHelpButtons($(window));

@ -86,6 +86,8 @@ async function requireLibrary(library) {
const loadedScriptPromises = {}; const loadedScriptPromises = {};
async function requireScript(url) { async function requireScript(url) {
url = window.glob.assetPath + "/" + url;
if (!loadedScriptPromises[url]) { if (!loadedScriptPromises[url]) {
loadedScriptPromises[url] = $.ajax({ loadedScriptPromises[url] = $.ajax({
url: url, url: url,
@ -97,12 +99,16 @@ async function requireScript(url) {
await loadedScriptPromises[url]; await loadedScriptPromises[url];
} }
async function requireCss(url) { async function requireCss(url, prependAssetPath = true) {
const cssLinks = Array const cssLinks = Array
.from(document.querySelectorAll('link')) .from(document.querySelectorAll('link'))
.map(el => el.href); .map(el => el.href);
if (!cssLinks.some(l => l.endsWith(url))) { if (!cssLinks.some(l => l.endsWith(url))) {
if (prependAssetPath) {
url = window.glob.assetPath + "/" + url;
}
$('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', url)); $('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', url));
} }
} }

@ -16,7 +16,7 @@ const TPL = `
} }
.global-menu-button { .global-menu-button {
background-image: url("images/icon-black.png"); background-image: url("${window.glob.assetPath}/images/icon-black.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 50% 45%; background-position: 50% 45%;
width: 100%; width: 100%;
@ -26,7 +26,7 @@ const TPL = `
} }
.global-menu-button:hover { .global-menu-button:hover {
background-image: url("images/icon-color.png"); background-image: url("${window.glob.assetPath}/images/icon-color.png");
} }
.global-menu-button-update-available { .global-menu-button-update-available {

@ -237,15 +237,17 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
$promotedAttributes = (await attributeRenderer.renderNormalAttributes(this.note)).$renderedAttributes; $promotedAttributes = (await attributeRenderer.renderNormalAttributes(this.note)).$renderedAttributes;
} }
const {assetPath} = window.glob;
this.$widget.find('.note-detail-printable:visible').printThis({ this.$widget.find('.note-detail-printable:visible').printThis({
header: $("<div>") header: $("<div>")
.append($("<h2>").text(this.note.title)) .append($("<h2>").text(this.note.title))
.append($promotedAttributes) .append($promotedAttributes)
.prop('outerHTML'), .prop('outerHTML'),
footer: ` footer: `
<script src="libraries/katex/katex.min.js"></script> <script src="${assetPath}/libraries/katex/katex.min.js"></script>
<script src="libraries/katex/mhchem.min.js"></script> <script src="${assetPath}/libraries/katex/mhchem.min.js"></script>
<script src="libraries/katex/auto-render.min.js"></script> <script src="${assetPath}/libraries/katex/auto-render.min.js"></script>
<script> <script>
document.body.className += ' ck-content printed-content'; document.body.className += ' ck-content printed-content';
@ -254,13 +256,13 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
`, `,
importCSS: false, importCSS: false,
loadCSS: [ loadCSS: [
"libraries/codemirror/codemirror.css", assetPath + "/libraries/codemirror/codemirror.css",
"libraries/ckeditor/ckeditor-content.css", assetPath + "/libraries/ckeditor/ckeditor-content.css",
"libraries/bootstrap/css/bootstrap.min.css", assetPath + "/libraries/bootstrap/css/bootstrap.min.css",
"libraries/katex/katex.min.css", assetPath + "/libraries/katex/katex.min.css",
"stylesheets/print.css", assetPath + "/stylesheets/print.css",
"stylesheets/relation_map.css", assetPath + "/stylesheets/relation_map.css",
"stylesheets/ckeditor-theme.css" assetPath + "/stylesheets/ckeditor-theme.css"
], ],
debug: true debug: true
}); });

@ -9,6 +9,7 @@ const env = require('../services/env');
const utils = require('../services/utils'); const utils = require('../services/utils');
const protectedSessionService = require("../services/protected_session"); const protectedSessionService = require("../services/protected_session");
const packageJson = require('../../package.json'); const packageJson = require('../../package.json');
const assetPath = require("../services/asset_path");
function index(req, res) { function index(req, res) {
const options = optionService.getOptionsMap(); const options = optionService.getOptionsMap();
@ -36,7 +37,8 @@ function index(req, res) {
extraHoistedNoteId: req.query.extraHoistedNoteId, extraHoistedNoteId: req.query.extraHoistedNoteId,
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(), isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
maxContentWidth: parseInt(options.maxContentWidth), maxContentWidth: parseInt(options.maxContentWidth),
triliumVersion: packageJson.version triliumVersion: packageJson.version,
assetPath: assetPath
}); });
} }
@ -46,7 +48,7 @@ function getThemeCssUrl(theme) {
} }
if (theme === 'dark') { if (theme === 'dark') {
return `stylesheets/theme-dark.css`; return `${assetPath}/stylesheets/theme-dark.css`;
} }
else { else {
const themeNote = attributeService.getNoteWithLabel('appTheme', theme); const themeNote = attributeService.getNoteWithLabel('appTheme', theme);

@ -5,13 +5,20 @@ const optionService = require('../services/options');
const myScryptService = require('../services/my_scrypt'); const myScryptService = require('../services/my_scrypt');
const log = require('../services/log'); const log = require('../services/log');
const passwordService = require("../services/password"); const passwordService = require("../services/password");
const assetPath = require("../services/asset_path");
function loginPage(req, res) { function loginPage(req, res) {
res.render('login', { failedAuth: false }); res.render('login', {
failedAuth: false,
assetPath: assetPath
});
} }
function setPasswordPage(req, res) { function setPasswordPage(req, res) {
res.render('set_password', { error: false }); res.render('set_password', {
error: false,
assetPath: assetPath
});
} }
function setPassword(req, res) { function setPassword(req, res) {
@ -32,7 +39,10 @@ function setPassword(req, res) {
} }
if (error) { if (error) {
res.render('set_password', { error }); res.render('set_password', {
error,
assetPath: assetPath
});
return; return;
} }
@ -62,7 +72,10 @@ function login(req, res) {
// note that logged IP address is usually meaningless since the traffic should come from a reverse proxy // note that logged IP address is usually meaningless since the traffic should come from a reverse proxy
log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`); log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`);
res.render('login', {'failedAuth': true}); res.render('login', {
failedAuth: true,
assetPath: assetPath
});
} }
} }

@ -3,6 +3,7 @@
const sqlInit = require('../services/sql_init'); const sqlInit = require('../services/sql_init');
const setupService = require('../services/setup'); const setupService = require('../services/setup');
const utils = require('../services/utils'); const utils = require('../services/utils');
const assetPath = require("../services/asset_path");
function setupPage(req, res) { function setupPage(req, res) {
if (sqlInit.isDbInitialized()) { if (sqlInit.isDbInitialized()) {
@ -28,7 +29,8 @@ function setupPage(req, res) {
} }
res.render('setup', { res.render('setup', {
syncInProgress: syncInProgress syncInProgress: syncInProgress,
assetPath: assetPath
}); });
} }

@ -0,0 +1,3 @@
const packageJson = require('../../package.json');
module.exports = "assets/v" + packageJson.version;

@ -6,6 +6,7 @@ const shaca = require("./shaca/shaca");
const shacaLoader = require("./shaca/shaca_loader"); const shacaLoader = require("./shaca/shaca_loader");
const shareRoot = require("./share_root"); const shareRoot = require("./share_root");
const contentRenderer = require("./content_renderer"); const contentRenderer = require("./content_renderer");
const assetPath = require("../services/asset_path");
function getSharedSubTreeRoot(note) { function getSharedSubTreeRoot(note) {
if (note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) { if (note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
@ -103,7 +104,8 @@ function register(router) {
header, header,
content, content,
isEmpty, isEmpty,
subRoot subRoot,
assetPath
}); });
} }

@ -34,7 +34,8 @@
isMainWindow: <%= isMainWindow %>, isMainWindow: <%= isMainWindow %>,
extraHoistedNoteId: '<%= extraHoistedNoteId %>', extraHoistedNoteId: '<%= extraHoistedNoteId %>',
isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>, isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>,
triliumVersion: "<%= triliumVersion %>" triliumVersion: "<%= triliumVersion %>",
assetPath: "<%= assetPath %>"
}; };
</script> </script>
@ -47,40 +48,40 @@
<!-- Required for correct loading of scripts in Electron --> <!-- Required for correct loading of scripts in Electron -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="libraries/jquery.min.js"></script> <script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script> <script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Include Fancytree library and skip --> <!-- Include Fancytree library and skip -->
<link href="stylesheets/tree.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/tree.css" rel="stylesheet">
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script> <script src="<%= assetPath %>/libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<script src="libraries/jquery.hotkeys.js"></script> <script src="<%= assetPath %>/libraries/jquery.hotkeys.js"></script>
<script src="libraries/autocomplete.jquery.min.js"></script> <script src="<%= assetPath %>/libraries/autocomplete.jquery.min.js"></script>
<script src="libraries/dayjs.min.js"></script> <script src="<%= assetPath %>/libraries/dayjs.min.js"></script>
<script src="libraries/split.min.js"></script> <script src="<%= assetPath %>/libraries/split.min.js"></script>
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="api/fonts" rel="stylesheet"> <link href="api/fonts" rel="stylesheet">
<link href="stylesheets/theme-light.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
<% if (themeCssUrl) { %> <% if (themeCssUrl) { %>
<link href="<%= themeCssUrl %>" rel="stylesheet"> <link href="<%= themeCssUrl %>" rel="stylesheet">
<% } %> <% } %>
<link href="stylesheets/style.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
<script> <script>
$("body").show(); $("body").show();
</script> </script>
<script src="app/desktop.js" crossorigin type="module"></script> <script src="<%= assetPath %>/app/desktop.js" crossorigin type="module"></script>
<link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css"> <link rel="stylesheet" type="text/css" href="<%= assetPath %>/libraries/boxicons/css/boxicons.min.css">
</body> </body>
</html> </html>

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Login</title> <title>Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="images/app-icons/ios/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="<%= assetPath %>/images/app-icons/ios/apple-touch-icon.png">
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
</head> </head>
<body> <body>
@ -68,6 +68,6 @@
} }
</script> </script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</body> </body>
</html> </html>

@ -115,31 +115,32 @@
csrfToken: '<%= csrfToken %>', csrfToken: '<%= csrfToken %>',
isDev: <%= isDev %>, isDev: <%= isDev %>,
appCssNoteIds: <%- JSON.stringify(appCssNoteIds) %>, appCssNoteIds: <%- JSON.stringify(appCssNoteIds) %>,
isProtectedSessionAvailable: <%= isProtectedSessionAvailable %> isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>,
assetPath: "<%= assetPath %>"
}; };
</script> </script>
<script src="libraries/jquery.min.js"></script> <script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<script src="libraries/dayjs.min.js"></script> <script src="<%= assetPath %>/libraries/dayjs.min.js"></script>
<link href="stylesheets/tree.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/tree.css" rel="stylesheet">
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script> <script src="<%= assetPath %>/libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script> <script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="app/mobile.js" crossorigin type="module"></script> <script src="<%= assetPath %>/app/mobile.js" crossorigin type="module"></script>
<link href="api/fonts" rel="stylesheet"> <link href="api/fonts" rel="stylesheet">
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="stylesheets/theme-light.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
<% if (themeCssUrl) { %> <% if (themeCssUrl) { %>
<link href="<%= themeCssUrl %>" rel="stylesheet"> <link href="<%= themeCssUrl %>" rel="stylesheet">
<% } %> <% } %>
<link href="stylesheets/style.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css"> <link rel="stylesheet" type="text/css" href="<%= assetPath %>/libraries/boxicons/css/boxicons.min.css">
</body> </body>
</html> </html>

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Login</title> <title>Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="images/app-icons/ios/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="<%= assetPath %>/images/app-icons/ios/apple-touch-icon.png">
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
</head> </head>
<body> <body>
@ -46,6 +46,6 @@
if (typeof module === 'object') {window.module = module; module = undefined;} if (typeof module === 'object') {window.module = module; module = undefined;}
</script> </script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</body> </body>
</html> </html>

@ -153,15 +153,15 @@
<!-- Required for correct loading of scripts in Electron --> <!-- Required for correct loading of scripts in Electron -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="libraries/jquery.min.js"></script> <script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<script src="libraries/jquery.hotkeys.js"></script> <script src="<%= assetPath %>/libraries/jquery.hotkeys.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script> <script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="libraries/knockout.min.js"></script> <script src="<%= assetPath %>/libraries/knockout.min.js"></script>
<script src="app/setup.js" crossorigin type="module"></script> <script src="<%= assetPath %>/app/setup.js" crossorigin type="module"></script>
<link href="stylesheets/theme-light.css" rel="stylesheet"> <link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
</body> </body>
</html> </html>

@ -12,13 +12,13 @@
<% } else { %> <% } else { %>
<link rel="shortcut icon" href="../favicon.ico"> <link rel="shortcut icon" href="../favicon.ico">
<% } %> <% } %>
<script src="../app/share.js"></script> <script src="../<%= assetPath %>/app/share.js"></script>
<% if (!note.hasLabel("shareOmitDefaultCss")) { %> <% if (!note.hasLabel("shareOmitDefaultCss")) { %>
<link href="../libraries/normalize.min.css" rel="stylesheet"> <link href="../<%= assetPath %>/libraries/normalize.min.css" rel="stylesheet">
<link href="../stylesheets/share.css" rel="stylesheet"> <link href="../<%= assetPath %>/stylesheets/share.css" rel="stylesheet">
<% } %> <% } %>
<% if (note.type === 'text' || note.type === 'book') { %> <% if (note.type === 'text' || note.type === 'book') { %>
<link href="../libraries/ckeditor/ckeditor-content.css" rel="stylesheet"> <link href="../<%= assetPath %>/libraries/ckeditor/ckeditor-content.css" rel="stylesheet">
<% } %> <% } %>
<% for (const cssRelation of note.getRelations("shareCss")) { %> <% for (const cssRelation of note.getRelations("shareCss")) { %>
<link href="api/notes/<%= cssRelation.value %>/download" rel="stylesheet"> <link href="api/notes/<%= cssRelation.value %>/download" rel="stylesheet">

@ -1,4 +1,5 @@
const path = require('path'); const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = { module.exports = {
mode: 'production', mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/desktop.js', mobile: './src/public/app/desktop.js',
}, },
output: { output: {
publicPath: 'app-dist/', publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'), path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'desktop.js' filename: 'desktop.js'
}, },

@ -1,4 +1,5 @@
const path = require('path'); const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = { module.exports = {
mode: 'production', mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/mobile.js', mobile: './src/public/app/mobile.js',
}, },
output: { output: {
publicPath: 'app-dist/', publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'), path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'mobile.js' filename: 'mobile.js'
}, },

@ -1,4 +1,5 @@
const path = require('path'); const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = { module.exports = {
mode: 'production', mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/setup.js', mobile: './src/public/app/setup.js',
}, },
output: { output: {
publicPath: 'app-dist/', publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'), path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'setup.js' filename: 'setup.js'
}, },