Repository URL to install this package:
Version:
3.1.7 ▾
|
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const InteropService_1 = require("@joplin/lib/services/interop/InteropService");
const CommandService_1 = require("@joplin/lib/services/CommandService");
const shim_1 = require("@joplin/lib/shim");
const types_1 = require("@joplin/lib/services/interop/types");
const locale_1 = require("@joplin/lib/locale");
const bridge_1 = require("./services/bridge");
const Setting_1 = require("@joplin/lib/models/Setting");
const Note_1 = require("@joplin/lib/models/Note");
const { friendlySafeFilename } = require('@joplin/lib/path-utils');
const time_1 = require("@joplin/lib/time");
const md5 = require('md5');
const url = require('url');
class InteropServiceHelper {
static exportNoteToHtmlFile(noteId, exportOptions) {
return __awaiter(this, void 0, void 0, function* () {
const tempFile = `${Setting_1.default.value('tempDir')}/${md5(Date.now() + Math.random())}.html`;
const fullExportOptions = Object.assign({ path: tempFile, format: types_1.ExportModuleOutputFormat.Html, target: types_1.FileSystemItem.File, sourceNoteIds: [noteId], customCss: '' }, exportOptions);
const service = InteropService_1.default.instance();
const result = yield service.export(fullExportOptions);
// eslint-disable-next-line no-console
console.info('Export HTML result: ', result);
return tempFile;
});
}
static exportNoteTo_(target, noteId, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
let win = null;
let htmlFile = null;
const cleanup = () => {
if (win)
win.destroy();
if (htmlFile)
void shim_1.default.fsDriver().remove(htmlFile);
};
try {
const exportOptions = {
customCss: options.customCss ? options.customCss : '',
plugins: options.plugins,
};
htmlFile = yield this.exportNoteToHtmlFile(noteId, exportOptions);
const windowOptions = {
show: false,
};
win = (0, bridge_1.default)().newBrowserWindow(windowOptions);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
return new Promise((resolve, reject) => {
win.webContents.on('did-finish-load', () => {
// did-finish-load will trigger when most assets are done loading, probably
// images, JavaScript and CSS. However it seems it might trigger *before*
// all fonts are loaded, which will break for example Katex rendering.
// So we need to add an additional timer to make sure fonts are loaded
// as it doesn't seem there's any easy way to figure that out.
shim_1.default.setTimeout(() => __awaiter(this, void 0, void 0, function* () {
if (target === 'pdf') {
try {
// The below line "opens" all <details> tags
// before printing. This assures that the
// contents of the tag are visible in printed
// pdfs.
// https://github.com/laurent22/joplin/issues/6254.
yield win.webContents.executeJavaScript('document.querySelectorAll(\'details\').forEach(el=>el.setAttribute(\'open\',\'\'))');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const data = yield win.webContents.printToPDF(options);
resolve(data);
}
catch (error) {
reject(error);
}
finally {
cleanup();
}
}
else {
// TODO: it is crashing at this point :( Appears to
// be a Chromium bug:
// https://github.com/electron/electron/issues/19946
// Maybe can be fixed by doing everything from main
// process? i.e. creating a function `print()` that
// takes the `htmlFile` variable as input.
//
// 2021-10-01: This old bug is fixed, and has been
// replaced by a brand new bug:
// https://github.com/electron/electron/issues/28192
// Still doesn't work but at least it doesn't crash
// the app.
//
// 2024-01-31: Printing with webContents.print still
// fails on Linux (even if run in the main process).
// As such, we use window.print(), which seems to work.
if (shim_1.default.isLinux()) {
yield win.webContents.executeJavaScript(`
// Blocks while the print dialog is open
window.print();
`);
shim_1.default.setTimeout(() => {
// To prevent a crash, the window can only be closed after a timeout.
// This timeout can't be too small, or else it may still crash (e.g. 100ms
// is too short).
//
// See https://github.com/electron/electron/issues/31635 for details
cleanup();
resolve(null);
}, 1000);
}
else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
win.webContents.print(options, (success, reason) => {
cleanup();
if (!success && reason !== 'cancelled')
reject(new Error(`Could not print: ${reason}`));
resolve(null);
});
}
}
}), 2000);
});
void win.loadURL(url.format({
pathname: htmlFile,
protocol: 'file:',
slashes: true,
}));
});
}
catch (error) {
cleanup();
throw error;
}
});
}
static exportNoteToPdf(noteId, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
return this.exportNoteTo_('pdf', noteId, options);
});
}
static printNote(noteId, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
return this.exportNoteTo_('printer', noteId, options);
});
}
static defaultFilename(noteId, fileExtension) {
return __awaiter(this, void 0, void 0, function* () {
// Default filename is just the date
const date = time_1.default.formatMsToLocal(new Date().getTime(), time_1.default.dateFormat());
let filename = friendlySafeFilename(`${date}`, 100);
if (noteId) {
const note = yield Note_1.default.load(noteId);
// In a rare case the passed note will be null, use the id for filename
filename = friendlySafeFilename(note ? note.title : noteId, 100);
}
return `${filename}.${fileExtension}`;
});
}
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
static export(_dispatch, module, options = null) {
return __awaiter(this, void 0, void 0, function* () {
if (!options)
options = {};
let path = null;
if (module.target === 'file') {
const noteId = options.sourceNoteIds && options.sourceNoteIds.length ? options.sourceNoteIds[0] : null;
path = yield (0, bridge_1.default)().showSaveDialog({
filters: [{ name: module.description, extensions: module.fileExtensions }],
defaultPath: yield this.defaultFilename(noteId, module.fileExtensions[0]),
});
}
else {
path = yield (0, bridge_1.default)().showOpenDialog({
properties: ['openDirectory', 'createDirectory'],
});
}
if (!path || (Array.isArray(path) && !path.length))
return;
if (Array.isArray(path))
path = path[0];
void CommandService_1.default.instance().execute('showModalMessage', (0, locale_1._)('Exporting to "%s" as "%s" format. Please wait...', path, module.format));
const exportOptions = {};
exportOptions.path = path;
exportOptions.format = module.format;
// exportOptions.modulePath = module.path;
if (options.plugins)
exportOptions.plugins = options.plugins;
exportOptions.customCss = options.customCss;
exportOptions.target = module.target;
exportOptions.includeConflicts = !!options.includeConflicts;
if (options.sourceFolderIds)
exportOptions.sourceFolderIds = options.sourceFolderIds;
if (options.sourceNoteIds)
exportOptions.sourceNoteIds = options.sourceNoteIds;
const service = InteropService_1.default.instance();
try {
const result = yield service.export(exportOptions);
// eslint-disable-next-line no-console
console.info('Export result: ', result);
}
catch (error) {
console.error(error);
(0, bridge_1.default)().showErrorMessageBox((0, locale_1._)('Could not export notes: %s', error.message));
}
void CommandService_1.default.instance().execute('hideModalMessage');
});
}
}
exports.default = InteropServiceHelper;
//# sourceMappingURL=InteropServiceHelper.js.map