mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Chore: Add eslint rule to enforce strict equality (eqeqeq)
This commit is contained in:
parent
8a8def39f0
commit
052d9f03d6
@ -76,6 +76,7 @@ module.exports = {
|
||||
|
||||
'no-array-constructor': ['error'],
|
||||
'radix': ['error'],
|
||||
'eqeqeq': ['error', 'always'],
|
||||
|
||||
// Warn only for now because fixing everything would take too much
|
||||
// refactoring, but new code should try to stick to it.
|
||||
|
@ -412,7 +412,7 @@ class AppGui {
|
||||
const widget = this.widget('mainWindow').focusedWidget;
|
||||
if (!widget) return null;
|
||||
|
||||
if (widget.name == 'noteList' || widget.name == 'folderList') {
|
||||
if (widget.name === 'noteList' || widget.name === 'folderList') {
|
||||
return widget.currentItem;
|
||||
}
|
||||
|
||||
@ -521,11 +521,11 @@ class AppGui {
|
||||
const args = splitCommandString(cmd);
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] == '$n') {
|
||||
if (args[i] === '$n') {
|
||||
args[i] = note ? note.id : '';
|
||||
} else if (args[i] == '$b') {
|
||||
} else if (args[i] === '$b') {
|
||||
args[i] = folder ? folder.id : '';
|
||||
} else if (args[i] == '$c') {
|
||||
} else if (args[i] === '$c') {
|
||||
const item = this.activeListItem();
|
||||
args[i] = item ? item.id : '';
|
||||
}
|
||||
|
@ -81,21 +81,21 @@ class Application extends BaseApplication {
|
||||
|
||||
pattern = pattern ? pattern.toString() : '';
|
||||
|
||||
if (type == BaseModel.TYPE_FOLDER && (pattern == Folder.conflictFolderTitle() || pattern == Folder.conflictFolderId())) return [Folder.conflictFolder()];
|
||||
if (type === BaseModel.TYPE_FOLDER && (pattern === Folder.conflictFolderTitle() || pattern === Folder.conflictFolderId())) return [Folder.conflictFolder()];
|
||||
|
||||
if (!options) options = {};
|
||||
|
||||
const parent = options.parent ? options.parent : app().currentFolder();
|
||||
const ItemClass = BaseItem.itemClass(type);
|
||||
|
||||
if (type == BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
|
||||
if (type === BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
|
||||
// Handle it as pattern
|
||||
if (!parent) throw new Error(_('No notebook selected.'));
|
||||
return await Note.previews(parent.id, { titlePattern: pattern });
|
||||
} else {
|
||||
// Single item
|
||||
let item = null;
|
||||
if (type == BaseModel.TYPE_NOTE) {
|
||||
if (type === BaseModel.TYPE_NOTE) {
|
||||
if (!parent) throw new Error(_('No notebook has been specified.'));
|
||||
item = await ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
|
||||
} else {
|
||||
@ -137,7 +137,7 @@ class Application extends BaseApplication {
|
||||
if (!options.booleanAnswerDefault) options.booleanAnswerDefault = 'y';
|
||||
if (!options.answers) options.answers = options.booleanAnswerDefault === 'y' ? [_('Y'), _('n')] : [_('N'), _('y')];
|
||||
|
||||
if (options.type == 'boolean') {
|
||||
if (options.type === 'boolean') {
|
||||
message += ` (${options.answers.join('/')})`;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ class Application extends BaseApplication {
|
||||
if (options.type === 'boolean') {
|
||||
if (answer === null) return false; // Pressed ESCAPE
|
||||
if (!answer) answer = options.answers[0];
|
||||
const positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
|
||||
const positiveIndex = options.booleanAnswerDefault === 'y' ? 0 : 1;
|
||||
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
|
||||
} else {
|
||||
return answer;
|
||||
@ -181,7 +181,7 @@ class Application extends BaseApplication {
|
||||
fs.readdirSync(__dirname).forEach(path => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
if (ext !== 'js') return;
|
||||
|
||||
const CommandClass = require(`./${path}`);
|
||||
let cmd = new CommandClass();
|
||||
|
@ -12,7 +12,7 @@ async function handleAutocompletionPromise(line) {
|
||||
const words = getArguments(line);
|
||||
// If there is only one word and it is not already a command name then you
|
||||
// should look for commands it could be
|
||||
if (words.length == 1) {
|
||||
if (words.length === 1) {
|
||||
if (names.indexOf(words[0]) === -1) {
|
||||
const x = names.filter(n => n.indexOf(words[0]) === 0);
|
||||
if (x.length === 1) {
|
||||
@ -78,38 +78,38 @@ async function handleAutocompletionPromise(line) {
|
||||
|
||||
const currentFolder = app().currentFolder();
|
||||
|
||||
if (argName == 'note' || argName == 'note-pattern') {
|
||||
if (argName === 'note' || argName === 'note-pattern') {
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
|
||||
l.push(...notes.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'notebook') {
|
||||
if (argName === 'notebook') {
|
||||
const folders = await Folder.search({ titlePattern: `${next}*` });
|
||||
l.push(...folders.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'item') {
|
||||
if (argName === 'item') {
|
||||
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') {
|
||||
if (argName === 'tag') {
|
||||
const tags = await Tag.search({ titlePattern: `${next}*` });
|
||||
l.push(...tags.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'file') {
|
||||
if (argName === 'file') {
|
||||
const files = await fs.readdir('.');
|
||||
l.push(...files);
|
||||
}
|
||||
|
||||
if (argName == 'tag-command') {
|
||||
if (argName === 'tag-command') {
|
||||
const c = filterList(['add', 'remove', 'list', 'notetags'], next);
|
||||
l.push(...c);
|
||||
}
|
||||
|
||||
if (argName == 'todo-command') {
|
||||
if (argName === 'todo-command') {
|
||||
const c = filterList(['toggle', 'clear'], next);
|
||||
l.push(...c);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ function getCommands() {
|
||||
fs.readdirSync(__dirname).forEach(path => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
if (ext !== 'js') return;
|
||||
|
||||
const CommandClass = require(`./${path}`);
|
||||
const cmd = new CommandClass();
|
||||
|
@ -222,7 +222,7 @@ async function main() {
|
||||
|
||||
for (const n in testUnits) {
|
||||
if (!testUnits.hasOwnProperty(n)) continue;
|
||||
if (onlyThisTest && n != onlyThisTest) continue;
|
||||
if (onlyThisTest && n !== onlyThisTest) continue;
|
||||
|
||||
await clearDatabase();
|
||||
const testName = n.substr(4).toLowerCase();
|
||||
|
@ -21,7 +21,7 @@ cliUtils.printArray = function(logFunction, rows) {
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
const item = row[j];
|
||||
const width = item ? item.toString().length : 0;
|
||||
const align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
const align = typeof item === 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
|
||||
if (colAligns.length <= j) colAligns[j] = align;
|
||||
}
|
||||
@ -32,7 +32,7 @@ cliUtils.printArray = function(logFunction, rows) {
|
||||
for (let col = 0; col < colWidths.length; col++) {
|
||||
const item = rows[row][col];
|
||||
const width = colWidths[col];
|
||||
const dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
const dir = colAligns[col] === ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
line.push(stringPadding(item, width, ' ', dir));
|
||||
}
|
||||
logFunction(line.join(' '));
|
||||
@ -45,13 +45,13 @@ cliUtils.parseFlags = function(flags) {
|
||||
for (let i = 0; i < flags.length; i++) {
|
||||
let f = flags[i].trim();
|
||||
|
||||
if (f.substr(0, 2) == '--') {
|
||||
if (f.substr(0, 2) === '--') {
|
||||
f = f.split(' ');
|
||||
output.long = f[0].substr(2).trim();
|
||||
if (f.length == 2) {
|
||||
if (f.length === 2) {
|
||||
output.arg = cliUtils.parseCommandArg(f[1].trim());
|
||||
}
|
||||
} else if (f.substr(0, 1) == '-') {
|
||||
} else if (f.substr(0, 1) === '-') {
|
||||
output.short = f.substr(1);
|
||||
}
|
||||
}
|
||||
@ -65,9 +65,9 @@ cliUtils.parseCommandArg = function(arg) {
|
||||
const c2 = arg[arg.length - 1];
|
||||
const name = arg.substr(1, arg.length - 2);
|
||||
|
||||
if (c1 == '<' && c2 == '>') {
|
||||
if (c1 === '<' && c2 === '>') {
|
||||
return { required: true, name: name };
|
||||
} else if (c1 == '[' && c2 == ']') {
|
||||
} else if (c1 === '[' && c2 === ']') {
|
||||
return { required: false, name: name };
|
||||
} else {
|
||||
throw new Error(`Invalid command arg: ${arg}`);
|
||||
@ -83,7 +83,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
const booleanFlags = [];
|
||||
const 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);
|
||||
@ -117,7 +117,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
const argOptions = {};
|
||||
for (const key in args) {
|
||||
if (!args.hasOwnProperty(key)) continue;
|
||||
if (key == '_') continue;
|
||||
if (key === '_') continue;
|
||||
argOptions[key] = args[key];
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ cliUtils.promptConfirm = function(message, answers = null) {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
rl.question(`${message} `, answer => {
|
||||
const ok = !answer || answer.toLowerCase() == answers[0].toLowerCase();
|
||||
const ok = !answer || answer.toLowerCase() === answers[0].toLowerCase();
|
||||
rl.close();
|
||||
resolve(ok);
|
||||
});
|
||||
|
@ -122,7 +122,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
|
||||
if (args.name == 'locale') {
|
||||
if (args.name === 'locale') {
|
||||
setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class Command extends BaseCommand {
|
||||
queryOptions.orderBy = options.sort;
|
||||
queryOptions.orderByDir = 'ASC';
|
||||
}
|
||||
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir == 'ASC' ? 'DESC' : 'ASC';
|
||||
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir === 'ASC' ? 'DESC' : 'ASC';
|
||||
queryOptions.caseInsensitive = true;
|
||||
if (options.type) {
|
||||
queryOptions.itemTypes = [];
|
||||
@ -55,7 +55,7 @@ class Command extends BaseCommand {
|
||||
queryOptions.uncompletedTodosOnTop = Setting.value('uncompletedTodosOnTop');
|
||||
|
||||
let modelType = null;
|
||||
if (pattern == '/' || !app().currentFolder()) {
|
||||
if (pattern === '/' || !app().currentFolder()) {
|
||||
queryOptions.includeConflictFolder = true;
|
||||
items = await Folder.all(queryOptions);
|
||||
modelType = Folder.modelType();
|
||||
@ -65,7 +65,7 @@ class Command extends BaseCommand {
|
||||
modelType = Note.modelType();
|
||||
}
|
||||
|
||||
if (options.format && options.format == 'json') {
|
||||
if (options.format && options.format === 'json') {
|
||||
this.stdout(JSON.stringify(items));
|
||||
} else {
|
||||
let hasTodos = false;
|
||||
@ -88,7 +88,7 @@ class Command extends BaseCommand {
|
||||
row.push(BaseModel.shortId(item.id));
|
||||
shortIdShown = true;
|
||||
|
||||
if (modelType == Folder.modelType()) {
|
||||
if (modelType === Folder.modelType()) {
|
||||
row.push(await Folder.noteCount(item.id));
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ class Command extends BaseCommand {
|
||||
|
||||
this.releaseLockFn_ = await Command.lockFile(lockFilePath);
|
||||
} catch (error) {
|
||||
if (error.code == 'ELOCKED') {
|
||||
if (error.code === 'ELOCKED') {
|
||||
const msg = _('Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at "%s" and resume the operation.', error.file);
|
||||
this.stdout(msg);
|
||||
return;
|
||||
@ -222,7 +222,7 @@ class Command extends BaseCommand {
|
||||
const newContext = await sync.start(options);
|
||||
Setting.setValue(contextKey, JSON.stringify(newContext));
|
||||
} catch (error) {
|
||||
if (error.code == 'alreadyStarted') {
|
||||
if (error.code === 'alreadyStarted') {
|
||||
this.stdout(error.message);
|
||||
} else {
|
||||
throw error;
|
||||
|
@ -30,21 +30,21 @@ class Command extends BaseCommand {
|
||||
|
||||
const command = args['tag-command'];
|
||||
|
||||
if (command == 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
if (command === 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
|
||||
if (command == 'add') {
|
||||
if (command === 'add') {
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
|
||||
if (!tag) tag = await Tag.save({ title: args.tag }, { userSideValidation: true });
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.addNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (command == 'remove') {
|
||||
} else if (command === 'remove') {
|
||||
if (!tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.removeNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (command == 'list') {
|
||||
} else if (command === 'list') {
|
||||
if (tag) {
|
||||
const notes = await Tag.notes(tag.id);
|
||||
notes.map(note => {
|
||||
@ -75,7 +75,7 @@ class Command extends BaseCommand {
|
||||
this.stdout(tag.title);
|
||||
});
|
||||
}
|
||||
} else if (command == 'notetags') {
|
||||
} else if (command === 'notetags') {
|
||||
if (args.tag) {
|
||||
const note = await app().loadItem(BaseModel.TYPE_NOTE, args.tag);
|
||||
if (!note) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
|
@ -29,13 +29,13 @@ class Command extends BaseCommand {
|
||||
id: note.id,
|
||||
};
|
||||
|
||||
if (action == 'toggle') {
|
||||
if (action === 'toggle') {
|
||||
if (!note.is_todo) {
|
||||
toSave = Note.toggleIsTodo(note);
|
||||
} else {
|
||||
toSave.todo_completed = note.todo_completed ? 0 : time.unixMs();
|
||||
}
|
||||
} else if (action == 'clear') {
|
||||
} else if (action === 'clear') {
|
||||
toSave.is_todo = 0;
|
||||
}
|
||||
|
||||
|
@ -2071,7 +2071,7 @@ function execCommand(client, command, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const childProcess = exec(cmd, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
if (error.signal == 'SIGTERM') {
|
||||
if (error.signal === 'SIGTERM') {
|
||||
resolve('Process was killed');
|
||||
} else {
|
||||
logger.error(stderr);
|
||||
@ -2103,7 +2103,7 @@ async function clientItems(client) {
|
||||
function randomTag(items) {
|
||||
const tags = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type_ != 5) continue;
|
||||
if (items[i].type_ !== 5) continue;
|
||||
tags.push(items[i]);
|
||||
}
|
||||
|
||||
@ -2113,7 +2113,7 @@ function randomTag(items) {
|
||||
function randomNote(items) {
|
||||
const notes = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type_ != 1) continue;
|
||||
if (items[i].type_ !== 1) continue;
|
||||
notes.push(items[i]);
|
||||
}
|
||||
|
||||
@ -2131,11 +2131,11 @@ async function execRandomCommand(client) {
|
||||
const item = randomElement(items);
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ == 1) {
|
||||
if (item.type_ === 1) {
|
||||
return execCommand(client, `rm -f ${item.id}`);
|
||||
} else if (item.type_ == 2) {
|
||||
} else if (item.type_ === 2) {
|
||||
return execCommand(client, `rm -r -f ${item.id}`);
|
||||
} else if (item.type_ == 5) {
|
||||
} else if (item.type_ === 5) {
|
||||
// tag
|
||||
} else {
|
||||
throw new Error(`Unknown type: ${item.type_}`);
|
||||
@ -2213,7 +2213,7 @@ function randomNextCheckTime() {
|
||||
|
||||
function findItem(items, itemId) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].id == itemId) return items[i];
|
||||
if (items[i].id === itemId) return items[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -2225,7 +2225,7 @@ function compareItems(item1, item2) {
|
||||
const p1 = item1[n];
|
||||
const p2 = item2[n];
|
||||
|
||||
if (n == 'notes_') {
|
||||
if (n === 'notes_') {
|
||||
p1.sort();
|
||||
p2.sort();
|
||||
if (JSON.stringify(p1) !== JSON.stringify(p2)) {
|
||||
@ -2246,7 +2246,7 @@ function findMissingItems_(items1, items2) {
|
||||
let found = false;
|
||||
for (let j = 0; j < items2.length; j++) {
|
||||
const item2 = items2[j];
|
||||
if (item1.id == item2.id) {
|
||||
if (item1.id === item2.id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -2340,9 +2340,9 @@ async function main() {
|
||||
let state = 'commands';
|
||||
|
||||
setInterval(async () => {
|
||||
if (state == 'waitForSyncCheck') return;
|
||||
if (state === 'waitForSyncCheck') return;
|
||||
|
||||
if (state == 'syncCheck') {
|
||||
if (state === 'syncCheck') {
|
||||
state = 'waitForSyncCheck';
|
||||
const clientItems = [];
|
||||
// Up to 3 sync operations must be performed by each clients in order for them
|
||||
@ -2371,7 +2371,7 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == 'waitForClients') {
|
||||
if (state === 'waitForClients') {
|
||||
for (let i = 0; i < clients.length; i++) {
|
||||
if (clients[i].activeCommandCount > 0) return;
|
||||
}
|
||||
@ -2380,7 +2380,7 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == 'commands') {
|
||||
if (state === 'commands') {
|
||||
if (nextSyncCheckTime <= time.unixMs()) {
|
||||
state = 'waitForClients';
|
||||
return;
|
||||
|
@ -82,13 +82,13 @@ if (process.platform === 'win32') {
|
||||
|
||||
process.stdout.on('error', function(err) {
|
||||
// https://stackoverflow.com/questions/12329816/error-write-epipe-when-piping-node-output-to-head#15884508
|
||||
if (err.code == 'EPIPE') {
|
||||
if (err.code === 'EPIPE') {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
application.start(process.argv).catch(error => {
|
||||
if (error.code == 'flagError') {
|
||||
if (error.code === 'flagError') {
|
||||
console.error(error.message);
|
||||
console.error(_('Type `joplin help` for usage information.'));
|
||||
} else {
|
||||
|
@ -30,7 +30,7 @@ describe('feature_NoteHistory', function() {
|
||||
});
|
||||
|
||||
afterEach(async (done) => {
|
||||
if (testApp !== null) await testApp.destroy();
|
||||
if (testApp) await testApp.destroy();
|
||||
testApp = null;
|
||||
done();
|
||||
});
|
||||
|
@ -352,7 +352,7 @@
|
||||
}
|
||||
|
||||
function isPagePdf() {
|
||||
return document.contentType == 'application/pdf';
|
||||
return document.contentType === 'application/pdf';
|
||||
}
|
||||
|
||||
function embedPageUrl() {
|
||||
|
@ -67,7 +67,7 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
return choosePort(HOST, DEFAULT_PORT);
|
||||
})
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
if (!port) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
|
@ -104,22 +104,22 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
protected async generalMiddleware(store: any, next: any, action: any) {
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'locale' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'locale' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
setLocale(Setting.value('locale'));
|
||||
// The bridge runs within the main process, with its own instance of locale.js
|
||||
// so it needs to be set too here.
|
||||
bridge().setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'showTrayIcon' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'showTrayIcon' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
this.updateTray();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'style.editor.fontFamily' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'style.editor.fontFamily' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
this.updateEditorFont();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'windowContentZoomFactor' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'windowContentZoomFactor' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
webFrame.setZoomFactor(Setting.value('windowContentZoomFactor') / 100);
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ class Application extends BaseApplication {
|
||||
await Folder.expandTree(newState.folders, action.folderId);
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type === 'SETTING_UPDATE_ALL')) {
|
||||
this.handleThemeAutoDetect();
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ class Application extends BaseApplication {
|
||||
|
||||
PerFolderSortOrderService.initialize();
|
||||
|
||||
CommandService.instance().initialize(this.store(), Setting.value('env') == 'dev', stateToWhenClauseContext);
|
||||
CommandService.instance().initialize(this.store(), Setting.value('env') === 'dev', stateToWhenClauseContext);
|
||||
|
||||
for (const command of commands) {
|
||||
CommandService.instance().registerDeclaration(command.declaration);
|
||||
|
@ -86,7 +86,7 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
||||
const ext = fileExtension(asset.name);
|
||||
if (platform === 'win32' && ext === 'exe') {
|
||||
if (shim.isPortable()) {
|
||||
found = asset.name == 'JoplinPortable.exe';
|
||||
found = asset.name === 'JoplinPortable.exe';
|
||||
} else {
|
||||
found = !!asset.name.match(/^Joplin-Setup-[\d.]+\.exe$/);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ const os = require('os');
|
||||
const sha512 = require('js-sha512');
|
||||
|
||||
const generateChecksumFile = () => {
|
||||
if (os.platform() != 'linux') {
|
||||
if (os.platform() !== 'linux') {
|
||||
return []; // SHA-512 is only for AppImage
|
||||
}
|
||||
const distDirName = 'dist';
|
||||
@ -18,7 +18,7 @@ const generateChecksumFile = () => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (appImageName == '') {
|
||||
if (appImageName === '') {
|
||||
throw 'AppImage not found!';
|
||||
}
|
||||
const appImagePath = path.join(distPath, appImageName);
|
||||
|
@ -37,7 +37,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
return { token: function(stream: any) {
|
||||
query.lastIndex = stream.pos;
|
||||
const match = query.exec(stream.string);
|
||||
if (match && match.index == stream.pos) {
|
||||
if (match && match.index === stream.pos) {
|
||||
stream.pos += match[0].length || 1;
|
||||
return 'search-marker';
|
||||
} else if (match) {
|
||||
@ -126,7 +126,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
|
||||
// SEARCHOVERLAY
|
||||
// We only want to highlight all matches when there is only 1 search term
|
||||
if (keywords.length !== 1 || keywords[0].value == '') {
|
||||
if (keywords.length !== 1 || keywords[0].value === '') {
|
||||
clearOverlay(this);
|
||||
const prev = keywords.length > 1 ? keywords[0].value : '';
|
||||
setPreviousKeywordValue(prev);
|
||||
|
@ -48,9 +48,9 @@ class AppNavComponent extends Component {
|
||||
let notesScreenVisible = false;
|
||||
let searchScreenVisible = false;
|
||||
|
||||
if (route.routeName == 'Notes') {
|
||||
if (route.routeName === 'Notes') {
|
||||
notesScreenVisible = true;
|
||||
} else if (route.routeName == 'Search') {
|
||||
} else if (route.routeName === 'Search') {
|
||||
searchScreenVisible = true;
|
||||
} else {
|
||||
Screen = this.props.screens[route.routeName].screen;
|
||||
@ -59,7 +59,7 @@ class AppNavComponent extends Component {
|
||||
// Keep the search screen loaded if the user is viewing a note from that search screen
|
||||
// so that if the back button is pressed, the screen is still loaded. However, unload
|
||||
// it if navigating away.
|
||||
const searchScreenLoaded = searchScreenVisible || (this.previousRouteName_ == 'Search' && route.routeName == 'Note');
|
||||
const searchScreenLoaded = searchScreenVisible || (this.previousRouteName_ === 'Search' && route.routeName === 'Note');
|
||||
|
||||
this.previousRouteName_ = route.routeName;
|
||||
|
||||
|
@ -57,7 +57,7 @@ class NoteListComponent extends Component {
|
||||
|
||||
filterNotes(notes) {
|
||||
const todoFilter = 'all'; // Setting.value('todoFilter');
|
||||
if (todoFilter == 'all') return notes;
|
||||
if (todoFilter === 'all') return notes;
|
||||
|
||||
const now = time.unixMs();
|
||||
const maxInterval = 1000 * 60 * 60 * 24;
|
||||
@ -67,8 +67,8 @@ class NoteListComponent extends Component {
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
const note = notes[i];
|
||||
if (note.is_todo) {
|
||||
if (todoFilter == 'recent' && note.user_updated_time < notRecentTime && !!note.todo_completed) continue;
|
||||
if (todoFilter == 'nonCompleted' && !!note.todo_completed) continue;
|
||||
if (todoFilter === 'recent' && note.user_updated_time < notRecentTime && !!note.todo_completed) continue;
|
||||
if (todoFilter === 'nonCompleted' && !!note.todo_completed) continue;
|
||||
}
|
||||
output.push(note);
|
||||
}
|
||||
@ -77,7 +77,7 @@ class NoteListComponent extends Component {
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
// Make sure scroll position is reset when switching from one folder to another or to a tag list.
|
||||
if (this.rootRef_ && newProps.notesSource != this.props.notesSource) {
|
||||
if (this.rootRef_ && newProps.notesSource !== this.props.notesSource) {
|
||||
this.rootRef_.scrollToOffset({ offset: 0, animated: false });
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ class ScreenHeaderComponent extends React.PureComponent {
|
||||
}
|
||||
|
||||
menu_select(value) {
|
||||
if (typeof value == 'function') {
|
||||
if (typeof value === 'function') {
|
||||
value();
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
{descriptionComp}
|
||||
</View>
|
||||
);
|
||||
} else if (md.type == Setting.TYPE_BOOL) {
|
||||
} else if (md.type === Setting.TYPE_BOOL) {
|
||||
return this.renderToggle(key, md.label(), value, updateSettingValue, descriptionComp);
|
||||
// return (
|
||||
// <View key={key}>
|
||||
@ -482,7 +482,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
// {descriptionComp}
|
||||
// </View>
|
||||
// );
|
||||
} else if (md.type == Setting.TYPE_INT) {
|
||||
} else if (md.type === Setting.TYPE_INT) {
|
||||
const unitLabel = md.unitLabel ? md.unitLabel(value) : value;
|
||||
// Note: Do NOT add the minimumTrackTintColor and maximumTrackTintColor props
|
||||
// on the Slider as they are buggy and can crash the app on certain devices.
|
||||
@ -499,7 +499,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
} else if (md.type == Setting.TYPE_STRING) {
|
||||
} else if (md.type === Setting.TYPE_STRING) {
|
||||
if (md.key === 'sync.2.path' && Platform.OS === 'android' && Platform.Version > 28) {
|
||||
return (
|
||||
<TouchableNativeFeedback key={key} onPress={this.selectDirectoryButtonPress} style={this.styles().settingContainer}>
|
||||
|
@ -103,8 +103,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
if (this.isModified()) {
|
||||
const buttonId = await dialogs.pop(this, _('This note has been modified:'), [{ text: _('Save changes'), id: 'save' }, { text: _('Discard changes'), id: 'discard' }, { text: _('Cancel'), id: 'cancel' }]);
|
||||
|
||||
if (buttonId == 'cancel') return true;
|
||||
if (buttonId == 'save') await this.saveNoteButton_press();
|
||||
if (buttonId === 'cancel') return true;
|
||||
if (buttonId === 'save') await this.saveNoteButton_press();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -126,7 +126,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.state.mode == 'edit') {
|
||||
if (this.state.mode === 'edit') {
|
||||
Keyboard.dismiss();
|
||||
|
||||
this.setState({
|
||||
@ -603,7 +603,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
reg.logger().info('New dimensions ', dimensions);
|
||||
|
||||
const format = mimeType == 'image/png' ? 'PNG' : 'JPEG';
|
||||
const format = mimeType === 'image/png' ? 'PNG' : 'JPEG';
|
||||
reg.logger().info(`Resizing image ${localFilePath}`);
|
||||
const resizedImage = await ImageResizer.createResizedImage(localFilePath, dimensions.width, dimensions.height, format, 85); // , 0, targetPath);
|
||||
|
||||
@ -676,7 +676,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
const targetPath = Resource.fullPath(resource);
|
||||
|
||||
try {
|
||||
if (mimeType == 'image/jpeg' || mimeType == 'image/jpg' || mimeType == 'image/png') {
|
||||
if (mimeType === 'image/jpeg' || mimeType === 'image/jpg' || mimeType === 'image/png') {
|
||||
const done = await this.resizeImage(localFilePath, targetPath, mimeType);
|
||||
if (!done) return;
|
||||
} else {
|
||||
@ -711,7 +711,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const newNote = Object.assign({}, this.state.note);
|
||||
|
||||
if (this.state.mode == 'edit' && !!this.selection) {
|
||||
if (this.state.mode === 'edit' && !!this.selection) {
|
||||
const newText = `\n${resourceTag}\n`;
|
||||
|
||||
const prefix = newNote.body.substring(0, this.selection.start);
|
||||
@ -1068,7 +1068,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
const keywords = this.props.searchQuery && !!this.props.ftsEnabled ? this.props.highlightedWords : emptyArray;
|
||||
|
||||
let bodyComponent = null;
|
||||
if (this.state.mode == 'view') {
|
||||
if (this.state.mode === 'view') {
|
||||
// Note: as of 2018-12-29 it's important not to display the viewer if the note body is empty,
|
||||
// to avoid the HACK_webviewLoadingState related bug.
|
||||
bodyComponent =
|
||||
@ -1154,7 +1154,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
},
|
||||
});
|
||||
|
||||
if (this.state.mode == 'edit') return null;
|
||||
if (this.state.mode === 'edit') return null;
|
||||
|
||||
return <ActionButton multiStates={true} buttons={buttons} buttonIndex={0} />;
|
||||
};
|
||||
@ -1162,7 +1162,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
const actionButtonComp = renderActionButton();
|
||||
|
||||
// Save button is not really needed anymore with the improved save logic
|
||||
const showSaveButton = false; // this.state.mode == 'edit' || this.isModified() || this.saveButtonHasBeenShown_;
|
||||
const showSaveButton = false; // this.state.mode === 'edit' || this.isModified() || this.saveButtonHasBeenShown_;
|
||||
const saveButtonDisabled = true;// !this.isModified();
|
||||
|
||||
if (showSaveButton) this.saveButtonHasBeenShown_ = true;
|
||||
|
@ -83,8 +83,8 @@ class LogScreenComponent extends BaseScreenComponent {
|
||||
render() {
|
||||
const renderRow = ({ item }) => {
|
||||
let textStyle = this.styles().rowText;
|
||||
if (item.level == Logger.LEVEL_WARN) textStyle = this.styles().rowTextWarn;
|
||||
if (item.level == Logger.LEVEL_ERROR) textStyle = this.styles().rowTextError;
|
||||
if (item.level === Logger.LEVEL_WARN) textStyle = this.styles().rowTextWarn;
|
||||
if (item.level === Logger.LEVEL_ERROR) textStyle = this.styles().rowTextError;
|
||||
|
||||
return (
|
||||
<View style={this.styles().row}>
|
||||
|
@ -109,7 +109,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
async componentDidUpdate(prevProps) {
|
||||
if (prevProps.notesOrder !== this.props.notesOrder || prevProps.selectedFolderId != this.props.selectedFolderId || prevProps.selectedTagId != this.props.selectedTagId || prevProps.selectedSmartFilterId != this.props.selectedSmartFilterId || prevProps.notesParentType != this.props.notesParentType) {
|
||||
if (prevProps.notesOrder !== this.props.notesOrder || prevProps.selectedFolderId !== this.props.selectedFolderId || prevProps.selectedTagId !== this.props.selectedTagId || prevProps.selectedSmartFilterId !== this.props.selectedSmartFilterId || prevProps.notesParentType !== this.props.notesParentType) {
|
||||
await this.refreshNotes(this.props);
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
parentId: parent.id,
|
||||
});
|
||||
|
||||
if (source == props.notesSource) return;
|
||||
if (source === props.notesSource) return;
|
||||
|
||||
let notes = [];
|
||||
if (props.notesParentType === 'Folder') {
|
||||
@ -180,11 +180,11 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
if (!props) props = this.props;
|
||||
|
||||
let output = null;
|
||||
if (props.notesParentType == 'Folder') {
|
||||
if (props.notesParentType === 'Folder') {
|
||||
output = Folder.byId(props.folders, props.selectedFolderId);
|
||||
} else if (props.notesParentType == 'Tag') {
|
||||
} else if (props.notesParentType === 'Tag') {
|
||||
output = Tag.byId(props.tags, props.selectedTagId);
|
||||
} else if (props.notesParentType == 'SmartFilter') {
|
||||
} else if (props.notesParentType === 'SmartFilter') {
|
||||
output = { id: this.props.selectedSmartFilterId, title: _('All notes') };
|
||||
} else {
|
||||
return null;
|
||||
@ -230,7 +230,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
const icon = Folder.unserializeIcon(parent.icon);
|
||||
const iconString = icon ? `${icon.emoji} ` : '';
|
||||
|
||||
let buttonFolderId = this.props.selectedFolderId != Folder.conflictFolderId() ? this.props.selectedFolderId : null;
|
||||
let buttonFolderId = this.props.selectedFolderId !== Folder.conflictFolderId() ? this.props.selectedFolderId : null;
|
||||
if (!buttonFolderId) buttonFolderId = this.props.activeFolderId;
|
||||
|
||||
const addFolderNoteButtons = !!buttonFolderId;
|
||||
|
@ -126,7 +126,7 @@ const generalMiddleware = (store: any) => (next: any) => async (action: any) =>
|
||||
|
||||
await reduxSharedMiddleware(store, next, action);
|
||||
|
||||
if (action.type == 'NAV_GO') Keyboard.dismiss();
|
||||
if (action.type === 'NAV_GO') Keyboard.dismiss();
|
||||
|
||||
if (['NOTE_UPDATE_ONE', 'NOTE_DELETE', 'FOLDER_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
|
||||
if (!await reg.syncTarget().syncStarted()) void reg.scheduleSync(5 * 1000, { syncSteps: ['update_remote', 'delete_remote'] }, true);
|
||||
@ -137,20 +137,20 @@ const generalMiddleware = (store: any) => (next: any) => async (action: any) =>
|
||||
await AlarmService.updateNoteNotification(action.id, action.type === 'NOTE_DELETE');
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'sync.interval' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'sync.interval' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
reg.setupRecurrentSync();
|
||||
}
|
||||
|
||||
if ((action.type == 'SETTING_UPDATE_ONE' && (action.key == 'dateFormat' || action.key == 'timeFormat')) || (action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if ((action.type === 'SETTING_UPDATE_ONE' && (action.key === 'dateFormat' || action.key === 'timeFormat')) || (action.type === 'SETTING_UPDATE_ALL')) {
|
||||
time.setDateFormat(Setting.value('dateFormat'));
|
||||
time.setTimeFormat(Setting.value('timeFormat'));
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'locale' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'locale' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
if ((action.type == 'SETTING_UPDATE_ONE' && (action.key.indexOf('encryption.') === 0)) || (action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if ((action.type === 'SETTING_UPDATE_ONE' && (action.key.indexOf('encryption.') === 0)) || (action.type === 'SETTING_UPDATE_ALL')) {
|
||||
await loadMasterKeysFromSettings(EncryptionService.instance());
|
||||
void DecryptionWorker.instance().scheduleStart();
|
||||
const loadedMasterKeyIds = EncryptionService.instance().loadedMasterKeyIds();
|
||||
@ -165,7 +165,7 @@ const generalMiddleware = (store: any) => (next: any) => async (action: any) =>
|
||||
void reg.scheduleSync(null, null, true);
|
||||
}
|
||||
|
||||
if (action.type == 'NAV_GO' && action.routeName == 'Notes') {
|
||||
if (action.type === 'NAV_GO' && action.routeName === 'Notes') {
|
||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ const appReducer = (state = appDefaultState, action: any) => {
|
||||
let newAction = null;
|
||||
while (navHistory.length) {
|
||||
newAction = navHistory.pop();
|
||||
if (newAction.routeName != state.route.routeName) break;
|
||||
if (newAction.routeName !== state.route.routeName) break;
|
||||
}
|
||||
|
||||
action = newAction ? newAction : navHistory.pop();
|
||||
@ -243,7 +243,7 @@ const appReducer = (state = appDefaultState, action: any) => {
|
||||
// If the route *name* is the same (even if the other parameters are different), we
|
||||
// overwrite the last route in the history with the current one. If the route name
|
||||
// is different, we push a new history entry.
|
||||
if (currentRoute.routeName == action.routeName) {
|
||||
if (currentRoute.routeName === action.routeName) {
|
||||
// nothing
|
||||
} else {
|
||||
navHistory.push(currentRoute);
|
||||
@ -258,7 +258,7 @@ const appReducer = (state = appDefaultState, action: any) => {
|
||||
// is probably not a common workflow.
|
||||
for (let i = 0; i < navHistory.length; i++) {
|
||||
const n = navHistory[i];
|
||||
if (n.routeName == action.routeName) {
|
||||
if (n.routeName === action.routeName) {
|
||||
navHistory[i] = Object.assign({}, action);
|
||||
}
|
||||
}
|
||||
@ -416,7 +416,7 @@ async function initialize(dispatch: Function) {
|
||||
mainLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
|
||||
mainLogger.setLevel(Logger.LEVEL_INFO);
|
||||
|
||||
if (Setting.value('env') == 'dev') {
|
||||
if (Setting.value('env') === 'dev') {
|
||||
mainLogger.addTarget(TargetType.Console);
|
||||
mainLogger.setLevel(Logger.LEVEL_DEBUG);
|
||||
}
|
||||
@ -434,7 +434,7 @@ async function initialize(dispatch: Function) {
|
||||
|
||||
const dbLogger = new Logger();
|
||||
dbLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
|
||||
if (Setting.value('env') == 'dev') {
|
||||
if (Setting.value('env') === 'dev') {
|
||||
dbLogger.addTarget(TargetType.Console);
|
||||
dbLogger.setLevel(Logger.LEVEL_INFO); // Set to LEVEL_DEBUG for full SQL queries
|
||||
} else {
|
||||
@ -473,7 +473,7 @@ async function initialize(dispatch: Function) {
|
||||
setRSA(RSA);
|
||||
|
||||
try {
|
||||
if (Setting.value('env') == 'prod') {
|
||||
if (Setting.value('env') === 'prod') {
|
||||
await db.open({ name: 'joplin.sqlite' });
|
||||
} else {
|
||||
await db.open({ name: 'joplin-1.sqlite' });
|
||||
@ -672,7 +672,7 @@ async function initialize(dispatch: Function) {
|
||||
// call will throw an error, alerting us of the issue. Otherwise it will
|
||||
// just print some messages in the console.
|
||||
// ----------------------------------------------------------------------------
|
||||
if (Setting.value('env') == 'dev') await runIntegrationTests();
|
||||
if (Setting.value('env') === 'dev') await runIntegrationTests();
|
||||
|
||||
reg.logger().info('Application initialized');
|
||||
}
|
||||
@ -697,7 +697,7 @@ class AppComponent extends React.Component {
|
||||
};
|
||||
|
||||
this.handleOpenURL_ = (event: any) => {
|
||||
if (event.url == ShareExtension.shareURL) {
|
||||
if (event.url === ShareExtension.shareURL) {
|
||||
void this.handleShareData();
|
||||
}
|
||||
};
|
||||
@ -723,7 +723,7 @@ class AppComponent extends React.Component {
|
||||
// https://discourse.joplinapp.org/t/webdav-config-encryption-config-randomly-lost-on-android/11364
|
||||
// https://discourse.joplinapp.org/t/android-keeps-on-resetting-my-sync-and-theme/11443
|
||||
public async componentDidMount() {
|
||||
if (this.props.appState == 'starting') {
|
||||
if (this.props.appState === 'starting') {
|
||||
this.props.dispatch({
|
||||
type: 'APP_STATE_SET',
|
||||
state: 'initializing',
|
||||
@ -829,7 +829,7 @@ class AppComponent extends React.Component {
|
||||
}
|
||||
|
||||
public UNSAFE_componentWillReceiveProps(newProps: any) {
|
||||
if (newProps.syncStarted != this.lastSyncStarted_) {
|
||||
if (newProps.syncStarted !== this.lastSyncStarted_) {
|
||||
if (!newProps.syncStarted) FoldersScreenUtils.refreshFolders();
|
||||
this.lastSyncStarted_ = newProps.syncStarted;
|
||||
}
|
||||
@ -844,7 +844,7 @@ class AppComponent extends React.Component {
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (this.props.appState != 'ready') return null;
|
||||
if (this.props.appState !== 'ready') return null;
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
let sideMenuContent = null;
|
||||
|
@ -19,7 +19,7 @@ class GeolocationReact {
|
||||
}
|
||||
|
||||
static currentPosition(options = null) {
|
||||
if (Setting.value('env') == 'dev') return this.currentPosition_testResponse();
|
||||
if (Setting.value('env') === 'dev') return this.currentPosition_testResponse();
|
||||
|
||||
if (!options) options = {};
|
||||
if (!('enableHighAccuracy' in options)) options.enableHighAccuracy = true;
|
||||
|
@ -18,7 +18,7 @@ export const binarySearch = function(items: any[], value: any) {
|
||||
stopIndex = items.length - 1,
|
||||
middle = Math.floor((stopIndex + startIndex) / 2);
|
||||
|
||||
while (items[middle] != value && startIndex < stopIndex) {
|
||||
while (items[middle] !== value && startIndex < stopIndex) {
|
||||
// adjust search area
|
||||
if (value < items[middle]) {
|
||||
stopIndex = middle - 1;
|
||||
@ -31,7 +31,7 @@ export const binarySearch = function(items: any[], value: any) {
|
||||
}
|
||||
|
||||
// make sure it's the right value
|
||||
return items[middle] != value ? -1 : middle;
|
||||
return items[middle] !== value ? -1 : middle;
|
||||
};
|
||||
|
||||
export const findByKey = function(array: any[], key: any, value: any) {
|
||||
|
@ -166,57 +166,57 @@ export default class BaseApplication {
|
||||
const arg = argv[0];
|
||||
const nextArg = argv.length >= 2 ? argv[1] : null;
|
||||
|
||||
if (arg == '--profile') {
|
||||
if (arg === '--profile') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--profile <dir-path>'), 'flagError');
|
||||
matched.profileDir = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--no-welcome') {
|
||||
if (arg === '--no-welcome') {
|
||||
matched.welcomeDisabled = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--env') {
|
||||
if (arg === '--env') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--env <dev|prod>'), 'flagError');
|
||||
matched.env = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--is-demo') {
|
||||
if (arg === '--is-demo') {
|
||||
Setting.setConstant('isDemo', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--open-dev-tools') {
|
||||
if (arg === '--open-dev-tools') {
|
||||
Setting.setConstant('flagOpenDevTools', true);
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--debug') {
|
||||
if (arg === '--debug') {
|
||||
// Currently only handled by ElectronAppWrapper (isDebugMode property)
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--update-geolocation-disabled') {
|
||||
if (arg === '--update-geolocation-disabled') {
|
||||
Note.updateGeolocationEnabled_ = false;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--stack-trace-enabled') {
|
||||
if (arg === '--stack-trace-enabled') {
|
||||
this.showStackTraces_ = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--log-level') {
|
||||
if (arg === '--log-level') {
|
||||
if (!nextArg) throw new JoplinError(_('Usage: %s', '--log-level <none|error|warn|info|debug>'), 'flagError');
|
||||
matched.logLevel = Logger.levelStringToId(nextArg);
|
||||
argv.splice(0, 2);
|
||||
@ -277,7 +277,7 @@ export default class BaseApplication {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] == '-') {
|
||||
if (arg.length && arg[0] === '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
break;
|
||||
@ -538,12 +538,12 @@ export default class BaseApplication {
|
||||
refreshFolders = true;
|
||||
}
|
||||
|
||||
if (action.type == 'HISTORY_BACKWARD' || action.type == 'HISTORY_FORWARD') {
|
||||
if (action.type === 'HISTORY_BACKWARD' || action.type === 'HISTORY_FORWARD') {
|
||||
refreshNotes = true;
|
||||
refreshNotesUseSelectedNoteId = true;
|
||||
}
|
||||
|
||||
if (action.type == 'HISTORY_BACKWARD' || action.type == 'HISTORY_FORWARD' || action.type == 'FOLDER_SELECT' || action.type === 'FOLDER_DELETE' || action.type === 'FOLDER_AND_NOTE_SELECT' || (action.type === 'SEARCH_UPDATE' && newState.notesParentType === 'Folder')) {
|
||||
if (action.type === 'HISTORY_BACKWARD' || action.type === 'HISTORY_FORWARD' || action.type === 'FOLDER_SELECT' || action.type === 'FOLDER_DELETE' || action.type === 'FOLDER_AND_NOTE_SELECT' || (action.type === 'SEARCH_UPDATE' && newState.notesParentType === 'Folder')) {
|
||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||
this.currentFolder_ = newState.selectedFolderId ? await Folder.load(newState.selectedFolderId) : null;
|
||||
refreshNotes = true;
|
||||
@ -554,23 +554,23 @@ export default class BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.hasGui() && (action.type == 'NOTE_IS_INSERTING_NOTES' && !action.value)) {
|
||||
if (this.hasGui() && (action.type === 'NOTE_IS_INSERTING_NOTES' && !action.value)) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && action.key == 'uncompletedTodosOnTop') || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && action.key === 'uncompletedTodosOnTop') || action.type === 'SETTING_UPDATE_ALL')) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && action.key == 'showCompletedTodos') || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && action.key === 'showCompletedTodos') || action.type === 'SETTING_UPDATE_ALL')) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && action.key.indexOf('notes.sortOrder') === 0) || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && action.key.indexOf('notes.sortOrder') === 0) || action.type === 'SETTING_UPDATE_ALL')) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (action.type == 'SMART_FILTER_SELECT') {
|
||||
if (action.type === 'SMART_FILTER_SELECT') {
|
||||
refreshNotes = true;
|
||||
refreshNotesUseSelectedNoteId = true;
|
||||
}
|
||||
@ -583,11 +583,11 @@ export default class BaseApplication {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (action.type == 'SEARCH_SELECT' || action.type === 'SEARCH_DELETE') {
|
||||
if (action.type === 'SEARCH_SELECT' || action.type === 'SEARCH_DELETE') {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (action.type == 'NOTE_TAG_REMOVE') {
|
||||
if (action.type === 'NOTE_TAG_REMOVE') {
|
||||
if (newState.notesParentType === 'Tag' && newState.selectedTagId === action.item.id) {
|
||||
if (newState.notes.length === newState.selectedNoteIds.length) {
|
||||
await this.refreshCurrentFolder();
|
||||
@ -615,14 +615,14 @@ export default class BaseApplication {
|
||||
refreshFolders = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (this.hasGui() && action.type === 'SETTING_UPDATE_ALL') {
|
||||
refreshFolders = 'now';
|
||||
}
|
||||
|
||||
if (this.hasGui() && action.type == 'SETTING_UPDATE_ONE' && (
|
||||
if (this.hasGui() && action.type === 'SETTING_UPDATE_ONE' && (
|
||||
action.key.indexOf('folders.sortOrder') === 0 ||
|
||||
action.key == 'showNoteCounts' ||
|
||||
action.key == 'showCompletedTodos')) {
|
||||
action.key === 'showNoteCounts' ||
|
||||
action.key === 'showCompletedTodos')) {
|
||||
refreshFolders = 'now';
|
||||
}
|
||||
|
||||
@ -634,9 +634,9 @@ export default class BaseApplication {
|
||||
void ResourceFetcher.instance().autoAddResources();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE') {
|
||||
await this.applySettingsSideEffects(action);
|
||||
} else if (action.type == 'SETTING_UPDATE_ALL') {
|
||||
} else if (action.type === 'SETTING_UPDATE_ALL') {
|
||||
await this.applySettingsSideEffects();
|
||||
}
|
||||
|
||||
@ -728,7 +728,7 @@ export default class BaseApplication {
|
||||
let initArgs = startFlags.matched;
|
||||
if (argv.length) this.showPromptString_ = false;
|
||||
|
||||
let appName = initArgs.env == 'dev' ? 'joplindev' : 'joplin';
|
||||
let appName = initArgs.env === 'dev' ? 'joplindev' : 'joplin';
|
||||
if (Setting.value('appId').indexOf('-desktop') >= 0) appName += '-desktop';
|
||||
Setting.setConstant('appName', appName);
|
||||
|
||||
|
@ -123,7 +123,7 @@ class BaseModel {
|
||||
|
||||
static byId(items: any[], id: string) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].id == id) return items[i];
|
||||
if (items[i].id === id) return items[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -138,7 +138,7 @@ class BaseModel {
|
||||
|
||||
static modelIndexById(items: any[], id: string) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].id == id) return i;
|
||||
if (items[i].id === id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -200,7 +200,7 @@ class BaseModel {
|
||||
static fieldType(name: string, defaultValue: any = null) {
|
||||
const fields = this.fields();
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
if (fields[i].name == name) return fields[i].type;
|
||||
if (fields[i].name === name) return fields[i].type;
|
||||
}
|
||||
if (defaultValue !== null) return defaultValue;
|
||||
throw new Error(`Unknown field: ${name}`);
|
||||
@ -391,7 +391,7 @@ class BaseModel {
|
||||
const output = [];
|
||||
for (const n in newModel) {
|
||||
if (!newModel.hasOwnProperty(n)) continue;
|
||||
if (n == 'type_') continue;
|
||||
if (n === 'type_') continue;
|
||||
if (!(n in oldModel) || newModel[n] !== oldModel[n]) {
|
||||
output.push(n);
|
||||
}
|
||||
|
@ -104,15 +104,15 @@ export default class BaseSyncTarget {
|
||||
public async synchronizer(): Promise<Synchronizer> {
|
||||
if (this.synchronizer_) return this.synchronizer_;
|
||||
|
||||
if (this.initState_ == 'started') {
|
||||
if (this.initState_ === 'started') {
|
||||
// Synchronizer is already being initialized, so wait here till it's done.
|
||||
return new Promise((resolve, reject) => {
|
||||
const iid = shim.setInterval(() => {
|
||||
if (this.initState_ == 'ready') {
|
||||
if (this.initState_ === 'ready') {
|
||||
shim.clearInterval(iid);
|
||||
resolve(this.synchronizer_);
|
||||
}
|
||||
if (this.initState_ == 'error') {
|
||||
if (this.initState_ === 'error') {
|
||||
shim.clearInterval(iid);
|
||||
reject(new Error('Could not initialise synchroniser'));
|
||||
}
|
||||
@ -141,6 +141,6 @@ export default class BaseSyncTarget {
|
||||
if (!this.synchronizer_) return false;
|
||||
if (!(await this.isAuthenticated())) return false;
|
||||
const sync = await this.synchronizer();
|
||||
return sync.state() != 'idle';
|
||||
return sync.state() !== 'idle';
|
||||
}
|
||||
}
|
||||
|
@ -139,9 +139,9 @@ class DropboxApi {
|
||||
|
||||
// console.info(method + ' ' + url);
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
if (options.source === 'file' && (method === 'POST' || method === 'PUT')) {
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
} else if (options.target === 'string') {
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
// file
|
||||
|
@ -296,19 +296,19 @@ export default class JoplinDatabase extends Database {
|
||||
const chain = [];
|
||||
for (let i = 0; i < tableRows.length; i++) {
|
||||
const tableName = tableRows[i].name;
|
||||
if (tableName == 'android_metadata') continue;
|
||||
if (tableName == 'table_fields') continue;
|
||||
if (tableName == 'sqlite_sequence') continue;
|
||||
if (tableName === 'android_metadata') continue;
|
||||
if (tableName === 'table_fields') continue;
|
||||
if (tableName === 'sqlite_sequence') continue;
|
||||
if (tableName.indexOf('notes_fts') === 0) continue;
|
||||
if (tableName == 'notes_spellfix') continue;
|
||||
if (tableName == 'search_aux') continue;
|
||||
if (tableName === 'notes_spellfix') continue;
|
||||
if (tableName === 'search_aux') continue;
|
||||
chain.push(() => {
|
||||
return this.selectAll(`PRAGMA table_info("${tableName}")`).then(pragmas => {
|
||||
for (let i = 0; i < pragmas.length; i++) {
|
||||
const item = pragmas[i];
|
||||
// In SQLite, if the default value is a string it has double quotes around it, so remove them here
|
||||
let defaultValue = item.dflt_value;
|
||||
if (typeof defaultValue == 'string' && defaultValue.length >= 2 && defaultValue[0] == '"' && defaultValue[defaultValue.length - 1] == '"') {
|
||||
if (typeof defaultValue === 'string' && defaultValue.length >= 2 && defaultValue[0] === '"' && defaultValue[defaultValue.length - 1] === '"') {
|
||||
defaultValue = defaultValue.substr(1, defaultValue.length - 2);
|
||||
}
|
||||
const q = Database.insertQuery('table_fields', {
|
||||
@ -367,7 +367,7 @@ export default class JoplinDatabase extends Database {
|
||||
|
||||
this.logger().info(`Upgrading database from version ${fromVersion}`);
|
||||
|
||||
if (currentVersionIndex == existingDatabaseVersions.length - 1) return fromVersion;
|
||||
if (currentVersionIndex === existingDatabaseVersions.length - 1) return fromVersion;
|
||||
|
||||
let latestVersion = fromVersion;
|
||||
|
||||
@ -377,11 +377,11 @@ export default class JoplinDatabase extends Database {
|
||||
|
||||
let queries: any[] = [];
|
||||
|
||||
if (targetVersion == 1) {
|
||||
if (targetVersion === 1) {
|
||||
queries = this.wrapQueries(this.sqlStringToLines(structureSql));
|
||||
}
|
||||
|
||||
if (targetVersion == 2) {
|
||||
if (targetVersion === 2) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE deleted_items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@ -397,16 +397,16 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push({ sql: 'CREATE INDEX deleted_items_sync_target ON deleted_items (sync_target)' });
|
||||
}
|
||||
|
||||
if (targetVersion == 3) {
|
||||
if (targetVersion === 3) {
|
||||
queries = this.alterColumnQueries('settings', { key: 'TEXT PRIMARY KEY', value: 'TEXT' });
|
||||
}
|
||||
|
||||
if (targetVersion == 4) {
|
||||
if (targetVersion === 4) {
|
||||
queries.push('INSERT INTO settings (`key`, `value`) VALUES (\'sync.3.context\', (SELECT `value` FROM settings WHERE `key` = \'sync.context\'))');
|
||||
queries.push('DELETE FROM settings WHERE `key` = "sync.context"');
|
||||
}
|
||||
|
||||
if (targetVersion == 5) {
|
||||
if (targetVersion === 5) {
|
||||
const tableNames = ['notes', 'folders', 'tags', 'note_tags', 'resources'];
|
||||
for (let i = 0; i < tableNames.length; i++) {
|
||||
const n = tableNames[i];
|
||||
@ -418,21 +418,21 @@ export default class JoplinDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
if (targetVersion == 6) {
|
||||
if (targetVersion === 6) {
|
||||
queries.push('CREATE TABLE alarms (id INTEGER PRIMARY KEY AUTOINCREMENT, note_id TEXT NOT NULL, trigger_time INT NOT NULL)');
|
||||
queries.push('CREATE INDEX alarm_note_id ON alarms (note_id)');
|
||||
}
|
||||
|
||||
if (targetVersion == 7) {
|
||||
if (targetVersion === 7) {
|
||||
queries.push('ALTER TABLE resources ADD COLUMN file_extension TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 8) {
|
||||
if (targetVersion === 8) {
|
||||
queries.push('ALTER TABLE sync_items ADD COLUMN sync_disabled INT NOT NULL DEFAULT "0"');
|
||||
queries.push('ALTER TABLE sync_items ADD COLUMN sync_disabled_reason TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 9) {
|
||||
if (targetVersion === 9) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE master_keys (
|
||||
id TEXT PRIMARY KEY,
|
||||
@ -490,11 +490,11 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push({ sql: 'INSERT INTO item_changes (item_type, item_id, type, created_time) SELECT 1, id, 1, ? FROM notes', params: [Date.now()] });
|
||||
};
|
||||
|
||||
if (targetVersion == 10) {
|
||||
if (targetVersion === 10) {
|
||||
upgradeVersion10();
|
||||
}
|
||||
|
||||
if (targetVersion == 11) {
|
||||
if (targetVersion === 11) {
|
||||
// This trick was needed because Electron Builder incorrectly released a dev branch containing v10 as it was
|
||||
// still being developed, and the db schema was not final at that time. So this v11 was created to
|
||||
// make sure any invalid db schema that was accidentally created was deleted and recreated.
|
||||
@ -503,17 +503,17 @@ export default class JoplinDatabase extends Database {
|
||||
upgradeVersion10();
|
||||
}
|
||||
|
||||
if (targetVersion == 12) {
|
||||
if (targetVersion === 12) {
|
||||
queries.push('ALTER TABLE folders ADD COLUMN parent_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 13) {
|
||||
if (targetVersion === 13) {
|
||||
queries.push('ALTER TABLE resources ADD COLUMN fetch_status INT NOT NULL DEFAULT "2"');
|
||||
queries.push('ALTER TABLE resources ADD COLUMN fetch_error TEXT NOT NULL DEFAULT ""');
|
||||
queries.push({ sql: 'UPDATE resources SET fetch_status = ?', params: [Resource.FETCH_STATUS_DONE] });
|
||||
}
|
||||
|
||||
if (targetVersion == 14) {
|
||||
if (targetVersion === 14) {
|
||||
const resourceLocalStates = `
|
||||
CREATE TABLE resource_local_states (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@ -548,7 +548,7 @@ export default class JoplinDatabase extends Database {
|
||||
);
|
||||
}
|
||||
|
||||
if (targetVersion == 15) {
|
||||
if (targetVersion === 15) {
|
||||
queries.push('CREATE VIRTUAL TABLE notes_fts USING fts4(content="notes", notindexed="id", id, title, body)');
|
||||
queries.push('INSERT INTO notes_fts(docid, id, title, body) SELECT rowid, id, title, body FROM notes WHERE is_conflict = 0 AND encryption_applied = 0');
|
||||
|
||||
@ -572,7 +572,7 @@ export default class JoplinDatabase extends Database {
|
||||
END;`);
|
||||
}
|
||||
|
||||
if (targetVersion == 18) {
|
||||
if (targetVersion === 18) {
|
||||
const notesNormalized = `
|
||||
CREATE TABLE notes_normalized (
|
||||
id TEXT NOT NULL,
|
||||
@ -613,7 +613,7 @@ export default class JoplinDatabase extends Database {
|
||||
END;`);
|
||||
}
|
||||
|
||||
if (targetVersion == 19) {
|
||||
if (targetVersion === 19) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE revisions (
|
||||
id TEXT PRIMARY KEY,
|
||||
@ -642,7 +642,7 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push('ALTER TABLE item_changes ADD COLUMN before_change_item TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 20) {
|
||||
if (targetVersion === 20) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE migrations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@ -657,11 +657,11 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push(this.addMigrationFile(20));
|
||||
}
|
||||
|
||||
if (targetVersion == 21) {
|
||||
if (targetVersion === 21) {
|
||||
queries.push('ALTER TABLE sync_items ADD COLUMN item_location INT NOT NULL DEFAULT 1');
|
||||
}
|
||||
|
||||
if (targetVersion == 22) {
|
||||
if (targetVersion === 22) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE resources_to_download (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@ -676,7 +676,7 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push('CREATE INDEX resources_to_download_updated_time ON resources_to_download (updated_time)');
|
||||
}
|
||||
|
||||
if (targetVersion == 23) {
|
||||
if (targetVersion === 23) {
|
||||
const newTableSql = `
|
||||
CREATE TABLE key_values (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@ -691,11 +691,11 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push('CREATE UNIQUE INDEX key_values_key ON key_values (key)');
|
||||
}
|
||||
|
||||
if (targetVersion == 24) {
|
||||
if (targetVersion === 24) {
|
||||
queries.push('ALTER TABLE notes ADD COLUMN `markup_language` INT NOT NULL DEFAULT 1'); // 1: Markdown, 2: HTML
|
||||
}
|
||||
|
||||
if (targetVersion == 25) {
|
||||
if (targetVersion === 25) {
|
||||
queries.push(`CREATE VIEW tags_with_note_count AS
|
||||
SELECT tags.id as id, tags.title as title, tags.created_time as created_time, tags.updated_time as updated_time, COUNT(notes.id) as note_count
|
||||
FROM tags
|
||||
@ -705,7 +705,7 @@ export default class JoplinDatabase extends Database {
|
||||
GROUP BY tags.id`);
|
||||
}
|
||||
|
||||
if (targetVersion == 26) {
|
||||
if (targetVersion === 26) {
|
||||
const tableNames = ['notes', 'folders', 'tags', 'note_tags', 'resources'];
|
||||
for (let i = 0; i < tableNames.length; i++) {
|
||||
const n = tableNames[i];
|
||||
@ -713,19 +713,19 @@ export default class JoplinDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
if (targetVersion == 27) {
|
||||
if (targetVersion === 27) {
|
||||
queries.push(this.addMigrationFile(27));
|
||||
}
|
||||
|
||||
if (targetVersion == 28) {
|
||||
if (targetVersion === 28) {
|
||||
queries.push('CREATE INDEX resources_size ON resources(size)');
|
||||
}
|
||||
|
||||
if (targetVersion == 29) {
|
||||
if (targetVersion === 29) {
|
||||
queries.push('ALTER TABLE version ADD COLUMN table_fields_version INT NOT NULL DEFAULT 0');
|
||||
}
|
||||
|
||||
if (targetVersion == 30) {
|
||||
if (targetVersion === 30) {
|
||||
// Change the type of the "order" field from INT to NUMERIC
|
||||
// Making it a float provides a much bigger range when inserting notes.
|
||||
// For example, with an INT, inserting a note C between note A with order 1000 and
|
||||
@ -762,7 +762,7 @@ export default class JoplinDatabase extends Database {
|
||||
);
|
||||
}
|
||||
|
||||
if (targetVersion == 31) {
|
||||
if (targetVersion === 31) {
|
||||
// This empty version is due to the revert of the hierarchical tag feature
|
||||
// We need to keep the version for the users who have upgraded using
|
||||
// the pre-release
|
||||
@ -772,7 +772,7 @@ export default class JoplinDatabase extends Database {
|
||||
// queries.push(this.addMigrationFile(31));
|
||||
}
|
||||
|
||||
if (targetVersion == 32) {
|
||||
if (targetVersion === 32) {
|
||||
// This is the same as version 25 - this is to complete the
|
||||
// revert of the hierarchical tag feature.
|
||||
queries.push(`CREATE VIEW IF NOT EXISTS tags_with_note_count AS
|
||||
@ -784,7 +784,7 @@ export default class JoplinDatabase extends Database {
|
||||
GROUP BY tags.id`);
|
||||
}
|
||||
|
||||
if (targetVersion == 33) {
|
||||
if (targetVersion === 33) {
|
||||
queries.push('DROP TRIGGER notes_fts_before_update');
|
||||
queries.push('DROP TRIGGER notes_fts_before_delete');
|
||||
queries.push('DROP TRIGGER notes_after_update');
|
||||
@ -867,24 +867,24 @@ export default class JoplinDatabase extends Database {
|
||||
queries.push(this.addMigrationFile(33));
|
||||
}
|
||||
|
||||
if (targetVersion == 34) {
|
||||
if (targetVersion === 34) {
|
||||
queries.push('CREATE VIRTUAL TABLE search_aux USING fts4aux(notes_fts)');
|
||||
queries.push('CREATE VIRTUAL TABLE notes_spellfix USING spellfix1');
|
||||
}
|
||||
|
||||
if (targetVersion == 35) {
|
||||
if (targetVersion === 35) {
|
||||
queries.push('ALTER TABLE notes_normalized ADD COLUMN todo_due INT NOT NULL DEFAULT 0');
|
||||
queries.push('CREATE INDEX notes_normalized_todo_due ON notes_normalized (todo_due)');
|
||||
queries.push(this.addMigrationFile(35));
|
||||
}
|
||||
|
||||
if (targetVersion == 36) {
|
||||
if (targetVersion === 36) {
|
||||
queries.push('ALTER TABLE folders ADD COLUMN share_id TEXT NOT NULL DEFAULT ""');
|
||||
queries.push('ALTER TABLE notes ADD COLUMN share_id TEXT NOT NULL DEFAULT ""');
|
||||
queries.push('ALTER TABLE resources ADD COLUMN share_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 38) {
|
||||
if (targetVersion === 38) {
|
||||
queries.push('DROP VIEW tags_with_note_count');
|
||||
queries.push(`CREATE VIEW tags_with_note_count AS
|
||||
SELECT tags.id as id, tags.title as title, tags.created_time as created_time, tags.updated_time as updated_time, COUNT(notes.id) as note_count,
|
||||
@ -896,17 +896,17 @@ export default class JoplinDatabase extends Database {
|
||||
GROUP BY tags.id`);
|
||||
}
|
||||
|
||||
if (targetVersion == 39) {
|
||||
if (targetVersion === 39) {
|
||||
queries.push('ALTER TABLE `notes` ADD COLUMN conflict_original_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 40) {
|
||||
if (targetVersion === 40) {
|
||||
queries.push('ALTER TABLE `folders` ADD COLUMN master_key_id TEXT NOT NULL DEFAULT ""');
|
||||
queries.push('ALTER TABLE `notes` ADD COLUMN master_key_id TEXT NOT NULL DEFAULT ""');
|
||||
queries.push('ALTER TABLE `resources` ADD COLUMN master_key_id TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
if (targetVersion == 41) {
|
||||
if (targetVersion === 41) {
|
||||
queries.push('ALTER TABLE `folders` ADD COLUMN icon TEXT NOT NULL DEFAULT ""');
|
||||
}
|
||||
|
||||
|
@ -177,13 +177,13 @@ export default class JoplinServerApi {
|
||||
|
||||
let response: any = null;
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
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}`;
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
} else if (options.target === 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
|
@ -168,7 +168,7 @@ class Logger {
|
||||
|
||||
for (let i = 0; i < this.targets_.length; i++) {
|
||||
const target = this.targets_[i];
|
||||
if (target.type == 'database') {
|
||||
if (target.type === 'database') {
|
||||
let sql = `SELECT * FROM logs WHERE level IN (${options.levels.join(',')}) ORDER BY timestamp DESC`;
|
||||
if (limit !== null) sql += ` LIMIT ${limit}`;
|
||||
return await target.database.selectAll(sql);
|
||||
@ -191,11 +191,11 @@ class Logger {
|
||||
|
||||
if (this.targetLevel(target) < level) continue;
|
||||
|
||||
if (target.type == 'console') {
|
||||
if (target.type === 'console') {
|
||||
let fn = 'log';
|
||||
if (level == LogLevel.Error) fn = 'error';
|
||||
if (level == LogLevel.Warn) fn = 'warn';
|
||||
if (level == LogLevel.Info) fn = 'info';
|
||||
if (level === LogLevel.Error) fn = 'error';
|
||||
if (level === LogLevel.Warn) fn = 'warn';
|
||||
if (level === LogLevel.Info) fn = 'info';
|
||||
const consoleObj = target.console ? target.console : console;
|
||||
let items: any[] = [];
|
||||
|
||||
@ -217,7 +217,7 @@ class Logger {
|
||||
}
|
||||
|
||||
consoleObj[fn](...items);
|
||||
} else if (target.type == 'file') {
|
||||
} else if (target.type === 'file') {
|
||||
const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
const line = [timestamp];
|
||||
if (targetPrefix) line.push(targetPrefix);
|
||||
@ -239,7 +239,7 @@ class Logger {
|
||||
}).finally(() => {
|
||||
if (release) release();
|
||||
});
|
||||
} else if (target.type == 'database') {
|
||||
} else if (target.type === 'database') {
|
||||
const msg = [];
|
||||
if (targetPrefix) msg.push(targetPrefix);
|
||||
msg.push(this.objectsToString(...object));
|
||||
@ -280,20 +280,20 @@ class Logger {
|
||||
}
|
||||
|
||||
static levelStringToId(s: string) {
|
||||
if (s == 'none') return LogLevel.None;
|
||||
if (s == 'error') return LogLevel.Error;
|
||||
if (s == 'warn') return LogLevel.Warn;
|
||||
if (s == 'info') return LogLevel.Info;
|
||||
if (s == 'debug') return LogLevel.Debug;
|
||||
if (s === 'none') return LogLevel.None;
|
||||
if (s === 'error') return LogLevel.Error;
|
||||
if (s === 'warn') return LogLevel.Warn;
|
||||
if (s === 'info') return LogLevel.Info;
|
||||
if (s === 'debug') return LogLevel.Debug;
|
||||
throw new Error(`Unknown log level: ${s}`);
|
||||
}
|
||||
|
||||
static levelIdToString(id: LogLevel) {
|
||||
if (id == LogLevel.None) return 'none';
|
||||
if (id == LogLevel.Error) return 'error';
|
||||
if (id == LogLevel.Warn) return 'warn';
|
||||
if (id == LogLevel.Info) return 'info';
|
||||
if (id == LogLevel.Debug) return 'debug';
|
||||
if (id === LogLevel.None) return 'none';
|
||||
if (id === LogLevel.Error) return 'error';
|
||||
if (id === LogLevel.Warn) return 'warn';
|
||||
if (id === LogLevel.Info) return 'info';
|
||||
if (id === LogLevel.Debug) return 'debug';
|
||||
throw new Error(`Unknown level ID: ${id}`);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ export default class SyncTargetOneDrive extends BaseSyncTarget {
|
||||
|
||||
if (this.api_) return this.api_;
|
||||
|
||||
const isPublic = Setting.value('appType') != 'cli' && Setting.value('appType') != 'desktop';
|
||||
const isPublic = Setting.value('appType') !== 'cli' && Setting.value('appType') !== 'desktop';
|
||||
|
||||
this.api_ = new OneDriveApi(this.oneDriveParameters().id, this.oneDriveParameters().secret, isPublic);
|
||||
|
||||
|
@ -241,12 +241,12 @@ export default class Synchronizer {
|
||||
logger.info('Operations completed: ');
|
||||
for (const n in report) {
|
||||
if (!report.hasOwnProperty(n)) continue;
|
||||
if (n == 'errors') continue;
|
||||
if (n == 'starting') continue;
|
||||
if (n == 'finished') continue;
|
||||
if (n == 'state') continue;
|
||||
if (n == 'startTime') continue;
|
||||
if (n == 'completedTime') continue;
|
||||
if (n === 'errors') continue;
|
||||
if (n === 'starting') continue;
|
||||
if (n === 'finished') continue;
|
||||
if (n === 'state') continue;
|
||||
if (n === 'startTime') continue;
|
||||
if (n === 'completedTime') continue;
|
||||
logger.info(`${n}: ${report[n] ? report[n] : '-'}`);
|
||||
}
|
||||
const folderCount = await Folder.count();
|
||||
@ -266,7 +266,7 @@ export default class Synchronizer {
|
||||
}
|
||||
|
||||
async cancel() {
|
||||
if (this.cancelling_ || this.state() == 'idle') return;
|
||||
if (this.cancelling_ || this.state() === 'idle') return;
|
||||
|
||||
// Stop queue but don't set it to null as it may be used to
|
||||
// retrieve the last few downloads.
|
||||
@ -277,7 +277,7 @@ export default class Synchronizer {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const iid = shim.setInterval(() => {
|
||||
if (this.state() == 'idle') {
|
||||
if (this.state() === 'idle') {
|
||||
shim.clearInterval(iid);
|
||||
resolve(null);
|
||||
}
|
||||
@ -360,7 +360,7 @@ export default class Synchronizer {
|
||||
public async start(options: any = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
if (this.state() != 'idle') {
|
||||
if (this.state() !== 'idle') {
|
||||
const error: any = new Error(sprintf('Synchronisation is already in progress. State: %s', this.state()));
|
||||
error.code = 'alreadyStarted';
|
||||
throw error;
|
||||
@ -641,7 +641,7 @@ export default class Synchronizer {
|
||||
|
||||
this.logSyncOperation(action, local, remote, reason);
|
||||
|
||||
if (local.type_ == BaseModel.TYPE_RESOURCE && (action == 'createRemote' || action === 'updateRemote')) {
|
||||
if (local.type_ === BaseModel.TYPE_RESOURCE && (action === 'createRemote' || action === 'updateRemote')) {
|
||||
const localState = await Resource.localState(local.id);
|
||||
if (localState.fetch_status !== Resource.FETCH_STATUS_DONE) {
|
||||
// This condition normally shouldn't happen
|
||||
@ -703,7 +703,7 @@ export default class Synchronizer {
|
||||
}
|
||||
}
|
||||
|
||||
if (action == 'createRemote' || action == 'updateRemote') {
|
||||
if (action === 'createRemote' || action === 'updateRemote') {
|
||||
let canSync = true;
|
||||
try {
|
||||
if (this.testingHooks_.indexOf('notesRejectedByTarget') >= 0 && local.type_ === BaseModel.TYPE_NOTE) throw new JoplinError('Testing rejectedByTarget', 'rejectedByTarget');
|
||||
@ -739,7 +739,7 @@ export default class Synchronizer {
|
||||
|
||||
await ItemClass.saveSyncTime(syncTargetId, local, local.updated_time);
|
||||
}
|
||||
} else if (action == 'itemConflict') {
|
||||
} else if (action === 'itemConflict') {
|
||||
// ------------------------------------------------------------------------------
|
||||
// For non-note conflicts, we take the remote version (i.e. the version that was
|
||||
// synced first) and overwrite the local content.
|
||||
@ -756,7 +756,7 @@ export default class Synchronizer {
|
||||
trackDeleted: false,
|
||||
});
|
||||
}
|
||||
} else if (action == 'noteConflict') {
|
||||
} else if (action === 'noteConflict') {
|
||||
// ------------------------------------------------------------------------------
|
||||
// First find out if the conflict matters. For example, if the conflict is on the title or body
|
||||
// we want to preserve all the changes. If it's on todo_completed it doesn't really matter
|
||||
@ -776,7 +776,7 @@ export default class Synchronizer {
|
||||
if (mustHandleConflict) {
|
||||
await Note.createConflictNote(local, ItemChange.SOURCE_SYNC);
|
||||
}
|
||||
} else if (action == 'resourceConflict') {
|
||||
} else if (action === 'resourceConflict') {
|
||||
// ------------------------------------------------------------------------------
|
||||
// Unlike notes we always handle the conflict for resources
|
||||
// ------------------------------------------------------------------------------
|
||||
@ -951,7 +951,7 @@ export default class Synchronizer {
|
||||
|
||||
this.logSyncOperation(action, local, remote, reason);
|
||||
|
||||
if (action == 'createLocal' || action == 'updateLocal') {
|
||||
if (action === 'createLocal' || action === 'updateLocal') {
|
||||
if (content === null) {
|
||||
logger.warn(`Remote has been deleted between now and the delta() call? In that case it will be handled during the next sync: ${path}`);
|
||||
continue;
|
||||
@ -971,10 +971,10 @@ export default class Synchronizer {
|
||||
nextQueries: BaseItem.updateSyncTimeQueries(syncTargetId, content, time.unixMs()),
|
||||
changeSource: ItemChange.SOURCE_SYNC,
|
||||
};
|
||||
if (action == 'createLocal') options.isNew = true;
|
||||
if (action == 'updateLocal') options.oldItem = local;
|
||||
if (action === 'createLocal') options.isNew = true;
|
||||
if (action === 'updateLocal') options.oldItem = local;
|
||||
|
||||
const creatingOrUpdatingResource = content.type_ == BaseModel.TYPE_RESOURCE && (action == 'createLocal' || action == 'updateLocal');
|
||||
const creatingOrUpdatingResource = content.type_ === BaseModel.TYPE_RESOURCE && (action === 'createLocal' || action === 'updateLocal');
|
||||
|
||||
if (creatingOrUpdatingResource) {
|
||||
if (content.size >= this.maxResourceSize()) {
|
||||
@ -1018,8 +1018,8 @@ export default class Synchronizer {
|
||||
// }
|
||||
|
||||
if (content.encryption_applied) this.dispatch({ type: 'SYNC_GOT_ENCRYPTED_ITEM' });
|
||||
} else if (action == 'deleteLocal') {
|
||||
if (local.type_ == BaseModel.TYPE_FOLDER) {
|
||||
} else if (action === 'deleteLocal') {
|
||||
if (local.type_ === BaseModel.TYPE_FOLDER) {
|
||||
localFoldersToDelete.push(local);
|
||||
continue;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class WebDavApi {
|
||||
// Check if the current name is within the DAV namespace. If it is, normalise it
|
||||
// by moving it to the "d:" namespace, which is what all the functions are using.
|
||||
const p = name.split(':');
|
||||
if (p.length == 2) {
|
||||
if (p.length === 2) {
|
||||
const ns = p[0];
|
||||
if (davNamespaces.indexOf(ns) >= 0) {
|
||||
name = `d:${p[1]}`;
|
||||
@ -386,13 +386,13 @@ class WebDavApi {
|
||||
// console.info('WebDAV Call', `${method} ${url}`, headers, options);
|
||||
// console.info(this.requestToCurl_(url, fetchOptions));
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
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}`;
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
} else if (options.target === 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else {
|
||||
|
@ -53,7 +53,7 @@ export const runtime = (): CommandRuntime => {
|
||||
return 'error';
|
||||
}
|
||||
|
||||
if (action == 'cancel') {
|
||||
if (action === 'cancel') {
|
||||
sync.cancel();
|
||||
return 'cancel';
|
||||
} else {
|
||||
|
@ -14,7 +14,7 @@ const reduxSharedMiddleware = async function(store, next, action) {
|
||||
|
||||
let refreshTags = false;
|
||||
|
||||
if (action.type == 'FOLDER_SET_COLLAPSED' || action.type == 'FOLDER_TOGGLE') {
|
||||
if (action.type === 'FOLDER_SET_COLLAPSED' || action.type === 'FOLDER_TOGGLE') {
|
||||
Setting.setValue('collapsedFolderIds', newState.collapsedFolderIds);
|
||||
}
|
||||
|
||||
@ -43,16 +43,16 @@ const reduxSharedMiddleware = async function(store, next, action) {
|
||||
DecryptionWorker.instance().scheduleStart();
|
||||
}
|
||||
|
||||
if (action.type == 'NOTE_DELETE' ||
|
||||
action.type == 'NOTE_UPDATE_ALL' ||
|
||||
action.type == 'NOTE_TAG_REMOVE' ||
|
||||
action.type == 'TAG_UPDATE_ONE') {
|
||||
if (action.type === 'NOTE_DELETE' ||
|
||||
action.type === 'NOTE_UPDATE_ALL' ||
|
||||
action.type === 'NOTE_TAG_REMOVE' ||
|
||||
action.type === 'TAG_UPDATE_ONE') {
|
||||
refreshTags = true;
|
||||
}
|
||||
|
||||
// handle the case when the selected note has been moved to another
|
||||
// folder and a new one is now selected, need to show correct tags for it
|
||||
if (action.type == 'NOTE_UPDATE_ONE' && action.changedFields.indexOf('parent_id') >= 0) {
|
||||
if (action.type === 'NOTE_UPDATE_ONE' && action.changedFields.indexOf('parent_id') >= 0) {
|
||||
refreshTags = true;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ function renderFoldersRecursive_(props, renderItem, items, parentId, depth, orde
|
||||
if (!folderIsVisible(props.folders, folder.id, props.collapsedFolderIds)) continue;
|
||||
const hasChildren = folderHasChildren_(folders, folder.id);
|
||||
order.push(folder.id);
|
||||
items.push(renderItem(folder, props.selectedFolderId == folder.id && props.notesParentType == 'Folder', hasChildren, depth));
|
||||
items.push(renderItem(folder, props.selectedFolderId === folder.id && props.notesParentType === 'Folder', hasChildren, depth));
|
||||
if (hasChildren) {
|
||||
const result = renderFoldersRecursive_(props, renderItem, items, folder.id, depth + 1, order);
|
||||
items = result.items;
|
||||
@ -69,7 +69,7 @@ shared.renderTags = function(props, renderItem) {
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
const tag = tags[i];
|
||||
order.push(tag.id);
|
||||
tagItems.push(renderItem(tag, props.selectedTagId == tag.id && props.notesParentType == 'Tag'));
|
||||
tagItems.push(renderItem(tag, props.selectedTagId === tag.id && props.notesParentType === 'Tag'));
|
||||
}
|
||||
return {
|
||||
items: tagItems,
|
||||
@ -123,7 +123,7 @@ shared.synchronize_press = async function(comp) {
|
||||
return 'error';
|
||||
}
|
||||
|
||||
if (action == 'cancel') {
|
||||
if (action === 'cancel') {
|
||||
sync.cancel();
|
||||
return 'cancel';
|
||||
} else {
|
||||
|
@ -69,16 +69,16 @@ export default class Database {
|
||||
}
|
||||
|
||||
public escapeField(field: string) {
|
||||
if (field == '*') return '*';
|
||||
if (field === '*') return '*';
|
||||
const 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}`);
|
||||
}
|
||||
|
||||
public escapeFields(fields: string[] | string): string[] | string {
|
||||
if (fields == '*') return '*';
|
||||
if (fields === '*') return '*';
|
||||
|
||||
const output = [];
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
@ -137,7 +137,7 @@ export default class Database {
|
||||
|
||||
return result; // No exception was thrown
|
||||
} catch (error) {
|
||||
if (error && (error.code == 'SQLITE_IOERR' || error.code == 'SQLITE_BUSY')) {
|
||||
if (error && (error.code === 'SQLITE_IOERR' || error.code === 'SQLITE_BUSY')) {
|
||||
if (totalWaitTime >= 20000) throw this.sqliteErrorToJsError(error, sql, params);
|
||||
// NOTE: don't put logger statements here because it might log to the database, which
|
||||
// could result in an error being thrown again.
|
||||
@ -193,7 +193,7 @@ export default class Database {
|
||||
async transactionExecBatch(queries: StringOrSqlQuery[]) {
|
||||
if (queries.length <= 0) return;
|
||||
|
||||
if (queries.length == 1) {
|
||||
if (queries.length === 1) {
|
||||
const q = this.wrapQuery(queries[0]);
|
||||
await this.exec(q.sql, q.params);
|
||||
return;
|
||||
@ -220,20 +220,20 @@ export default class Database {
|
||||
}
|
||||
|
||||
static enumId(type: string, s: string) {
|
||||
if (type == 'settings') {
|
||||
if (s == 'int') return 1;
|
||||
if (s == 'string') return 2;
|
||||
if (type === 'settings') {
|
||||
if (s === 'int') return 1;
|
||||
if (s === 'string') return 2;
|
||||
}
|
||||
if (type == 'fieldType') {
|
||||
if (type === 'fieldType') {
|
||||
if (s) s = s.toUpperCase();
|
||||
if (s == 'INTEGER') s = 'INT';
|
||||
if (s === 'INTEGER') s = 'INT';
|
||||
if (!(`TYPE_${s}` in this)) throw new Error(`Unkonwn fieldType: ${s}`);
|
||||
return (this as any)[`TYPE_${s}`];
|
||||
}
|
||||
if (type == 'syncTarget') {
|
||||
if (s == 'memory') return 1;
|
||||
if (s == 'filesystem') return 2;
|
||||
if (s == 'onedrive') return 3;
|
||||
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}`);
|
||||
}
|
||||
@ -253,9 +253,9 @@ export default class Database {
|
||||
|
||||
static formatValue(type: number, value: any) {
|
||||
if (value === null || value === undefined) return null;
|
||||
if (type == this.TYPE_INT) return Number(value);
|
||||
if (type == this.TYPE_TEXT) return value;
|
||||
if (type == this.TYPE_NUMERIC) return Number(value);
|
||||
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}`);
|
||||
}
|
||||
|
||||
@ -265,11 +265,11 @@ export default class Database {
|
||||
let statement = '';
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line == '') continue;
|
||||
if (line.substr(0, 2) == '--') continue;
|
||||
if (line === '') continue;
|
||||
if (line.substr(0, 2) === '--') continue;
|
||||
statement += line.trim();
|
||||
if (line[line.length - 1] == ',') statement += ' ';
|
||||
if (line[line.length - 1] == ';') {
|
||||
if (line[line.length - 1] === ',') statement += ' ';
|
||||
if (line[line.length - 1] === ';') {
|
||||
output.push(statement);
|
||||
statement = '';
|
||||
}
|
||||
@ -299,9 +299,9 @@ export default class Database {
|
||||
const params = [];
|
||||
for (const key in data) {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (key[key.length - 1] == '_') continue;
|
||||
if (keySql != '') keySql += ', ';
|
||||
if (valueSql != '') valueSql += ', ';
|
||||
if (key[key.length - 1] === '_') continue;
|
||||
if (keySql !== '') keySql += ', ';
|
||||
if (valueSql !== '') valueSql += ', ';
|
||||
keySql += `\`${key}\``;
|
||||
valueSql += '?';
|
||||
params.push(data[key]);
|
||||
@ -319,13 +319,13 @@ export default class Database {
|
||||
const params = [];
|
||||
for (const key in data) {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (key[key.length - 1] == '_') continue;
|
||||
if (sql != '') sql += ', ';
|
||||
if (key[key.length - 1] === '_') continue;
|
||||
if (sql !== '') sql += ', ';
|
||||
sql += `\`${key}\`=?`;
|
||||
params.push(data[key]);
|
||||
}
|
||||
|
||||
if (typeof where != 'string') {
|
||||
if (typeof where !== 'string') {
|
||||
const s = [];
|
||||
for (const n in where) {
|
||||
if (!where.hasOwnProperty(n)) continue;
|
||||
|
@ -53,7 +53,7 @@ class FileApiDriverOneDrive {
|
||||
try {
|
||||
item = await this.api_.execJson('GET', this.makePath_(path), this.itemFilter_());
|
||||
} catch (error) {
|
||||
if (error.code == 'itemNotFound') return null;
|
||||
if (error.code === 'itemNotFound') return null;
|
||||
throw error;
|
||||
}
|
||||
return item;
|
||||
@ -107,7 +107,7 @@ class FileApiDriverOneDrive {
|
||||
if (!options) options = {};
|
||||
|
||||
try {
|
||||
if (options.target == 'file') {
|
||||
if (options.target === 'file') {
|
||||
const response = await this.api_.exec('GET', `${this.makePath_(path)}:/content`, null, null, options);
|
||||
return response;
|
||||
} else {
|
||||
@ -115,7 +115,7 @@ class FileApiDriverOneDrive {
|
||||
return content;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code == 'itemNotFound') return null;
|
||||
if (error.code === 'itemNotFound') return null;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ class FileApiDriverOneDrive {
|
||||
// We need to check the file size as files > 4 MBs are uploaded in a different way than files < 4 MB (see https://docs.microsoft.com/de-de/onedrive/developer/rest-api/concepts/upload?view=odsp-graph-online)
|
||||
let byteSize = null;
|
||||
|
||||
if (options.source == 'file') {
|
||||
if (options.source === 'file') {
|
||||
byteSize = (await shim.fsDriver().stat(options.path)).size;
|
||||
} else {
|
||||
options.headers = { 'Content-Type': 'text/plain' };
|
||||
|
@ -16,10 +16,8 @@ function addResourceTag(lines, resource, attributes) {
|
||||
if (resourceUtils.isImageMimeType(resource.mime)) {
|
||||
lines.push(resourceUtils.imgElement({ src, attributes }));
|
||||
} else if (resource.mime === 'audio/x-m4a') {
|
||||
/**
|
||||
* TODO: once https://github.com/laurent22/joplin/issues/1794 is resolved,
|
||||
* come back to this and make sure it works.
|
||||
*/
|
||||
// TODO: once https://github.com/laurent22/joplin/issues/1794 is resolved,
|
||||
// come back to this and make sure it works.
|
||||
lines.push(resourceUtils.audioElement({
|
||||
src,
|
||||
alt: attributes.alt,
|
||||
@ -90,7 +88,7 @@ function enexXmlToHtml_(stream, resources) {
|
||||
let resource = null;
|
||||
for (let i = 0; i < resources.length; i++) {
|
||||
const r = resources[i];
|
||||
if (r.id == hash) {
|
||||
if (r.id === hash) {
|
||||
resource = r;
|
||||
removeRemainingResource(r.id);
|
||||
break;
|
||||
@ -122,9 +120,9 @@ function enexXmlToHtml_(stream, resources) {
|
||||
if (resource && !!resource.id) {
|
||||
section.lines = addResourceTag(section.lines, resource, nodeAttributes);
|
||||
}
|
||||
} else if (tagName == 'en-todo') {
|
||||
} else if (tagName === 'en-todo') {
|
||||
const nodeAttributes = attributeToLowerCase(node);
|
||||
const checkedHtml = nodeAttributes.checked && nodeAttributes.checked.toLowerCase() == 'true' ? ' checked="checked" ' : ' ';
|
||||
const checkedHtml = nodeAttributes.checked && nodeAttributes.checked.toLowerCase() === 'true' ? ' checked="checked" ' : ' ';
|
||||
section.lines.push(`<input${checkedHtml}type="checkbox" onclick="return false;" />`);
|
||||
} else if (htmlUtils.isSelfClosingTag(tagName)) {
|
||||
section.lines.push(`<${tagName}${attributesStr}/>`);
|
||||
|
@ -58,11 +58,11 @@ interface EnexXmlToMdArrayResult {
|
||||
}
|
||||
|
||||
function processMdArrayNewLines(md: string[]): string {
|
||||
while (md.length && md[0] == BLOCK_OPEN) {
|
||||
while (md.length && md[0] === BLOCK_OPEN) {
|
||||
md.shift();
|
||||
}
|
||||
|
||||
while (md.length && md[md.length - 1] == BLOCK_CLOSE) {
|
||||
while (md.length && md[md.length - 1] === BLOCK_CLOSE) {
|
||||
md.pop();
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
let last = '';
|
||||
for (let i = 0; i < md.length; i++) {
|
||||
const v = md[i];
|
||||
if (isNewLineBlock(last) && isNewLineBlock(v) && last == v) {
|
||||
if (isNewLineBlock(last) && isNewLineBlock(v) && last === v) {
|
||||
// Skip it
|
||||
} else {
|
||||
temp.push(v);
|
||||
@ -83,7 +83,7 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
last = '';
|
||||
for (let i = 0; i < md.length; i++) {
|
||||
const v = md[i];
|
||||
if (last == BLOCK_CLOSE && v == BLOCK_OPEN) {
|
||||
if (last === BLOCK_CLOSE && v === BLOCK_OPEN) {
|
||||
temp.pop();
|
||||
temp.push(NEWLINE_MERGED);
|
||||
} else {
|
||||
@ -97,7 +97,7 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
last = '';
|
||||
for (let i = 0; i < md.length; i++) {
|
||||
const v = md[i];
|
||||
if (last == NEWLINE && (v == NEWLINE_MERGED || v == BLOCK_CLOSE)) {
|
||||
if (last === NEWLINE && (v === NEWLINE_MERGED || v === BLOCK_CLOSE)) {
|
||||
// Skip it
|
||||
} else {
|
||||
temp.push(v);
|
||||
@ -111,7 +111,7 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
last = '';
|
||||
for (let i = 0; i < md.length; i++) {
|
||||
const v = md[i];
|
||||
if (last == NEWLINE && (v == NEWLINE_MERGED || v == BLOCK_OPEN)) {
|
||||
if (last === NEWLINE && (v === NEWLINE_MERGED || v === BLOCK_OPEN)) {
|
||||
// Skip it
|
||||
} else {
|
||||
temp.push(v);
|
||||
@ -121,7 +121,7 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
md = temp;
|
||||
|
||||
if (md.length > 2) {
|
||||
if (md[md.length - 2] == NEWLINE_MERGED && md[md.length - 1] == NEWLINE) {
|
||||
if (md[md.length - 2] === NEWLINE_MERGED && md[md.length - 1] === NEWLINE) {
|
||||
md.pop();
|
||||
}
|
||||
}
|
||||
@ -132,10 +132,10 @@ function processMdArrayNewLines(md: string[]): string {
|
||||
for (let i = 0; i < md.length; i++) {
|
||||
const v = md[i];
|
||||
let add = '';
|
||||
if (v == BLOCK_CLOSE || v == BLOCK_OPEN || v == NEWLINE || v == NEWLINE_MERGED) {
|
||||
if (v === BLOCK_CLOSE || v === BLOCK_OPEN || v === NEWLINE || v === NEWLINE_MERGED) {
|
||||
add = '\n';
|
||||
} else if (v == SPACE) {
|
||||
if (previous == SPACE || previous == '\n' || start) {
|
||||
} else if (v === SPACE) {
|
||||
if (previous === SPACE || previous === '\n' || start) {
|
||||
continue; // skip
|
||||
} else {
|
||||
add = ' ';
|
||||
@ -285,7 +285,7 @@ function formatMdLayout(lines: string[]) {
|
||||
}
|
||||
|
||||
function isWhiteSpace(c: string): boolean {
|
||||
return c == '\n' || c == '\r' || c == '\v' || c == '\f' || c == '\t' || c == ' ';
|
||||
return c === '\n' || c === '\r' || c === '\v' || c === '\f' || c === '\t' || c === ' ';
|
||||
}
|
||||
|
||||
// Like QString::simpified(), except that it preserves non-breaking spaces (which
|
||||
@ -315,16 +315,16 @@ function collapseWhiteSpaceAndAppend(lines: string[], state: any, text: string)
|
||||
lines.push(text);
|
||||
} else {
|
||||
// Remove all \n and \r from the left and right of the text
|
||||
while (text.length && (text[0] == '\n' || text[0] == '\r')) text = text.substr(1);
|
||||
while (text.length && (text[text.length - 1] == '\n' || text[text.length - 1] == '\r')) text = text.substr(0, text.length - 1);
|
||||
while (text.length && (text[0] === '\n' || text[0] === '\r')) text = text.substr(1);
|
||||
while (text.length && (text[text.length - 1] === '\n' || text[text.length - 1] === '\r')) text = text.substr(0, text.length - 1);
|
||||
|
||||
// Collapse all white spaces to just one. If there are spaces to the left and right of the string
|
||||
// also collapse them to just one space.
|
||||
const spaceLeft = text.length && text[0] == ' ';
|
||||
const spaceRight = text.length && text[text.length - 1] == ' ';
|
||||
const spaceLeft = text.length && text[0] === ' ';
|
||||
const spaceRight = text.length && text[text.length - 1] === ' ';
|
||||
text = simplifyString(text);
|
||||
|
||||
if (!spaceLeft && !spaceRight && text == '') return lines;
|
||||
if (!spaceLeft && !spaceRight && text === '') return lines;
|
||||
|
||||
if (state.inQuote) {
|
||||
// Add a ">" at the beginning of the block then at the beginning of each lines. So it turns this:
|
||||
@ -380,19 +380,19 @@ function isBlockTag(n: string) {
|
||||
}
|
||||
|
||||
function isStrongTag(n: string) {
|
||||
return n == 'strong' || n == 'b' || n == 'big';
|
||||
return n === 'strong' || n === 'b' || n === 'big';
|
||||
}
|
||||
|
||||
function isStrikeTag(n: string) {
|
||||
return n == 'strike' || n == 's' || n == 'del';
|
||||
return n === 'strike' || n === 's' || n === 'del';
|
||||
}
|
||||
|
||||
function isEmTag(n: string) {
|
||||
return n == 'em' || n == 'i' || n == 'u';
|
||||
return n === 'em' || n === 'i' || n === 'u';
|
||||
}
|
||||
|
||||
function isAnchor(n: string) {
|
||||
return n == 'a';
|
||||
return n === 'a';
|
||||
}
|
||||
|
||||
function isIgnoredEndTag(n: string) {
|
||||
@ -400,7 +400,7 @@ function isIgnoredEndTag(n: string) {
|
||||
}
|
||||
|
||||
function isListTag(n: string) {
|
||||
return n == 'ol' || n == 'ul';
|
||||
return n === 'ol' || n === 'ul';
|
||||
}
|
||||
|
||||
// Elements that don't require any special treatment beside adding a newline character
|
||||
@ -413,7 +413,7 @@ function isInlineCodeTag(n: string) {
|
||||
}
|
||||
|
||||
function isNewLineBlock(s: string) {
|
||||
return s == BLOCK_OPEN || s == BLOCK_CLOSE;
|
||||
return s === BLOCK_OPEN || s === BLOCK_CLOSE;
|
||||
}
|
||||
|
||||
function attributeToLowerCase(node: any) {
|
||||
@ -467,7 +467,7 @@ function trimBlockOpenAndClose(lines: string[]): string[] {
|
||||
}
|
||||
|
||||
function isSpanWithStyle(attributes: any) {
|
||||
if (attributes != undefined) {
|
||||
if (attributes) {
|
||||
if ('style' in attributes) {
|
||||
return true;
|
||||
} else {
|
||||
@ -484,7 +484,7 @@ function isSpanStyleBold(attributes: any) {
|
||||
style = style.replace(/\s+/g, '');
|
||||
if (style.includes('font-weight:bold') || style.includes('font-weight:700') || style.includes('font-weight:800') || style.includes('font-weight:900')) {
|
||||
return true;
|
||||
} else if (style.search(/font-family:.*,Bold.*;/) != -1) {
|
||||
} else if (style.search(/font-family:.*,Bold.*;/) !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -647,9 +647,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
// handled as table-related. This is to ensure that the table
|
||||
// structure is valid.
|
||||
|
||||
if (n == 'en-note') {
|
||||
if (n === 'en-note') {
|
||||
// Start of note
|
||||
} else if (n == 'table') {
|
||||
} else if (n === 'table') {
|
||||
const newSection: Section = {
|
||||
type: SectionType.Table,
|
||||
lines: [],
|
||||
@ -657,9 +657,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
};
|
||||
section.lines.push(newSection);
|
||||
section = newSection;
|
||||
} else if (n == 'tbody' || n == 'thead') {
|
||||
} else if (n === 'tbody' || n === 'thead') {
|
||||
// Ignore it
|
||||
} else if (n == 'tr') {
|
||||
} else if (n === 'tr') {
|
||||
// Note: Even if we encounter tags in the wrong place, we
|
||||
// create the sections anyway so that the data is imported.
|
||||
// Invalid HTML like would most likely be from clipped
|
||||
@ -671,7 +671,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
// error in drawTable() later on.
|
||||
//
|
||||
// https://discourse.joplinapp.org/t/not-all-notes-imported-from-evernote/13056/12?u=laurent
|
||||
if (section.type != 'table') {
|
||||
if (section.type !== 'table') {
|
||||
displaySaxWarning(this, 'Found a <tr> tag outside of a table');
|
||||
// return;
|
||||
}
|
||||
@ -685,13 +685,13 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
|
||||
section.lines.push(newSection);
|
||||
section = newSection;
|
||||
} else if (n == 'td' || n == 'th') {
|
||||
if (section.type != 'tr') {
|
||||
} else if (n === 'td' || n === 'th') {
|
||||
if (section.type !== 'tr') {
|
||||
displaySaxWarning(this, 'Found a <td> tag outside of a <tr>');
|
||||
// return;
|
||||
}
|
||||
|
||||
if (n == 'th') section.isHeader = true;
|
||||
if (n === 'th') section.isHeader = true;
|
||||
|
||||
const newSection: Section = {
|
||||
type: SectionType.Td,
|
||||
@ -701,8 +701,8 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
|
||||
section.lines.push(newSection);
|
||||
section = newSection;
|
||||
} else if (n == 'caption') {
|
||||
if (section.type != 'table') {
|
||||
} else if (n === 'caption') {
|
||||
if (section.type !== 'table') {
|
||||
displaySaxWarning(this, 'Found a <caption> tag outside of a <table>');
|
||||
}
|
||||
|
||||
@ -739,7 +739,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
} else if (isListTag(n)) {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
state.lists.push({ tag: n, counter: 1, startedText: false });
|
||||
} else if (n == 'li') {
|
||||
} else if (n === 'li') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
if (!state.lists.length) {
|
||||
displaySaxWarning(this, 'Found <li> tag without being inside a list');
|
||||
@ -750,7 +750,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
container.startedText = false;
|
||||
|
||||
const indent = ' '.repeat(state.lists.length - 1);
|
||||
if (container.tag == 'ul') {
|
||||
if (container.tag === 'ul') {
|
||||
section.lines.push(`${indent}- `);
|
||||
} else {
|
||||
section.lines.push(`${indent + container.counter}. `);
|
||||
@ -764,9 +764,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
section.lines.push('<s>');
|
||||
} else if (isInlineCodeTag(n)) {
|
||||
section.lines.push('`');
|
||||
} else if (n == 'q') {
|
||||
} else if (n === 'q') {
|
||||
section.lines.push('"');
|
||||
} else if (n == 'img') {
|
||||
} else if (n === 'img') {
|
||||
if (nodeAttributes.src) {
|
||||
// Many (most?) img tags don't have no source associated, especially when they were imported from HTML
|
||||
let s = '![';
|
||||
@ -781,48 +781,48 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
collapseWhiteSpaceAndAppend(section.lines, state, '[');
|
||||
} else if (isEmTag(n)) {
|
||||
section.lines.push('*');
|
||||
} else if (n == 'en-todo') {
|
||||
const x = nodeAttributes && nodeAttributes.checked && nodeAttributes.checked.toLowerCase() == 'true' ? 'X' : ' ';
|
||||
} else if (n === 'en-todo') {
|
||||
const x = nodeAttributes && nodeAttributes.checked && nodeAttributes.checked.toLowerCase() === 'true' ? 'X' : ' ';
|
||||
section.lines.push(`- [${x}] `);
|
||||
} else if (n == 'hr') {
|
||||
} else if (n === 'hr') {
|
||||
// Needs to be surrounded by new lines so that it's properly rendered as a line when converting to HTML
|
||||
section.lines.push(NEWLINE);
|
||||
section.lines.push('* * *');
|
||||
section.lines.push(NEWLINE);
|
||||
section.lines.push(NEWLINE);
|
||||
} else if (n == 'h1') {
|
||||
} else if (n === 'h1') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('# ');
|
||||
} else if (n == 'h2') {
|
||||
} else if (n === 'h2') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('## ');
|
||||
} else if (n == 'h3') {
|
||||
} else if (n === 'h3') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('### ');
|
||||
} else if (n == 'h4') {
|
||||
} else if (n === 'h4') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('#### ');
|
||||
} else if (n == 'h5') {
|
||||
} else if (n === 'h5') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('##### ');
|
||||
} else if (n == 'h6') {
|
||||
} else if (n === 'h6') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
section.lines.push('###### ');
|
||||
} else if (n == 'blockquote') {
|
||||
} else if (n === 'blockquote') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
state.inQuote = true;
|
||||
} else if (n === 'pre') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
state.inPre = true;
|
||||
} else if (n == 'br') {
|
||||
} else if (n === 'br') {
|
||||
section.lines.push(NEWLINE);
|
||||
} else if (n == 'en-media') {
|
||||
} else if (n === 'en-media') {
|
||||
const hash = nodeAttributes.hash;
|
||||
|
||||
let resource = null;
|
||||
for (let i = 0; i < resources.length; i++) {
|
||||
const r = resources[i];
|
||||
if (r.id == hash) {
|
||||
if (r.id === hash) {
|
||||
resource = r;
|
||||
removeRemainingResource(r.id);
|
||||
break;
|
||||
@ -891,7 +891,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
if (resource && !!resource.id) {
|
||||
section.lines = addResourceTag(section.lines, resource, nodeAttributes.alt);
|
||||
}
|
||||
} else if (n == 'span') {
|
||||
} else if (n === 'span') {
|
||||
if (isSpanWithStyle(nodeAttributes)) {
|
||||
// Found style(s) in span tag
|
||||
state.spanAttributes.push(nodeAttributes);
|
||||
@ -916,7 +916,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
|
||||
const poppedTag = state.tags.pop();
|
||||
|
||||
if (n == 'en-note') {
|
||||
if (n === 'en-note') {
|
||||
// End of note
|
||||
} else if (!poppedTag.visible) {
|
||||
if (section && section.parent) section = section.parent;
|
||||
@ -946,11 +946,11 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
}
|
||||
} else if (isNewLineOnlyEndTag(n)) {
|
||||
section.lines.push(BLOCK_CLOSE);
|
||||
} else if (n == 'td' || n == 'th') {
|
||||
} else if (n === 'td' || n === 'th') {
|
||||
if (section && section.parent) section = section.parent;
|
||||
} else if (n == 'tr' || n == 'caption') {
|
||||
} else if (n === 'tr' || n === 'caption') {
|
||||
if (section && section.parent) section = section.parent;
|
||||
} else if (n == 'table') {
|
||||
} else if (n === 'table') {
|
||||
if (section && section.parent) section = section.parent;
|
||||
} else if (isIgnoredEndTag(n)) {
|
||||
// Skip
|
||||
@ -965,9 +965,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
section.lines.push('`');
|
||||
} else if (isEmTag(n)) {
|
||||
section.lines.push('*');
|
||||
} else if (n == 'q') {
|
||||
} else if (n === 'q') {
|
||||
section.lines.push('"');
|
||||
} else if (n == 'blockquote') {
|
||||
} else if (n === 'blockquote') {
|
||||
section.lines.push(BLOCK_OPEN);
|
||||
state.inQuote = false;
|
||||
} else if (n === 'pre') {
|
||||
@ -995,7 +995,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
}
|
||||
}
|
||||
|
||||
if (previous == '[') {
|
||||
if (previous === '[') {
|
||||
// We have a link that had some content but, after parsing, nothing is left. The content was most likely
|
||||
// something that shows up via CSS and which we cannot support. For example:
|
||||
//
|
||||
@ -1024,7 +1024,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
section.lines.push('(L)');
|
||||
section.lines.push(`](${url})`);
|
||||
}
|
||||
} else if (!previous || previous == url) {
|
||||
} else if (!previous || previous === url) {
|
||||
section.lines.pop();
|
||||
section.lines.pop();
|
||||
section.lines.push(url);
|
||||
@ -1090,9 +1090,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
|
||||
section.lines.push(`](${url})`);
|
||||
}
|
||||
}
|
||||
} else if (n == 'en-media') {
|
||||
} else if (n === 'en-media') {
|
||||
// Skip
|
||||
} else if (n == 'span') {
|
||||
} else if (n === 'span') {
|
||||
const attributes = state.spanAttributes.pop();
|
||||
if (isSpanWithStyle(attributes)) {
|
||||
if (isSpanStyleBold(attributes)) {
|
||||
|
@ -169,7 +169,7 @@ async function processNoteResource(resource: ExtractedResource) {
|
||||
resource.dataFilePath = `${Setting.value('tempDir')}/${resource.id}.empty`;
|
||||
await fs.writeFile(resource.dataFilePath, '');
|
||||
} else {
|
||||
if (resource.dataEncoding == 'base64') {
|
||||
if (resource.dataEncoding === 'base64') {
|
||||
const decodedFilePath = `${resource.dataFilePath}.decoded`;
|
||||
await decodeBase64File(resource.dataFilePath, decodedFilePath);
|
||||
resource.dataFilePath = decodedFilePath;
|
||||
@ -505,7 +505,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
} else if (noteResourceAttributes) {
|
||||
noteResourceAttributes[n] = text;
|
||||
} else if (noteResource) {
|
||||
if (n == 'data') {
|
||||
if (n === 'data') {
|
||||
if (!noteResource.dataEncoding) {
|
||||
const attr = currentNodeAttributes();
|
||||
noteResource.dataEncoding = attr.encoding;
|
||||
@ -523,17 +523,17 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
(noteResource as any)[n] += text;
|
||||
}
|
||||
} else if (note) {
|
||||
if (n == 'title') {
|
||||
if (n === 'title') {
|
||||
note.title = text;
|
||||
} else if (n == 'created') {
|
||||
} else if (n === 'created') {
|
||||
note.created_time = dateToTimestamp(text, 0);
|
||||
} else if (n == 'updated') {
|
||||
} else if (n === 'updated') {
|
||||
note.updated_time = dateToTimestamp(text, 0);
|
||||
} else if (n == 'tag') {
|
||||
} else if (n === 'tag') {
|
||||
note.tags.push(text);
|
||||
} else if (n == 'note') {
|
||||
} else if (n === 'note') {
|
||||
// Ignore - white space between the opening tag <note> and the first sub-tag
|
||||
} else if (n == 'content') {
|
||||
} else if (n === 'content') {
|
||||
// Ignore - white space between the opening tag <content> and the <![CDATA[< block where the content actually is
|
||||
} else {
|
||||
console.warn(createErrorWithNoteTitle(this, new Error(`Unsupported note tag: ${n}`)));
|
||||
@ -545,19 +545,19 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
const n = node.name.toLowerCase();
|
||||
nodes.push(node);
|
||||
|
||||
if (n == 'note') {
|
||||
if (n === 'note') {
|
||||
note = {
|
||||
resources: [],
|
||||
tags: [],
|
||||
bodyXml: '',
|
||||
};
|
||||
} else if (n == 'resource-attributes') {
|
||||
} else if (n === 'resource-attributes') {
|
||||
noteResourceAttributes = {};
|
||||
} else if (n == 'recognition') {
|
||||
} else if (n === 'recognition') {
|
||||
if (noteResource) noteResourceRecognition = {};
|
||||
} else if (n == 'note-attributes') {
|
||||
} else if (n === 'note-attributes') {
|
||||
noteAttributes = {};
|
||||
} else if (n == 'resource') {
|
||||
} else if (n === 'resource') {
|
||||
noteResource = {
|
||||
hasData: false,
|
||||
};
|
||||
@ -570,7 +570,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
if (noteResourceRecognition) {
|
||||
noteResourceRecognition.objID = extractRecognitionObjId(data);
|
||||
} else if (note) {
|
||||
if (n == 'content') {
|
||||
if (n === 'content') {
|
||||
note.bodyXml += data;
|
||||
}
|
||||
}
|
||||
@ -579,7 +579,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
saxStream.on('closetag', handleSaxStreamEvent(function(n: string) {
|
||||
nodes.pop();
|
||||
|
||||
if (n == 'note') {
|
||||
if (n === 'note') {
|
||||
note = removeUndefinedProperties(note);
|
||||
|
||||
progressState.loaded++;
|
||||
@ -593,14 +593,14 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
});
|
||||
}
|
||||
note = null;
|
||||
} else if (n == 'recognition' && noteResource) {
|
||||
} else if (n === 'recognition' && noteResource) {
|
||||
noteResource.id = noteResourceRecognition.objID;
|
||||
noteResourceRecognition = null;
|
||||
} else if (n == 'resource-attributes') {
|
||||
} else if (n === 'resource-attributes') {
|
||||
noteResource.filename = noteResourceAttributes['file-name'];
|
||||
if (noteResourceAttributes['source-url']) noteResource.sourceUrl = noteResourceAttributes['source-url'];
|
||||
noteResourceAttributes = null;
|
||||
} else if (n == 'note-attributes') {
|
||||
} else if (n === 'note-attributes') {
|
||||
note.latitude = noteAttributes.latitude;
|
||||
note.longitude = noteAttributes.longitude;
|
||||
note.altitude = noteAttributes.altitude;
|
||||
@ -613,7 +613,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
|
||||
note.source_url = noteAttributes['source-url'] ? noteAttributes['source-url'].trim() : '';
|
||||
|
||||
noteAttributes = null;
|
||||
} else if (n == 'resource') {
|
||||
} else if (n === 'resource') {
|
||||
let mimeType = noteResource.mime ? noteResource.mime.trim() : '';
|
||||
|
||||
// Evernote sometimes gives an invalid or generic
|
||||
|
@ -491,7 +491,7 @@ function closestSupportedLocale(canonicalName: string, defaultToEnglish: boolean
|
||||
for (let i = 0; i < locales.length; i++) {
|
||||
const locale = locales[i];
|
||||
const language = locale.split('_')[0];
|
||||
if (requiredLanguage == language) return locale;
|
||||
if (requiredLanguage === language) return locale;
|
||||
}
|
||||
|
||||
return defaultToEnglish ? 'en_GB' : null;
|
||||
@ -532,14 +532,14 @@ function countryDisplayName(canonicalName: string) {
|
||||
let extraString;
|
||||
|
||||
if (countryCode) {
|
||||
if (languageCode == 'zh' && countryCode == 'CN') {
|
||||
if (languageCode === 'zh' && countryCode === 'CN') {
|
||||
extraString = '简体'; // "Simplified" in "Simplified Chinese"
|
||||
} else {
|
||||
extraString = countryName(countryCode);
|
||||
}
|
||||
}
|
||||
|
||||
if (languageCode == 'zh' && (countryCode == '' || countryCode == 'TW')) extraString = '繁體'; // "Traditional" in "Traditional Chinese"
|
||||
if (languageCode === 'zh' && (countryCode === '' || countryCode === 'TW')) extraString = '繁體'; // "Traditional" in "Traditional Chinese"
|
||||
|
||||
if (extraString) {
|
||||
output += ` (${extraString})`;
|
||||
@ -564,7 +564,7 @@ function localeStrings(canonicalName: string) {
|
||||
}
|
||||
|
||||
function setLocale(canonicalName: string) {
|
||||
if (currentLocale_ == canonicalName) return;
|
||||
if (currentLocale_ === canonicalName) return;
|
||||
currentLocale_ = closestSupportedLocale(canonicalName);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ export default class BaseItem extends BaseModel {
|
||||
|
||||
static loadClass(className: string, classRef: any) {
|
||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||
if (BaseItem.syncItemDefinitions_[i].className == className) {
|
||||
if (BaseItem.syncItemDefinitions_[i].className === className) {
|
||||
BaseItem.syncItemDefinitions_[i].classRef = classRef;
|
||||
return;
|
||||
}
|
||||
@ -108,7 +108,7 @@ export default class BaseItem extends BaseModel {
|
||||
// Need to dynamically load the classes like this to avoid circular dependencies
|
||||
static getClass(name: string) {
|
||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||
if (BaseItem.syncItemDefinitions_[i].className == name) {
|
||||
if (BaseItem.syncItemDefinitions_[i].className === name) {
|
||||
const classRef = BaseItem.syncItemDefinitions_[i].classRef;
|
||||
if (!classRef) throw new Error(`Class has not been loaded: ${name}`);
|
||||
return BaseItem.syncItemDefinitions_[i].classRef;
|
||||
@ -120,7 +120,7 @@ export default class BaseItem extends BaseModel {
|
||||
|
||||
static getClassByItemType(itemType: ModelType) {
|
||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||
if (BaseItem.syncItemDefinitions_[i].type == itemType) {
|
||||
if (BaseItem.syncItemDefinitions_[i].type === itemType) {
|
||||
return BaseItem.syncItemDefinitions_[i].classRef;
|
||||
}
|
||||
}
|
||||
@ -151,8 +151,8 @@ export default class BaseItem extends BaseModel {
|
||||
let p: any = path.split('/');
|
||||
p = p[p.length - 1];
|
||||
p = p.split('.');
|
||||
if (p.length != 2) return false;
|
||||
return p[0].length == 32 && p[1] == 'md';
|
||||
if (p.length !== 2) return false;
|
||||
return p[0].length === 32 && p[1] === 'md';
|
||||
}
|
||||
|
||||
static itemClass(item: any): any {
|
||||
@ -164,7 +164,7 @@ export default class BaseItem extends BaseModel {
|
||||
} else {
|
||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||
const d = BaseItem.syncItemDefinitions_[i];
|
||||
if (Number(item) == d.type) return this.getClass(d.className);
|
||||
if (Number(item) === d.type) return this.getClass(d.className);
|
||||
}
|
||||
throw new JoplinError(`Unknown type: ${item}`, 'unknownItemType');
|
||||
}
|
||||
@ -249,7 +249,7 @@ export default class BaseItem extends BaseModel {
|
||||
// Don't create a deleted_items entry when conflicted notes are deleted
|
||||
// since no other client have (or should have) them.
|
||||
let conflictNoteIds: string[] = [];
|
||||
if (this.modelType() == BaseModel.TYPE_NOTE) {
|
||||
if (this.modelType() === BaseModel.TYPE_NOTE) {
|
||||
const conflictNotes = await this.db().selectAll(`SELECT id FROM notes WHERE id IN ("${ids.join('","')}") AND is_conflict = 1`);
|
||||
conflictNoteIds = conflictNotes.map((n: NoteEntity) => {
|
||||
return n.id;
|
||||
@ -323,7 +323,7 @@ export default class BaseItem extends BaseModel {
|
||||
}
|
||||
|
||||
static unserialize_format(type: ModelType, propName: string, propValue: any) {
|
||||
if (propName[propName.length - 1] == '_') return propValue; // Private property
|
||||
if (propName[propName.length - 1] === '_') return propValue; // Private property
|
||||
|
||||
const ItemClass = this.itemClass(type);
|
||||
|
||||
@ -372,7 +372,7 @@ export default class BaseItem extends BaseModel {
|
||||
|
||||
for (let i = 0; i < shownKeys.length; i++) {
|
||||
let key = shownKeys[i];
|
||||
if (key == 'title' || key == 'body') continue;
|
||||
if (key === 'title' || key === 'body') continue;
|
||||
|
||||
let value = null;
|
||||
if (typeof key === 'function') {
|
||||
@ -483,10 +483,10 @@ export default class BaseItem extends BaseModel {
|
||||
for (let i = lines.length - 1; i >= 0; i--) {
|
||||
let line = lines[i];
|
||||
|
||||
if (state == 'readingProps') {
|
||||
if (state === 'readingProps') {
|
||||
line = line.trim();
|
||||
|
||||
if (line == '') {
|
||||
if (line === '') {
|
||||
state = 'readingBody';
|
||||
continue;
|
||||
}
|
||||
@ -496,7 +496,7 @@ export default class BaseItem extends BaseModel {
|
||||
const key = line.substr(0, p).trim();
|
||||
const value = line.substr(p + 1).trim();
|
||||
output[key] = value;
|
||||
} else if (state == 'readingBody') {
|
||||
} else if (state === 'readingBody') {
|
||||
body.splice(0, 0, line);
|
||||
}
|
||||
}
|
||||
@ -628,8 +628,8 @@ export default class BaseItem extends BaseModel {
|
||||
// 'SELECT * FROM [ITEMS] items JOIN sync_items s ON s.item_id = items.id WHERE sync_target = ? AND'
|
||||
|
||||
let extraWhere: any = [];
|
||||
if (className == 'Note') extraWhere.push('is_conflict = 0');
|
||||
if (className == 'Resource') extraWhere.push('encryption_blob_encrypted = 0');
|
||||
if (className === 'Note') extraWhere.push('is_conflict = 0');
|
||||
if (className === 'Resource') extraWhere.push('encryption_blob_encrypted = 0');
|
||||
if (ItemClass.encryptionSupported()) extraWhere.push('encryption_applied = 0');
|
||||
|
||||
extraWhere = extraWhere.length ? `AND ${extraWhere.join(' AND ')}` : '';
|
||||
@ -727,7 +727,7 @@ export default class BaseItem extends BaseModel {
|
||||
|
||||
static modelTypeToClassName(type: number) {
|
||||
for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) {
|
||||
if (BaseItem.syncItemDefinitions_[i].type == type) return BaseItem.syncItemDefinitions_[i].className;
|
||||
if (BaseItem.syncItemDefinitions_[i].type === type) return BaseItem.syncItemDefinitions_[i].className;
|
||||
}
|
||||
throw new Error(`Invalid type: ${type}`);
|
||||
}
|
||||
@ -795,7 +795,7 @@ export default class BaseItem extends BaseModel {
|
||||
const ItemClass = this.getClass(className);
|
||||
|
||||
let selectSql = `SELECT id FROM ${ItemClass.tableName()}`;
|
||||
if (ItemClass.modelType() == this.TYPE_NOTE) selectSql += ' WHERE is_conflict = 0';
|
||||
if (ItemClass.modelType() === this.TYPE_NOTE) selectSql += ' WHERE is_conflict = 0';
|
||||
|
||||
queries.push(`DELETE FROM sync_items WHERE item_location = ${BaseItem.SYNC_ITEM_LOCATION_LOCAL} AND item_type = ${ItemClass.modelType()} AND item_id NOT IN (${selectSql})`);
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ export default class Folder extends BaseItem {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const model = models[i];
|
||||
|
||||
if (model.parent_id == parentId) {
|
||||
if (model.parent_id === parentId) {
|
||||
const children = getNestedChildren(models, model.id);
|
||||
|
||||
if (children.length > 0) {
|
||||
@ -666,7 +666,7 @@ export default class Folder extends BaseItem {
|
||||
}
|
||||
|
||||
static load(id: string, _options: any = null): Promise<FolderEntity> {
|
||||
if (id == this.conflictFolderId()) return Promise.resolve(this.conflictFolder());
|
||||
if (id === this.conflictFolderId()) return Promise.resolve(this.conflictFolder());
|
||||
return super.load(id);
|
||||
}
|
||||
|
||||
@ -681,7 +681,7 @@ export default class Folder extends BaseItem {
|
||||
if (isRootSharedFolder(folder)) return false;
|
||||
|
||||
const conflictFolderId = Folder.conflictFolderId();
|
||||
if (folderId == conflictFolderId || targetFolderId == conflictFolderId) return false;
|
||||
if (folderId === conflictFolderId || targetFolderId === conflictFolderId) return false;
|
||||
|
||||
if (!targetFolderId) return true;
|
||||
|
||||
@ -728,7 +728,7 @@ export default class Folder extends BaseItem {
|
||||
}
|
||||
|
||||
if (options.stripLeftSlashes === true && o.title) {
|
||||
while (o.title.length && (o.title[0] == '/' || o.title[0] == '\\')) {
|
||||
while (o.title.length && (o.title[0] === '/' || o.title[0] === '\\')) {
|
||||
o.title = o.title.substr(1);
|
||||
}
|
||||
}
|
||||
@ -748,7 +748,7 @@ export default class Folder extends BaseItem {
|
||||
// }
|
||||
|
||||
if (options.reservedTitleCheck === true && o.title) {
|
||||
if (o.title == Folder.conflictFolderTitle()) throw new Error(_('Notebooks cannot be named "%s", which is a reserved title.', o.title));
|
||||
if (o.title === Folder.conflictFolderTitle()) throw new Error(_('Notebooks cannot be named "%s", which is a reserved title.', o.title));
|
||||
}
|
||||
|
||||
syncDebugLog.info('Folder Save:', o);
|
||||
|
@ -300,7 +300,7 @@ export default class Note extends BaseItem {
|
||||
if (aProp < bProp) r = +1;
|
||||
if (aProp > bProp) r = -1;
|
||||
}
|
||||
if (order.dir == 'ASC') r = -r;
|
||||
if (order.dir === 'ASC') r = -r;
|
||||
if (r !== 0) return r;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ export default class Note extends BaseItem {
|
||||
// it's confusing to have conflicts but with an empty conflict folder.
|
||||
if (parentId === Folder.conflictFolderId()) options.showCompletedTodos = true;
|
||||
|
||||
if (parentId == Folder.conflictFolderId()) {
|
||||
if (parentId === Folder.conflictFolderId()) {
|
||||
options.conditions.push('is_conflict = 1');
|
||||
} else {
|
||||
options.conditions.push('is_conflict = 0');
|
||||
@ -527,7 +527,7 @@ export default class Note extends BaseItem {
|
||||
}
|
||||
|
||||
static async copyToFolder(noteId: string, folderId: string) {
|
||||
if (folderId == this.getClass('Folder').conflictFolderId()) throw new Error(_('Cannot copy note to "%s" notebook', this.getClass('Folder').conflictFolderTitle()));
|
||||
if (folderId === this.getClass('Folder').conflictFolderId()) throw new Error(_('Cannot copy note to "%s" notebook', this.getClass('Folder').conflictFolderTitle()));
|
||||
|
||||
return Note.duplicate(noteId, {
|
||||
changes: {
|
||||
@ -539,7 +539,7 @@ export default class Note extends BaseItem {
|
||||
}
|
||||
|
||||
static async moveToFolder(noteId: string, folderId: string) {
|
||||
if (folderId == this.getClass('Folder').conflictFolderId()) throw new Error(_('Cannot move note to "%s" notebook', this.getClass('Folder').conflictFolderTitle()));
|
||||
if (folderId === this.getClass('Folder').conflictFolderId()) throw new Error(_('Cannot move note to "%s" notebook', this.getClass('Folder').conflictFolderTitle()));
|
||||
|
||||
// When moving a note to a different folder, the user timestamp is not updated.
|
||||
// However updated_time is updated so that the note can be synced later on.
|
||||
|
@ -452,7 +452,7 @@ class Setting extends BaseModel {
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
try {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('filesystem');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('filesystem');
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
@ -471,7 +471,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('nextcloud');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Nextcloud WebDAV URL'),
|
||||
@ -483,7 +483,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('nextcloud');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Nextcloud username'),
|
||||
@ -494,7 +494,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('nextcloud');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Nextcloud password'),
|
||||
@ -506,7 +506,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('webdav');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('webdav');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('WebDAV URL'),
|
||||
@ -518,7 +518,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('webdav');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('webdav');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('WebDAV username'),
|
||||
@ -529,7 +529,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('webdav');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('webdav');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('WebDAV password'),
|
||||
@ -542,7 +542,7 @@ class Setting extends BaseModel {
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
try {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
@ -560,7 +560,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
},
|
||||
filter: value => {
|
||||
return value ? value.trim() : '';
|
||||
@ -574,7 +574,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
},
|
||||
filter: value => {
|
||||
return value ? value.trim() : '';
|
||||
@ -588,7 +588,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('S3 access key'),
|
||||
@ -599,7 +599,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('S3 secret key'),
|
||||
@ -610,7 +610,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.Bool,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('amazon_s3');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('amazon_s3');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Force path style'),
|
||||
@ -621,7 +621,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinServer');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('joplinServer');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Joplin Server URL'),
|
||||
@ -639,7 +639,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinServer');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('joplinServer');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Joplin Server email'),
|
||||
@ -650,7 +650,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinServer');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('joplinServer');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Joplin Server password'),
|
||||
@ -678,7 +678,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinCloud');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('joplinCloud');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Joplin Cloud email'),
|
||||
@ -689,7 +689,7 @@ class Setting extends BaseModel {
|
||||
type: SettingItemType.String,
|
||||
section: 'sync',
|
||||
show: (settings: any) => {
|
||||
return settings['sync.target'] == SyncTargetRegistry.nameToId('joplinCloud');
|
||||
return settings['sync.target'] === SyncTargetRegistry.nameToId('joplinCloud');
|
||||
},
|
||||
public: true,
|
||||
label: () => _('Joplin Cloud password'),
|
||||
@ -1856,7 +1856,7 @@ class Setting extends BaseModel {
|
||||
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
const c = this.cache_[i];
|
||||
if (c.key == key) {
|
||||
if (c.key === key) {
|
||||
const md = this.settingMetadata(key);
|
||||
|
||||
if (md.isEnum === true) {
|
||||
@ -1973,11 +1973,11 @@ class Setting extends BaseModel {
|
||||
static valueToString(key: string, value: any) {
|
||||
const md = this.settingMetadata(key);
|
||||
value = this.formatValue(key, value);
|
||||
if (md.type == SettingItemType.Int) return value.toFixed(0);
|
||||
if (md.type == SettingItemType.Bool) return value ? '1' : '0';
|
||||
if (md.type == SettingItemType.Array) return value ? JSON.stringify(value) : '[]';
|
||||
if (md.type == SettingItemType.Object) return value ? JSON.stringify(value) : '{}';
|
||||
if (md.type == SettingItemType.String) return value ? `${value}` : '';
|
||||
if (md.type === SettingItemType.Int) return value.toFixed(0);
|
||||
if (md.type === SettingItemType.Bool) return value ? '1' : '0';
|
||||
if (md.type === SettingItemType.Array) return value ? JSON.stringify(value) : '[]';
|
||||
if (md.type === SettingItemType.Object) return value ? JSON.stringify(value) : '{}';
|
||||
if (md.type === SettingItemType.String) return value ? `${value}` : '';
|
||||
|
||||
throw new Error(`Unhandled value type: ${md.type}`);
|
||||
}
|
||||
@ -1990,9 +1990,9 @@ class Setting extends BaseModel {
|
||||
static formatValue(key: string, value: any) {
|
||||
const md = this.settingMetadata(key);
|
||||
|
||||
if (md.type == SettingItemType.Int) return !value ? 0 : Math.floor(Number(value));
|
||||
if (md.type === SettingItemType.Int) return !value ? 0 : Math.floor(Number(value));
|
||||
|
||||
if (md.type == SettingItemType.Bool) {
|
||||
if (md.type === SettingItemType.Bool) {
|
||||
if (typeof value === 'string') {
|
||||
value = value.toLowerCase();
|
||||
if (value === 'true') return true;
|
||||
@ -2039,14 +2039,14 @@ class Setting extends BaseModel {
|
||||
if (key in this.constants_) {
|
||||
const v = (this.constants_ as any)[key];
|
||||
const output = typeof v === 'function' ? v() : v;
|
||||
if (output == 'SET_ME') throw new Error(`SET_ME constant has not been set: ${key}`);
|
||||
if (output === 'SET_ME') throw new Error(`SET_ME constant has not been set: ${key}`);
|
||||
return output;
|
||||
}
|
||||
|
||||
if (!this.cache_) throw new Error('Settings have not been initialized!');
|
||||
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
if (this.cache_[i].key == key) {
|
||||
if (this.cache_[i].key === key) {
|
||||
return copyIfNeeded(this.cache_[i].value);
|
||||
}
|
||||
}
|
||||
@ -2079,7 +2079,7 @@ class Setting extends BaseModel {
|
||||
static enumOptionLabel(key: string, value: any) {
|
||||
const options = this.enumOptions(key);
|
||||
for (const n in options) {
|
||||
if (n == value) return options[n];
|
||||
if (n === value) return options[n];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -236,11 +236,11 @@ export default class OneDriveApi {
|
||||
if (!options.headers) options.headers = {};
|
||||
if (!options.target) options.target = 'string';
|
||||
|
||||
if (method != 'GET') {
|
||||
if (method !== 'GET') {
|
||||
options.method = method;
|
||||
}
|
||||
|
||||
if (method == 'PATCH' || method == 'POST') {
|
||||
if (method === 'PATCH' || method === 'POST') {
|
||||
options.headers['Content-Type'] = 'application/json';
|
||||
if (data) data = JSON.stringify(data);
|
||||
}
|
||||
@ -279,9 +279,9 @@ export default class OneDriveApi {
|
||||
try {
|
||||
if (path.includes('/createUploadSession')) {
|
||||
response = await this.uploadBigFile(url, options);
|
||||
} else if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
} else if (options.source === 'file' && (method === 'POST' || method === 'PUT')) {
|
||||
response = await shim.uploadBlob(url, options);
|
||||
} else if (options.target == 'string') {
|
||||
} else if (options.target === 'string') {
|
||||
response = await shim.fetch(url, options);
|
||||
} else {
|
||||
// file
|
||||
@ -311,11 +311,11 @@ export default class OneDriveApi {
|
||||
|
||||
const error = this.oneDriveErrorResponseToError(errorResponse);
|
||||
|
||||
if (error.code == 'InvalidAuthenticationToken' || error.code == 'unauthenticated') {
|
||||
if (error.code === 'InvalidAuthenticationToken' || error.code === 'unauthenticated') {
|
||||
logger.info('Token expired: refreshing...');
|
||||
await this.refreshAccessToken();
|
||||
continue;
|
||||
} else if (error && ((error.error && error.error.code == 'generalException') || error.code == 'generalException' || error.code == 'EAGAIN')) {
|
||||
} else if (error && ((error.error && error.error.code === 'generalException') || error.code === 'generalException' || error.code === 'EAGAIN')) {
|
||||
// Rare error (one Google hit) - I guess the request can be repeated
|
||||
// { error:
|
||||
// { code: 'generalException',
|
||||
@ -351,7 +351,7 @@ export default class OneDriveApi {
|
||||
logger.info(`OneDrive Throttle, sync thread sleeping for ${sleepSeconds} seconds...`);
|
||||
await handleRequestRepeat(error, Number(sleepSeconds));
|
||||
continue;
|
||||
} else if (error.code == 'itemNotFound' && method == 'DELETE') {
|
||||
} else if (error.code === 'itemNotFound' && method === 'DELETE') {
|
||||
// Deleting a non-existing item is ok - noop
|
||||
return;
|
||||
} else {
|
||||
|
@ -6,26 +6,26 @@ const { defaultState, MAX_HISTORY } = require('./reducer');
|
||||
function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes, tags = null, selectedTagIndex = null) {
|
||||
let state = defaultState;
|
||||
|
||||
if (selectedFolderIndex != null) {
|
||||
if (selectedFolderIndex !== null) {
|
||||
state = reducer(state, { type: 'FOLDER_SELECT', id: folders[selectedFolderIndex].id });
|
||||
}
|
||||
if (folders != null) {
|
||||
if (folders !== null) {
|
||||
state = reducer(state, { type: 'FOLDER_UPDATE_ALL', items: folders });
|
||||
}
|
||||
if (notes != null) {
|
||||
if (notes !== null) {
|
||||
state = reducer(state, { type: 'NOTE_UPDATE_ALL', notes: notes, noteSource: 'test' });
|
||||
}
|
||||
if (selectedNoteIndexes != null) {
|
||||
if (selectedNoteIndexes !== null) {
|
||||
const selectedIds = [];
|
||||
for (let i = 0; i < selectedNoteIndexes.length; i++) {
|
||||
selectedIds.push(notes[selectedNoteIndexes[i]].id);
|
||||
}
|
||||
state = reducer(state, { type: 'NOTE_SELECT', ids: selectedIds });
|
||||
}
|
||||
if (tags != null) {
|
||||
if (tags !== null) {
|
||||
state = reducer(state, { type: 'TAG_UPDATE_ALL', items: tags });
|
||||
}
|
||||
if (selectedTagIndex != null) {
|
||||
if (selectedTagIndex !== null) {
|
||||
state = reducer(state, { type: 'TAG_SELECT', id: tags[selectedTagIndex].id });
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes,
|
||||
}
|
||||
|
||||
function goToNote(notes, selectedNoteIndexes, state) {
|
||||
if (selectedNoteIndexes != null) {
|
||||
if (selectedNoteIndexes !== null) {
|
||||
const selectedIds = [];
|
||||
for (let i = 0; i < selectedNoteIndexes.length; i++) {
|
||||
selectedIds.push(notes[selectedNoteIndexes[i]].id);
|
||||
@ -74,7 +74,7 @@ function createExpectedState(items, keepIndexes, selectedIndexes) {
|
||||
function getIds(items, indexes = null) {
|
||||
const ids = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (indexes == null || i in indexes) {
|
||||
if (!indexes || i in indexes) {
|
||||
ids.push(items[i].id);
|
||||
}
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ function handleItemDelete(draft: Draft<State>, action: any) {
|
||||
if (isSelected) {
|
||||
// the selected item is deleted so select the following item
|
||||
// if multiple items are selected then just use the first one
|
||||
if (selectedItemKeys[0] == item.id) {
|
||||
if (selectedItemKeys[0] === item.id) {
|
||||
newSelectedIndexes.push(newItems.length);
|
||||
}
|
||||
} else {
|
||||
@ -367,16 +367,16 @@ function handleItemDelete(draft: Draft<State>, action: any) {
|
||||
newSelectedIndexes.push(newItems.length);
|
||||
}
|
||||
}
|
||||
if (item.id == action.id) {
|
||||
if (item.id === action.id) {
|
||||
continue;
|
||||
}
|
||||
newItems.push(item);
|
||||
}
|
||||
|
||||
if (newItems.length == 0) {
|
||||
if (newItems.length === 0) {
|
||||
newSelectedIndexes = []; // no remaining items so no selection
|
||||
|
||||
} else if (newSelectedIndexes.length == 0) {
|
||||
} else if (newSelectedIndexes.length === 0) {
|
||||
newSelectedIndexes.push(0); // no selection exists so select the top
|
||||
|
||||
} else {
|
||||
@ -397,7 +397,7 @@ function handleItemDelete(draft: Draft<State>, action: any) {
|
||||
}
|
||||
(draft as any)[selectedItemKey] = isSingular ? newIds[0] : newIds;
|
||||
|
||||
if ((newIds.length == 0) && draft.notesParentType !== 'Folder') {
|
||||
if ((newIds.length === 0) && draft.notesParentType !== 'Folder') {
|
||||
draft.notesParentType = 'Folder';
|
||||
}
|
||||
}
|
||||
@ -416,7 +416,7 @@ function updateOneItem(draft: Draft<State>, action: any, keyName: string = '') {
|
||||
let found = false;
|
||||
for (let i = 0; i < newItems.length; i++) {
|
||||
const n = newItems[i];
|
||||
if (n.id == item.id) {
|
||||
if (n.id === item.id) {
|
||||
newItems[i] = Object.assign({}, newItems[i], item);
|
||||
found = true;
|
||||
break;
|
||||
@ -552,9 +552,9 @@ const getContextFromHistory = (ctx: any) => {
|
||||
function getNoteHistoryInfo(state: State) {
|
||||
const selectedNoteIds = state.selectedNoteIds;
|
||||
const notes = state.notes;
|
||||
if (selectedNoteIds != null && selectedNoteIds.length > 0) {
|
||||
if (selectedNoteIds && selectedNoteIds.length > 0) {
|
||||
const currNote = notes.find(note => note.id === selectedNoteIds[0]);
|
||||
if (currNote != null) {
|
||||
if (currNote) {
|
||||
return {
|
||||
id: currNote.id,
|
||||
parent_id: currNote.parent_id,
|
||||
@ -575,7 +575,7 @@ function handleHistory(draft: Draft<State>, action: any) {
|
||||
switch (action.type) {
|
||||
case 'HISTORY_BACKWARD': {
|
||||
const note = draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1];
|
||||
if (currentNote != null && (draft.forwardHistoryNotes.length === 0 || currentNote.id != draft.forwardHistoryNotes[draft.forwardHistoryNotes.length - 1].id)) {
|
||||
if (currentNote && (draft.forwardHistoryNotes.length === 0 || currentNote.id !== draft.forwardHistoryNotes[draft.forwardHistoryNotes.length - 1].id)) {
|
||||
draft.forwardHistoryNotes = draft.forwardHistoryNotes.concat(currentNote).slice(-MAX_HISTORY);
|
||||
}
|
||||
|
||||
@ -591,7 +591,7 @@ function handleHistory(draft: Draft<State>, action: any) {
|
||||
case 'HISTORY_FORWARD': {
|
||||
const note = draft.forwardHistoryNotes[draft.forwardHistoryNotes.length - 1];
|
||||
|
||||
if (currentNote != null && (draft.backwardHistoryNotes.length === 0 || currentNote.id != draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1].id)) {
|
||||
if (currentNote && (draft.backwardHistoryNotes.length === 0 || currentNote.id !== draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1].id)) {
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.concat(currentNote).slice(-MAX_HISTORY);
|
||||
}
|
||||
|
||||
@ -606,12 +606,12 @@ function handleHistory(draft: Draft<State>, action: any) {
|
||||
break;
|
||||
}
|
||||
case 'NOTE_SELECT':
|
||||
if (currentNote != null && action.id != currentNote.id) {
|
||||
if (currentNote && action.id !== currentNote.id) {
|
||||
draft.forwardHistoryNotes = [];
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.concat(currentNote).slice(-MAX_HISTORY);
|
||||
}
|
||||
// History should be free from duplicates.
|
||||
if (draft.backwardHistoryNotes != null && draft.backwardHistoryNotes.length > 0 &&
|
||||
if (draft.backwardHistoryNotes && draft.backwardHistoryNotes.length > 0 &&
|
||||
action.id === draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1].id) {
|
||||
draft.backwardHistoryNotes.pop();
|
||||
}
|
||||
@ -619,7 +619,7 @@ function handleHistory(draft: Draft<State>, action: any) {
|
||||
case 'TAG_SELECT':
|
||||
case 'FOLDER_AND_NOTE_SELECT':
|
||||
case 'FOLDER_SELECT':
|
||||
if (currentNote != null) {
|
||||
if (currentNote) {
|
||||
if (draft.forwardHistoryNotes.length) draft.forwardHistoryNotes = [];
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.concat(currentNote).slice(-MAX_HISTORY);
|
||||
}
|
||||
@ -644,22 +644,22 @@ function handleHistory(draft: Draft<State>, action: any) {
|
||||
break;
|
||||
}
|
||||
case 'SEARCH_UPDATE':
|
||||
if (currentNote != null && (draft.backwardHistoryNotes.length === 0 ||
|
||||
draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1].id != currentNote.id)) {
|
||||
if (currentNote && (draft.backwardHistoryNotes.length === 0 ||
|
||||
draft.backwardHistoryNotes[draft.backwardHistoryNotes.length - 1].id !== currentNote.id)) {
|
||||
if (draft.forwardHistoryNotes.length) draft.forwardHistoryNotes = [];
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.concat(currentNote).slice(-MAX_HISTORY);
|
||||
}
|
||||
break;
|
||||
case 'FOLDER_DELETE':
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.filter(note => note.parent_id != action.id);
|
||||
draft.forwardHistoryNotes = draft.forwardHistoryNotes.filter(note => note.parent_id != action.id);
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.filter(note => note.parent_id !== action.id);
|
||||
draft.forwardHistoryNotes = draft.forwardHistoryNotes.filter(note => note.parent_id !== action.id);
|
||||
|
||||
draft.backwardHistoryNotes = removeAdjacentDuplicates(draft.backwardHistoryNotes);
|
||||
draft.forwardHistoryNotes = removeAdjacentDuplicates(draft.forwardHistoryNotes);
|
||||
break;
|
||||
case 'NOTE_DELETE': {
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.filter(note => note.id != action.id);
|
||||
draft.forwardHistoryNotes = draft.forwardHistoryNotes.filter(note => note.id != action.id);
|
||||
draft.backwardHistoryNotes = draft.backwardHistoryNotes.filter(note => note.id !== action.id);
|
||||
draft.forwardHistoryNotes = draft.forwardHistoryNotes.filter(note => note.id !== action.id);
|
||||
|
||||
draft.backwardHistoryNotes = removeAdjacentDuplicates(draft.backwardHistoryNotes);
|
||||
draft.forwardHistoryNotes = removeAdjacentDuplicates(draft.forwardHistoryNotes);
|
||||
@ -802,7 +802,7 @@ const reducer = produce((draft: Draft<State> = defaultState, action: any) => {
|
||||
|
||||
const noteIsInFolder = function(note: any, folderId: string) {
|
||||
if (note.is_conflict && isViewingConflictFolder) return true;
|
||||
if (!('parent_id' in modNote) || note.parent_id == folderId) return true;
|
||||
if (!('parent_id' in modNote) || note.parent_id === folderId) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
@ -812,7 +812,7 @@ const reducer = produce((draft: Draft<State> = defaultState, action: any) => {
|
||||
let found = false;
|
||||
for (let i = 0; i < newNotes.length; i++) {
|
||||
const n = newNotes[i];
|
||||
if (n.id == modNote.id) {
|
||||
if (n.id === modNote.id) {
|
||||
if (n.is_conflict && !modNote.is_conflict) {
|
||||
// Note was a conflict but was moved outside of
|
||||
// the conflict folder
|
||||
|
@ -42,11 +42,11 @@ describe('Synchronizer.conflicts', function() {
|
||||
// Other than the id (since the conflicted note is a duplicate), and the is_conflict property
|
||||
// the conflicted and original note must be the same in every way, to make sure no data has been lost.
|
||||
const conflictedNote = conflictedNotes[0];
|
||||
expect(conflictedNote.id == note2conf.id).toBe(false);
|
||||
expect(conflictedNote.id === note2conf.id).toBe(false);
|
||||
expect(conflictedNote.conflict_original_id).toBe(note2conf.id);
|
||||
for (const n in conflictedNote) {
|
||||
if (!conflictedNote.hasOwnProperty(n)) continue;
|
||||
if (n == 'id' || n == 'is_conflict' || n == 'conflict_original_id') continue;
|
||||
if (n === 'id' || n === 'is_conflict' || n === 'conflict_original_id') continue;
|
||||
expect(conflictedNote[n]).toBe(note2conf[n]);
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ const shim = {
|
||||
isNode: () => {
|
||||
if (typeof process === 'undefined') return false;
|
||||
if (shim.isElectron()) return true;
|
||||
return process.title == 'node' || (process.title && process.title.indexOf('gulp') === 0);
|
||||
return process.title === 'node' || (process.title && process.title.indexOf('gulp') === 0);
|
||||
},
|
||||
|
||||
isReactNative: () => {
|
||||
@ -115,16 +115,16 @@ const shim = {
|
||||
|
||||
// Unfortunately the error 'Network request failed' doesn't have a type
|
||||
// or error code, so hopefully that message won't change and is not localized
|
||||
if (error.message == 'Network request failed') return true;
|
||||
if (error.message === 'Network request failed') return true;
|
||||
|
||||
// request to https://public-ch3302....1fab24cb1bd5f.md failed, reason: socket hang up"
|
||||
if (error.code == 'ECONNRESET') return true;
|
||||
if (error.code === 'ECONNRESET') return true;
|
||||
|
||||
// OneDrive (or Node?) sometimes sends back a "not found" error for resources
|
||||
// that definitely exist and in this case repeating the request works.
|
||||
// Error is:
|
||||
// request to https://graph.microsoft.com/v1.0/drive/special/approot failed, reason: getaddrinfo ENOTFOUND graph.microsoft.com graph.microsoft.com:443
|
||||
if (error.code == 'ENOTFOUND') return true;
|
||||
if (error.code === 'ENOTFOUND') return true;
|
||||
|
||||
// network timeout at: https://public-ch3302...859f9b0e3ab.md
|
||||
if (error.message && error.message.indexOf('network timeout') === 0) return true;
|
||||
@ -136,7 +136,7 @@ const shim = {
|
||||
// code: 'EAI_AGAIN' } } reason: { FetchError: request to https://api.ipify.org/?format=json failed, reason: getaddrinfo EAI_AGAIN api.ipify.org:443
|
||||
//
|
||||
// It's a Microsoft error: "A temporary failure in name resolution occurred."
|
||||
if (error.code == 'EAI_AGAIN') return true;
|
||||
if (error.code === 'EAI_AGAIN') return true;
|
||||
|
||||
// request to https://public-...8fd8bc6bb68e9c4d17a.md failed, reason: connect ETIMEDOUT 204.79.197.213:443
|
||||
// Code: ETIMEDOUT
|
||||
|
@ -111,7 +111,7 @@ function escapeFilename(s, maxLength = 32) {
|
||||
output = output.replace(unsafe[i], '_');
|
||||
}
|
||||
|
||||
if (output.toLowerCase() == 'nul') output = 'n_l'; // For Windows...
|
||||
if (output.toLowerCase() === 'nul') output = 'n_l'; // For Windows...
|
||||
|
||||
return output.substr(0, maxLength);
|
||||
}
|
||||
@ -152,8 +152,8 @@ function splitCommandString(command, options = null) {
|
||||
for (let i = 0; i < command.length; i++) {
|
||||
const c = command[i];
|
||||
|
||||
if (state == 'quotes') {
|
||||
if (c != quote) {
|
||||
if (state === 'quotes') {
|
||||
if (c !== quote) {
|
||||
current += c;
|
||||
} else {
|
||||
args.push(current);
|
||||
@ -169,19 +169,19 @@ function splitCommandString(command, options = null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\\' && options.handleEscape) {
|
||||
if (c === '\\' && options.handleEscape) {
|
||||
escapeNext = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '"' || c == '\'') {
|
||||
if (c === '"' || c === '\'') {
|
||||
state = 'quotes';
|
||||
quote = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state == 'arg') {
|
||||
if (c == ' ' || c == '\t') {
|
||||
if (state === 'arg') {
|
||||
if (c === ' ' || c === '\t') {
|
||||
args.push(current);
|
||||
current = '';
|
||||
state = 'start';
|
||||
@ -191,17 +191,17 @@ function splitCommandString(command, options = null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c != ' ' && c != '\t') {
|
||||
if (c !== ' ' && c !== '\t') {
|
||||
state = 'arg';
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == 'quotes') {
|
||||
if (state === 'quotes') {
|
||||
throw new Error(`Unclosed quote in command line: ${command}`);
|
||||
}
|
||||
|
||||
if (current != '') {
|
||||
if (current !== '') {
|
||||
args.push(current);
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ function setSyncTargetName(name: string) {
|
||||
const previousName = syncTargetName_;
|
||||
syncTargetName_ = name;
|
||||
syncTargetId_ = SyncTargetRegistry.nameToId(syncTargetName_);
|
||||
sleepTime = syncTargetId_ == SyncTargetRegistry.nameToId('filesystem') ? 1001 : 100;// 400;
|
||||
sleepTime = syncTargetId_ === SyncTargetRegistry.nameToId('filesystem') ? 1001 : 100;// 400;
|
||||
isNetworkSyncTarget_ = ['nextcloud', 'dropbox', 'onedrive', 'amazon_s3', 'joplinServer'].includes(syncTargetName_);
|
||||
synchronizers_ = [];
|
||||
return previousName;
|
||||
@ -563,13 +563,13 @@ async function initFileApi() {
|
||||
if (fileApis_[syncTargetId_]) return;
|
||||
|
||||
let fileApi = null;
|
||||
if (syncTargetId_ == SyncTargetRegistry.nameToId('filesystem')) {
|
||||
if (syncTargetId_ === SyncTargetRegistry.nameToId('filesystem')) {
|
||||
fs.removeSync(syncDir);
|
||||
fs.mkdirpSync(syncDir);
|
||||
fileApi = new FileApi(syncDir, new FileApiDriverLocal());
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('memory')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('memory')) {
|
||||
fileApi = new FileApi('/root', new FileApiDriverMemory());
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('nextcloud')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('nextcloud')) {
|
||||
const options = require(`${oldTestDir}/support/nextcloud-auth.json`);
|
||||
const api = new WebDavApi({
|
||||
baseUrl: () => options.baseUrl,
|
||||
@ -577,7 +577,7 @@ async function initFileApi() {
|
||||
password: () => options.password,
|
||||
});
|
||||
fileApi = new FileApi('', new FileApiDriverWebDav(api));
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('dropbox')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('dropbox')) {
|
||||
// To get a token, go to the App Console:
|
||||
// https://www.dropbox.com/developers/apps/
|
||||
// Then select "JoplinTest" and click "Generated access token"
|
||||
@ -587,7 +587,7 @@ async function initFileApi() {
|
||||
if (!authToken) throw new Error(`Dropbox auth token missing in ${authTokenPath}`);
|
||||
api.setAuthToken(authToken);
|
||||
fileApi = new FileApi('', new FileApiDriverDropbox(api));
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('onedrive')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('onedrive')) {
|
||||
// To get a token, open the URL below corresponding to your account type,
|
||||
// then copy the *complete* redirection URL in onedrive-auth.txt. Keep in mind that auth
|
||||
// data only lasts 1h for OneDrive.
|
||||
@ -620,7 +620,7 @@ async function initFileApi() {
|
||||
|
||||
const appDir = await api.appDirectory();
|
||||
fileApi = new FileApi(appDir, new FileApiDriverOneDrive(api));
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('amazon_s3')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('amazon_s3')) {
|
||||
|
||||
// We make sure for S3 tests run in band because tests
|
||||
// share the same directory which will cause locking errors.
|
||||
@ -632,7 +632,7 @@ async function initFileApi() {
|
||||
if (!amazonS3Creds || !amazonS3Creds.credentials) throw new Error(`AWS auth JSON missing in ${amazonS3CredsPath} format should be: { "credentials": { "accessKeyId": "", "secretAccessKey": "", } "bucket": "mybucket", region: "", forcePathStyle: ""}`);
|
||||
const api = new S3Client({ region: amazonS3Creds.region, credentials: amazonS3Creds.credentials, s3UseArnRegion: true, forcePathStyle: amazonS3Creds.forcePathStyle, endpoint: amazonS3Creds.endpoint });
|
||||
fileApi = new FileApi('', new FileApiDriverAmazonS3(api, amazonS3Creds.bucket));
|
||||
} else if (syncTargetId_ == SyncTargetRegistry.nameToId('joplinServer')) {
|
||||
} else if (syncTargetId_ === SyncTargetRegistry.nameToId('joplinServer')) {
|
||||
mustRunInBand();
|
||||
|
||||
const joplinServerAuth = JSON.parse(await readCredentialFile('joplin-server-test-units-2.json'));
|
||||
|
@ -137,7 +137,7 @@ export function execCommand(command: string, options: any = null): Promise<strin
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, options, (error: any, stdout: any, stderr: any) => {
|
||||
if (error) {
|
||||
if (error.signal == 'SIGTERM') {
|
||||
if (error.signal === 'SIGTERM') {
|
||||
resolve('Process was killed');
|
||||
} else {
|
||||
reject(error);
|
||||
@ -301,9 +301,9 @@ export function fileExists(filePath: string) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.stat(filePath, function(err: any) {
|
||||
if (err == null) {
|
||||
if (!err) {
|
||||
resolve(true);
|
||||
} else if (err.code == 'ENOENT') {
|
||||
} else if (err.code === 'ENOENT') {
|
||||
resolve(false);
|
||||
} else {
|
||||
reject(err);
|
||||
|
Loading…
Reference in New Issue
Block a user