mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Chore: Apply eslint rules
This commit is contained in:
parent
ab29d7e872
commit
e648392330
@ -28,7 +28,7 @@ class ResourceServer {
|
||||
|
||||
baseUrl() {
|
||||
if (!this.port_) return '';
|
||||
return 'http://127.0.0.1:' + this.port_;
|
||||
return `http://127.0.0.1:${this.port_}`;
|
||||
}
|
||||
|
||||
setLinkHandler(handler) {
|
||||
@ -53,7 +53,7 @@ class ResourceServer {
|
||||
const url = urlParser.parse(request.url, true);
|
||||
let resourceId = url.pathname.split('/');
|
||||
if (resourceId.length < 2) {
|
||||
writeResponse('Error: could not get resource ID from path name: ' + url.pathname);
|
||||
writeResponse(`Error: could not get resource ID from path name: ${url.pathname}`);
|
||||
return;
|
||||
}
|
||||
resourceId = resourceId[1];
|
||||
@ -62,7 +62,7 @@ class ResourceServer {
|
||||
|
||||
try {
|
||||
const done = await this.linkHandler_(resourceId, response);
|
||||
if (!done) throw new Error('Unhandled resource: ' + resourceId);
|
||||
if (!done) throw new Error(`Unhandled resource: ${resourceId}`);
|
||||
} catch (error) {
|
||||
response.setHeader('Content-Type', 'text/plain');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
|
@ -288,7 +288,7 @@ class AppGui {
|
||||
if (!cmd) return;
|
||||
const isConfigPassword = cmd.indexOf('config ') >= 0 && cmd.indexOf('password') >= 0;
|
||||
if (isConfigPassword) return;
|
||||
this.stdout(chalk.cyan.bold('> ' + cmd));
|
||||
this.stdout(chalk.cyan.bold(`> ${cmd}`));
|
||||
}
|
||||
|
||||
setupKeymap(keymap) {
|
||||
@ -297,7 +297,7 @@ class AppGui {
|
||||
for (let i = 0; i < keymap.length; i++) {
|
||||
const item = Object.assign({}, keymap[i]);
|
||||
|
||||
if (!item.command) throw new Error('Missing command for keymap item: ' + JSON.stringify(item));
|
||||
if (!item.command) throw new Error(`Missing command for keymap item: ${JSON.stringify(item)}`);
|
||||
|
||||
if (!('type' in item)) item.type = 'exec';
|
||||
|
||||
@ -440,7 +440,7 @@ class AppGui {
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ === BaseModel.TYPE_FOLDER) {
|
||||
await this.processPromptCommand('rmbook ' + item.id);
|
||||
await this.processPromptCommand(`rmbook ${item.id}`);
|
||||
} else if (item.type_ === BaseModel.TYPE_TAG) {
|
||||
this.stdout(_('To delete a tag, untag the associated notes.'));
|
||||
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
|
||||
@ -473,7 +473,7 @@ class AppGui {
|
||||
this.addCommandToConsole(cmd);
|
||||
await this.processPromptCommand(cmd);
|
||||
} else {
|
||||
throw new Error('Unknown command: ' + cmd);
|
||||
throw new Error(`Unknown command: ${cmd}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,7 +593,7 @@ class AppGui {
|
||||
if (!s) return false;
|
||||
s = s.trim().toLowerCase();
|
||||
for (let i = 0; i < protocols.length; i++) {
|
||||
if (s.indexOf(protocols[i] + '://') === 0) return true;
|
||||
if (s.indexOf(`${protocols[i]}://`) === 0) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@ -627,7 +627,7 @@ class AppGui {
|
||||
if (link.type === 'item') {
|
||||
const itemId = link.id;
|
||||
let item = await BaseItem.loadItemById(itemId);
|
||||
if (!item) throw new Error('No item with ID ' + itemId); // Should be nearly impossible
|
||||
if (!item) throw new Error(`No item with ID ${itemId}`); // Should be nearly impossible
|
||||
|
||||
if (item.type_ === BaseModel.TYPE_RESOURCE) {
|
||||
if (item.mime) response.setHeader('Content-Type', item.mime);
|
||||
@ -640,11 +640,11 @@ class AppGui {
|
||||
<head><meta charset="UTF-8"/></head><body>
|
||||
`,
|
||||
];
|
||||
html.push('<pre>' + htmlentities(item.title) + '\n\n' + htmlentities(item.body) + '</pre>');
|
||||
html.push(`<pre>${htmlentities(item.title)}\n\n${htmlentities(item.body)}</pre>`);
|
||||
html.push('</body></html>');
|
||||
response.write(html.join(''));
|
||||
} else {
|
||||
throw new Error('Unsupported item type: ' + item.type_);
|
||||
throw new Error(`Unsupported item type: ${item.type_}`);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -676,7 +676,7 @@ class AppGui {
|
||||
return url;
|
||||
}
|
||||
|
||||
return linkStyle(this.resourceServer_.baseUrl() + '/' + index);
|
||||
return linkStyle(`${this.resourceServer_.baseUrl()}/${index}`);
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -777,7 +777,7 @@ class AppGui {
|
||||
} else if (keymapItem.type === 'tkwidgets') {
|
||||
this.widget('root').handleKey(this.tkWidgetKeys_[keymapItem.command]);
|
||||
} else {
|
||||
throw new Error('Unknown command type: ' + JSON.stringify(keymapItem));
|
||||
throw new Error(`Unknown command type: ${JSON.stringify(keymapItem)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,10 +136,10 @@ class Application extends BaseApplication {
|
||||
if (!options.answers) options.answers = options.booleanAnswerDefault === 'y' ? [_('Y'), _('n')] : [_('N'), _('y')];
|
||||
|
||||
if (options.type == 'boolean') {
|
||||
message += ' (' + options.answers.join('/') + ')';
|
||||
message += ` (${options.answers.join('/')})`;
|
||||
}
|
||||
|
||||
let answer = await this.gui().prompt('', message + ' ', options);
|
||||
let answer = await this.gui().prompt('', `${message} `, options);
|
||||
|
||||
if (options.type === 'boolean') {
|
||||
if (answer === null) return false; // Pressed ESCAPE
|
||||
@ -181,7 +181,7 @@ class Application extends BaseApplication {
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
|
||||
let CommandClass = require('./' + path);
|
||||
let CommandClass = require(`./${path}`);
|
||||
let cmd = new CommandClass();
|
||||
if (!cmd.enabled()) return;
|
||||
cmd = this.setupCommand(cmd);
|
||||
@ -248,7 +248,7 @@ class Application extends BaseApplication {
|
||||
|
||||
let CommandClass = null;
|
||||
try {
|
||||
CommandClass = require(__dirname + '/command-' + name + '.js');
|
||||
CommandClass = require(`${__dirname}/command-${name}.js`);
|
||||
} catch (error) {
|
||||
if (error.message && error.message.indexOf('Cannot find module') >= 0) {
|
||||
let e = new Error(_('No such command: %s', name));
|
||||
@ -343,7 +343,7 @@ class Application extends BaseApplication {
|
||||
itemsByCommand[defaultKeyMap[i].command] = defaultKeyMap[i];
|
||||
}
|
||||
|
||||
const filePath = Setting.value('profileDir') + '/keymap.json';
|
||||
const filePath = `${Setting.value('profileDir')}/keymap.json`;
|
||||
if (await fs.pathExists(filePath)) {
|
||||
try {
|
||||
let configString = await fs.readFile(filePath, 'utf-8');
|
||||
@ -355,7 +355,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = 'Could not load keymap ' + filePath + '\n' + msg;
|
||||
msg = `Could not load keymap ${filePath}\n${msg}`;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ async function handleAutocompletionPromise(line) {
|
||||
if (names.indexOf(words[0]) === -1) {
|
||||
let x = names.filter(n => n.indexOf(words[0]) === 0);
|
||||
if (x.length === 1) {
|
||||
return x[0] + ' ';
|
||||
return `${x[0]} `;
|
||||
}
|
||||
return x.length > 0 ? x.map(a => a + ' ') : line;
|
||||
return x.length > 0 ? x.map(a => `${a} `) : line;
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
@ -56,7 +56,7 @@ async function handleAutocompletionPromise(line) {
|
||||
return line;
|
||||
}
|
||||
let ret = l.map(a => toCommandLine(a));
|
||||
ret.prefix = toCommandLine(words.slice(0, -1)) + ' ';
|
||||
ret.prefix = `${toCommandLine(words.slice(0, -1))} `;
|
||||
return ret;
|
||||
}
|
||||
//Complete an argument
|
||||
@ -74,23 +74,23 @@ async function handleAutocompletionPromise(line) {
|
||||
const currentFolder = app().currentFolder();
|
||||
|
||||
if (argName == 'note' || argName == 'note-pattern') {
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: next + '*' }) : [];
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
|
||||
l.push(...notes.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'notebook') {
|
||||
const folders = await Folder.search({ titlePattern: next + '*' });
|
||||
const folders = await Folder.search({ titlePattern: `${next}*` });
|
||||
l.push(...folders.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'item') {
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: next + '*' }) : [];
|
||||
const folders = await Folder.search({ titlePattern: next + '*' });
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
|
||||
const folders = await Folder.search({ titlePattern: `${next}*` });
|
||||
l.push(...notes.map(n => n.title), folders.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'tag') {
|
||||
let tags = await Tag.search({ titlePattern: next + '*' });
|
||||
let tags = await Tag.search({ titlePattern: `${next}*` });
|
||||
l.push(...tags.map(n => n.title));
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ async function handleAutocompletionPromise(line) {
|
||||
return toCommandLine([...words.slice(0, -1), l[0]]);
|
||||
} else if (l.length > 1) {
|
||||
let ret = l.map(a => toCommandLine(a));
|
||||
ret.prefix = toCommandLine(words.slice(0, -1)) + ' ';
|
||||
ret.prefix = `${toCommandLine(words.slice(0, -1))} `;
|
||||
return ret;
|
||||
}
|
||||
return line;
|
||||
@ -128,9 +128,9 @@ function toCommandLine(args) {
|
||||
return args
|
||||
.map(function(a) {
|
||||
if (a.indexOf('"') !== -1 || a.indexOf(' ') !== -1) {
|
||||
return '\'' + a + '\'';
|
||||
return `'${a}'`;
|
||||
} else if (a.indexOf('\'') !== -1) {
|
||||
return '"' + a + '"';
|
||||
return `"${a}"`;
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
@ -138,11 +138,11 @@ function toCommandLine(args) {
|
||||
.join(' ');
|
||||
} else {
|
||||
if (args.indexOf('"') !== -1 || args.indexOf(' ') !== -1) {
|
||||
return '\'' + args + '\' ';
|
||||
return `'${args}' `;
|
||||
} else if (args.indexOf('\'') !== -1) {
|
||||
return '"' + args + '" ';
|
||||
return `"${args}" `;
|
||||
} else {
|
||||
return args + ' ';
|
||||
return `${args} `;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ function getCommands() {
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
|
||||
let CommandClass = require('./' + path);
|
||||
let CommandClass = require(`./${path}`);
|
||||
let cmd = new CommandClass();
|
||||
if (!cmd.enabled()) return;
|
||||
if (cmd.hidden()) return;
|
||||
@ -102,14 +102,14 @@ function getFooter() {
|
||||
|
||||
output.push('WEBSITE');
|
||||
output.push('');
|
||||
output.push(INDENT + 'https://joplinapp.org');
|
||||
output.push(`${INDENT}https://joplinapp.org`);
|
||||
|
||||
output.push('');
|
||||
|
||||
output.push('LICENSE');
|
||||
output.push('');
|
||||
let filePath = rootDir + '/LICENSE_' + languageCode();
|
||||
if (!fs.existsSync(filePath)) filePath = rootDir + '/LICENSE';
|
||||
let filePath = `${rootDir}/LICENSE_${languageCode()}`;
|
||||
if (!fs.existsSync(filePath)) filePath = `${rootDir}/LICENSE`;
|
||||
const licenseText = fs.readFileSync(filePath, 'utf8');
|
||||
output.push(wrap(licenseText, INDENT));
|
||||
|
||||
@ -131,7 +131,7 @@ async function main() {
|
||||
const commandsText = commandBlocks.join('\n\n');
|
||||
const footerText = getFooter();
|
||||
|
||||
console.info(headerText + '\n\n' + 'USAGE' + '\n\n' + commandsText + '\n\n' + footerText);
|
||||
console.info(`${headerText}\n\n` + 'USAGE' + `\n\n${commandsText}\n\n${footerText}`);
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
|
@ -16,8 +16,8 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
console.error('Unhandled promise rejection', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
const baseDir = dirname(__dirname) + '/tests/cli-integration';
|
||||
const joplinAppPath = __dirname + '/main.js';
|
||||
const baseDir = `${dirname(__dirname)}/tests/cli-integration`;
|
||||
const joplinAppPath = `${__dirname}/main.js`;
|
||||
|
||||
const logger = new Logger();
|
||||
logger.addTarget('console');
|
||||
@ -33,16 +33,16 @@ db.setLogger(dbLogger);
|
||||
function createClient(id) {
|
||||
return {
|
||||
id: id,
|
||||
profileDir: baseDir + '/client' + id,
|
||||
profileDir: `${baseDir}/client${id}`,
|
||||
};
|
||||
}
|
||||
|
||||
const client = createClient(1);
|
||||
|
||||
function execCommand(client, command) {
|
||||
let exePath = 'node ' + joplinAppPath;
|
||||
let cmd = exePath + ' --update-geolocation-disabled --env dev --profile ' + client.profileDir + ' ' + command;
|
||||
logger.info(client.id + ': ' + command);
|
||||
let exePath = `node ${joplinAppPath}`;
|
||||
let cmd = `${exePath} --update-geolocation-disabled --env dev --profile ${client.profileDir} ${command}`;
|
||||
logger.info(`${client.id}: ${command}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(cmd, (error, stdout, stderr) => {
|
||||
@ -217,7 +217,7 @@ async function main() {
|
||||
|
||||
logger.info(await execCommand(client, 'version'));
|
||||
|
||||
await db.open({ name: client.profileDir + '/database.sqlite' });
|
||||
await db.open({ name: `${client.profileDir}/database.sqlite` });
|
||||
BaseModel.db_ = db;
|
||||
await Setting.load();
|
||||
|
||||
@ -230,7 +230,7 @@ async function main() {
|
||||
|
||||
await clearDatabase();
|
||||
let testName = n.substr(4).toLowerCase();
|
||||
process.stdout.write(testName + ': ');
|
||||
process.stdout.write(`${testName}: `);
|
||||
await testUnits[n]();
|
||||
console.info('');
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ cliUtils.parseFlags = function(flags) {
|
||||
};
|
||||
|
||||
cliUtils.parseCommandArg = function(arg) {
|
||||
if (arg.length <= 2) throw new Error('Invalid command arg: ' + arg);
|
||||
if (arg.length <= 2) throw new Error(`Invalid command arg: ${arg}`);
|
||||
|
||||
const c1 = arg[0];
|
||||
const c2 = arg[arg.length - 1];
|
||||
@ -69,7 +69,7 @@ cliUtils.parseCommandArg = function(arg) {
|
||||
} else if (c1 == '[' && c2 == ']') {
|
||||
return { required: false, name: name };
|
||||
} else {
|
||||
throw new Error('Invalid command arg: ' + arg);
|
||||
throw new Error(`Invalid command arg: ${arg}`);
|
||||
}
|
||||
};
|
||||
|
||||
@ -82,7 +82,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
let booleanFlags = [];
|
||||
let aliases = {};
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].length != 2) throw new Error('Invalid options: ' + options[i]);
|
||||
if (options[i].length != 2) throw new Error(`Invalid options: ${options[i]}`);
|
||||
let flags = options[i][0];
|
||||
|
||||
flags = cliUtils.parseFlags(flags);
|
||||
@ -136,7 +136,7 @@ cliUtils.promptMcq = function(message, answers) {
|
||||
message += '\n\n';
|
||||
for (let n in answers) {
|
||||
if (!answers.hasOwnProperty(n)) continue;
|
||||
message += _('%s: %s', n, answers[n]) + '\n';
|
||||
message += `${_('%s: %s', n, answers[n])}\n`;
|
||||
}
|
||||
|
||||
message += '\n';
|
||||
@ -165,10 +165,10 @@ cliUtils.promptConfirm = function(message, answers = null) {
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
message += ' (' + answers.join('/') + ')';
|
||||
message += ` (${answers.join('/')})`;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
rl.question(message + ' ', answer => {
|
||||
rl.question(`${message} `, answer => {
|
||||
const ok = !answer || answer.toLowerCase() == answers[0].toLowerCase();
|
||||
rl.close();
|
||||
resolve(ok);
|
||||
|
@ -168,7 +168,7 @@ class Command extends BaseCommand {
|
||||
// });
|
||||
}
|
||||
|
||||
lines.push('# ' + toTitleCase(tableName));
|
||||
lines.push(`# ${toTitleCase(tableName)}`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_FOLDER) {
|
||||
@ -181,9 +181,9 @@ class Command extends BaseCommand {
|
||||
lines.push(this.createPropertiesTable(tableFields));
|
||||
lines.push('');
|
||||
|
||||
lines.push('## GET /' + tableName);
|
||||
lines.push(`## GET /${tableName}`);
|
||||
lines.push('');
|
||||
lines.push('Gets all ' + tableName);
|
||||
lines.push(`Gets all ${tableName}`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_FOLDER) {
|
||||
@ -191,9 +191,9 @@ class Command extends BaseCommand {
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## GET /' + tableName + '/:id');
|
||||
lines.push(`## GET /${tableName}/:id`);
|
||||
lines.push('');
|
||||
lines.push('Gets ' + singular + ' with ID :id');
|
||||
lines.push(`Gets ${singular} with ID :id`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_TAG) {
|
||||
@ -224,9 +224,9 @@ class Command extends BaseCommand {
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## POST /' + tableName);
|
||||
lines.push(`## POST /${tableName}`);
|
||||
lines.push('');
|
||||
lines.push('Creates a new ' + singular);
|
||||
lines.push(`Creates a new ${singular}`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_RESOURCE) {
|
||||
@ -270,14 +270,14 @@ class Command extends BaseCommand {
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## PUT /' + tableName + '/:id');
|
||||
lines.push(`## PUT /${tableName}/:id`);
|
||||
lines.push('');
|
||||
lines.push('Sets the properties of the ' + singular + ' with ID :id');
|
||||
lines.push(`Sets the properties of the ${singular} with ID :id`);
|
||||
lines.push('');
|
||||
|
||||
lines.push('## DELETE /' + tableName + '/:id');
|
||||
lines.push(`## DELETE /${tableName}/:id`);
|
||||
lines.push('');
|
||||
lines.push('Deletes the ' + singular + ' with ID :id');
|
||||
lines.push(`Deletes the ${singular} with ID :id`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_TAG) {
|
||||
|
@ -97,13 +97,13 @@ class Command extends BaseCommand {
|
||||
while (true) {
|
||||
try {
|
||||
const outputDir = options.output ? options.output : require('os').tmpdir();
|
||||
let outFile = outputDir + '/' + pathUtils.filename(args.path) + '.' + Date.now() + '.bin';
|
||||
let outFile = `${outputDir}/${pathUtils.filename(args.path)}.${Date.now()}.bin`;
|
||||
await EncryptionService.instance().decryptFile(args.path, outFile);
|
||||
const buffer = await readChunk(outFile, 0, 64);
|
||||
const detectedType = imageType(buffer);
|
||||
|
||||
if (detectedType) {
|
||||
const newOutFile = outFile + '.' + detectedType.ext;
|
||||
const newOutFile = `${outFile}.${detectedType.ext}`;
|
||||
await shim.fsDriver().move(outFile, newOutFile);
|
||||
outFile = newOutFile;
|
||||
}
|
||||
@ -150,7 +150,7 @@ class Command extends BaseCommand {
|
||||
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
const path = paths[i];
|
||||
const fullPath = targetPath + '/' + path;
|
||||
const fullPath = `${targetPath}/${path}`;
|
||||
const stat = await fs.stat(fullPath);
|
||||
|
||||
// this.stdout(fullPath);
|
||||
@ -160,7 +160,7 @@ class Command extends BaseCommand {
|
||||
for (let j = 0; j < resourcePaths.length; j++) {
|
||||
const resourcePath = resourcePaths[j];
|
||||
resourceCount++;
|
||||
const fullResourcePath = fullPath + '/' + resourcePath;
|
||||
const fullResourcePath = `${fullPath}/${resourcePath}`;
|
||||
const isEncrypted = await EncryptionService.instance().fileIsEncrypted(fullResourcePath);
|
||||
if (isEncrypted) {
|
||||
encryptedResourceCount++;
|
||||
@ -194,9 +194,9 @@ class Command extends BaseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
this.stdout('Encrypted items: ' + encryptedItemCount + '/' + itemCount);
|
||||
this.stdout('Encrypted resources: ' + encryptedResourceCount + '/' + resourceCount);
|
||||
this.stdout('Other items (never encrypted): ' + otherItemCount);
|
||||
this.stdout(`Encrypted items: ${encryptedItemCount}/${itemCount}`);
|
||||
this.stdout(`Encrypted resources: ${encryptedResourceCount}/${resourceCount}`);
|
||||
this.stdout(`Other items (never encrypted): ${otherItemCount}`);
|
||||
|
||||
if (options.verbose) {
|
||||
this.stdout('');
|
||||
|
@ -60,7 +60,7 @@ class Command extends BaseCommand {
|
||||
|
||||
const originalContent = await Note.serializeForEdit(note);
|
||||
|
||||
tempFilePath = Setting.value('tempDir') + '/' + uuid.create() + '.md';
|
||||
tempFilePath = `${Setting.value('tempDir')}/${uuid.create()}.md`;
|
||||
editorArgs.push(tempFilePath);
|
||||
|
||||
await fs.writeFile(tempFilePath, originalContent);
|
||||
|
@ -20,9 +20,9 @@ class Command extends BaseCommand {
|
||||
async action() {
|
||||
const service = new ReportService();
|
||||
const csv = await service.basicItemList({ format: 'csv' });
|
||||
const filePath = Setting.value('profileDir') + '/syncReport-' + new Date().getTime() + '.csv';
|
||||
const filePath = `${Setting.value('profileDir')}/syncReport-${new Date().getTime()}.csv`;
|
||||
await fs.writeFileSync(filePath, csv);
|
||||
this.stdout('Sync status exported to ' + filePath);
|
||||
this.stdout(`Sync status exported to ${filePath}`);
|
||||
|
||||
app()
|
||||
.gui()
|
||||
|
@ -18,7 +18,7 @@ class Command extends BaseCommand {
|
||||
const formats = service
|
||||
.modules()
|
||||
.filter(m => m.type === 'exporter')
|
||||
.map(m => m.format + (m.description ? ' (' + m.description + ')' : ''));
|
||||
.map(m => m.format + (m.description ? ` (${m.description})` : ''));
|
||||
|
||||
return [['--format <format>', _('Destination format: %s', formats.join(', '))], ['--note <note>', _('Exports only the given note.')], ['--notebook <notebook>', _('Exports only the given notebook.')]];
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class Command extends BaseCommand {
|
||||
|
||||
let title = item.title;
|
||||
if (!shortIdShown && (seenTitles.indexOf(item.title) >= 0 || !item.title)) {
|
||||
title += ' (' + BaseModel.shortId(item.id) + ')';
|
||||
title += ` (${BaseModel.shortId(item.id)})`;
|
||||
} else {
|
||||
seenTitles.push(item.title);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Start, stop or check the API server. To specify on which port it should run, set the api.port config variable. Commands are (%s).', ['start', 'stop', 'status'].join('|')) + ' This is an experimental feature - use at your own risks! It is recommended that the server runs off its own separate profile so that no two CLI instances access that profile at the same time. Use --profile to specify the profile path.';
|
||||
return `${_('Start, stop or check the API server. To specify on which port it should run, set the api.port config variable. Commands are (%s).', ['start', 'stop', 'status'].join('|'))} This is an experimental feature - use at your own risks! It is recommended that the server runs off its own separate profile so that no two CLI instances access that profile at the same time. Use --profile to specify the profile path.`;
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
@ -20,7 +20,7 @@ class Command extends BaseCommand {
|
||||
const ClipperServer = require('lib/ClipperServer');
|
||||
const stdoutFn = (s) => this.stdout(s);
|
||||
const clipperLogger = new Logger();
|
||||
clipperLogger.addTarget('file', { path: Setting.value('profileDir') + '/log-clipper.txt' });
|
||||
clipperLogger.addTarget('file', { path: `${Setting.value('profileDir')}/log-clipper.txt` });
|
||||
clipperLogger.addTarget('console', { console: {
|
||||
info: stdoutFn,
|
||||
warn: stdoutFn,
|
||||
@ -29,7 +29,7 @@ class Command extends BaseCommand {
|
||||
ClipperServer.instance().setDispatch(() => {});
|
||||
ClipperServer.instance().setLogger(clipperLogger);
|
||||
|
||||
const pidPath = Setting.value('profileDir') + '/clipper-pid.txt';
|
||||
const pidPath = `${Setting.value('profileDir')}/clipper-pid.txt`;
|
||||
const runningOnPort = await ClipperServer.instance().isRunning();
|
||||
|
||||
if (command === 'start') {
|
||||
|
@ -16,7 +16,7 @@ class Command extends BaseCommand {
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const f = fields[i];
|
||||
if (f.name === 'id') continue;
|
||||
s.push(f.name + ' (' + Database.enumName('fieldType', f.type) + ')');
|
||||
s.push(`${f.name} (${Database.enumName('fieldType', f.type)})`);
|
||||
}
|
||||
|
||||
return _('Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s', s.join(', '));
|
||||
|
@ -22,7 +22,7 @@ class Command extends BaseCommand {
|
||||
|
||||
if (i > 0) this.stdout('');
|
||||
|
||||
this.stdout('# ' + section.title);
|
||||
this.stdout(`# ${section.title}`);
|
||||
this.stdout('');
|
||||
|
||||
for (let n in section.body) {
|
||||
|
@ -72,7 +72,7 @@ class Command extends BaseCommand {
|
||||
});
|
||||
this.oneDriveApiUtils_ = null;
|
||||
|
||||
Setting.setValue('sync.' + this.syncTargetId_ + '.auth', auth ? JSON.stringify(auth) : null);
|
||||
Setting.setValue(`sync.${this.syncTargetId_}.auth`, auth ? JSON.stringify(auth) : null);
|
||||
if (!auth) {
|
||||
this.stdout(_('Authentication was not completed (did not receive an authentication token).'));
|
||||
return false;
|
||||
@ -93,7 +93,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
const response = await api.execAuthToken(authCode);
|
||||
Setting.setValue('sync.' + this.syncTargetId_ + '.auth', response.access_token);
|
||||
Setting.setValue(`sync.${this.syncTargetId_}.auth`, response.access_token);
|
||||
api.setAuthToken(response.access_token);
|
||||
return true;
|
||||
}
|
||||
@ -117,7 +117,7 @@ class Command extends BaseCommand {
|
||||
this.releaseLockFn_ = null;
|
||||
|
||||
// Lock is unique per profile/database
|
||||
const lockFilePath = require('os').tmpdir() + '/synclock_' + md5(escape(Setting.value('profileDir'))); // https://github.com/pvorb/node-md5/issues/41
|
||||
const lockFilePath = `${require('os').tmpdir()}/synclock_${md5(escape(Setting.value('profileDir')))}`; // https://github.com/pvorb/node-md5/issues/41
|
||||
if (!(await fs.pathExists(lockFilePath))) await fs.writeFile(lockFilePath, 'synclock');
|
||||
|
||||
try {
|
||||
@ -178,7 +178,7 @@ class Command extends BaseCommand {
|
||||
|
||||
this.stdout(_('Starting synchronisation...'));
|
||||
|
||||
const contextKey = 'sync.' + this.syncTargetId_ + '.context';
|
||||
const contextKey = `sync.${this.syncTargetId_}.context`;
|
||||
let context = Setting.value(contextKey);
|
||||
|
||||
context = context ? JSON.parse(context) : {};
|
||||
|
@ -9,9 +9,9 @@ const lodash = require('lodash');
|
||||
const exec = require('child_process').exec;
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const baseDir = dirname(__dirname) + '/tests/fuzzing';
|
||||
const syncDir = baseDir + '/sync';
|
||||
const joplinAppPath = __dirname + '/main.js';
|
||||
const baseDir = `${dirname(__dirname)}/tests/fuzzing`;
|
||||
const syncDir = `${baseDir}/sync`;
|
||||
const joplinAppPath = `${__dirname}/main.js`;
|
||||
let syncDurations = [];
|
||||
|
||||
const fsDriver = new FsDriverNode();
|
||||
@ -29,7 +29,7 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
function createClient(id) {
|
||||
return {
|
||||
id: id,
|
||||
profileDir: baseDir + '/client' + id,
|
||||
profileDir: `${baseDir}/client${id}`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ async function createClients() {
|
||||
promises.push(fs.remove(client.profileDir));
|
||||
promises.push(
|
||||
execCommand(client, 'config sync.target 2').then(() => {
|
||||
return execCommand(client, 'config sync.2.path ' + syncDir);
|
||||
return execCommand(client, `config sync.2.path ${syncDir}`);
|
||||
})
|
||||
);
|
||||
output.push(client);
|
||||
@ -2064,12 +2064,12 @@ function randomWord() {
|
||||
}
|
||||
|
||||
function execCommand(client, command, options = {}) {
|
||||
let exePath = 'node ' + joplinAppPath;
|
||||
let cmd = exePath + ' --update-geolocation-disabled --env dev --log-level debug --profile ' + client.profileDir + ' ' + command;
|
||||
logger.info(client.id + ': ' + command);
|
||||
let exePath = `node ${joplinAppPath}`;
|
||||
let cmd = `${exePath} --update-geolocation-disabled --env dev --log-level debug --profile ${client.profileDir} ${command}`;
|
||||
logger.info(`${client.id}: ${command}`);
|
||||
|
||||
if (options.killAfter) {
|
||||
logger.info('Kill after: ' + options.killAfter);
|
||||
logger.info(`Kill after: ${options.killAfter}`);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -2100,7 +2100,7 @@ async function clientItems(client) {
|
||||
try {
|
||||
return JSON.parse(itemsJson);
|
||||
} catch (error) {
|
||||
throw new Error('Cannot parse JSON: ' + itemsJson);
|
||||
throw new Error(`Cannot parse JSON: ${itemsJson}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2136,13 +2136,13 @@ async function execRandomCommand(client) {
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ == 1) {
|
||||
return execCommand(client, 'rm -f ' + item.id);
|
||||
return execCommand(client, `rm -f ${item.id}`);
|
||||
} else if (item.type_ == 2) {
|
||||
return execCommand(client, 'rm -r -f ' + item.id);
|
||||
return execCommand(client, `rm -r -f ${item.id}`);
|
||||
} else if (item.type_ == 5) {
|
||||
// tag
|
||||
} else {
|
||||
throw new Error('Unknown type: ' + item.type_);
|
||||
throw new Error(`Unknown type: ${item.type_}`);
|
||||
}
|
||||
},
|
||||
30,
|
||||
@ -2168,7 +2168,7 @@ async function execRandomCommand(client) {
|
||||
let item = randomNote(items);
|
||||
if (!item) return;
|
||||
|
||||
return execCommand(client, 'set ' + item.id + ' title "' + randomWord() + '"');
|
||||
return execCommand(client, `set ${item.id} title "${randomWord()}"`);
|
||||
},
|
||||
50,
|
||||
],
|
||||
@ -2180,9 +2180,9 @@ async function execRandomCommand(client) {
|
||||
if (!note) return;
|
||||
|
||||
let tag = randomTag(items);
|
||||
let tagTitle = !tag || Math.random() >= 0.9 ? 'tag-' + randomWord() : tag.title;
|
||||
let tagTitle = !tag || Math.random() >= 0.9 ? `tag-${randomWord()}` : tag.title;
|
||||
|
||||
return execCommand(client, 'tag add ' + tagTitle + ' ' + note.id);
|
||||
return execCommand(client, `tag add ${tagTitle} ${note.id}`);
|
||||
},
|
||||
50,
|
||||
],
|
||||
@ -2211,7 +2211,7 @@ function averageSyncDuration() {
|
||||
|
||||
function randomNextCheckTime() {
|
||||
let output = time.unixMs() + 1000 + Math.random() * 1000 * 120;
|
||||
logger.info('Next sync check: ' + time.unixMsToIso(output) + ' (' + Math.round((output - time.unixMs()) / 1000) + ' sec.)');
|
||||
logger.info(`Next sync check: ${time.unixMsToIso(output)} (${Math.round((output - time.unixMs()) / 1000)} sec.)`);
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -2274,7 +2274,7 @@ async function compareClientItems(clientItems) {
|
||||
let items = clientItems[i];
|
||||
itemCounts.push(items.length);
|
||||
}
|
||||
logger.info('Item count: ' + itemCounts.join(', '));
|
||||
logger.info(`Item count: ${itemCounts.join(', ')}`);
|
||||
|
||||
let missingItems = findMissingItems(clientItems[0], clientItems[1]);
|
||||
if (missingItems[0].length || missingItems[1].length) {
|
||||
@ -2290,7 +2290,7 @@ async function compareClientItems(clientItems) {
|
||||
for (let clientId = 1; clientId < clientItems.length; clientId++) {
|
||||
let item2 = findItem(clientItems[clientId], item1.id);
|
||||
if (!item2) {
|
||||
logger.error('Item not found on client ' + clientId + ':');
|
||||
logger.error(`Item not found on client ${clientId}:`);
|
||||
logger.error(item1);
|
||||
process.exit(1);
|
||||
}
|
||||
@ -2329,12 +2329,12 @@ async function main() {
|
||||
|
||||
execRandomCommand(clients[clientId])
|
||||
.catch(error => {
|
||||
logger.info('Client ' + clientId + ':');
|
||||
logger.info(`Client ${clientId}:`);
|
||||
logger.error(error);
|
||||
})
|
||||
.then(r => {
|
||||
if (r) {
|
||||
logger.info('Client ' + clientId + ':\n' + r.trim());
|
||||
logger.info(`Client ${clientId}:\n${r.trim()}`);
|
||||
}
|
||||
clients[clientId].activeCommandCount--;
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ class FolderListWidget extends ListWidget {
|
||||
} else if (item.type_ === Folder.modelType()) {
|
||||
output.push(' '.repeat(this.folderDepth(this.folders, item.id)) + Folder.displayTitle(item));
|
||||
} else if (item.type_ === Tag.modelType()) {
|
||||
output.push('[' + Folder.displayTitle(item) + ']');
|
||||
output.push(`[${Folder.displayTitle(item)}]`);
|
||||
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
|
||||
output.push(_('Search:'));
|
||||
output.push(item.title);
|
||||
@ -172,7 +172,7 @@ class FolderListWidget extends ListWidget {
|
||||
if (this.notesParentType === 'Folder') return this.selectedFolderId;
|
||||
if (this.notesParentType === 'Tag') return this.selectedTagId;
|
||||
if (this.notesParentType === 'Search') return this.selectedSearchId;
|
||||
throw new Error('Unknown parent type: ' + this.notesParentType);
|
||||
throw new Error(`Unknown parent type: ${this.notesParentType}`);
|
||||
}
|
||||
|
||||
get selectedJoplinItem() {
|
||||
|
@ -11,7 +11,7 @@ class NoteListWidget extends ListWidget {
|
||||
this.itemRenderer = note => {
|
||||
let label = Note.displayTitle(note); // + ' ' + note.id;
|
||||
if (note.is_todo) {
|
||||
label = '[' + (note.todo_completed ? 'X' : ' ') + '] ' + label;
|
||||
label = `[${note.todo_completed ? 'X' : ' '}] ${label}`;
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ class NoteWidget extends TextWidget {
|
||||
if (this.note_ && this.note_.encryption_applied) {
|
||||
this.text = _('One or more items are currently encrypted and you may need to supply a master password. To do so please type `e2ee decrypt`. If you have already supplied the password, the encrypted items are being decrypted in the background and will be available soon.');
|
||||
} else {
|
||||
this.text = this.note_ ? this.note_.title + '\n\n' + this.note_.body : '';
|
||||
this.text = this.note_ ? `${this.note_.title}\n\n${this.note_.body}` : '';
|
||||
}
|
||||
|
||||
if (this.lastLoadedNoteId_ !== this.noteId_) this.scrollTop = 0;
|
||||
|
@ -60,7 +60,7 @@ function renderCommandHelp(cmd, width = null) {
|
||||
|
||||
if ('value' in md) {
|
||||
if (md.type === Setting.TYPE_STRING) {
|
||||
defaultString = md.value ? '"' + md.value + '"' : null;
|
||||
defaultString = md.value ? `"${md.value}"` : null;
|
||||
} else if (md.type === Setting.TYPE_INT) {
|
||||
defaultString = (md.value ? md.value : 0).toString();
|
||||
} else if (md.type === Setting.TYPE_BOOL) {
|
||||
|
@ -9,7 +9,7 @@ require('app-module-path').addPath(__dirname);
|
||||
const compareVersion = require('compare-version');
|
||||
const nodeVersion = process && process.versions && process.versions.node ? process.versions.node : '0.0.0';
|
||||
if (compareVersion(nodeVersion, '8.0.0') < 0) {
|
||||
console.error('Joplin requires Node 8+. Detected version ' + nodeVersion);
|
||||
console.error(`Joplin requires Node 8+. Detected version ${nodeVersion}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class OneDriveApiNodeUtils {
|
||||
const port = await netUtils.findAvailablePort(this.possibleOAuthDancePorts(), 0);
|
||||
if (!port) throw new Error(_('All potential ports are in use - please report the issue at %s', 'https://github.com/laurent22/joplin'));
|
||||
|
||||
let authCodeUrl = this.api().authCodeUrl('http://localhost:' + port);
|
||||
let authCodeUrl = this.api().authCodeUrl(`http://localhost:${port}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.oauthServer_ = http.createServer();
|
||||
@ -80,7 +80,7 @@ class OneDriveApiNodeUtils {
|
||||
if (!query.code) return writeResponse(400, '"code" query parameter is missing');
|
||||
|
||||
this.api()
|
||||
.execTokenRequest(query.code, 'http://localhost:' + port.toString())
|
||||
.execTokenRequest(query.code, `http://localhost:${port.toString()}`)
|
||||
.then(() => {
|
||||
writeResponse(200, _('The application has been authorised - you may now close this browser tab.'));
|
||||
targetConsole.log('');
|
||||
@ -114,7 +114,7 @@ class OneDriveApiNodeUtils {
|
||||
|
||||
targetConsole.log(_('Please open the following URL in your browser to authenticate the application. The application will create a directory in "Apps/Joplin" and will only read and write files in this directory. It will have no access to any files outside this directory nor to any other personal data. No data will be shared with any third party.'));
|
||||
targetConsole.log('');
|
||||
targetConsole.log('http://127.0.0.1:' + port + '/auth');
|
||||
targetConsole.log(`http://127.0.0.1:${port}/auth`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -27,22 +27,22 @@ describe('EnexToMd', function() {
|
||||
});
|
||||
|
||||
it('should convert from Enex to Markdown', asyncTest(async () => {
|
||||
const basePath = __dirname + '/enex_to_md';
|
||||
const basePath = `${__dirname}/enex_to_md`;
|
||||
const files = await shim.fsDriver().readDirStats(basePath);
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const htmlFilename = files[i].path;
|
||||
if (htmlFilename.indexOf('.html') < 0) continue;
|
||||
|
||||
const htmlPath = basePath + '/' + htmlFilename;
|
||||
const mdPath = basePath + '/' + filename(htmlFilename) + '.md';
|
||||
const htmlPath = `${basePath}/${htmlFilename}`;
|
||||
const mdPath = `${basePath}/${filename(htmlFilename)}.md`;
|
||||
|
||||
// if (htmlFilename !== 'multiline_inner_text.html') continue;
|
||||
|
||||
const html = await shim.fsDriver().readFile(htmlPath);
|
||||
let expectedMd = await shim.fsDriver().readFile(mdPath);
|
||||
|
||||
let actualMd = await enexXmlToMd('<div>' + html + '</div>', []);
|
||||
let actualMd = await enexXmlToMd(`<div>${html}</div>`, []);
|
||||
|
||||
if (os.EOL === '\r\n') {
|
||||
expectedMd = expectedMd.replace(/\r\n/g, '\n');
|
||||
@ -51,7 +51,7 @@ describe('EnexToMd', function() {
|
||||
|
||||
if (actualMd !== expectedMd) {
|
||||
console.info('');
|
||||
console.info('Error converting file: ' + htmlFilename);
|
||||
console.info(`Error converting file: ${htmlFilename}`);
|
||||
console.info('--------------------------------- Got:');
|
||||
console.info(actualMd.split('\n'));
|
||||
console.info('--------------------------------- Expected:');
|
||||
|
@ -28,7 +28,7 @@ describe('HtmlToMd', function() {
|
||||
});
|
||||
|
||||
it('should convert from Html to Markdown', asyncTest(async () => {
|
||||
const basePath = __dirname + '/html_to_md';
|
||||
const basePath = `${__dirname}/html_to_md`;
|
||||
const files = await shim.fsDriver().readDirStats(basePath);
|
||||
const htmlToMd = new HtmlToMd();
|
||||
|
||||
@ -36,8 +36,8 @@ describe('HtmlToMd', function() {
|
||||
const htmlFilename = files[i].path;
|
||||
if (htmlFilename.indexOf('.html') < 0) continue;
|
||||
|
||||
const htmlPath = basePath + '/' + htmlFilename;
|
||||
const mdPath = basePath + '/' + filename(htmlFilename) + '.md';
|
||||
const htmlPath = `${basePath}/${htmlFilename}`;
|
||||
const mdPath = `${basePath}/${filename(htmlFilename)}.md`;
|
||||
|
||||
// if (htmlFilename !== 'table_with_pipe.html') continue;
|
||||
|
||||
@ -54,7 +54,7 @@ describe('HtmlToMd', function() {
|
||||
const html = await shim.fsDriver().readFile(htmlPath);
|
||||
let expectedMd = await shim.fsDriver().readFile(mdPath);
|
||||
|
||||
let actualMd = await htmlToMd.parse('<div>' + html + '</div>', htmlToMdOptions);
|
||||
let actualMd = await htmlToMd.parse(`<div>${html}</div>`, htmlToMdOptions);
|
||||
|
||||
if (os.EOL === '\r\n') {
|
||||
expectedMd = expectedMd.replace(/\r\n/g, '\n');
|
||||
@ -63,7 +63,7 @@ describe('HtmlToMd', function() {
|
||||
|
||||
if (actualMd !== expectedMd) {
|
||||
console.info('');
|
||||
console.info('Error converting file: ' + htmlFilename);
|
||||
console.info(`Error converting file: ${htmlFilename}`);
|
||||
console.info('--------------------------------- Got:');
|
||||
console.info(actualMd);
|
||||
console.info('--------------------------------- Raw:');
|
||||
|
@ -38,7 +38,7 @@ describe('StringUtils', function() {
|
||||
|
||||
const actual = StringUtils.surroundKeywords(keywords, input, prefix, suffix);
|
||||
|
||||
expect(actual).toBe(expected, 'Test case ' + i);
|
||||
expect(actual).toBe(expected, `Test case ${i}`);
|
||||
}
|
||||
|
||||
done();
|
||||
|
@ -165,9 +165,9 @@ describe('Encryption', function() {
|
||||
masterKey = await MasterKey.save(masterKey);
|
||||
await service.loadMasterKey(masterKey, '123456', true);
|
||||
|
||||
const sourcePath = __dirname + '/../tests/support/photo.jpg';
|
||||
const encryptedPath = __dirname + '/data/photo.crypted';
|
||||
const decryptedPath = __dirname + '/data/photo.jpg';
|
||||
const sourcePath = `${__dirname}/../tests/support/photo.jpg`;
|
||||
const encryptedPath = `${__dirname}/data/photo.crypted`;
|
||||
const decryptedPath = `${__dirname}/data/photo.jpg`;
|
||||
|
||||
await service.encryptFile(sourcePath, encryptedPath);
|
||||
await service.decryptFile(encryptedPath, decryptedPath);
|
||||
|
@ -25,23 +25,23 @@ describe('models_Note', function() {
|
||||
it('should find resource and note IDs', asyncTest(async () => {
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', body: 'Lien vers première note : ' + Note.markdownTag(note1), parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', body: `Lien vers première note : ${Note.markdownTag(note1)}`, parent_id: folder1.id });
|
||||
|
||||
let items = await Note.linkedItems(note2.body);
|
||||
expect(items.length).toBe(1);
|
||||
expect(items[0].id).toBe(note1.id);
|
||||
|
||||
await shim.attachFileToNote(note2, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note2, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note2 = await Note.load(note2.id);
|
||||
items = await Note.linkedItems(note2.body);
|
||||
expect(items.length).toBe(2);
|
||||
expect(items[0].type_).toBe(BaseModel.TYPE_NOTE);
|
||||
expect(items[1].type_).toBe(BaseModel.TYPE_RESOURCE);
|
||||
|
||||
const resource2 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
|
||||
const resource3 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
|
||||
note2.body += '<img alt="bla" src=":/' + resource2.id + '"/>';
|
||||
note2.body += '<img src=\':/' + resource3.id + '\' />';
|
||||
const resource2 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
const resource3 = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
note2.body += `<img alt="bla" src=":/${resource2.id}"/>`;
|
||||
note2.body += `<img src=':/${resource3.id}' />`;
|
||||
items = await Note.linkedItems(note2.body);
|
||||
expect(items.length).toBe(4);
|
||||
}));
|
||||
|
@ -16,7 +16,7 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
const testImagePath = __dirname + '/../tests/support/photo.jpg';
|
||||
const testImagePath = `${__dirname}/../tests/support/photo.jpg`;
|
||||
|
||||
describe('models_Resource', function() {
|
||||
|
||||
|
@ -22,13 +22,13 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
});
|
||||
|
||||
function exportDir() {
|
||||
return __dirname + '/export';
|
||||
return `${__dirname}/export`;
|
||||
}
|
||||
|
||||
function fieldsEqual(model1, model2, fieldNames) {
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
const f = fieldNames[i];
|
||||
expect(model1[f]).toBe(model2[f], 'For key ' + f);
|
||||
expect(model1[f]).toBe(model2[f], `For key ${f}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ describe('services_InteropService', function() {
|
||||
const service = new InteropService();
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
folder1 = await Folder.load(folder1.id);
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
@ -84,7 +84,7 @@ describe('services_InteropService', function() {
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await Note.load(note1.id);
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
@ -123,7 +123,7 @@ describe('services_InteropService', function() {
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await Note.load(note1.id);
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
@ -139,7 +139,7 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import tags', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
let tag1 = await Tag.save({ title: 'mon tag' });
|
||||
@ -179,10 +179,10 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import resources', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
note1 = await Note.load(note1.id);
|
||||
let resourceIds = await Note.linkedResourceIds(note1.body);
|
||||
let resource1 = await Resource.load(resourceIds[0]);
|
||||
@ -215,7 +215,7 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import single notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
@ -235,7 +235,7 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import single folders', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
@ -256,7 +256,7 @@ describe('services_InteropService', function() {
|
||||
it('should export and import folder and its sub-folders', asyncTest(async () => {
|
||||
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let folder2 = await Folder.save({ title: 'folder2', parent_id: folder1.id });
|
||||
let folder3 = await Folder.save({ title: 'folder3', parent_id: folder2.id });
|
||||
@ -290,10 +290,10 @@ describe('services_InteropService', function() {
|
||||
|
||||
it('should export and import links to notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
const filePath = `${exportDir()}/test.jex`;
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', body: 'Lien vers première note : ' + Note.markdownTag(note1), parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', body: `Lien vers première note : ${Note.markdownTag(note1)}`, parent_id: folder1.id });
|
||||
|
||||
await service.export({ path: filePath, sourceFolderIds: [folder1.id] });
|
||||
|
||||
@ -324,7 +324,7 @@ describe('services_InteropService', function() {
|
||||
// verify that the json files exist and can be parsed
|
||||
const items = [folder1, note1];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const jsonFile = filePath + '/' + items[i].id + '.json';
|
||||
const jsonFile = `${filePath}/${items[i].id}.json`;
|
||||
let json = await fs.readFile(jsonFile, 'utf-8');
|
||||
let obj = JSON.parse(json);
|
||||
expect(obj.id).toBe(items[i].id);
|
||||
@ -350,13 +350,13 @@ describe('services_InteropService', function() {
|
||||
|
||||
await service.export({ path: outDir, format: 'md' });
|
||||
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/生活.md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (1).md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (2).md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled.md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled (1).md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/folder1/salut, ça roule _.md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(outDir + '/ジョプリン/ジョプリン.md')).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/生活.md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/生活 (1).md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/生活 (2).md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/Untitled.md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/Untitled (1).md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/folder1/salut, ça roule _.md`)).toBe(true);
|
||||
expect(await shim.fsDriver().exists(`${outDir}/ジョプリン/ジョプリン.md`)).toBe(true);
|
||||
}));
|
||||
|
||||
});
|
||||
|
@ -26,13 +26,13 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
function exportDir() {
|
||||
return __dirname + '/export';
|
||||
return `${__dirname}/export`;
|
||||
}
|
||||
|
||||
function fieldsEqual(model1, model2, fieldNames) {
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
const f = fieldNames[i];
|
||||
expect(model1[f]).toBe(model2[f], 'For key ' + f);
|
||||
expect(model1[f]).toBe(model2[f], `For key ${f}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
const resourcePath = Resource.fullPath(resource1);
|
||||
|
||||
@ -82,7 +82,7 @@ describe('services_ResourceService', function() {
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
|
||||
await service.indexNoteResources();
|
||||
@ -102,7 +102,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
it('should not delete a resource that has never been associated with any note, because it probably means the resource came via sync, and associated note has not arrived yet', asyncTest(async () => {
|
||||
const service = new ResourceService();
|
||||
const resource = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
|
||||
const resource = await shim.createResourceFromPath(`${__dirname}/../tests/support/photo.jpg`);
|
||||
|
||||
await service.indexNoteResources();
|
||||
await service.deleteOrphanResources(0);
|
||||
@ -115,12 +115,12 @@ describe('services_ResourceService', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
await Note.save({ id: note1.id, body: 'This is HTML: <img src=":/' + resource1.id + '"/>' });
|
||||
await Note.save({ id: note1.id, body: `This is HTML: <img src=":/${resource1.id}"/>` });
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
@ -134,7 +134,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
|
||||
await service.indexNoteResources();
|
||||
@ -171,7 +171,7 @@ describe('services_ResourceService', function() {
|
||||
await encryptionService().loadMasterKeysFromSettings();
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg'); // R1
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`); // R1
|
||||
await resourceService().indexNoteResources();
|
||||
await synchronizer().start();
|
||||
expect(await allSyncTargetItemsEncrypted()).toBe(true);
|
||||
@ -184,7 +184,7 @@ describe('services_ResourceService', function() {
|
||||
await decryptionWorker().start();
|
||||
{
|
||||
const n1 = await Note.load(note1.id);
|
||||
await shim.attachFileToNote(n1, __dirname + '/../tests/support/photo.jpg'); // R2
|
||||
await shim.attachFileToNote(n1, `${__dirname}/../tests/support/photo.jpg`); // R2
|
||||
}
|
||||
await synchronizer().start();
|
||||
|
||||
@ -201,7 +201,7 @@ describe('services_ResourceService', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
note1 = await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await resourceService().indexNoteResources();
|
||||
const bodyWithResource = note1.body;
|
||||
await Note.save({ id: note1.id, body: '' });
|
||||
|
@ -297,9 +297,9 @@ describe('services_SearchEngine', function() {
|
||||
const titleValues = actual.terms.title ? actual.terms.title.map(v => v.value) : undefined;
|
||||
const bodyValues = actual.terms.body ? actual.terms.body.map(v => v.value) : undefined;
|
||||
|
||||
expect(JSON.stringify(_Values)).toBe(JSON.stringify(expected._), 'Test case (_) ' + i);
|
||||
expect(JSON.stringify(titleValues)).toBe(JSON.stringify(expected.title), 'Test case (title) ' + i);
|
||||
expect(JSON.stringify(bodyValues)).toBe(JSON.stringify(expected.body), 'Test case (body) ' + i);
|
||||
expect(JSON.stringify(_Values)).toBe(JSON.stringify(expected._), `Test case (_) ${i}`);
|
||||
expect(JSON.stringify(titleValues)).toBe(JSON.stringify(expected.title), `Test case (title) ${i}`);
|
||||
expect(JSON.stringify(bodyValues)).toBe(JSON.stringify(expected.body), `Test case (body) ${i}`);
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -51,7 +51,7 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should update folders', async (done) => {
|
||||
let f1 = await Folder.save({ title: 'mon carnet' });
|
||||
const response = await api.route('PUT', 'folders/' + f1.id, null, JSON.stringify({
|
||||
const response = await api.route('PUT', `folders/${f1.id}`, null, JSON.stringify({
|
||||
title: 'modifié',
|
||||
}));
|
||||
|
||||
@ -63,7 +63,7 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should delete folders', async (done) => {
|
||||
let f1 = await Folder.save({ title: 'mon carnet' });
|
||||
await api.route('DELETE', 'folders/' + f1.id);
|
||||
await api.route('DELETE', `folders/${f1.id}`);
|
||||
|
||||
let f1b = await Folder.load(f1.id);
|
||||
expect(!f1b).toBe(true);
|
||||
@ -87,7 +87,7 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should get one folder', async (done) => {
|
||||
let f1 = await Folder.save({ title: 'mon carnet' });
|
||||
const response = await api.route('GET', 'folders/' + f1.id);
|
||||
const response = await api.route('GET', `folders/${f1.id}`);
|
||||
expect(response.id).toBe(f1.id);
|
||||
|
||||
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'folders/doesntexist'));
|
||||
@ -98,12 +98,12 @@ describe('services_rest_Api', function() {
|
||||
|
||||
it('should get the folder notes', async (done) => {
|
||||
let f1 = await Folder.save({ title: 'mon carnet' });
|
||||
const response2 = await api.route('GET', 'folders/' + f1.id + '/notes');
|
||||
const response2 = await api.route('GET', `folders/${f1.id}/notes`);
|
||||
expect(response2.length).toBe(0);
|
||||
|
||||
const n1 = await Note.save({ title: 'un', parent_id: f1.id });
|
||||
const n2 = await Note.save({ title: 'deux', parent_id: f1.id });
|
||||
const response = await api.route('GET', 'folders/' + f1.id + '/notes');
|
||||
const response = await api.route('GET', `folders/${f1.id}/notes`);
|
||||
expect(response.length).toBe(2);
|
||||
|
||||
done();
|
||||
@ -127,10 +127,10 @@ describe('services_rest_Api', function() {
|
||||
response = await api.route('GET', 'notes');
|
||||
expect(response.length).toBe(3);
|
||||
|
||||
response = await api.route('GET', 'notes/' + n1.id);
|
||||
response = await api.route('GET', `notes/${n1.id}`);
|
||||
expect(response.id).toBe(n1.id);
|
||||
|
||||
response = await api.route('GET', 'notes/' + n3.id, { fields: 'id,title' });
|
||||
response = await api.route('GET', `notes/${n3.id}`, { fields: 'id,title' });
|
||||
expect(Object.getOwnPropertyNames(response).length).toBe(3);
|
||||
expect(response.id).toBe(n3.id);
|
||||
expect(response.title).toBe('trois');
|
||||
@ -270,7 +270,7 @@ describe('services_rest_Api', function() {
|
||||
const filePath = Resource.fullPath(resource);
|
||||
expect(await shim.fsDriver().exists(filePath)).toBe(true);
|
||||
|
||||
await api.route('DELETE', 'resources/' + resource.id);
|
||||
await api.route('DELETE', `resources/${resource.id}`);
|
||||
expect(await shim.fsDriver().exists(filePath)).toBe(false);
|
||||
expect(!(await Resource.load(resource.id))).toBe(true);
|
||||
|
||||
@ -329,7 +329,7 @@ describe('services_rest_Api', function() {
|
||||
const tag = await Tag.save({ title: 'mon étiquette' });
|
||||
const note = await Note.save({ title: 'ma note' });
|
||||
|
||||
const response = await api.route('POST', 'tags/' + tag.id + '/notes', null, JSON.stringify({
|
||||
const response = await api.route('POST', `tags/${tag.id}/notes`, null, JSON.stringify({
|
||||
id: note.id,
|
||||
}));
|
||||
|
||||
@ -344,7 +344,7 @@ describe('services_rest_Api', function() {
|
||||
const note = await Note.save({ title: 'ma note' });
|
||||
await Tag.addNote(tag.id, note.id);
|
||||
|
||||
const response = await api.route('DELETE', 'tags/' + tag.id + '/notes/' + note.id);
|
||||
const response = await api.route('DELETE', `tags/${tag.id}/notes/${note.id}`);
|
||||
|
||||
const noteIds = await Tag.noteIds(tag.id);
|
||||
expect(noteIds.length).toBe(0);
|
||||
@ -360,15 +360,15 @@ describe('services_rest_Api', function() {
|
||||
await Tag.addNote(tag.id, note1.id);
|
||||
await Tag.addNote(tag.id, note2.id);
|
||||
|
||||
const response = await api.route('GET', 'tags/' + tag.id + '/notes');
|
||||
const response = await api.route('GET', `tags/${tag.id}/notes`);
|
||||
expect(response.length).toBe(2);
|
||||
expect('id' in response[0]).toBe(true);
|
||||
expect('title' in response[0]).toBe(true);
|
||||
|
||||
const response2 = await api.route('GET', 'notes/' + note1.id + '/tags');
|
||||
const response2 = await api.route('GET', `notes/${note1.id}/tags`);
|
||||
expect(response2.length).toBe(1);
|
||||
await Tag.addNote(tag2.id, note1.id);
|
||||
const response3 = await api.route('GET', 'notes/' + note1.id + '/tags');
|
||||
const response3 = await api.route('GET', `notes/${note1.id}/tags`);
|
||||
expect(response3.length).toBe(2);
|
||||
|
||||
done();
|
||||
|
@ -196,13 +196,13 @@ describe('Synchronizer', function() {
|
||||
for (let n in conflictedNote) {
|
||||
if (!conflictedNote.hasOwnProperty(n)) continue;
|
||||
if (n == 'id' || n == 'is_conflict') continue;
|
||||
expect(conflictedNote[n]).toBe(note2conf[n], 'Property: ' + n);
|
||||
expect(conflictedNote[n]).toBe(note2conf[n], `Property: ${n}`);
|
||||
}
|
||||
|
||||
let noteUpdatedFromRemote = await Note.load(note1.id);
|
||||
for (let n in noteUpdatedFromRemote) {
|
||||
if (!noteUpdatedFromRemote.hasOwnProperty(n)) continue;
|
||||
expect(noteUpdatedFromRemote[n]).toBe(note2[n], 'Property: ' + n);
|
||||
expect(noteUpdatedFromRemote[n]).toBe(note2[n], `Property: ${n}`);
|
||||
}
|
||||
}));
|
||||
|
||||
@ -850,7 +850,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
let resourcePath1 = Resource.fullPath(resource1);
|
||||
await synchronizer().start();
|
||||
@ -883,7 +883,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
let resourcePath1 = Resource.fullPath(resource1);
|
||||
await synchronizer().start();
|
||||
@ -910,7 +910,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await synchronizer().start();
|
||||
|
||||
await switchClient(2);
|
||||
@ -933,7 +933,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
let resourcePath1 = Resource.fullPath(resource1);
|
||||
await synchronizer().start();
|
||||
@ -949,7 +949,7 @@ describe('Synchronizer', function() {
|
||||
await synchronizer().start();
|
||||
expect((await remoteNotesFoldersResources()).length).toBe(2);
|
||||
|
||||
const remoteBlob = await fileApi().stat('.resource/' + resource1.id);
|
||||
const remoteBlob = await fileApi().stat(`.resource/${resource1.id}`);
|
||||
expect(!remoteBlob).toBe(true);
|
||||
|
||||
await switchClient(1);
|
||||
@ -967,7 +967,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
let resourcePath1 = Resource.fullPath(resource1);
|
||||
await synchronizer().start();
|
||||
@ -1049,7 +1049,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
let resource1 = (await Resource.all())[0];
|
||||
await Resource.setFileSizeOnly(resource1.id, -1);
|
||||
let resourcePath1 = Resource.fullPath(resource1);
|
||||
@ -1075,7 +1075,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await synchronizer().start();
|
||||
|
||||
expect(await allSyncTargetItemsEncrypted()).toBe(false);
|
||||
@ -1094,7 +1094,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
let folder1 = await Folder.save({ title: 'folder1' });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
const masterKey = await loadEncryptionMasterKey();
|
||||
await encryptionService().enableEncryption(masterKey, '123456');
|
||||
await encryptionService().loadMasterKeysFromSettings();
|
||||
@ -1307,7 +1307,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
it('should not download resources over the limit', asyncTest(async () => {
|
||||
const note1 = await Note.save({ title: 'note' });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
await synchronizer().start();
|
||||
|
||||
await switchClient(2);
|
||||
@ -1337,7 +1337,7 @@ describe('Synchronizer', function() {
|
||||
// does get uploaded.
|
||||
|
||||
const note1 = await Note.save({ title: 'note' });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
const resource = (await Resource.all())[0];
|
||||
await Resource.setLocalState(resource.id, { fetch_status: Resource.FETCH_STATUS_IDLE });
|
||||
await synchronizer().start();
|
||||
@ -1352,7 +1352,7 @@ describe('Synchronizer', function() {
|
||||
|
||||
it('should decrypt the resource metadata, but not try to decrypt the file, if it is not present', asyncTest(async () => {
|
||||
const note1 = await Note.save({ title: 'note' });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
await shim.attachFileToNote(note1, `${__dirname}/../tests/support/photo.jpg`);
|
||||
const masterKey = await loadEncryptionMasterKey();
|
||||
await encryptionService().enableEncryption(masterKey, '123456');
|
||||
await encryptionService().loadMasterKeysFromSettings();
|
||||
|
@ -56,8 +56,8 @@ Resource.fsDriver_ = fsDriver;
|
||||
EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
|
||||
const logDir = __dirname + '/../tests/logs';
|
||||
const tempDir = __dirname + '/../tests/tmp';
|
||||
const logDir = `${__dirname}/../tests/logs`;
|
||||
const tempDir = `${__dirname}/../tests/tmp`;
|
||||
fs.mkdirpSync(logDir, 0o755);
|
||||
fs.mkdirpSync(tempDir, 0o755);
|
||||
|
||||
@ -71,20 +71,20 @@ SyncTargetRegistry.addClass(SyncTargetDropbox);
|
||||
const syncTargetId_ = SyncTargetRegistry.nameToId('memory');
|
||||
//const syncTargetId_ = SyncTargetRegistry.nameToId('filesystem');
|
||||
// const syncTargetId_ = SyncTargetRegistry.nameToId('dropbox');
|
||||
const syncDir = __dirname + '/../tests/sync';
|
||||
const syncDir = `${__dirname}/../tests/sync`;
|
||||
|
||||
const sleepTime = syncTargetId_ == SyncTargetRegistry.nameToId('filesystem') ? 1001 : 100;//400;
|
||||
|
||||
console.info('Testing with sync target: ' + SyncTargetRegistry.idToName(syncTargetId_));
|
||||
console.info(`Testing with sync target: ${SyncTargetRegistry.idToName(syncTargetId_)}`);
|
||||
|
||||
const dbLogger = new Logger();
|
||||
dbLogger.addTarget('console');
|
||||
dbLogger.addTarget('file', { path: logDir + '/log.txt' });
|
||||
dbLogger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
dbLogger.setLevel(Logger.LEVEL_WARN);
|
||||
|
||||
const logger = new Logger();
|
||||
logger.addTarget('console');
|
||||
logger.addTarget('file', { path: logDir + '/log.txt' });
|
||||
logger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
logger.setLevel(Logger.LEVEL_WARN); // Set to DEBUG to display sync process in console
|
||||
|
||||
BaseItem.loadClass('Note', Note);
|
||||
@ -116,7 +116,7 @@ function sleep(n) {
|
||||
}
|
||||
|
||||
async function switchClient(id) {
|
||||
if (!databases_[id]) throw new Error('Call setupDatabaseAndSynchronizer(' + id + ') first!!');
|
||||
if (!databases_[id]) throw new Error(`Call setupDatabaseAndSynchronizer(${id}) first!!`);
|
||||
|
||||
await time.msleep(sleepTime); // Always leave a little time so that updated_time properties don't overlap
|
||||
await Setting.saveAll();
|
||||
@ -162,8 +162,8 @@ async function clearDatabase(id = null) {
|
||||
|
||||
const queries = [];
|
||||
for (const n of tableNames) {
|
||||
queries.push('DELETE FROM ' + n);
|
||||
queries.push('DELETE FROM sqlite_sequence WHERE name="' + n + '"'); // Reset autoincremented IDs
|
||||
queries.push(`DELETE FROM ${n}`);
|
||||
queries.push(`DELETE FROM sqlite_sequence WHERE name="${n}"`); // Reset autoincremented IDs
|
||||
}
|
||||
|
||||
await databases_[id].transactionExecBatch(queries);
|
||||
@ -181,7 +181,7 @@ async function setupDatabase(id = null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filePath = __dirname + '/data/test-' + id + '.sqlite';
|
||||
const filePath = `${__dirname}/data/test-${id}.sqlite`;
|
||||
|
||||
try {
|
||||
await fs.unlink(filePath);
|
||||
@ -199,7 +199,7 @@ async function setupDatabase(id = null) {
|
||||
|
||||
function resourceDir(id = null) {
|
||||
if (id === null) id = currentClient_;
|
||||
return __dirname + '/data/resources-' + id;
|
||||
return `${__dirname}/data/resources-${id}`;
|
||||
}
|
||||
|
||||
async function setupDatabaseAndSynchronizer(id = null) {
|
||||
@ -310,9 +310,9 @@ function fileApi() {
|
||||
fileApi_ = new FileApi('', new FileApiDriverWebDav(api));
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('dropbox')) {
|
||||
const api = new DropboxApi();
|
||||
const authTokenPath = __dirname + '/support/dropbox-auth.txt';
|
||||
const authTokenPath = `${__dirname}/support/dropbox-auth.txt`;
|
||||
const authToken = fs.readFileSync(authTokenPath, 'utf8');
|
||||
if (!authToken) throw new Error('Dropbox auth token missing in ' + authTokenPath);
|
||||
if (!authToken) throw new Error(`Dropbox auth token missing in ${authTokenPath}`);
|
||||
api.setAuthToken(authToken);
|
||||
fileApi_ = new FileApi('', new FileApiDriverDropbox(api));
|
||||
}
|
||||
@ -380,7 +380,7 @@ async function allSyncTargetItemsEncrypted() {
|
||||
totalCount++;
|
||||
|
||||
if (remoteContent.type_ === BaseModel.TYPE_RESOURCE) {
|
||||
const content = await fileApi().get('.resource/' + remoteContent.id);
|
||||
const content = await fileApi().get(`.resource/${remoteContent.id}`);
|
||||
totalCount++;
|
||||
if (content.substr(0, 5) === 'JED01') encryptedCount++;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ browser_.runtime.onMessage.addListener(async (command) => {
|
||||
newArea.height *= zoom;
|
||||
content.crop_rect = newArea;
|
||||
|
||||
fetch(command.api_base_url + '/notes', {
|
||||
fetch(`${command.api_base_url}/notes`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
|
@ -26,9 +26,9 @@
|
||||
if (url.indexOf('//') === 0) {
|
||||
return location.protocol + url;
|
||||
} else if (url[0] === '/') {
|
||||
return location.protocol + '//' + location.host + url;
|
||||
return `${location.protocol}//${location.host}${url}`;
|
||||
} else {
|
||||
return baseUrl() + '/' + url;
|
||||
return `${baseUrl()}/${url}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@
|
||||
}
|
||||
|
||||
async function prepareCommandResponse(command) {
|
||||
console.info('Got command: ' + command.name);
|
||||
console.info(`Got command: ${command.name}`);
|
||||
|
||||
const convertToMarkup = command.preProcessFor ? command.preProcessFor : 'markdown';
|
||||
|
||||
@ -343,15 +343,15 @@
|
||||
messageComp.style.position = 'fixed';
|
||||
messageComp.style.opacity = '0.95';
|
||||
messageComp.style.fontSize = '14px';
|
||||
messageComp.style.width = messageCompWidth + 'px';
|
||||
messageComp.style.maxWidth = messageCompWidth + 'px';
|
||||
messageComp.style.width = `${messageCompWidth}px`;
|
||||
messageComp.style.maxWidth = `${messageCompWidth}px`;
|
||||
messageComp.style.border = '1px solid black';
|
||||
messageComp.style.background = 'white';
|
||||
messageComp.style.color = 'black';
|
||||
messageComp.style.top = '10px';
|
||||
messageComp.style.textAlign = 'center';
|
||||
messageComp.style.padding = '10px';
|
||||
messageComp.style.left = Math.round(document.body.clientWidth / 2 - messageCompWidth / 2) + 'px';
|
||||
messageComp.style.left = `${Math.round(document.body.clientWidth / 2 - messageCompWidth / 2)}px`;
|
||||
messageComp.style.zIndex = overlay.style.zIndex + 1;
|
||||
|
||||
messageComp.textContent = 'Drag and release to capture a screenshot';
|
||||
@ -375,10 +375,10 @@
|
||||
let selectionArea = {};
|
||||
|
||||
const updateSelection = function() {
|
||||
selection.style.left = selectionArea.x + 'px';
|
||||
selection.style.top = selectionArea.y + 'px';
|
||||
selection.style.width = selectionArea.width + 'px';
|
||||
selection.style.height = selectionArea.height + 'px';
|
||||
selection.style.left = `${selectionArea.x}px`;
|
||||
selection.style.top = `${selectionArea.y}px`;
|
||||
selection.style.width = `${selectionArea.width}px`;
|
||||
selection.style.height = `${selectionArea.height}px`;
|
||||
};
|
||||
|
||||
const setSelectionSizeFromMouse = function(event) {
|
||||
@ -448,7 +448,7 @@
|
||||
return clippedContentResponse(pageTitle(), url, getImageSizes(document), getAnchorNames(document));
|
||||
|
||||
} else {
|
||||
throw new Error('Unknown command: ' + JSON.stringify(command));
|
||||
throw new Error(`Unknown command: ${JSON.stringify(command)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
const fs = require('fs-extra');
|
||||
|
||||
fs.copySync(__dirname + '/../../../../ReactNativeClient/lib/randomClipperPort.js', __dirname + '/../src/randomClipperPort.js');
|
||||
fs.copySync(`${__dirname}/../../../../ReactNativeClient/lib/randomClipperPort.js`, `${__dirname}/../src/randomClipperPort.js`);
|
||||
|
@ -16,7 +16,7 @@ function commandUserString(command) {
|
||||
if (command.name === 'pageUrl') s.push('URL only');
|
||||
|
||||
const p = command.preProcessFor ? command.preProcessFor : 'markdown';
|
||||
s.push('(' + p + ')');
|
||||
s.push(`(${p})`);
|
||||
|
||||
return s.join(' ');
|
||||
}
|
||||
@ -234,7 +234,7 @@ class AppComponent extends Component {
|
||||
this.focusNewTagInput_ = false;
|
||||
let lastRef = null;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const ref = this.refs['tagSelector' + i];
|
||||
const ref = this.refs[`tagSelector${i}`];
|
||||
if (!ref) break;
|
||||
lastRef = ref;
|
||||
}
|
||||
@ -245,7 +245,7 @@ class AppComponent extends Component {
|
||||
render() {
|
||||
if (!this.state.contentScriptLoaded) {
|
||||
let msg = 'Loading...';
|
||||
if (this.state.contentScriptError) msg = 'The Joplin extension is not available on this tab due to: ' + this.state.contentScriptError;
|
||||
if (this.state.contentScriptError) msg = `The Joplin extension is not available on this tab due to: ${this.state.contentScriptError}`;
|
||||
return <div style={{padding: 10, fontSize: 12, maxWidth: 200}}>{msg}</div>;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ class AppComponent extends Component {
|
||||
} else if (operation.success) {
|
||||
msg = 'Note was successfully created!';
|
||||
} else {
|
||||
msg = 'There was some error creating the note: ' + operation.errorMessage;
|
||||
msg = `There was some error creating the note: ${operation.errorMessage}`;
|
||||
}
|
||||
|
||||
previewComponent = (
|
||||
@ -300,7 +300,7 @@ class AppComponent extends Component {
|
||||
const foundState = this.props.clipperServer.foundState;
|
||||
|
||||
if (foundState === 'found') {
|
||||
msg = 'Ready on port ' + this.props.clipperServer.port;
|
||||
msg = `Ready on port ${this.props.clipperServer.port}`;
|
||||
led = led_green;
|
||||
} else {
|
||||
msg = stateToString(foundState);
|
||||
@ -308,7 +308,7 @@ class AppComponent extends Component {
|
||||
if (foundState === 'not_found') helpLink = <a className="Help" onClick={this.clipperServerHelpLink_click} href="help">[Help]</a>;
|
||||
}
|
||||
|
||||
msg = 'Service status: ' + msg;
|
||||
msg = `Service status: ${msg}`;
|
||||
|
||||
return <div className="StatusBar"><img alt={foundState} className="Led" src={led}/><span className="ServerStatus">{ msg }{ helpLink }</span></div>;
|
||||
};
|
||||
@ -346,7 +346,7 @@ class AppComponent extends Component {
|
||||
for (let i = 0; i < this.state.selectedTags.length; i++) {
|
||||
comps.push(<div key={i}>
|
||||
<input
|
||||
ref={'tagSelector' + i}
|
||||
ref={`tagSelector${i}`}
|
||||
data-index={i}
|
||||
type="text"
|
||||
list="tags"
|
||||
|
@ -19,7 +19,7 @@ class Bridge {
|
||||
console.info('Popup: Got command:', command);
|
||||
|
||||
if (command.warning) {
|
||||
console.warn('Popup: Got warning: ' + command.warning);
|
||||
console.warn(`Popup: Got warning: ${command.warning}`);
|
||||
this.dispatch({ type: 'WARNING_SET', text: command.warning });
|
||||
} else {
|
||||
this.dispatch({ type: 'WARNING_SET', text: '' });
|
||||
@ -125,10 +125,10 @@ class Bridge {
|
||||
state = randomClipperPort(state, this.env());
|
||||
|
||||
try {
|
||||
console.info('findClipperServerPort: Trying ' + state.port);
|
||||
const response = await fetch('http://127.0.0.1:' + state.port + '/ping');
|
||||
console.info(`findClipperServerPort: Trying ${state.port}`);
|
||||
const response = await fetch(`http://127.0.0.1:${state.port}/ping`);
|
||||
const text = await response.text();
|
||||
console.info('findClipperServerPort: Got response: ' + text);
|
||||
console.info(`findClipperServerPort: Got response: ${text}`);
|
||||
if (text.trim() === 'JoplinClipperServer') {
|
||||
this.clipperServerPortStatus_ = 'found';
|
||||
this.clipperServerPort_ = state.port;
|
||||
@ -182,7 +182,7 @@ class Bridge {
|
||||
|
||||
async clipperServerBaseUrl() {
|
||||
const port = await this.clipperServerPort();
|
||||
return 'http://127.0.0.1:' + port;
|
||||
return `http://127.0.0.1:${port}`;
|
||||
}
|
||||
|
||||
async tabsExecuteScript(options) {
|
||||
@ -192,7 +192,7 @@ class Bridge {
|
||||
this.browser().tabs.executeScript(options, () => {
|
||||
const e = this.browser().runtime.lastError;
|
||||
if (e) {
|
||||
const msg = ['tabsExecuteScript: Cannot load ' + JSON.stringify(options)];
|
||||
const msg = [`tabsExecuteScript: Cannot load ${JSON.stringify(options)}`];
|
||||
if (e.message) msg.push(e.message);
|
||||
reject(new Error(msg.join(': ')));
|
||||
}
|
||||
@ -277,7 +277,7 @@ class Bridge {
|
||||
}
|
||||
|
||||
async clipperApiExec(method, path, query, body) {
|
||||
console.info('Popup: ' + method + ' ' + path);
|
||||
console.info(`Popup: ${method} ${path}`);
|
||||
|
||||
const baseUrl = await this.clipperServerBaseUrl();
|
||||
|
||||
@ -295,13 +295,13 @@ class Bridge {
|
||||
const s = [];
|
||||
for (const k in query) {
|
||||
if (!query.hasOwnProperty(k)) continue;
|
||||
s.push(encodeURIComponent(k) + '=' + encodeURIComponent(query[k]));
|
||||
s.push(`${encodeURIComponent(k)}=${encodeURIComponent(query[k])}`);
|
||||
}
|
||||
queryString = s.join('&');
|
||||
if (queryString) queryString = '?' + queryString;
|
||||
if (queryString) queryString = `?${queryString}`;
|
||||
}
|
||||
|
||||
const response = await fetch(baseUrl + '/' + path + queryString, fetchOptions);
|
||||
const response = await fetch(`${baseUrl}/${path}${queryString}`, fetchOptions);
|
||||
if (!response.ok) {
|
||||
const msg = await response.text();
|
||||
throw new Error(msg);
|
||||
|
@ -39,7 +39,7 @@ class ElectronAppWrapper {
|
||||
const stateOptions = {
|
||||
defaultWidth: 800,
|
||||
defaultHeight: 600,
|
||||
file: 'window-state-' + this.env_ + '.json',
|
||||
file: `window-state-${this.env_}.json`,
|
||||
};
|
||||
|
||||
if (this.profilePath_) stateOptions.path = this.profilePath_;
|
||||
@ -145,9 +145,9 @@ class ElectronAppWrapper {
|
||||
|
||||
buildDir() {
|
||||
if (this.buildDir_) return this.buildDir_;
|
||||
let dir = __dirname + '/build';
|
||||
let dir = `${__dirname}/build`;
|
||||
if (!fs.pathExistsSync(dir)) {
|
||||
dir = dirname(__dirname) + '/build';
|
||||
dir = `${dirname(__dirname)}/build`;
|
||||
if (!fs.pathExistsSync(dir)) throw new Error('Cannot find build dir');
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ class ElectronAppWrapper {
|
||||
// Note: this must be called only after the "ready" event of the app has been dispatched
|
||||
createTray(contextMenu) {
|
||||
try {
|
||||
this.tray_ = new Tray(this.buildDir() + '/icons/' + this.trayIconFilename_());
|
||||
this.tray_ = new Tray(`${this.buildDir()}/icons/${this.trayIconFilename_()}`);
|
||||
this.tray_.setToolTip(this.electronApp_.getName());
|
||||
this.tray_.setContextMenu(contextMenu);
|
||||
|
||||
|
@ -62,7 +62,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
checkForUpdateLoggerPath() {
|
||||
return Setting.value('profileDir') + '/log-autoupdater.txt';
|
||||
return `${Setting.value('profileDir')}/log-autoupdater.txt`;
|
||||
}
|
||||
|
||||
reducer(state = appDefaultState, action) {
|
||||
@ -203,7 +203,7 @@ class Application extends BaseApplication {
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = 'In reducer: ' + error.message + ' Action: ' + JSON.stringify(action);
|
||||
error.message = `In reducer: ${error.message} Action: ${JSON.stringify(action)}`;
|
||||
throw error;
|
||||
}
|
||||
|
||||
@ -272,16 +272,16 @@ class Application extends BaseApplication {
|
||||
|
||||
const sortNoteFolderItems = (type) => {
|
||||
const sortItems = [];
|
||||
const sortOptions = Setting.enumOptions(type + '.sortOrder.field');
|
||||
const sortOptions = Setting.enumOptions(`${type}.sortOrder.field`);
|
||||
for (let field in sortOptions) {
|
||||
if (!sortOptions.hasOwnProperty(field)) continue;
|
||||
sortItems.push({
|
||||
label: sortOptions[field],
|
||||
screens: ['Main'],
|
||||
type: 'checkbox',
|
||||
checked: Setting.value(type + '.sortOrder.field') === field,
|
||||
checked: Setting.value(`${type}.sortOrder.field`) === field,
|
||||
click: () => {
|
||||
Setting.setValue(type + '.sortOrder.field', field);
|
||||
Setting.setValue(`${type}.sortOrder.field`, field);
|
||||
this.refreshMenu();
|
||||
},
|
||||
});
|
||||
@ -290,12 +290,12 @@ class Application extends BaseApplication {
|
||||
sortItems.push({ type: 'separator' });
|
||||
|
||||
sortItems.push({
|
||||
label: Setting.settingMetadata(type + '.sortOrder.reverse').label(),
|
||||
label: Setting.settingMetadata(`${type}.sortOrder.reverse`).label(),
|
||||
type: 'checkbox',
|
||||
checked: Setting.value(type + '.sortOrder.reverse'),
|
||||
checked: Setting.value(`${type}.sortOrder.reverse`),
|
||||
screens: ['Main'],
|
||||
click: () => {
|
||||
Setting.setValue(type + '.sortOrder.reverse', !Setting.value(type + '.sortOrder.reverse'));
|
||||
Setting.setValue(`${type}.sortOrder.reverse`, !Setting.value(`${type}.sortOrder.reverse`));
|
||||
},
|
||||
});
|
||||
|
||||
@ -408,7 +408,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
exportItems.push({
|
||||
label: 'PDF - ' + _('PDF File'),
|
||||
label: `PDF - ${_('PDF File')}`,
|
||||
screens: ['Main'],
|
||||
click: async () => {
|
||||
this.dispatch({
|
||||
@ -567,11 +567,11 @@ class Application extends BaseApplication {
|
||||
_('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform),
|
||||
];
|
||||
if (gitInfo) {
|
||||
message.push('\n' + gitInfo);
|
||||
message.push(`\n${gitInfo}`);
|
||||
console.info(gitInfo);
|
||||
}
|
||||
bridge().showInfoMessageBox(message.join('\n'), {
|
||||
icon: bridge().electronApp().buildDir() + '/icons/32x32.png',
|
||||
icon: `${bridge().electronApp().buildDir()}/icons/32x32.png`,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1027,7 +1027,7 @@ class Application extends BaseApplication {
|
||||
const note = selectedNoteIds.length === 1 ? await Note.load(selectedNoteIds[0]) : null;
|
||||
|
||||
for (const itemId of ['copy', 'paste', 'cut', 'selectAll', 'bold', 'italic', 'link', 'code', 'insertDateTime', 'commandStartExternalEditing', 'setTags', 'showLocalSearch']) {
|
||||
const menuItem = Menu.getApplicationMenu().getMenuItemById('edit:' + itemId);
|
||||
const menuItem = Menu.getApplicationMenu().getMenuItemById(`edit:${itemId}`);
|
||||
if (!menuItem) continue;
|
||||
menuItem.enabled = !!note && note.markup_language === Note.MARKUP_LANGUAGE_MARKDOWN;
|
||||
}
|
||||
@ -1052,13 +1052,13 @@ class Application extends BaseApplication {
|
||||
|
||||
updateEditorFont() {
|
||||
const fontFamilies = [];
|
||||
if (Setting.value('style.editor.fontFamily')) fontFamilies.push('"' + Setting.value('style.editor.fontFamily') + '"');
|
||||
if (Setting.value('style.editor.fontFamily')) fontFamilies.push(`"${Setting.value('style.editor.fontFamily')}"`);
|
||||
fontFamilies.push('monospace');
|
||||
|
||||
// The '*' and '!important' parts are necessary to make sure Russian text is displayed properly
|
||||
// https://github.com/laurent22/joplin/issues/155
|
||||
|
||||
const css = '.ace_editor * { font-family: ' + fontFamilies.join(', ') + ' !important; }';
|
||||
const css = `.ace_editor * { font-family: ${fontFamilies.join(', ')} !important; }`;
|
||||
const styleTag = document.createElement('style');
|
||||
styleTag.type = 'text/css';
|
||||
styleTag.appendChild(document.createTextNode(css));
|
||||
@ -1073,7 +1073,7 @@ class Application extends BaseApplication {
|
||||
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = 'Could not load custom css from ' + filePath + '\n' + msg;
|
||||
msg = `Could not load custom css from ${filePath}\n${msg}`;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
@ -1139,7 +1139,7 @@ class Application extends BaseApplication {
|
||||
ids: Setting.value('collapsedFolderIds'),
|
||||
});
|
||||
|
||||
const cssString = await this.loadCustomCss(Setting.value('profileDir') + '/userstyle.css');
|
||||
const cssString = await this.loadCustomCss(`${Setting.value('profileDir')}/userstyle.css`);
|
||||
|
||||
this.store().dispatch({
|
||||
type: 'LOAD_CUSTOM_CSS',
|
||||
@ -1193,7 +1193,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
const clipperLogger = new Logger();
|
||||
clipperLogger.addTarget('file', { path: Setting.value('profileDir') + '/log-clipper.txt' });
|
||||
clipperLogger.addTarget('file', { path: `${Setting.value('profileDir')}/log-clipper.txt` });
|
||||
clipperLogger.addTarget('console');
|
||||
|
||||
ClipperServer.instance().setLogger(clipperLogger);
|
||||
|
@ -42,7 +42,7 @@ async function fetchLatestRelease(options) {
|
||||
|
||||
if (!response.ok) {
|
||||
const responseText = await response.text();
|
||||
throw new Error('Cannot get latest release info: ' + responseText.substr(0,500));
|
||||
throw new Error(`Cannot get latest release info: ${responseText.substr(0,500)}`);
|
||||
}
|
||||
|
||||
json = await response.json();
|
||||
@ -53,7 +53,7 @@ async function fetchLatestRelease(options) {
|
||||
|
||||
if (!response.ok) {
|
||||
const responseText = await response.text();
|
||||
throw new Error('Cannot get latest release info: ' + responseText.substr(0,500));
|
||||
throw new Error(`Cannot get latest release info: ${responseText.substr(0,500)}`);
|
||||
}
|
||||
|
||||
json = await response.json();
|
||||
@ -112,11 +112,11 @@ function checkForUpdates(inBackground, window, logFilePath, options) {
|
||||
|
||||
checkInBackground_ = inBackground;
|
||||
|
||||
autoUpdateLogger_.info('checkForUpdates: Checking with options ' + JSON.stringify(options));
|
||||
autoUpdateLogger_.info(`checkForUpdates: Checking with options ${JSON.stringify(options)}`);
|
||||
|
||||
fetchLatestRelease(options).then(release => {
|
||||
autoUpdateLogger_.info('Current version: ' + packageInfo.version);
|
||||
autoUpdateLogger_.info('Latest version: ' + release.version);
|
||||
autoUpdateLogger_.info(`Current version: ${packageInfo.version}`);
|
||||
autoUpdateLogger_.info(`Latest version: ${release.version}`);
|
||||
autoUpdateLogger_.info('Is Pre-release:', release.prerelease);
|
||||
|
||||
if (compareVersions(release.version, packageInfo.version) <= 0) {
|
||||
@ -126,12 +126,12 @@ function checkForUpdates(inBackground, window, logFilePath, options) {
|
||||
buttons: [_('OK')],
|
||||
});
|
||||
} else {
|
||||
const releaseNotes = release.notes.trim() ? '\n\n' + release.notes.trim() : '';
|
||||
const releaseNotes = release.notes.trim() ? `\n\n${release.notes.trim()}` : '';
|
||||
const newVersionString = release.prerelease ? _('%s (pre-release)', release.version) : release.version;
|
||||
|
||||
const buttonIndex = dialog.showMessageBox(parentWindow_, {
|
||||
type: 'info',
|
||||
message: _('An update is available, do you want to download it now?') + '\n\n' + _('Your version: %s', packageInfo.version) + '\n' + _('New version: %s', newVersionString) + releaseNotes,
|
||||
message: `${_('An update is available, do you want to download it now?')}\n\n${_('Your version: %s', packageInfo.version)}\n${_('New version: %s', newVersionString)}${releaseNotes}`,
|
||||
buttons: [_('Yes'), _('No')],
|
||||
});
|
||||
|
||||
|
@ -4,7 +4,7 @@ const execSync = require('child_process').execSync;
|
||||
// Electron Builder strip off certain important keys from package.json, which we need, in particular build.appId
|
||||
// so this script is used to preserve the keys that we need.
|
||||
|
||||
const packageInfo = require(__dirname + '/package.json');
|
||||
const packageInfo = require(`${__dirname}/package.json`);
|
||||
|
||||
let removeKeys = ['scripts', 'devDependencies', 'optionalDependencies', 'dependencies'];
|
||||
|
||||
@ -30,8 +30,8 @@ if (typeof branch !== 'undefined' && typeof hash !== 'undefined') {
|
||||
packageInfo.git = { branch: branch, hash: hash };
|
||||
}
|
||||
|
||||
let fileContent = '// Auto-generated by compile-package-info.js\n// Do not change directly\nconst packageInfo = ' + JSON.stringify(packageInfo, null, 4) + ';';
|
||||
let fileContent = `// Auto-generated by compile-package-info.js\n// Do not change directly\nconst packageInfo = ${JSON.stringify(packageInfo, null, 4)};`;
|
||||
fileContent += '\n';
|
||||
fileContent += 'module.exports = packageInfo;';
|
||||
|
||||
fs.writeFileSync(__dirname + '/packageInfo.js', fileContent);
|
||||
fs.writeFileSync(`${__dirname}/packageInfo.js`, fileContent);
|
||||
|
@ -1,8 +1,8 @@
|
||||
const fs = require('fs-extra');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
|
||||
const babelPath = __dirname + '/node_modules/.bin/babel' + (process.platform === 'win32' ? '.cmd' : '');
|
||||
const basePath = __dirname + '/../..';
|
||||
const babelPath = `${__dirname}/node_modules/.bin/babel${process.platform === 'win32' ? '.cmd' : ''}`;
|
||||
const basePath = `${__dirname}/../..`;
|
||||
|
||||
function fileIsNewerThan(path1, path2) {
|
||||
if (!fs.existsSync(path2)) return true;
|
||||
@ -15,7 +15,7 @@ function fileIsNewerThan(path1, path2) {
|
||||
|
||||
function convertJsx(path) {
|
||||
fs.readdirSync(path).forEach((filename) => {
|
||||
const jsxPath = path + '/' + filename;
|
||||
const jsxPath = `${path}/${filename}`;
|
||||
const p = jsxPath.split('.');
|
||||
if (p.length <= 1) return;
|
||||
const ext = p[p.length - 1];
|
||||
@ -24,10 +24,10 @@ function convertJsx(path) {
|
||||
|
||||
const basePath = p.join('.');
|
||||
|
||||
const jsPath = basePath + '.min.js';
|
||||
const jsPath = `${basePath}.min.js`;
|
||||
|
||||
if (fileIsNewerThan(jsxPath, jsPath)) {
|
||||
console.info('Compiling ' + jsxPath + '...');
|
||||
console.info(`Compiling ${jsxPath}...`);
|
||||
const result = spawnSync(babelPath, ['--presets', 'react', '--out-file', jsPath, jsxPath]);
|
||||
if (result.status !== 0) {
|
||||
const msg = [];
|
||||
@ -41,13 +41,13 @@ function convertJsx(path) {
|
||||
});
|
||||
}
|
||||
|
||||
convertJsx(__dirname + '/gui');
|
||||
convertJsx(__dirname + '/plugins');
|
||||
convertJsx(`${__dirname}/gui`);
|
||||
convertJsx(`${__dirname}/plugins`);
|
||||
|
||||
const libContent = [
|
||||
fs.readFileSync(basePath + '/ReactNativeClient/lib/string-utils-common.js', 'utf8'),
|
||||
fs.readFileSync(basePath + '/ReactNativeClient/lib/markJsUtils.js', 'utf8'),
|
||||
fs.readFileSync(basePath + '/ReactNativeClient/lib/renderers/webviewLib.js', 'utf8'),
|
||||
fs.readFileSync(`${basePath}/ReactNativeClient/lib/string-utils-common.js`, 'utf8'),
|
||||
fs.readFileSync(`${basePath}/ReactNativeClient/lib/markJsUtils.js`, 'utf8'),
|
||||
fs.readFileSync(`${basePath}/ReactNativeClient/lib/renderers/webviewLib.js`, 'utf8'),
|
||||
];
|
||||
|
||||
fs.writeFileSync(__dirname + '/gui/note-viewer/lib.js', libContent.join('\n'), 'utf8');
|
||||
fs.writeFileSync(`${__dirname}/gui/note-viewer/lib.js`, libContent.join('\n'), 'utf8');
|
||||
|
@ -1,7 +1,7 @@
|
||||
const execCommand = function(command) {
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
console.info('Running: ' + command);
|
||||
console.info(`Running: ${command}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, (error, stdout) => {
|
||||
@ -25,14 +25,14 @@ const isWindows = () => {
|
||||
async function main() {
|
||||
// electron-rebuild --arch ia32 && electron-rebuild --arch x64
|
||||
|
||||
let exePath = __dirname + '/node_modules/.bin/electron-rebuild';
|
||||
let exePath = `${__dirname}/node_modules/.bin/electron-rebuild`;
|
||||
if (isWindows()) exePath += '.cmd';
|
||||
|
||||
if (isWindows()) {
|
||||
console.info(await execCommand(['"' + exePath + '"', '--arch ia32'].join(' ')));
|
||||
console.info(await execCommand(['"' + exePath + '"', '--arch x64'].join(' ')));
|
||||
console.info(await execCommand([`"${exePath}"`, '--arch ia32'].join(' ')));
|
||||
console.info(await execCommand([`"${exePath}"`, '--arch x64'].join(' ')));
|
||||
} else {
|
||||
console.info(await execCommand(['"' + exePath + '"'].join(' ')));
|
||||
console.info(await execCommand([`"${exePath}"`].join(' ')));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ function ConfigMenuBarButton(props) {
|
||||
|
||||
return (
|
||||
<button style={style.button} onClick={props.onClick}>
|
||||
<i style={iconStyle} className={'fa ' + props.iconName}></i>
|
||||
<i style={iconStyle} className={`fa ${props.iconName}`}></i>
|
||||
<span style={labelStyle}>{props.label}</span>
|
||||
</button>
|
||||
);
|
||||
|
@ -49,14 +49,14 @@ class ConfigScreenComponent extends React.Component {
|
||||
if (section.name === name) return section;
|
||||
}
|
||||
|
||||
throw new Error('Invalid section name: ' + name);
|
||||
throw new Error(`Invalid section name: ${name}`);
|
||||
}
|
||||
|
||||
screenFromName(screenName) {
|
||||
if (screenName === 'encryption') return <EncryptionConfigScreen theme={this.props.theme}/>;
|
||||
if (screenName === 'server') return <ClipperConfigScreen theme={this.props.theme}/>;
|
||||
|
||||
throw new Error('Invalid screen name: ' + screenName);
|
||||
throw new Error(`Invalid screen name: ${screenName}`);
|
||||
}
|
||||
|
||||
switchSection(name) {
|
||||
@ -249,7 +249,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
<div key={key + value.toString()} style={rowStyle}>
|
||||
<div style={controlStyle}>
|
||||
<input
|
||||
id={'setting_checkbox_' + key}
|
||||
id={`setting_checkbox_${key}`}
|
||||
type="checkbox"
|
||||
checked={!!value}
|
||||
onChange={event => {
|
||||
@ -261,7 +261,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
onCheckboxClick(event);
|
||||
}}
|
||||
style={checkboxLabelStyle}
|
||||
htmlFor={'setting_checkbox_' + key}
|
||||
htmlFor={`setting_checkbox_${key}`}
|
||||
>
|
||||
{md.label()}
|
||||
</label>
|
||||
@ -289,7 +289,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
if (!cmdArray[0] && !cmdArray[1]) return '';
|
||||
let cmdString = pathUtils.quotePath(cmdArray[0]);
|
||||
if (!cmdString) cmdString = '""';
|
||||
if (cmdArray[1]) cmdString += ' ' + cmdArray[1];
|
||||
if (cmdArray[1]) cmdString += ` ${cmdArray[1]}`;
|
||||
return cmdString;
|
||||
};
|
||||
|
||||
@ -390,7 +390,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
};
|
||||
|
||||
const label = [md.label()];
|
||||
if (md.unitLabel) label.push('(' + md.unitLabel() + ')');
|
||||
if (md.unitLabel) label.push(`(${md.unitLabel()})`);
|
||||
|
||||
const inputStyle = Object.assign({}, textInputBaseStyle);
|
||||
|
||||
@ -414,7 +414,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
console.warn('Type not implemented: ' + key);
|
||||
console.warn(`Type not implemented: ${key}`);
|
||||
}
|
||||
|
||||
return output;
|
||||
|
@ -6,19 +6,19 @@ const { _ } = require('lib/locale.js');
|
||||
function platformAssets(type) {
|
||||
if (type === 'firefox') {
|
||||
return {
|
||||
logoImage: bridge().buildDir() + '/images/firefox-logo.svg',
|
||||
logoImage: `${bridge().buildDir()}/images/firefox-logo.svg`,
|
||||
locationLabel: _('Firefox Extension'),
|
||||
};
|
||||
}
|
||||
|
||||
if (type === 'chrome') {
|
||||
return {
|
||||
logoImage: bridge().buildDir() + '/images/chrome-logo.svg',
|
||||
logoImage: `${bridge().buildDir()}/images/chrome-logo.svg`,
|
||||
locationLabel: _('Chrome Web Store'),
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error('Invalid type:' + type);
|
||||
throw new Error(`Invalid type:${type}`);
|
||||
}
|
||||
|
||||
function ExtensionBadge(props) {
|
||||
|
@ -123,9 +123,9 @@ class HeaderComponent extends React.Component {
|
||||
if (options.title) iconStyle.marginRight = 5;
|
||||
if ('undefined' != typeof options.iconRotation) {
|
||||
iconStyle.transition = 'transform 0.15s ease-in-out';
|
||||
iconStyle.transform = 'rotate(' + options.iconRotation + 'deg)';
|
||||
iconStyle.transform = `rotate(${options.iconRotation}deg)`;
|
||||
}
|
||||
icon = <i style={iconStyle} className={'fa ' + options.iconName}></i>;
|
||||
icon = <i style={iconStyle} className={`fa ${options.iconName}`}></i>;
|
||||
}
|
||||
|
||||
const isEnabled = !('enabled' in options) || options.enabled;
|
||||
@ -195,7 +195,7 @@ class HeaderComponent extends React.Component {
|
||||
};
|
||||
|
||||
const iconName = state.searchQuery ? 'fa-times' : 'fa-search';
|
||||
const icon = <i style={iconStyle} className={'fa ' + iconName}></i>;
|
||||
const icon = <i style={iconStyle} className={`fa ${iconName}`}></i>;
|
||||
if (options.onQuery) this.searchOnQuery_ = options.onQuery;
|
||||
|
||||
const usageLink = !this.state.showSearchUsageLink ? null : (
|
||||
@ -222,7 +222,7 @@ class HeaderComponent extends React.Component {
|
||||
style.height = theme.headerHeight;
|
||||
style.display = 'flex';
|
||||
style.flexDirection = 'row';
|
||||
style.borderBottom = '1px solid ' + theme.dividerColor;
|
||||
style.borderBottom = `1px solid ${theme.dividerColor}`;
|
||||
style.boxSizing = 'border-box';
|
||||
|
||||
const items = [];
|
||||
@ -252,9 +252,9 @@ class HeaderComponent extends React.Component {
|
||||
const item = this.props.items[i];
|
||||
|
||||
if (item.type === 'search') {
|
||||
items.push(this.makeSearch('item_' + i + '_search', itemStyle, item, this.state));
|
||||
items.push(this.makeSearch(`item_${i}_search`, itemStyle, item, this.state));
|
||||
} else {
|
||||
items.push(this.makeButton('item_' + i + '_' + item.title, itemStyle, item));
|
||||
items.push(this.makeButton(`item_${i}_${item.title}`, itemStyle, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class IconButton extends React.Component {
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize * 1.4,
|
||||
};
|
||||
const icon = <i style={iconStyle} className={'fa ' + this.props.iconName}></i>;
|
||||
const icon = <i style={iconStyle} className={`fa ${this.props.iconName}`}></i>;
|
||||
|
||||
const rootStyle = Object.assign(
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ class NoteListComponent extends React.Component {
|
||||
display: 'flex',
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: theme.backgroundColor,
|
||||
borderBottom: '1px solid ' + theme.dividerColor,
|
||||
borderBottom: `1px solid ${theme.dividerColor}`,
|
||||
},
|
||||
listItemSelected: {
|
||||
backgroundColor: theme.selectedColor,
|
||||
@ -222,7 +222,7 @@ class NoteListComponent extends React.Component {
|
||||
// Need to include "todo_completed" in key so that checkbox is updated when
|
||||
// item is changed via sync.
|
||||
return (
|
||||
<div key={item.id + '_' + item.todo_completed} style={style}>
|
||||
<div key={`${item.id}_${item.todo_completed}`} style={style}>
|
||||
{checkbox}
|
||||
<a
|
||||
ref={ref}
|
||||
@ -393,7 +393,7 @@ class NoteListComponent extends React.Component {
|
||||
const padding = 10;
|
||||
const emptyDivStyle = Object.assign(
|
||||
{
|
||||
padding: padding + 'px',
|
||||
padding: `${padding}px`,
|
||||
fontSize: theme.fontSize,
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
|
@ -76,7 +76,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
|
||||
formNote.location = '';
|
||||
if (Number(note.latitude) || Number(note.longitude)) {
|
||||
formNote.location = note.latitude + ', ' + note.longitude;
|
||||
formNote.location = `${note.latitude}, ${note.longitude}`;
|
||||
}
|
||||
|
||||
formNote.revisionsLink = note.id;
|
||||
@ -328,7 +328,7 @@ class NotePropertiesDialog extends React.Component {
|
||||
if (editCompHandler) {
|
||||
editComp = (
|
||||
<a href="#" onClick={editCompHandler} style={styles.editPropertyButton}>
|
||||
<i className={'fa ' + editCompIcon} aria-hidden="true" style={{ marginLeft: '.5em' }}></i>
|
||||
<i className={`fa ${editCompIcon}`} aria-hidden="true" style={{ marginLeft: '.5em' }}></i>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const markupToHtml = new MarkupToHtml({
|
||||
resourceBaseUrl: 'file://' + Setting.value('resourceDir') + '/',
|
||||
resourceBaseUrl: `file://${Setting.value('resourceDir')}/`,
|
||||
});
|
||||
|
||||
const result = markupToHtml.render(markupLanguage, noteBody, theme, {
|
||||
@ -138,7 +138,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
|
||||
revisionListItems.push(
|
||||
<option key={rev.id} value={rev.id}>
|
||||
{time.formatMsToLocal(rev.item_updated_time) + ' (' + stats + ')'}
|
||||
{`${time.formatMsToLocal(rev.item_updated_time)} (${stats})`}
|
||||
</option>
|
||||
);
|
||||
}
|
||||
@ -149,7 +149,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
|
||||
const titleInput = (
|
||||
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 10, borderWidth: 1, borderBottomStyle: 'solid', borderColor: theme.dividerColor, paddingBottom: 10 }}>
|
||||
<button onClick={this.backButton_click} style={Object.assign({}, theme.buttonStyle, { marginRight: 10, height: theme.inputStyle.height })}>
|
||||
{'⬅ ' + _('Back')}
|
||||
{`⬅ ${_('Back')}`}
|
||||
</button>
|
||||
<input readOnly type="text" style={style.titleInput} value={this.state.note ? this.state.note.title : ''} />
|
||||
<select disabled={!this.state.revisions.length} value={this.state.currentRevId} style={style.revisionList} onChange={this.revisionList_onChange}>
|
||||
|
@ -53,7 +53,7 @@ class NoteSearchBarComponent extends React.Component {
|
||||
color: theme.color,
|
||||
};
|
||||
|
||||
const icon = <i style={iconStyle} className={'fa ' + iconName}></i>;
|
||||
const icon = <i style={iconStyle} className={`fa ${iconName}`}></i>;
|
||||
|
||||
return (
|
||||
<a href="#" style={searchButton} onClick={clickHandler}>
|
||||
|
@ -135,7 +135,7 @@ class NoteTextComponent extends React.Component {
|
||||
const image = clipboard.readImage();
|
||||
|
||||
const fileExt = mimeUtils.toFileExtension(format);
|
||||
const filePath = Setting.value('tempDir') + '/' + md5(Date.now()) + '.' + fileExt;
|
||||
const filePath = `${Setting.value('tempDir')}/${md5(Date.now())}.${fileExt}`;
|
||||
|
||||
await shim.writeImageToFile(image, format, filePath);
|
||||
await this.commandAttachFile([filePath]);
|
||||
@ -362,7 +362,7 @@ class NoteTextComponent extends React.Component {
|
||||
markupToHtml() {
|
||||
if (this.markupToHtml_) return this.markupToHtml_;
|
||||
this.markupToHtml_ = new MarkupToHtml({
|
||||
resourceBaseUrl: 'file://' + Setting.value('resourceDir') + '/',
|
||||
resourceBaseUrl: `file://${Setting.value('resourceDir')}/`,
|
||||
});
|
||||
return this.markupToHtml_;
|
||||
}
|
||||
@ -712,7 +712,7 @@ class NoteTextComponent extends React.Component {
|
||||
const args = event.args;
|
||||
const arg0 = args && args.length >= 1 ? args[0] : null;
|
||||
|
||||
if (msg !== 'percentScroll') console.info('Got ipc-message: ' + msg, args);
|
||||
if (msg !== 'percentScroll') console.info(`Got ipc-message: ${msg}`, args);
|
||||
|
||||
if (msg.indexOf('checkboxclick:') === 0) {
|
||||
// Ugly hack because setting the body here will make the scrollbar
|
||||
@ -733,7 +733,7 @@ class NoteTextComponent extends React.Component {
|
||||
this.setState({ localSearch: ls });
|
||||
} else if (msg.indexOf('markForDownload:') === 0) {
|
||||
const s = msg.split(':');
|
||||
if (s.length < 2) throw new Error('Invalid message: ' + msg);
|
||||
if (s.length < 2) throw new Error(`Invalid message: ${msg}`);
|
||||
ResourceFetcher.instance().markForDownload(s[1]);
|
||||
} else if (msg === 'percentScroll') {
|
||||
this.ignoreNextEditorScroll_ = true;
|
||||
@ -751,7 +751,7 @@ class NoteTextComponent extends React.Component {
|
||||
new MenuItem({
|
||||
label: _('Open...'),
|
||||
click: async () => {
|
||||
const ok = bridge().openExternal('file://' + resourcePath);
|
||||
const ok = bridge().openExternal(`file://${resourcePath}`);
|
||||
if (!ok) bridge().showErrorMessageBox(_('This file could not be opened: %s', resourcePath));
|
||||
},
|
||||
})
|
||||
@ -797,7 +797,7 @@ class NoteTextComponent extends React.Component {
|
||||
})
|
||||
);
|
||||
} else {
|
||||
reg.logger().error('Unhandled item type: ' + itemType);
|
||||
reg.logger().error(`Unhandled item type: ${itemType}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -807,7 +807,7 @@ class NoteTextComponent extends React.Component {
|
||||
const itemId = resourceUrlInfo.itemId;
|
||||
const item = await BaseItem.loadItemById(itemId);
|
||||
|
||||
if (!item) throw new Error('No item with ID ' + itemId);
|
||||
if (!item) throw new Error(`No item with ID ${itemId}`);
|
||||
|
||||
if (item.type_ === BaseModel.TYPE_RESOURCE) {
|
||||
const localState = await Resource.localState(item);
|
||||
@ -829,7 +829,7 @@ class NoteTextComponent extends React.Component {
|
||||
},
|
||||
});
|
||||
} else {
|
||||
throw new Error('Unsupported item type: ' + item.type_);
|
||||
throw new Error(`Unsupported item type: ${item.type_}`);
|
||||
}
|
||||
} else if (urlUtils.urlProtocol(msg)) {
|
||||
if (msg.indexOf('file://') === 0) {
|
||||
@ -929,8 +929,8 @@ class NoteTextComponent extends React.Component {
|
||||
const letters = ['F', 'T', 'P', 'Q', 'L', ',', 'G', 'K'];
|
||||
for (let i = 0; i < letters.length; i++) {
|
||||
const l = letters[i];
|
||||
cancelledKeys.push('Ctrl+' + l);
|
||||
cancelledKeys.push('Command+' + l);
|
||||
cancelledKeys.push(`Ctrl+${l}`);
|
||||
cancelledKeys.push(`Command+${l}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < cancelledKeys.length; i++) {
|
||||
@ -940,7 +940,7 @@ class NoteTextComponent extends React.Component {
|
||||
// an exception from this undocumented function seems to cancel it without any
|
||||
// side effect.
|
||||
// https://stackoverflow.com/questions/36075846
|
||||
throw new Error('HACK: Overriding Ace Editor shortcut: ' + k);
|
||||
throw new Error(`HACK: Overriding Ace Editor shortcut: ${k}`);
|
||||
});
|
||||
}
|
||||
|
||||
@ -970,12 +970,12 @@ class NoteTextComponent extends React.Component {
|
||||
const leftSpaces = lineLeftSpaces(line);
|
||||
const lineNoLeftSpaces = line.trimLeft();
|
||||
|
||||
if (lineNoLeftSpaces.indexOf('- [ ] ') === 0 || lineNoLeftSpaces.indexOf('- [x] ') === 0 || lineNoLeftSpaces.indexOf('- [X] ') === 0) return leftSpaces + '- [ ] ';
|
||||
if (lineNoLeftSpaces.indexOf('- ') === 0) return leftSpaces + '- ';
|
||||
if (lineNoLeftSpaces.indexOf('* ') === 0 && line.trim() !== '* * *') return leftSpaces + '* ';
|
||||
if (lineNoLeftSpaces.indexOf('- [ ] ') === 0 || lineNoLeftSpaces.indexOf('- [x] ') === 0 || lineNoLeftSpaces.indexOf('- [X] ') === 0) return `${leftSpaces}- [ ] `;
|
||||
if (lineNoLeftSpaces.indexOf('- ') === 0) return `${leftSpaces}- `;
|
||||
if (lineNoLeftSpaces.indexOf('* ') === 0 && line.trim() !== '* * *') return `${leftSpaces}* `;
|
||||
|
||||
const bulletNumber = markdownUtils.olLineNumber(lineNoLeftSpaces);
|
||||
if (bulletNumber) return leftSpaces + (bulletNumber + 1) + '. ';
|
||||
if (bulletNumber) return `${leftSpaces + (bulletNumber + 1)}. `;
|
||||
|
||||
return this.$getIndent(line);
|
||||
};
|
||||
@ -1032,7 +1032,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
if (!bodyToRender.trim() && visiblePanes.indexOf('viewer') >= 0 && visiblePanes.indexOf('editor') < 0) {
|
||||
// Fixes https://github.com/laurent22/joplin/issues/217
|
||||
bodyToRender = '<i>' + _('This note has no content. Click on "%s" to toggle the editor and edit the note.', _('Layout')) + '</i>';
|
||||
bodyToRender = `<i>${_('This note has no content. Click on "%s" to toggle the editor and edit the note.', _('Layout'))}</i>`;
|
||||
}
|
||||
|
||||
const result = this.markupToHtml().render(markupLanguage, bodyToRender, theme, mdOptions);
|
||||
@ -1155,7 +1155,7 @@ class NoteTextComponent extends React.Component {
|
||||
for (let i = 0; i < filePaths.length; i++) {
|
||||
const filePath = filePaths[i];
|
||||
try {
|
||||
reg.logger().info('Attaching ' + filePath);
|
||||
reg.logger().info(`Attaching ${filePath}`);
|
||||
note = await shim.attachFileToNote(note, filePath, position, createFileURL);
|
||||
reg.logger().info('File was attached.');
|
||||
this.setState({
|
||||
@ -1183,7 +1183,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
// helper function to style the title for printing
|
||||
title_(title) {
|
||||
return '<div style="font-size: 2em; font-weight: bold; border-bottom: 1px solid rgb(230,230,230); padding-bottom: .3em;">' + title + '</div><br>';
|
||||
return `<div style="font-size: 2em; font-weight: bold; border-bottom: 1px solid rgb(230,230,230); padding-bottom: .3em;">${title}</div><br>`;
|
||||
}
|
||||
|
||||
async printTo_(target, options) {
|
||||
@ -1192,7 +1192,7 @@ class NoteTextComponent extends React.Component {
|
||||
}
|
||||
|
||||
const previousBody = this.state.note.body;
|
||||
const tempBody = this.title_(this.state.note.title) + '\n\n' + previousBody;
|
||||
const tempBody = `${this.title_(this.state.note.title)}\n\n${previousBody}`;
|
||||
|
||||
const previousTheme = Setting.value('theme');
|
||||
Setting.setValue('theme', Setting.THEME_LIGHT);
|
||||
@ -1470,7 +1470,7 @@ class NoteTextComponent extends React.Component {
|
||||
let bulletNumber = markdownUtils.olLineNumber(this.selectionRangeCurrentLine());
|
||||
if (!bulletNumber) bulletNumber = markdownUtils.olLineNumber(this.selectionRangePreviousLine());
|
||||
if (!bulletNumber) bulletNumber = 0;
|
||||
this.addListItem(bulletNumber + 1 + '. ', '', _('List item'));
|
||||
this.addListItem(`${bulletNumber + 1}. `, '', _('List item'));
|
||||
}
|
||||
|
||||
commandTextHeading() {
|
||||
@ -1483,7 +1483,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
async commandTextLink() {
|
||||
const url = await dialogs.prompt(_('Insert Hyperlink'));
|
||||
this.wrapSelectionWithStrings('[', '](' + url + ')');
|
||||
this.wrapSelectionWithStrings('[', `](${url})`);
|
||||
}
|
||||
|
||||
itemContextMenu() {
|
||||
@ -1796,7 +1796,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
const rootStyle = Object.assign(
|
||||
{
|
||||
borderLeft: borderWidth + 'px solid ' + theme.dividerColor,
|
||||
borderLeft: `${borderWidth}px solid ${theme.dividerColor}`,
|
||||
boxSizing: 'border-box',
|
||||
paddingLeft: 10,
|
||||
paddingRight: 0,
|
||||
@ -1887,9 +1887,9 @@ class NoteTextComponent extends React.Component {
|
||||
overflowY: 'hidden',
|
||||
float: 'left',
|
||||
verticalAlign: 'top',
|
||||
paddingTop: paddingTop + 'px',
|
||||
lineHeight: theme.textAreaLineHeight + 'px',
|
||||
fontSize: theme.editorFontSize + 'px',
|
||||
paddingTop: `${paddingTop}px`,
|
||||
lineHeight: `${theme.textAreaLineHeight}px`,
|
||||
fontSize: `${theme.editorFontSize}px`,
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
editorTheme: theme.editorTheme,
|
||||
@ -1913,7 +1913,7 @@ class NoteTextComponent extends React.Component {
|
||||
}
|
||||
|
||||
if (visiblePanes.indexOf('viewer') >= 0 && visiblePanes.indexOf('editor') >= 0) {
|
||||
viewerStyle.borderLeft = '1px solid ' + theme.dividerColor;
|
||||
viewerStyle.borderLeft = `1px solid ${theme.dividerColor}`;
|
||||
} else {
|
||||
viewerStyle.borderLeft = 'none';
|
||||
}
|
||||
@ -2010,8 +2010,8 @@ class NoteTextComponent extends React.Component {
|
||||
mode={markupLanguage === Note.MARKUP_LANGUAGE_HTML ? 'text' : 'markdown'}
|
||||
theme={editorRootStyle.editorTheme}
|
||||
style={editorRootStyle}
|
||||
width={editorStyle.width + 'px'}
|
||||
height={editorStyle.height + 'px'}
|
||||
width={`${editorStyle.width}px`}
|
||||
height={`${editorStyle.height}px`}
|
||||
fontSize={editorStyle.fontSize}
|
||||
showGutter={false}
|
||||
name="note-editor"
|
||||
@ -2038,7 +2038,7 @@ class NoteTextComponent extends React.Component {
|
||||
/>
|
||||
);
|
||||
|
||||
const noteSearchBarComp = !this.state.showLocalSearch ? null : <NoteSearchBar ref={this.noteSearchBar_} style={{ display: 'flex', height: searchBarHeight, width: innerWidth, borderTop: '1px solid ' + theme.dividerColor }} onChange={this.noteSearchBar_change} onNext={this.noteSearchBar_next} onPrevious={this.noteSearchBar_previous} onClose={this.noteSearchBar_close} />;
|
||||
const noteSearchBarComp = !this.state.showLocalSearch ? null : <NoteSearchBar ref={this.noteSearchBar_} style={{ display: 'flex', height: searchBarHeight, width: innerWidth, borderTop: `1px solid ${theme.dividerColor}` }} onChange={this.noteSearchBar_change} onNext={this.noteSearchBar_next} onPrevious={this.noteSearchBar_previous} onClose={this.noteSearchBar_close} />;
|
||||
|
||||
return (
|
||||
<div style={rootStyle} onDrop={this.onDrop_}>
|
||||
|
@ -56,7 +56,7 @@ class OneDriveLoginScreenComponent extends React.Component {
|
||||
this.props.dispatch({ type: 'NAV_BACK' });
|
||||
reg.scheduleSync(0);
|
||||
} catch (error) {
|
||||
bridge().showErrorMessageBox('Could not login to OneDrive. Please try again.\n\n' + error.message + '\n\n' + url.match(/.{1,64}/g).join('\n'));
|
||||
bridge().showErrorMessageBox(`Could not login to OneDrive. Please try again.\n\n${error.message}\n\n${url.match(/.{1,64}/g).join('\n')}`);
|
||||
}
|
||||
|
||||
this.authCode_ = null;
|
||||
|
@ -39,7 +39,7 @@ class PromptDialog extends React.Component {
|
||||
}
|
||||
|
||||
styles(themeId, width, height, visible) {
|
||||
const styleKey = themeId + '_' + width + '_' + height + '_' + visible;
|
||||
const styleKey = `${themeId}_${width}_${height}_${visible}`;
|
||||
if (styleKey === this.styleKey_) return this.styles_;
|
||||
|
||||
const theme = themeStyle(themeId);
|
||||
@ -61,7 +61,7 @@ class PromptDialog extends React.Component {
|
||||
display: visible ? 'flex' : 'none',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'center',
|
||||
paddingTop: paddingTop + 'px',
|
||||
paddingTop: `${paddingTop}px`,
|
||||
};
|
||||
|
||||
this.styles_.promptDialog = {
|
||||
|
@ -427,7 +427,7 @@ class SideBarComponent extends React.Component {
|
||||
};
|
||||
|
||||
const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'fa-plus-square' : 'fa-minus-square';
|
||||
const expandIcon = <i style={expandIconStyle} className={'fa ' + iconName}></i>;
|
||||
const expandIcon = <i style={expandIconStyle} className={`fa ${iconName}`}></i>;
|
||||
const expandLink = hasChildren ? (
|
||||
<a style={expandLinkStyle} href="#" folderid={folder.id} onClick={this.onFolderToggleClick_}>
|
||||
{expandIcon}
|
||||
@ -515,7 +515,7 @@ class SideBarComponent extends React.Component {
|
||||
|
||||
makeHeader(key, label, iconName, extraProps = {}) {
|
||||
const style = this.style().header;
|
||||
const icon = <i style={{ fontSize: style.fontSize, marginRight: 5 }} className={'fa ' + iconName} />;
|
||||
const icon = <i style={{ fontSize: style.fontSize, marginRight: 5 }} className={`fa ${iconName}`} />;
|
||||
|
||||
if (extraProps.toggleblock || extraProps.onClick) {
|
||||
style.cursor = 'pointer';
|
||||
@ -603,7 +603,7 @@ class SideBarComponent extends React.Component {
|
||||
|
||||
const focusItem = focusItems[newIndex];
|
||||
|
||||
let actionName = focusItem.type.toUpperCase() + '_SELECT';
|
||||
let actionName = `${focusItem.type.toUpperCase()}_SELECT`;
|
||||
|
||||
this.props.dispatch({
|
||||
type: actionName,
|
||||
@ -664,7 +664,7 @@ class SideBarComponent extends React.Component {
|
||||
iconStyle.animation = 'icon-infinite-rotation 1s linear infinite';
|
||||
}
|
||||
|
||||
const icon = <i style={iconStyle} className={'fa ' + iconName} />;
|
||||
const icon = <i style={iconStyle} className={`fa ${iconName}`} />;
|
||||
return (
|
||||
<a
|
||||
className="synchronize-button"
|
||||
|
@ -27,7 +27,7 @@ class StatusScreenComponent extends React.Component {
|
||||
}
|
||||
|
||||
async exportDebugReportClick() {
|
||||
const filename = 'syncReport-' + new Date().getTime() + '.csv';
|
||||
const filename = `syncReport-${new Date().getTime()}.csv`;
|
||||
|
||||
const filePath = bridge().showSaveDialog({
|
||||
title: _('Please select where the sync status should be exported to'),
|
||||
@ -57,7 +57,7 @@ class StatusScreenComponent extends React.Component {
|
||||
|
||||
function renderSectionTitleHtml(key, title) {
|
||||
return (
|
||||
<h2 key={'section_' + key} style={theme.h2Style}>
|
||||
<h2 key={`section_${key}`} style={theme.h2Style}>
|
||||
{title}
|
||||
</h2>
|
||||
);
|
||||
@ -95,7 +95,7 @@ class StatusScreenComponent extends React.Component {
|
||||
if (!text) text = '\xa0';
|
||||
|
||||
itemsHtml.push(
|
||||
<div style={theme.textStyle} key={'item_' + n}>
|
||||
<div style={theme.textStyle} key={`item_${n}`}>
|
||||
<span>{text}</span>
|
||||
{retryLink}
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@ class TagListComponent extends React.Component {
|
||||
|
||||
style.display = 'flex';
|
||||
style.flexDirection = 'row';
|
||||
style.borderBottom = '1px solid ' + theme.dividerColor;
|
||||
style.borderBottom = `1px solid ${theme.dividerColor}`;
|
||||
style.boxSizing = 'border-box';
|
||||
style.fontSize = theme.fontSize;
|
||||
|
||||
|
@ -11,7 +11,7 @@ class ToolbarComponent extends React.Component {
|
||||
style.height = theme.toolbarHeight;
|
||||
style.display = 'flex';
|
||||
style.flexDirection = 'row';
|
||||
style.borderBottom = '1px solid ' + theme.dividerColor;
|
||||
style.borderBottom = `1px solid ${theme.dividerColor}`;
|
||||
style.boxSizing = 'border-box';
|
||||
|
||||
const itemComps = [];
|
||||
@ -23,7 +23,7 @@ class ToolbarComponent extends React.Component {
|
||||
key += o.title ? o.title : '';
|
||||
const itemType = !('type' in o) ? 'button' : o.type;
|
||||
|
||||
if (!key) key = o.type + '_' + i;
|
||||
if (!key) key = `${o.type}_${i}`;
|
||||
|
||||
const props = Object.assign(
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ class ToolbarButton extends React.Component {
|
||||
color: theme.color,
|
||||
};
|
||||
if (title) iconStyle.marginRight = 5;
|
||||
icon = <i style={iconStyle} className={'fa ' + this.props.iconName}></i>;
|
||||
icon = <i style={iconStyle} className={`fa ${this.props.iconName}`}></i>;
|
||||
}
|
||||
|
||||
const isEnabled = !('enabled' in this.props) || this.props.enabled === true;
|
||||
|
@ -128,7 +128,7 @@ class NoteListUtils {
|
||||
if (noteIds.length === 1) {
|
||||
exportMenu.append(
|
||||
new MenuItem({
|
||||
label: 'PDF - ' + _('PDF File'),
|
||||
label: `PDF - ${_('PDF File')}`,
|
||||
click: () => {
|
||||
props.dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
|
@ -132,7 +132,7 @@ class Dialog extends React.PureComponent {
|
||||
const s = splitted[i].trim();
|
||||
if (!s) continue;
|
||||
|
||||
output.push('title:' + s + '*');
|
||||
output.push(`title:${s}*`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
@ -153,11 +153,11 @@ class Dialog extends React.PureComponent {
|
||||
|
||||
if (this.state.query.indexOf('#') === 0) { // TAGS
|
||||
listType = BaseModel.TYPE_TAG;
|
||||
searchQuery = '*' + this.state.query.split(' ')[0].substr(1).trim() + '*';
|
||||
searchQuery = `*${this.state.query.split(' ')[0].substr(1).trim()}*`;
|
||||
results = await Tag.searchAllWithNotes({ titlePattern: searchQuery });
|
||||
} else if (this.state.query.indexOf('@') === 0) { // FOLDERS
|
||||
listType = BaseModel.TYPE_FOLDER;
|
||||
searchQuery = '*' + this.state.query.split(' ')[0].substr(1).trim() + '*';
|
||||
searchQuery = `*${this.state.query.split(' ')[0].substr(1).trim()}*`;
|
||||
results = await Folder.search({ titlePattern: searchQuery });
|
||||
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
@ -246,7 +246,7 @@ class Dialog extends React.PureComponent {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
const style = this.style();
|
||||
const rowStyle = item.id === this.state.selectedItemId ? style.rowSelected : style.row;
|
||||
const titleHtml = surroundKeywords(this.state.keywords, item.title, '<span style="font-weight: bold; color: ' + theme.colorBright + ';">', '</span>');
|
||||
const titleHtml = surroundKeywords(this.state.keywords, item.title, `<span style="font-weight: bold; color: ${theme.colorBright};">`, '</span>');
|
||||
|
||||
const pathComp = !item.path ? null : <div style={style.rowPath}>{item.path}</div>;
|
||||
|
||||
|
@ -26,7 +26,7 @@ globalStyle.marginRight = globalStyle.margin;
|
||||
globalStyle.marginLeft = globalStyle.margin;
|
||||
globalStyle.marginTop = globalStyle.margin;
|
||||
globalStyle.marginBottom = globalStyle.margin;
|
||||
globalStyle.htmlMarginLeft = ((globalStyle.marginLeft / 10) * 0.6).toFixed(2) + 'em';
|
||||
globalStyle.htmlMarginLeft = `${((globalStyle.marginLeft / 10) * 0.6).toFixed(2)}em`;
|
||||
|
||||
globalStyle.icon = {
|
||||
fontSize: 30,
|
||||
@ -348,7 +348,7 @@ function themeStyle(theme) {
|
||||
textAreaLineHeight: Math.round(globalStyle.textAreaLineHeight * editorFontSize / 12),
|
||||
|
||||
// For WebView - must correspond to the properties above
|
||||
htmlFontSize: Math.round(15 * zoomRatio) + 'px',
|
||||
htmlFontSize: `${Math.round(15 * zoomRatio)}px`,
|
||||
htmlLineHeight: '1.6em', //Math.round(20 * zoomRatio) + 'px'
|
||||
|
||||
htmlCodeFontSize: '.9em',
|
||||
|
@ -509,9 +509,9 @@ class BaseApplication {
|
||||
determineProfileDir(initArgs) {
|
||||
if (initArgs.profileDir) return initArgs.profileDir;
|
||||
|
||||
if (process && process.env && process.env.PORTABLE_EXECUTABLE_DIR) return process.env.PORTABLE_EXECUTABLE_DIR + '/JoplinProfile';
|
||||
if (process && process.env && process.env.PORTABLE_EXECUTABLE_DIR) return `${process.env.PORTABLE_EXECUTABLE_DIR}/JoplinProfile`;
|
||||
|
||||
return os.homedir() + '/.config/' + Setting.value('appName');
|
||||
return `${os.homedir()}/.config/${Setting.value('appName')}`;
|
||||
}
|
||||
|
||||
async testing() {
|
||||
@ -548,12 +548,12 @@ class BaseApplication {
|
||||
|
||||
const profileDir = this.determineProfileDir(initArgs);
|
||||
const resourceDirName = 'resources';
|
||||
const resourceDir = profileDir + '/' + resourceDirName;
|
||||
const tempDir = profileDir + '/tmp';
|
||||
const resourceDir = `${profileDir}/${resourceDirName}`;
|
||||
const tempDir = `${profileDir}/tmp`;
|
||||
|
||||
Setting.setConstant('env', initArgs.env);
|
||||
Setting.setConstant('profileDir', profileDir);
|
||||
Setting.setConstant('templateDir', profileDir + '/templates');
|
||||
Setting.setConstant('templateDir', `${profileDir}/templates`);
|
||||
Setting.setConstant('resourceDirName', resourceDirName);
|
||||
Setting.setConstant('resourceDir', resourceDir);
|
||||
Setting.setConstant('tempDir', tempDir);
|
||||
@ -567,29 +567,29 @@ class BaseApplication {
|
||||
// Clean up any remaining watched files (they start with "edit-")
|
||||
await shim.fsDriver().removeAllThatStartWith(profileDir, 'edit-');
|
||||
|
||||
const extraFlags = await this.readFlagsFromFile(profileDir + '/flags.txt');
|
||||
const extraFlags = await this.readFlagsFromFile(`${profileDir}/flags.txt`);
|
||||
initArgs = Object.assign(initArgs, extraFlags);
|
||||
|
||||
this.logger_.addTarget('file', { path: profileDir + '/log.txt' });
|
||||
this.logger_.addTarget('file', { path: `${profileDir}/log.txt` });
|
||||
if (Setting.value('env') === 'dev') this.logger_.addTarget('console', { level: Logger.LEVEL_WARN });
|
||||
this.logger_.setLevel(initArgs.logLevel);
|
||||
|
||||
reg.setLogger(this.logger_);
|
||||
reg.dispatch = () => {};
|
||||
|
||||
this.dbLogger_.addTarget('file', { path: profileDir + '/log-database.txt' });
|
||||
this.dbLogger_.addTarget('file', { path: `${profileDir}/log-database.txt` });
|
||||
this.dbLogger_.setLevel(initArgs.logLevel);
|
||||
|
||||
if (Setting.value('env') === 'dev') {
|
||||
this.dbLogger_.setLevel(Logger.LEVEL_INFO);
|
||||
}
|
||||
|
||||
this.logger_.info('Profile directory: ' + profileDir);
|
||||
this.logger_.info(`Profile directory: ${profileDir}`);
|
||||
|
||||
this.database_ = new JoplinDatabase(new DatabaseDriverNode());
|
||||
this.database_.setLogExcludedQueryTypes(['SELECT']);
|
||||
this.database_.setLogger(this.dbLogger_);
|
||||
await this.database_.open({ name: profileDir + '/database.sqlite' });
|
||||
await this.database_.open({ name: `${profileDir}/database.sqlite` });
|
||||
|
||||
// if (Setting.value('env') === 'dev') await this.database_.clearForTesting();
|
||||
|
||||
@ -600,7 +600,7 @@ class BaseApplication {
|
||||
|
||||
if (Setting.value('firstStart')) {
|
||||
const locale = shim.detectAndSetLocale(Setting);
|
||||
reg.logger().info('First start: detected locale as ' + locale);
|
||||
reg.logger().info(`First start: detected locale as ${locale}`);
|
||||
|
||||
if (Setting.value('env') === 'dev') {
|
||||
Setting.setValue('showTrayIcon', 0);
|
||||
|
@ -74,7 +74,7 @@ class BaseModel {
|
||||
const e = BaseModel.typeEnum_[i];
|
||||
if (e[1] === type) return e[0].substr(5).toLowerCase();
|
||||
}
|
||||
throw new Error('Unknown model type: ' + type);
|
||||
throw new Error(`Unknown model type: ${type}`);
|
||||
}
|
||||
|
||||
static hasField(name) {
|
||||
@ -89,7 +89,7 @@ class BaseModel {
|
||||
let p = withPrefix === true ? this.tableName() : withPrefix;
|
||||
let temp = [];
|
||||
for (let i = 0; i < output.length; i++) {
|
||||
temp.push(p + '.' + output[i]);
|
||||
temp.push(`${p}.${output[i]}`);
|
||||
}
|
||||
|
||||
return temp;
|
||||
@ -101,7 +101,7 @@ class BaseModel {
|
||||
if (fields[i].name == name) return fields[i].type;
|
||||
}
|
||||
if (defaultValue !== null) return defaultValue;
|
||||
throw new Error('Unknown field: ' + name);
|
||||
throw new Error(`Unknown field: ${name}`);
|
||||
}
|
||||
|
||||
static fields() {
|
||||
@ -141,8 +141,8 @@ class BaseModel {
|
||||
|
||||
static count(options = null) {
|
||||
if (!options) options = {};
|
||||
let sql = 'SELECT count(*) as total FROM `' + this.tableName() + '`';
|
||||
if (options.where) sql += ' WHERE ' + options.where;
|
||||
let sql = `SELECT count(*) as total FROM \`${this.tableName()}\``;
|
||||
if (options.where) sql += ` WHERE ${options.where}`;
|
||||
return this.db()
|
||||
.selectOne(sql)
|
||||
.then(r => {
|
||||
@ -159,7 +159,7 @@ class BaseModel {
|
||||
}
|
||||
|
||||
static loadByPartialId(partialId) {
|
||||
return this.modelSelectAll('SELECT * FROM `' + this.tableName() + '` WHERE `id` LIKE ?', [partialId + '%']);
|
||||
return this.modelSelectAll(`SELECT * FROM \`${this.tableName()}\` WHERE \`id\` LIKE ?`, [`${partialId}%`]);
|
||||
}
|
||||
|
||||
static applySqlOptions(options, sql, params = null) {
|
||||
@ -171,19 +171,19 @@ class BaseModel {
|
||||
const o = options.order[i];
|
||||
let item = o.by;
|
||||
if (options.caseInsensitive === true) item += ' COLLATE NOCASE';
|
||||
if (o.dir) item += ' ' + o.dir;
|
||||
if (o.dir) item += ` ${o.dir}`;
|
||||
items.push(item);
|
||||
}
|
||||
sql += ' ORDER BY ' + items.join(', ');
|
||||
sql += ` ORDER BY ${items.join(', ')}`;
|
||||
}
|
||||
|
||||
if (options.limit) sql += ' LIMIT ' + options.limit;
|
||||
if (options.limit) sql += ` LIMIT ${options.limit}`;
|
||||
|
||||
return { sql: sql, params: params };
|
||||
}
|
||||
|
||||
static async allIds(options = null) {
|
||||
let q = this.applySqlOptions(options, 'SELECT id FROM `' + this.tableName() + '`');
|
||||
let q = this.applySqlOptions(options, `SELECT id FROM \`${this.tableName()}\``);
|
||||
const rows = await this.db().selectAll(q.sql, q.params);
|
||||
return rows.map(r => r.id);
|
||||
}
|
||||
@ -192,7 +192,7 @@ class BaseModel {
|
||||
if (!options) options = {};
|
||||
if (!options.fields) options.fields = '*';
|
||||
|
||||
let q = this.applySqlOptions(options, 'SELECT ' + this.db().escapeFields(options.fields) + ' FROM `' + this.tableName() + '`');
|
||||
let q = this.applySqlOptions(options, `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``);
|
||||
return this.modelSelectAll(q.sql);
|
||||
}
|
||||
|
||||
@ -201,8 +201,8 @@ class BaseModel {
|
||||
if (!options) options = {};
|
||||
if (!options.fields) options.fields = '*';
|
||||
|
||||
let sql = 'SELECT ' + this.db().escapeFields(options.fields) + ' FROM `' + this.tableName() + '`';
|
||||
sql += ' WHERE id IN ("' + ids.join('","') + '")';
|
||||
let sql = `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``;
|
||||
sql += ` WHERE id IN ("${ids.join('","')}")`;
|
||||
let q = this.applySqlOptions(options, sql);
|
||||
return this.modelSelectAll(q.sql);
|
||||
}
|
||||
@ -222,8 +222,8 @@ class BaseModel {
|
||||
|
||||
if ('limit' in options && options.limit <= 0) return [];
|
||||
|
||||
let sql = 'SELECT ' + this.db().escapeFields(options.fields) + ' FROM `' + this.tableName() + '`';
|
||||
if (conditions.length) sql += ' WHERE ' + conditions.join(' AND ');
|
||||
let sql = `SELECT ${this.db().escapeFields(options.fields)} FROM \`${this.tableName()}\``;
|
||||
if (conditions.length) sql += ` WHERE ${conditions.join(' AND ')}`;
|
||||
|
||||
let query = this.applySqlOptions(options, sql, params);
|
||||
return this.modelSelectAll(query.sql, query.params);
|
||||
@ -250,13 +250,13 @@ class BaseModel {
|
||||
static loadByField(fieldName, fieldValue, options = null) {
|
||||
if (!options) options = {};
|
||||
if (!('caseInsensitive' in options)) options.caseInsensitive = false;
|
||||
let sql = 'SELECT * FROM `' + this.tableName() + '` WHERE `' + fieldName + '` = ?';
|
||||
let sql = `SELECT * FROM \`${this.tableName()}\` WHERE \`${fieldName}\` = ?`;
|
||||
if (options.caseInsensitive) sql += ' COLLATE NOCASE';
|
||||
return this.modelSelectOne(sql, [fieldValue]);
|
||||
}
|
||||
|
||||
static loadByTitle(fieldValue) {
|
||||
return this.modelSelectOne('SELECT * FROM `' + this.tableName() + '` WHERE `title` = ?', [fieldValue]);
|
||||
return this.modelSelectOne(`SELECT * FROM \`${this.tableName()}\` WHERE \`title\` = ?`, [fieldValue]);
|
||||
}
|
||||
|
||||
static diffObjects(oldModel, newModel) {
|
||||
@ -514,14 +514,14 @@ class BaseModel {
|
||||
|
||||
static delete(id) {
|
||||
if (!id) throw new Error('Cannot delete object without an ID');
|
||||
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]);
|
||||
return this.db().exec(`DELETE FROM ${this.tableName()} WHERE id = ?`, [id]);
|
||||
}
|
||||
|
||||
static batchDelete(ids, options = null) {
|
||||
if (!ids.length) return;
|
||||
options = this.modOptions(options);
|
||||
const idFieldName = options.idFieldName ? options.idFieldName : 'id';
|
||||
const sql = 'DELETE FROM ' + this.tableName() + ' WHERE ' + idFieldName + ' IN ("' + ids.join('","') + '")';
|
||||
const sql = `DELETE FROM ${this.tableName()} WHERE ${idFieldName} IN ("${ids.join('","')}")`;
|
||||
return this.db().exec(sql);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Cache {
|
||||
Cache.storage = async function() {
|
||||
if (Cache.storage_) return Cache.storage_;
|
||||
Cache.storage_ = require('node-persist');
|
||||
await Cache.storage_.init({ dir: require('os').tmpdir() + '/joplin-cache', ttl: 1000 * 60 });
|
||||
await Cache.storage_.init({ dir: `${require('os').tmpdir()}/joplin-cache`, ttl: 1000 * 60 });
|
||||
return Cache.storage_;
|
||||
};
|
||||
|
||||
|
@ -129,7 +129,7 @@ class ClipperServer {
|
||||
if (instance.type === 'attachment') {
|
||||
const filename = instance.attachmentFilename ? instance.attachmentFilename : 'file';
|
||||
writeCorsHeaders(code, instance.contentType ? instance.contentType : 'application/octet-stream', {
|
||||
'Content-disposition': 'attachment; filename=' + filename,
|
||||
'Content-disposition': `attachment; filename=${filename}`,
|
||||
'Content-Length': instance.body.length,
|
||||
});
|
||||
response.end(instance.body);
|
||||
@ -148,7 +148,7 @@ class ClipperServer {
|
||||
}
|
||||
};
|
||||
|
||||
this.logger().info('Request: ' + request.method + ' ' + request.url);
|
||||
this.logger().info(`Request: ${request.method} ${request.url}`);
|
||||
|
||||
const url = urlParser.parse(request.url, true);
|
||||
|
||||
@ -204,7 +204,7 @@ class ClipperServer {
|
||||
|
||||
enableServerDestroy(this.server_);
|
||||
|
||||
this.logger().info('Starting Clipper server on port ' + this.port_);
|
||||
this.logger().info(`Starting Clipper server on port ${this.port_}`);
|
||||
|
||||
this.server_.listen(this.port_, '127.0.0.1');
|
||||
|
||||
|
@ -42,25 +42,25 @@ class DropboxApi {
|
||||
}
|
||||
|
||||
loginUrl() {
|
||||
return 'https://www.dropbox.com/oauth2/authorize?response_type=code&client_id=' + this.clientId();
|
||||
return `https://www.dropbox.com/oauth2/authorize?response_type=code&client_id=${this.clientId()}`;
|
||||
}
|
||||
|
||||
baseUrl(endPointFormat) {
|
||||
if (['content', 'api'].indexOf(endPointFormat) < 0) throw new Error('Invalid end point format: ' + endPointFormat);
|
||||
return 'https://' + endPointFormat + '.dropboxapi.com/2';
|
||||
if (['content', 'api'].indexOf(endPointFormat) < 0) throw new Error(`Invalid end point format: ${endPointFormat}`);
|
||||
return `https://${endPointFormat}.dropboxapi.com/2`;
|
||||
}
|
||||
|
||||
requestToCurl_(url, options) {
|
||||
let output = [];
|
||||
output.push('curl');
|
||||
if (options.method) output.push('-X ' + options.method);
|
||||
if (options.method) output.push(`-X ${options.method}`);
|
||||
if (options.headers) {
|
||||
for (let n in options.headers) {
|
||||
if (!options.headers.hasOwnProperty(n)) continue;
|
||||
output.push('-H ' + '\'' + n + ': ' + options.headers[n] + '\'');
|
||||
output.push(`${'-H ' + '\''}${n}: ${options.headers[n]}'`);
|
||||
}
|
||||
}
|
||||
if (options.body) output.push('--data ' + '"' + options.body + '"');
|
||||
if (options.body) output.push(`${'--data ' + '"'}${options.body}"`);
|
||||
output.push(url);
|
||||
|
||||
return output.join(' ');
|
||||
@ -78,7 +78,7 @@ class DropboxApi {
|
||||
for (var property in postData) {
|
||||
var encodedKey = encodeURIComponent(property);
|
||||
var encodedValue = encodeURIComponent(postData[property]);
|
||||
formBody.push(encodedKey + '=' + encodedValue);
|
||||
formBody.push(`${encodedKey}=${encodedValue}`);
|
||||
}
|
||||
formBody = formBody.join('&');
|
||||
|
||||
@ -110,7 +110,7 @@ class DropboxApi {
|
||||
|
||||
const authToken = this.authToken();
|
||||
|
||||
if (authToken) headers['Authorization'] = 'Bearer ' + authToken;
|
||||
if (authToken) headers['Authorization'] = `Bearer ${authToken}`;
|
||||
|
||||
const endPointFormat = ['files/upload', 'files/download'].indexOf(path) >= 0 ? 'content' : 'api';
|
||||
|
||||
@ -127,7 +127,7 @@ class DropboxApi {
|
||||
if (options.path) fetchOptions.path = options.path;
|
||||
if (body) fetchOptions.body = body;
|
||||
|
||||
const url = path.indexOf('https://') === 0 ? path : this.baseUrl(endPointFormat) + '/' + path;
|
||||
const url = path.indexOf('https://') === 0 ? path : `${this.baseUrl(endPointFormat)}/${path}`;
|
||||
|
||||
let tryCount = 0;
|
||||
|
||||
@ -174,8 +174,8 @@ class DropboxApi {
|
||||
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = (responseText + '').substr(0, 1024);
|
||||
const error = new JoplinError(method + ' ' + path + ': ' + message + ' (' + response.status + '): ' + shortResponseText, code);
|
||||
const shortResponseText = (`${responseText}`).substr(0, 1024);
|
||||
const error = new JoplinError(`${method} ${path}: ${message} (${response.status}): ${shortResponseText}`, code);
|
||||
error.httpStatus = response.status;
|
||||
return error;
|
||||
};
|
||||
@ -197,7 +197,7 @@ class DropboxApi {
|
||||
} catch (error) {
|
||||
tryCount++;
|
||||
if (error && typeof error.code === 'string' && error.code.indexOf('too_many_write_operations') >= 0) {
|
||||
this.logger().warn('too_many_write_operations ' + tryCount);
|
||||
this.logger().warn(`too_many_write_operations ${tryCount}`);
|
||||
if (tryCount >= 3) {
|
||||
throw error;
|
||||
}
|
||||
|
@ -52,10 +52,10 @@ class SyncTargetDropbox extends BaseSyncTarget {
|
||||
|
||||
api.on('authRefreshed', auth => {
|
||||
this.logger().info('Saving updated Dropbox auth.');
|
||||
Setting.setValue('sync.' + SyncTargetDropbox.id() + '.auth', auth ? auth : null);
|
||||
Setting.setValue(`sync.${SyncTargetDropbox.id()}.auth`, auth ? auth : null);
|
||||
});
|
||||
|
||||
const authToken = Setting.value('sync.' + SyncTargetDropbox.id() + '.auth');
|
||||
const authToken = Setting.value(`sync.${SyncTargetDropbox.id()}.auth`);
|
||||
api.setAuthToken(authToken);
|
||||
|
||||
const appDir = '';
|
||||
|
@ -51,10 +51,10 @@ class SyncTargetOneDrive extends BaseSyncTarget {
|
||||
|
||||
this.api_.on('authRefreshed', a => {
|
||||
this.logger().info('Saving updated OneDrive auth.');
|
||||
Setting.setValue('sync.' + this.syncTargetId() + '.auth', a ? JSON.stringify(a) : null);
|
||||
Setting.setValue(`sync.${this.syncTargetId()}.auth`, a ? JSON.stringify(a) : null);
|
||||
});
|
||||
|
||||
let auth = Setting.value('sync.' + this.syncTargetId() + '.auth');
|
||||
let auth = Setting.value(`sync.${this.syncTargetId()}.auth`);
|
||||
if (auth) {
|
||||
try {
|
||||
auth = JSON.parse(auth);
|
||||
|
@ -1,7 +1,7 @@
|
||||
class SyncTargetRegistry {
|
||||
static classById(syncTargetId) {
|
||||
const info = SyncTargetRegistry.reg_[syncTargetId];
|
||||
if (!info) throw new Error('Invalid id: ' + syncTargetId);
|
||||
if (!info) throw new Error(`Invalid id: ${syncTargetId}`);
|
||||
return info.classRef;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ class SyncTargetRegistry {
|
||||
if (!this.reg_.hasOwnProperty(n)) continue;
|
||||
if (this.reg_[n].name === name) return this.reg_[n].id;
|
||||
}
|
||||
throw new Error('Name not found: ' + name);
|
||||
throw new Error(`Name not found: ${name}`);
|
||||
}
|
||||
|
||||
static idToMetadata(id) {
|
||||
@ -28,7 +28,7 @@ class SyncTargetRegistry {
|
||||
if (!this.reg_.hasOwnProperty(n)) continue;
|
||||
if (this.reg_[n].id === id) return this.reg_[n];
|
||||
}
|
||||
throw new Error('ID not found: ' + id);
|
||||
throw new Error(`ID not found: ${id}`);
|
||||
}
|
||||
|
||||
static idToName(id) {
|
||||
|
@ -52,11 +52,11 @@ class SyncTargetWebDAV extends BaseSyncTarget {
|
||||
|
||||
try {
|
||||
const result = await fileApi.stat('');
|
||||
if (!result) throw new Error('WebDAV directory not found: ' + options.path());
|
||||
if (!result) throw new Error(`WebDAV directory not found: ${options.path()}`);
|
||||
output.ok = true;
|
||||
} catch (error) {
|
||||
output.errorMessage = error.message;
|
||||
if (error.code) output.errorMessage += ' (Code ' + error.code + ')';
|
||||
if (error.code) output.errorMessage += ` (Code ${error.code})`;
|
||||
}
|
||||
|
||||
return output;
|
||||
|
@ -80,7 +80,7 @@ class TaskQueue {
|
||||
}
|
||||
|
||||
async waitForResult(taskId) {
|
||||
if (!this.isWaiting(taskId) && !this.isProcessing(taskId) && !this.isDone(taskId)) throw new Error('No such task: ' + taskId);
|
||||
if (!this.isWaiting(taskId) && !this.isProcessing(taskId) && !this.isDone(taskId)) throw new Error(`No such task: ${taskId}`);
|
||||
|
||||
while (true) {
|
||||
// if (this.stopping_) {
|
||||
@ -99,7 +99,7 @@ class TaskQueue {
|
||||
async stop() {
|
||||
this.stopping_ = true;
|
||||
|
||||
this.logger_.info('TaskQueue.stop: ' + this.name_ + ': waiting for tasks to complete: ' + Object.keys(this.processingTasks_).length);
|
||||
this.logger_.info(`TaskQueue.stop: ${this.name_}: waiting for tasks to complete: ${Object.keys(this.processingTasks_).length}`);
|
||||
|
||||
// In general it's not a big issue if some tasks are still running because
|
||||
// it won't call anything unexpected in caller code, since the caller has
|
||||
@ -108,12 +108,12 @@ class TaskQueue {
|
||||
while (Object.keys(this.processingTasks_).length) {
|
||||
await time.sleep(0.1);
|
||||
if (Date.now() - startTime >= 30000) {
|
||||
this.logger_.warn('TaskQueue.stop: ' + this.name_ + ': timed out waiting for task to complete');
|
||||
this.logger_.warn(`TaskQueue.stop: ${this.name_}: timed out waiting for task to complete`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.logger_.info('TaskQueue.stop: ' + this.name_ + ': Done, waited for ' + (Date.now() - startTime));
|
||||
this.logger_.info(`TaskQueue.stop: ${this.name_}: Done, waited for ${Date.now() - startTime}`);
|
||||
}
|
||||
|
||||
isStopping() {
|
||||
|
@ -38,7 +38,7 @@ TemplateUtils.loadTemplates = async function(filePath) {
|
||||
files = await shim.fsDriver().readDirStats(filePath);
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = 'Could not read template names from ' + filePath + '\n' + msg;
|
||||
msg = `Could not read template names from ${filePath}\n${msg}`;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
@ -50,11 +50,11 @@ TemplateUtils.loadTemplates = async function(filePath) {
|
||||
files.forEach(async file => {
|
||||
if (file.path.endsWith('.md')) {
|
||||
try {
|
||||
let fileString = await shim.fsDriver().readFile(filePath + '/' + file.path, 'utf-8');
|
||||
let fileString = await shim.fsDriver().readFile(`${filePath}/${file.path}`, 'utf-8');
|
||||
templates.push({ label: file.path, value: fileString });
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = 'Could not load template ' + file.path + '\n' + msg;
|
||||
msg = `Could not load template ${file.path}\n${msg}`;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ class WebDavApi {
|
||||
// Note: Non-ASCII passwords will throw an error about Latin1 characters - https://github.com/laurent22/joplin/issues/246
|
||||
// Tried various things like the below, but it didn't work on React Native:
|
||||
//return base64.encode(utf8.encode(this.options_.username() + ':' + this.options_.password()));
|
||||
return base64.encode(this.options_.username() + ':' + this.options_.password());
|
||||
return base64.encode(`${this.options_.username()}:${this.options_.password()}`);
|
||||
} catch (error) {
|
||||
error.message = 'Cannot encode username/password: ' + error.message;
|
||||
error.message = `Cannot encode username/password: ${error.message}`;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ class WebDavApi {
|
||||
if (p.length == 2) {
|
||||
const ns = p[0];
|
||||
if (davNamespaces.indexOf(ns) >= 0) {
|
||||
name = 'd:' + p[1];
|
||||
name = `d:${p[1]}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ class WebDavApi {
|
||||
return output;
|
||||
}
|
||||
|
||||
throw new Error('Invalid output type: ' + outputType);
|
||||
throw new Error(`Invalid output type: ${outputType}`);
|
||||
}
|
||||
|
||||
async execPropFind(path, depth, fields = null, options = null) {
|
||||
@ -181,7 +181,7 @@ class WebDavApi {
|
||||
|
||||
let fieldsXml = '';
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
fieldsXml += '<' + fields[i] + '/>';
|
||||
fieldsXml += `<${fields[i]}/>`;
|
||||
}
|
||||
|
||||
// To find all available properties:
|
||||
@ -195,9 +195,9 @@ class WebDavApi {
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<d:propfind xmlns:d="DAV:">
|
||||
<d:prop xmlns:oc="http://owncloud.org/ns">
|
||||
` +
|
||||
fieldsXml +
|
||||
`
|
||||
${
|
||||
fieldsXml
|
||||
}
|
||||
</d:prop>
|
||||
</d:propfind>`;
|
||||
|
||||
@ -208,14 +208,14 @@ class WebDavApi {
|
||||
let output = [];
|
||||
output.push('curl');
|
||||
output.push('-v');
|
||||
if (options.method) output.push('-X ' + options.method);
|
||||
if (options.method) output.push(`-X ${options.method}`);
|
||||
if (options.headers) {
|
||||
for (let n in options.headers) {
|
||||
if (!options.headers.hasOwnProperty(n)) continue;
|
||||
output.push('-H ' + '"' + n + ': ' + options.headers[n] + '"');
|
||||
output.push(`${'-H ' + '"'}${n}: ${options.headers[n]}"`);
|
||||
}
|
||||
}
|
||||
if (options.body) output.push('--data ' + '\'' + options.body + '\'');
|
||||
if (options.body) output.push(`${'--data ' + '\''}${options.body}'`);
|
||||
output.push(url);
|
||||
|
||||
return output.join(' ');
|
||||
@ -300,7 +300,7 @@ class WebDavApi {
|
||||
|
||||
const authToken = this.authToken();
|
||||
|
||||
if (authToken) headers['Authorization'] = 'Basic ' + authToken;
|
||||
if (authToken) headers['Authorization'] = `Basic ${authToken}`;
|
||||
|
||||
// On iOS, the network lib appends a If-None-Match header to PROPFIND calls, which is kind of correct because
|
||||
// the call is idempotent and thus could be cached. According to RFC-7232 though only GET and HEAD should have
|
||||
@ -311,7 +311,7 @@ class WebDavApi {
|
||||
// The "solution", an ugly one, is to send a purposely invalid string as eTag, which will bypass the If-None-Match check - Seafile
|
||||
// finds out that no resource has this ID and simply sends the requested data.
|
||||
// Also add a random value to make sure the eTag is unique for each call.
|
||||
if (['GET', 'HEAD'].indexOf(method) < 0) headers['If-None-Match'] = 'JoplinIgnore-' + Math.floor(Math.random() * 100000);
|
||||
if (['GET', 'HEAD'].indexOf(method) < 0) headers['If-None-Match'] = `JoplinIgnore-${Math.floor(Math.random() * 100000)}`;
|
||||
|
||||
const fetchOptions = {};
|
||||
fetchOptions.headers = headers;
|
||||
@ -319,7 +319,7 @@ class WebDavApi {
|
||||
if (options.path) fetchOptions.path = options.path;
|
||||
if (body) fetchOptions.body = body;
|
||||
|
||||
const url = this.baseUrl() + '/' + path;
|
||||
const url = `${this.baseUrl()}/${path}`;
|
||||
|
||||
let response = null;
|
||||
|
||||
@ -329,11 +329,11 @@ class WebDavApi {
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
if (fetchOptions.path) {
|
||||
const fileStat = await shim.fsDriver().stat(fetchOptions.path);
|
||||
if (fileStat) fetchOptions.headers['Content-Length'] = fileStat.size + '';
|
||||
if (fileStat) fetchOptions.headers['Content-Length'] = `${fileStat.size}`;
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = shim.stringByteLength(body) + '';
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
// file
|
||||
@ -348,8 +348,8 @@ class WebDavApi {
|
||||
const newError = (message, code = 0) => {
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = (responseText + '').substr(0, 1024);
|
||||
return new JoplinError(method + ' ' + path + ': ' + message + ' (' + code + '): ' + shortResponseText, code);
|
||||
const shortResponseText = (`${responseText}`).substr(0, 1024);
|
||||
return new JoplinError(`${method} ${path}: ${message} (${code}): ${shortResponseText}`, code);
|
||||
};
|
||||
|
||||
let responseJson_ = null;
|
||||
@ -376,7 +376,7 @@ class WebDavApi {
|
||||
if (json && json['d:error']) {
|
||||
const code = json['d:error']['s:exception'] ? json['d:error']['s:exception'].join(' ') : response.status;
|
||||
const message = json['d:error']['s:message'] ? json['d:error']['s:message'].join('\n') : 'Unknown error 1';
|
||||
throw newError(message + ' (Exception ' + code + ')', response.status);
|
||||
throw newError(`${message} (Exception ${code})`, response.status);
|
||||
}
|
||||
|
||||
throw newError('Unknown error 2', response.status);
|
||||
|
@ -19,7 +19,7 @@ class WelcomeUtils {
|
||||
|
||||
for (let i = 0; i < folderAssets.length; i++) {
|
||||
const folderAsset = folderAssets[i];
|
||||
const folder = await Folder.save({ title: folderAsset.title + ' (' + Setting.appTypeToLabel(Setting.value('appType')) + ')' });
|
||||
const folder = await Folder.save({ title: `${folderAsset.title} (${Setting.appTypeToLabel(Setting.value('appType'))})` });
|
||||
if (!output.defaultFolderId) output.defaultFolderId = folder.id;
|
||||
}
|
||||
|
||||
@ -34,15 +34,15 @@ class WelcomeUtils {
|
||||
if (!noteAsset.resources.hasOwnProperty(resourceUrl)) continue;
|
||||
const resourceAsset = noteAsset.resources[resourceUrl];
|
||||
const ext = fileExtension(resourceUrl);
|
||||
const tempFilePath = tempDir + '/' + uuid.create() + '.tmp.' + ext;
|
||||
const tempFilePath = `${tempDir}/${uuid.create()}.tmp.${ext}`;
|
||||
await shim.fsDriver().writeFile(tempFilePath, resourceAsset.body, 'base64');
|
||||
const resource = await shim.createResourceFromPath(tempFilePath, {
|
||||
title: basename(resourceUrl),
|
||||
});
|
||||
await shim.fsDriver().remove(tempFilePath);
|
||||
|
||||
const regex = new RegExp(pregQuote('(' + resourceUrl + ')'), 'g');
|
||||
noteBody = noteBody.replace(regex, '(:/' + resource.id + ')');
|
||||
const regex = new RegExp(pregQuote(`(${resourceUrl})`), 'g');
|
||||
noteBody = noteBody.replace(regex, `(:/${resource.id})`);
|
||||
}
|
||||
|
||||
const note = await Note.save({
|
||||
|
@ -80,7 +80,7 @@ class ActionButtonComponent extends React.Component {
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
let button = buttons[i];
|
||||
let buttonTitle = button.title ? button.title : '';
|
||||
let key = buttonTitle.replace(/\s/g, '_') + '_' + button.icon;
|
||||
let key = `${buttonTitle.replace(/\s/g, '_')}_${button.icon}`;
|
||||
buttonComps.push(
|
||||
<ReactNativeActionButton.Item key={key} buttonColor={button.color} title={buttonTitle} onPress={button.onPress}>
|
||||
<Icon name={button.icon} style={styles.actionButtonIcon} />
|
||||
@ -97,7 +97,7 @@ class ActionButtonComponent extends React.Component {
|
||||
|
||||
if (this.props.multiStates) {
|
||||
if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state');
|
||||
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error('Button index out of bounds: ' + this.state.buttonIndex + '/' + this.props.buttons.length);
|
||||
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error(`Button index out of bounds: ${this.state.buttonIndex}/${this.props.buttons.length}`);
|
||||
let button = this.props.buttons[this.state.buttonIndex];
|
||||
let mainIcon = <Icon name={button.icon} style={styles.actionButtonIcon} />;
|
||||
return (
|
||||
|
@ -45,7 +45,7 @@ globalStyle.marginRight = globalStyle.margin;
|
||||
globalStyle.marginLeft = globalStyle.margin;
|
||||
globalStyle.marginTop = globalStyle.margin;
|
||||
globalStyle.marginBottom = globalStyle.margin;
|
||||
globalStyle.htmlMarginLeft = ((globalStyle.marginLeft / 10) * 0.6).toFixed(2) + 'em';
|
||||
globalStyle.htmlMarginLeft = `${((globalStyle.marginLeft / 10) * 0.6).toFixed(2)}em`;
|
||||
|
||||
let themeCache_ = {};
|
||||
|
||||
|
@ -66,7 +66,7 @@ class NoteBodyViewer extends Component {
|
||||
|
||||
// If the length of the body has changed, then it's something other than a checkbox that has changed,
|
||||
// for example a resource that has been attached to the note while in View mode. In that case, update.
|
||||
return (safeGetNoteProp(this.props, 'body') + '').length !== (safeGetNoteProp(nextProps, 'body') + '').length;
|
||||
return (`${safeGetNoteProp(this.props, 'body')}`).length !== (`${safeGetNoteProp(nextProps, 'body')}`).length;
|
||||
}
|
||||
|
||||
rebuildMd() {
|
||||
@ -140,9 +140,9 @@ class NoteBodyViewer extends Component {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
` +
|
||||
html +
|
||||
`
|
||||
${
|
||||
html
|
||||
}
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
@ -176,7 +176,7 @@ class NoteBodyViewer extends Component {
|
||||
// `baseUrl` is where the images will be loaded from. So images must use a path relative to resourceDir.
|
||||
const source = {
|
||||
html: html,
|
||||
baseUrl: 'file://' + Setting.value('resourceDir') + '/',
|
||||
baseUrl: `file://${Setting.value('resourceDir')}/`,
|
||||
};
|
||||
|
||||
// Note: useWebKit={false} is needed to go around this bug:
|
||||
|
@ -263,10 +263,10 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||
let o = this.props.menuOptions[i];
|
||||
|
||||
if (o.isDivider) {
|
||||
menuOptionComponents.push(<View key={'menuOption_' + key++} style={this.styles().divider} />);
|
||||
menuOptionComponents.push(<View key={`menuOption_${key++}`} style={this.styles().divider} />);
|
||||
} else {
|
||||
menuOptionComponents.push(
|
||||
<MenuOption value={o.onPress} key={'menuOption_' + key++} style={this.styles().contextMenuItem}>
|
||||
<MenuOption value={o.onPress} key={`menuOption_${key++}`} style={this.styles().contextMenuItem}>
|
||||
<Text style={this.styles().contextMenuItemText}>{o.title}</Text>
|
||||
</MenuOption>
|
||||
);
|
||||
@ -274,7 +274,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||
}
|
||||
|
||||
if (menuOptionComponents.length) {
|
||||
menuOptionComponents.push(<View key={'menuOption_' + key++} style={this.styles().divider} />);
|
||||
menuOptionComponents.push(<View key={`menuOption_${key++}`} style={this.styles().divider} />);
|
||||
}
|
||||
} else {
|
||||
menuOptionComponents.push(
|
||||
@ -299,7 +299,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
const f = folders[i];
|
||||
pickerItems.push({ label: ' '.repeat(indent) + ' ' + Folder.displayTitle(f), value: f.id });
|
||||
pickerItems.push({ label: `${' '.repeat(indent)} ${Folder.displayTitle(f)}`, value: f.id });
|
||||
pickerItems = addFolderChildren(f.children, pickerItems, indent + 1);
|
||||
}
|
||||
|
||||
|
@ -68,12 +68,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
const logItemCsv = service.csvCreate(logItemRows);
|
||||
|
||||
const itemListCsv = await service.basicItemList({ format: 'csv' });
|
||||
const filePath = RNFS.ExternalDirectoryPath + '/syncReport-' + new Date().getTime() + '.txt';
|
||||
const filePath = `${RNFS.ExternalDirectoryPath}/syncReport-${new Date().getTime()}.txt`;
|
||||
|
||||
const finalText = [logItemCsv, itemListCsv].join('\n================================================================================\n');
|
||||
|
||||
await RNFS.writeFile(filePath, finalText);
|
||||
alert('Debug report exported to ' + filePath);
|
||||
alert(`Debug report exported to ${filePath}`);
|
||||
this.setState({ creatingReport: false });
|
||||
};
|
||||
|
||||
@ -454,7 +454,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
|
||||
settingComps.push(
|
||||
<View key="version_info_app" style={this.styles().settingContainer}>
|
||||
<Text style={this.styles().settingText}>{'Joplin ' + VersionInfo.appVersion}</Text>
|
||||
<Text style={this.styles().settingText}>{`Joplin ${VersionInfo.appVersion}`}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
|
@ -97,7 +97,7 @@ class LogScreenComponent extends BaseScreenComponent {
|
||||
|
||||
return (
|
||||
<View style={this.styles().row}>
|
||||
<Text style={textStyle}>{time.formatMsToLocal(item.timestamp, 'MM-DDTHH:mm:ss') + ': ' + item.message}</Text>
|
||||
<Text style={textStyle}>{`${time.formatMsToLocal(item.timestamp, 'MM-DDTHH:mm:ss')}: ${item.message}`}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -409,12 +409,12 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
reg.logger().info('New dimensions ', dimensions);
|
||||
|
||||
const format = mimeType == 'image/png' ? 'PNG' : 'JPEG';
|
||||
reg.logger().info('Resizing image ' + localFilePath);
|
||||
reg.logger().info(`Resizing image ${localFilePath}`);
|
||||
const resizedImage = await ImageResizer.createResizedImage(localFilePath, dimensions.width, dimensions.height, format, 85); //, 0, targetPath);
|
||||
|
||||
const resizedImagePath = resizedImage.uri;
|
||||
reg.logger().info('Resized image ', resizedImagePath);
|
||||
reg.logger().info('Moving ' + resizedImagePath + ' => ' + targetPath);
|
||||
reg.logger().info(`Moving ${resizedImagePath} => ${targetPath}`);
|
||||
|
||||
await RNFS.copyFile(resizedImagePath, targetPath);
|
||||
|
||||
@ -462,8 +462,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
mimeType = 'image/jpg';
|
||||
}
|
||||
|
||||
reg.logger().info('Got file: ' + localFilePath);
|
||||
reg.logger().info('Got type: ' + mimeType);
|
||||
reg.logger().info(`Got file: ${localFilePath}`);
|
||||
reg.logger().info(`Got type: ${mimeType}`);
|
||||
|
||||
let resource = Resource.new();
|
||||
resource.id = uuid.create();
|
||||
@ -499,7 +499,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
const itDoes = await shim.fsDriver().waitTillExists(targetPath);
|
||||
if (!itDoes) throw new Error('Resource file was not created: ' + targetPath);
|
||||
if (!itDoes) throw new Error(`Resource file was not created: ${targetPath}`);
|
||||
|
||||
const fileStat = await shim.fsDriver().stat(targetPath);
|
||||
resource.size = fileStat.size;
|
||||
@ -509,7 +509,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
const resourceTag = Resource.markdownTag(resource);
|
||||
|
||||
const newNote = Object.assign({}, this.state.note);
|
||||
newNote.body += '\n' + resourceTag;
|
||||
newNote.body += `\n${resourceTag}`;
|
||||
this.setState({ note: newNote });
|
||||
|
||||
this.refreshResource(resource);
|
||||
@ -563,7 +563,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
async share_onPress() {
|
||||
await Share.share({
|
||||
message: this.state.note.title + '\n\n' + this.state.note.body,
|
||||
message: `${this.state.note.title}\n\n${this.state.note.body}`,
|
||||
title: this.state.note.title,
|
||||
});
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const makeCheckboxText = function(selected, sign, label) {
|
||||
const s = sign === 'tick' ? '✓' : '⬤';
|
||||
return (selected ? s + ' ' : '') + label;
|
||||
return (selected ? `${s} ` : '') + label;
|
||||
};
|
||||
|
||||
for (let field in sortNoteOptions) {
|
||||
@ -49,17 +49,17 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('notes.sortOrder.reverse'), 'tick', '[ ' + Setting.settingMetadata('notes.sortOrder.reverse').label() + ' ]'),
|
||||
text: makeCheckboxText(Setting.value('notes.sortOrder.reverse'), 'tick', `[ ${Setting.settingMetadata('notes.sortOrder.reverse').label()} ]`),
|
||||
id: { name: 'notes.sortOrder.reverse', value: !Setting.value('notes.sortOrder.reverse') },
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('uncompletedTodosOnTop'), 'tick', '[ ' + Setting.settingMetadata('uncompletedTodosOnTop').label() + ' ]'),
|
||||
text: makeCheckboxText(Setting.value('uncompletedTodosOnTop'), 'tick', `[ ${Setting.settingMetadata('uncompletedTodosOnTop').label()} ]`),
|
||||
id: { name: 'uncompletedTodosOnTop', value: !Setting.value('uncompletedTodosOnTop') },
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('showCompletedTodos'), 'tick', '[ ' + Setting.settingMetadata('showCompletedTodos').label() + ' ]'),
|
||||
text: makeCheckboxText(Setting.value('showCompletedTodos'), 'tick', `[ ${Setting.settingMetadata('showCompletedTodos').label()} ]`),
|
||||
id: { name: 'showCompletedTodos', value: !Setting.value('showCompletedTodos') },
|
||||
});
|
||||
|
||||
|
@ -59,7 +59,7 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
|
||||
this.props.dispatch({ type: 'NAV_BACK' });
|
||||
reg.scheduleSync(0);
|
||||
} catch (error) {
|
||||
alert('Could not login to OneDrive. Please try again\n\n' + error.message + '\n\n' + url);
|
||||
alert(`Could not login to OneDrive. Please try again\n\n${error.message}\n\n${url}`);
|
||||
}
|
||||
|
||||
this.authCode_ = null;
|
||||
|
@ -125,7 +125,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
notes = await Note.previews(null, {
|
||||
anywherePattern: '*' + temp.join('*') + '*',
|
||||
anywherePattern: `*${temp.join('*')}*`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class StatusScreenComponent extends BaseScreenComponent {
|
||||
let style = Object.assign({}, baseStyle);
|
||||
style.fontWeight = 'bold';
|
||||
if (i > 0) style.paddingTop = 20;
|
||||
lines.push({ key: 'section_' + i, isSection: true, text: section.title });
|
||||
lines.push({ key: `section_${i}`, isSection: true, text: section.title });
|
||||
|
||||
for (let n in section.body) {
|
||||
if (!section.body.hasOwnProperty(n)) continue;
|
||||
@ -82,10 +82,10 @@ class StatusScreenComponent extends BaseScreenComponent {
|
||||
text = item;
|
||||
}
|
||||
|
||||
lines.push({ key: 'item_' + i + '_' + n, text: text, retryHandler: retryHandler });
|
||||
lines.push({ key: `item_${i}_${n}`, text: text, retryHandler: retryHandler });
|
||||
}
|
||||
|
||||
lines.push({ key: 'divider2_' + i, isDivider: true });
|
||||
lines.push({ key: `divider2_${i}`, isDivider: true });
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -16,7 +16,7 @@ shared.init = function(comp) {
|
||||
shared.checkSyncConfig = async function(comp, settings) {
|
||||
const syncTargetId = settings['sync.target'];
|
||||
const SyncTargetClass = SyncTargetRegistry.classById(syncTargetId);
|
||||
const options = Setting.subValues('sync.' + syncTargetId, settings);
|
||||
const options = Setting.subValues(`sync.${syncTargetId}`, settings);
|
||||
comp.setState({ checkSyncConfigResult: 'checking' });
|
||||
const result = await SyncTargetClass.checkConfig(ObjectUtils.convertValuesToFunctions(options));
|
||||
comp.setState({ checkSyncConfigResult: result });
|
||||
|
@ -34,7 +34,7 @@ class Shared {
|
||||
try {
|
||||
const response = await api.execAuthToken(this.comp_.state.authCode);
|
||||
|
||||
Setting.setValue('sync.' + this.syncTargetId() + '.auth', response.access_token);
|
||||
Setting.setValue(`sync.${this.syncTargetId()}.auth`, response.access_token);
|
||||
api.setAuthToken(response.access_token);
|
||||
await showInfoMessageBox(_('The application has been authorised!'));
|
||||
this.comp_.props.dispatch({ type: 'NAV_BACK' });
|
||||
|
@ -16,7 +16,7 @@ function folderIsVisible(folders, folderId, collapsedFolderIds) {
|
||||
|
||||
while (true) {
|
||||
let folder = BaseModel.byId(folders, folderId);
|
||||
if (!folder) throw new Error('No folder with id ' + folder.id);
|
||||
if (!folder) throw new Error(`No folder with id ${folder.id}`);
|
||||
if (!folder.parent_id) return true;
|
||||
if (collapsedFolderIds.indexOf(folder.parent_id) >= 0) return false;
|
||||
folderId = folder.parent_id;
|
||||
|
@ -76,7 +76,7 @@ class SideMenuContentNoteComponent extends Component {
|
||||
|
||||
for (const option of options) {
|
||||
if (option.isDivider) {
|
||||
items.push(this.renderDivider('divider_' + dividerIndex++));
|
||||
items.push(this.renderDivider(`divider_${dividerIndex++}`));
|
||||
} else {
|
||||
items.push(this.renderSideBarButton(option.title, option.title, null, option.onPress));
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ class Database {
|
||||
escapeField(field) {
|
||||
if (field == '*') return '*';
|
||||
let p = field.split('.');
|
||||
if (p.length == 1) return '`' + field + '`';
|
||||
if (p.length == 2) return p[0] + '.`' + p[1] + '`';
|
||||
if (p.length == 1) return `\`${field}\``;
|
||||
if (p.length == 2) return `${p[0]}.\`${p[1]}\``;
|
||||
|
||||
throw new Error('Invalid field format: ' + field);
|
||||
throw new Error(`Invalid field format: ${field}`);
|
||||
}
|
||||
|
||||
escapeFields(fields) {
|
||||
@ -101,7 +101,7 @@ class Database {
|
||||
const output = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const v = rows[i][field];
|
||||
if (!v) throw new Error('No such field: ' + field + '. Query was: ' + sql);
|
||||
if (!v) throw new Error(`No such field: ${field}. Query was: ${sql}`);
|
||||
output.push(rows[i][field]);
|
||||
}
|
||||
return output;
|
||||
@ -148,15 +148,15 @@ class Database {
|
||||
if (type == 'fieldType') {
|
||||
if (s) s = s.toUpperCase();
|
||||
if (s == 'INTEGER') s = 'INT';
|
||||
if (!('TYPE_' + s in this)) throw new Error('Unkonwn fieldType: ' + s);
|
||||
return this['TYPE_' + s];
|
||||
if (!(`TYPE_${s}` in this)) throw new Error(`Unkonwn fieldType: ${s}`);
|
||||
return this[`TYPE_${s}`];
|
||||
}
|
||||
if (type == 'syncTarget') {
|
||||
if (s == 'memory') return 1;
|
||||
if (s == 'filesystem') return 2;
|
||||
if (s == 'onedrive') return 3;
|
||||
}
|
||||
throw new Error('Unknown enum type or value: ' + type + ', ' + s);
|
||||
throw new Error(`Unknown enum type or value: ${type}, ${s}`);
|
||||
}
|
||||
|
||||
static enumName(type, id) {
|
||||
@ -165,7 +165,7 @@ class Database {
|
||||
if (id === Database.TYPE_INT) return 'int';
|
||||
if (id === Database.TYPE_TEXT) return 'text';
|
||||
if (id === Database.TYPE_NUMERIC) return 'numeric';
|
||||
throw new Error('Invalid type id: ' + id);
|
||||
throw new Error(`Invalid type id: ${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ class Database {
|
||||
if (type == this.TYPE_INT) return Number(value);
|
||||
if (type == this.TYPE_TEXT) return value;
|
||||
if (type == this.TYPE_NUMERIC) return Number(value);
|
||||
throw new Error('Unknown type: ' + type);
|
||||
throw new Error(`Unknown type: ${type}`);
|
||||
}
|
||||
|
||||
sqlStringToLines(sql) {
|
||||
@ -218,12 +218,12 @@ class Database {
|
||||
if (key[key.length - 1] == '_') continue;
|
||||
if (keySql != '') keySql += ', ';
|
||||
if (valueSql != '') valueSql += ', ';
|
||||
keySql += '`' + key + '`';
|
||||
keySql += `\`${key}\``;
|
||||
valueSql += '?';
|
||||
params.push(data[key]);
|
||||
}
|
||||
return {
|
||||
sql: 'INSERT INTO `' + tableName + '` (' + keySql + ') VALUES (' + valueSql + ')',
|
||||
sql: `INSERT INTO \`${tableName}\` (${keySql}) VALUES (${valueSql})`,
|
||||
params: params,
|
||||
};
|
||||
}
|
||||
@ -237,7 +237,7 @@ class Database {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (key[key.length - 1] == '_') continue;
|
||||
if (sql != '') sql += ', ';
|
||||
sql += '`' + key + '`=?';
|
||||
sql += `\`${key}\`=?`;
|
||||
params.push(data[key]);
|
||||
}
|
||||
|
||||
@ -246,13 +246,13 @@ class Database {
|
||||
for (let n in where) {
|
||||
if (!where.hasOwnProperty(n)) continue;
|
||||
params.push(where[n]);
|
||||
s.push('`' + n + '`=?');
|
||||
s.push(`\`${n}\`=?`);
|
||||
}
|
||||
where = s.join(' AND ');
|
||||
}
|
||||
|
||||
return {
|
||||
sql: 'UPDATE `' + tableName + '` SET ' + sql + ' WHERE ' + where,
|
||||
sql: `UPDATE \`${tableName}\` SET ${sql} WHERE ${where}`,
|
||||
params: params,
|
||||
};
|
||||
}
|
||||
@ -267,7 +267,7 @@ class Database {
|
||||
let fieldsWithType = [];
|
||||
for (let n in fields) {
|
||||
if (!fields.hasOwnProperty(n)) continue;
|
||||
fieldsWithType.push(this.escapeField(n) + ' ' + fields[n]);
|
||||
fieldsWithType.push(`${this.escapeField(n)} ${fields[n]}`);
|
||||
}
|
||||
|
||||
let sql = `
|
||||
@ -279,7 +279,7 @@ class Database {
|
||||
DROP TABLE _BACKUP_TABLE_NAME_;
|
||||
`;
|
||||
|
||||
sql = sql.replace(/_BACKUP_TABLE_NAME_/g, this.escapeField(tableName + '_backup'));
|
||||
sql = sql.replace(/_BACKUP_TABLE_NAME_/g, this.escapeField(`${tableName}_backup`));
|
||||
sql = sql.replace(/_TABLE_NAME_/g, this.escapeField(tableName));
|
||||
sql = sql.replace(/_FIELDS_NO_TYPE_/g, this.escapeFields(fieldsNoType).join(','));
|
||||
sql = sql.replace(/_FIELDS_TYPE_/g, fieldsWithType.join(','));
|
||||
@ -296,7 +296,7 @@ class Database {
|
||||
}
|
||||
|
||||
wrapQuery(sql, params = null) {
|
||||
if (!sql) throw new Error('Cannot wrap empty string: ' + sql);
|
||||
if (!sql) throw new Error(`Cannot wrap empty string: ${sql}`);
|
||||
|
||||
if (sql.constructor === Array) {
|
||||
let output = {};
|
||||
|
@ -17,7 +17,7 @@ class FileApiDriverDropbox {
|
||||
|
||||
makePath_(path) {
|
||||
if (!path) return '';
|
||||
return '/' + path;
|
||||
return `/${path}`;
|
||||
}
|
||||
|
||||
hasErrorCode_(error, errorCode) {
|
||||
@ -224,7 +224,7 @@ class FileApiDriverDropbox {
|
||||
|
||||
// It returns "failed" if it didn't work but anyway throw an error if it's anything other than complete or in_progress
|
||||
if (check['.tag'] !== 'in_progress') {
|
||||
throw new Error('Batch delete failed? ' + JSON.stringify(check));
|
||||
throw new Error(`Batch delete failed? ${JSON.stringify(check)}`);
|
||||
}
|
||||
await time.sleep(2);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ const { basicDelta } = require('lib/file-api');
|
||||
class FileApiDriverLocal {
|
||||
fsErrorToJsError_(error, path = null) {
|
||||
let msg = error.toString();
|
||||
if (path !== null) msg += '. Path: ' + path;
|
||||
if (path !== null) msg += `. Path: ${path}`;
|
||||
let output = new Error(msg);
|
||||
if (error.code) output.code = error.code;
|
||||
return output;
|
||||
|
@ -50,7 +50,7 @@ class FileApiDriverMemory {
|
||||
|
||||
async setTimestamp(path, timestampMs) {
|
||||
let item = this.itemByPath(path);
|
||||
if (!item) return Promise.reject(new Error('File not found: ' + path));
|
||||
if (!item) return Promise.reject(new Error(`File not found: ${path}`));
|
||||
item.updated_time = timestampMs;
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ class FileApiDriverMemory {
|
||||
for (let i = 0; i < this.items_.length; i++) {
|
||||
let item = this.items_[i];
|
||||
if (item.path == path) continue;
|
||||
if (item.path.indexOf(path + '/') === 0) {
|
||||
if (item.path.indexOf(`${path}/`) === 0) {
|
||||
let s = item.path.substr(path.length + 1);
|
||||
if (s.split('/').length === 1) {
|
||||
let it = Object.assign({}, item);
|
||||
@ -80,7 +80,7 @@ class FileApiDriverMemory {
|
||||
async get(path, options) {
|
||||
let item = this.itemByPath(path);
|
||||
if (!item) return Promise.resolve(null);
|
||||
if (item.isDir) return Promise.reject(new Error(path + ' is a directory, not a file'));
|
||||
if (item.isDir) return Promise.reject(new Error(`${path} is a directory, not a file`));
|
||||
|
||||
let output = null;
|
||||
if (options.target === 'file') {
|
||||
@ -128,7 +128,7 @@ class FileApiDriverMemory {
|
||||
|
||||
async move(oldPath, newPath) {
|
||||
let sourceItem = this.itemByPath(oldPath);
|
||||
if (!sourceItem) return Promise.reject(new Error('Path not found: ' + oldPath));
|
||||
if (!sourceItem) return Promise.reject(new Error(`Path not found: ${oldPath}`));
|
||||
this.delete(newPath); // Overwrite if newPath already exists
|
||||
sourceItem.path = newPath;
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ class FileApiDriverOneDrive {
|
||||
let body = {
|
||||
fileSystemInfo: {
|
||||
lastModifiedDateTime:
|
||||
moment
|
||||
`${moment
|
||||
.unix(timestamp / 1000)
|
||||
.utc()
|
||||
.format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z',
|
||||
.format('YYYY-MM-DDTHH:mm:ss.SSS')}Z`,
|
||||
},
|
||||
};
|
||||
let item = await this.api_.execJson('PATCH', this.makePath_(path), null, body);
|
||||
@ -78,7 +78,7 @@ class FileApiDriverOneDrive {
|
||||
|
||||
async list(path, options = null) {
|
||||
let query = this.itemFilter_();
|
||||
let url = this.makePath_(path) + ':/children';
|
||||
let url = `${this.makePath_(path)}:/children`;
|
||||
|
||||
if (options.context) {
|
||||
query = null;
|
||||
@ -99,10 +99,10 @@ class FileApiDriverOneDrive {
|
||||
|
||||
try {
|
||||
if (options.target == 'file') {
|
||||
let response = await this.api_.exec('GET', this.makePath_(path) + ':/content', null, null, options);
|
||||
let response = await this.api_.exec('GET', `${this.makePath_(path)}:/content`, null, null, options);
|
||||
return response;
|
||||
} else {
|
||||
let content = await this.api_.execText('GET', this.makePath_(path) + ':/content');
|
||||
let content = await this.api_.execText('GET', `${this.makePath_(path)}:/content`);
|
||||
return content;
|
||||
}
|
||||
} catch (error) {
|
||||
@ -116,7 +116,7 @@ class FileApiDriverOneDrive {
|
||||
if (item) return item;
|
||||
|
||||
let parentPath = dirname(path);
|
||||
item = await this.api_.execJson('POST', this.makePath_(parentPath) + ':/children', this.itemFilter_(), {
|
||||
item = await this.api_.execJson('POST', `${this.makePath_(parentPath)}:/children`, this.itemFilter_(), {
|
||||
name: basename(path),
|
||||
folder: {},
|
||||
});
|
||||
@ -131,10 +131,10 @@ class FileApiDriverOneDrive {
|
||||
|
||||
try {
|
||||
if (options.source == 'file') {
|
||||
response = await this.api_.exec('PUT', this.makePath_(path) + ':/content', null, null, options);
|
||||
response = await this.api_.exec('PUT', `${this.makePath_(path)}:/content`, null, null, options);
|
||||
} else {
|
||||
options.headers = { 'Content-Type': 'text/plain' };
|
||||
response = await this.api_.exec('PUT', this.makePath_(path) + ':/content', null, content, options);
|
||||
response = await this.api_.exec('PUT', `${this.makePath_(path)}:/content`, null, content, options);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error && error.code === 'BadRequest' && error.message === 'Maximum request length exceeded.') {
|
||||
@ -202,7 +202,7 @@ class FileApiDriverOneDrive {
|
||||
};
|
||||
|
||||
const freshStartDelta = () => {
|
||||
const url = this.makePath_(path) + ':/delta';
|
||||
const url = `${this.makePath_(path)}:/delta`;
|
||||
const query = this.itemFilter_();
|
||||
query.select += ',deleted';
|
||||
return { url: url, query: query };
|
||||
@ -273,7 +273,7 @@ class FileApiDriverOneDrive {
|
||||
nextLink = response['@odata.nextLink'];
|
||||
output.hasMore = true;
|
||||
} else {
|
||||
if (!response['@odata.deltaLink']) throw new Error('Delta link missing: ' + JSON.stringify(response));
|
||||
if (!response['@odata.deltaLink']) throw new Error(`Delta link missing: ${JSON.stringify(response)}`);
|
||||
nextLink = response['@odata.deltaLink'];
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user