This commit is contained in:
antelle 2016-07-17 14:30:38 +03:00
parent ddf11a2ec4
commit c96431c46c
92 changed files with 1090 additions and 939 deletions

View File

@ -19,8 +19,8 @@ trim_trailing_whitespace = false
[*.json]
indent_size = 2
[.jshintrc]
indent_size = 2
[.eslintrc]
indent_size = 4
[*.scss]
indent_size = 2

22
.eslintrc Normal file
View File

@ -0,0 +1,22 @@
{
"extends": "standard",
"rules": {
"indent": ["error", 4, { "SwitchCase": 1 }],
"semi": ["error", "always"],
"one-var": "off",
"space-before-function-paren": "off",
"no-throw-literal": "off",
"camelcase": ["error", { "properties": "always" }],
"no-console": "error",
"no-alert": "error",
"no-debugger": "error",
"prefer-arrow-callback": "error"
},
"globals": {
"_": true,
"$": true
},
"env": {
"browser": true
}
}

View File

@ -1,6 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="Eslint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>

View File

@ -5,25 +5,31 @@
<option bitwise="true" />
<option boss="false" />
<option browser="true" />
<option browserify="false" />
<option camelcase="false" />
<option couch="false" />
<option curly="true" />
<option debug="false" />
<option devel="false" />
<option dojo="false" />
<option elision="false" />
<option enforceall="false" />
<option eqeqeq="true" />
<option eqnull="false" />
<option es3="false" />
<option es5="false" />
<option esnext="false" />
<option evil="false" />
<option expr="false" />
<option forin="true" />
<option freeze="false" />
<option funcscope="false" />
<option futurehostile="false" />
<option gcl="false" />
<option globalstrict="false" />
<option immed="false" />
<option iterator="false" />
<option jasmine="false" />
<option jquery="false" />
<option lastsemic="false" />
<option latedef="false" />
@ -31,11 +37,14 @@
<option laxcomma="false" />
<option loopfunc="false" />
<option maxerr="50" />
<option mocha="false" />
<option module="false" />
<option mootools="false" />
<option moz="false" />
<option multistr="false" />
<option newcap="false" />
<option noarg="true" />
<option nocomma="false" />
<option node="false" />
<option noempty="true" />
<option nomen="false" />
@ -50,19 +59,25 @@
<option plusplus="false" />
<option proto="false" />
<option prototypejs="false" />
<option qunit="false" />
<option quotmark="false" />
<option rhino="false" />
<option scripturl="false" />
<option shadow="false" />
<option shelljs="false" />
<option singleGroups="false" />
<option smarttabs="false" />
<option strict="true" />
<option sub="false" />
<option supernew="false" />
<option trailing="false" />
<option typed="false" />
<option undef="true" />
<option unused="false" />
<option validthis="false" />
<option varstmt="false" />
<option white="false" />
<option withstmt="false" />
<option worker="false" />
<option wsh="false" />
<option yui="false" />

View File

@ -1,95 +0,0 @@
{
"maxerr" : 50, // {int} Maximum error before stopping
// Enforcing
"bitwise" : false, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : true, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc.
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : false, // true: Require variables/functions to be defined before being used
"newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters.
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : "single", // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // Unused variables:
// true : all variables, last function parameter
// "vars" : all variables only
// "strict" : all variables, all function parameters
"strict" : "global", // true: Requires all functions run in ES5 Strict Mode
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : 160, // {int} Max number of characters per line
"varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed.
// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : false, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"noyield" : false, // true: Tolerate generator functions with no yield statement in them.
"notypeof" : false, // true: Tolerate invalid typeof operator values
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function
// Environments
"browser" : true, // Web Browser (window, document, etc)
"browserify" : false, // Browserify (node.js code in the browser)
"couch" : false, // CouchDB
"devel" : false, // Development/debugging (alert, confirm, etc)
"dojo" : false, // Dojo Toolkit
"jasmine" : true, // Jasmine
"jquery" : false, // jQuery
"mocha" : true, // Mocha
"mootools" : false, // MooTools
"node" : false, // Node.js
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
"phantom" : false, // PhantomJS
"prototypejs" : false, // Prototype and Scriptaculous
"qunit" : false, // QUnit
"rhino" : false, // Rhino
"shelljs" : false, // ShellJS
"typed" : false, // Globals for typed array constructions
"worker" : false, // Web Workers
"wsh" : false, // Windows Scripting Host
"yui" : false, // Yahoo User Interface
"-W097" : false, // global scrict
// Custom Globals
"globals" : {
"require": true,
"module": true,
"$": true,
"_": true
}
}

View File

@ -1,11 +1,10 @@
'use strict';
/* eslint-env node */
var fs = require('fs'),
path = require('path');
/* jshint node:true */
/* jshint browser:false */
var StringReplacePlugin = require('string-replace-webpack-plugin');
module.exports = function(grunt) {
@ -25,8 +24,8 @@ module.exports = function(grunt) {
}
function replaceFont(css) {
css.walkAtRules('font-face', function (rule) {
var fontFamily = rule.nodes.filter(function(n) { return n.prop === 'font-family'; })[0];
css.walkAtRules('font-face', rule => {
var fontFamily = rule.nodes.filter(n => n.prop === 'font-family')[0];
if (!fontFamily) {
throw 'Bad font rule: ' + rule.toString();
}
@ -41,8 +40,8 @@ module.exports = function(grunt) {
var data = fs.readFileSync('tmp/fonts/' + fontFile, 'base64');
var src = 'url(data:application/font-woff;charset=utf-8;base64,{data}) format(\'woff\')'
.replace('{data}', data);
//var src = 'url(\'../fonts/fontawesome-webfont.woff\') format(\'woff\')';
rule.nodes = rule.nodes.filter(function(n) { return n.prop !== 'src'; });
// var src = 'url(\'../fonts/fontawesome-webfont.woff\') format(\'woff\')';
rule.nodes = rule.nodes.filter(n => n.prop !== 'src');
rule.append({ prop: 'src', value: src });
});
}
@ -180,11 +179,10 @@ module.exports = function(grunt) {
nonull: true
}
},
jshint: {
options: {
jshintrc: true
},
all: ['app/scripts/**/*.js']
eslint: {
app: ['app/scripts/**/*.js'],
electron: ['electron/**/*.js', '!electron/node_modules/**'],
grunt: ['Gruntfile.js', 'grunt/**/*.js']
},
sass: {
options: {
@ -304,7 +302,7 @@ module.exports = function(grunt) {
overwrite: true,
'app-copyright': 'Copyright © 2016 Antelle',
'app-version': pkg.version,
'build-version': '<%= gitinfo.local.branch.current.shortSHA %>',
'build-version': '<%= gitinfo.local.branch.current.shortSHA %>'
},
linux: {
options: {
@ -475,7 +473,7 @@ module.exports = function(grunt) {
},
'concurrent': {
options: {
logConcurrentOutput: true,
logConcurrentOutput: true
},
'dev-server': [
'watch',
@ -490,7 +488,7 @@ module.exports = function(grunt) {
'gitinfo',
'bower-install-simple',
'clean',
'jshint',
'eslint',
'copy:html',
'copy:favicon',
'copy:touchicon',
@ -508,26 +506,26 @@ module.exports = function(grunt) {
grunt.registerTask('build-desktop-app-content', [
'copy:desktop-app-content',
'string-replace:desktop-html',
'string-replace:desktop-html'
]);
grunt.registerTask('build-desktop-update', [
'compress:desktop-update',
'sign-archive:desktop-update',
'validate-desktop-update',
'validate-desktop-update'
]);
grunt.registerTask('build-desktop-executables', [
'electron',
'copy:desktop-windows-helper-ia32',
'copy:desktop-windows-helper-x64',
'copy:desktop-windows-helper-x64'
]);
grunt.registerTask('build-desktop-archives', [
'compress:win32-x64',
'compress:win32-ia32',
'compress:linux-x64',
'compress:linux-ia32',
'compress:linux-ia32'
]);
grunt.registerTask('build-desktop-dist-darwin', [

View File

@ -12,7 +12,7 @@ var AppModel = require('./models/app-model'),
ThemeChanger = require('./util/theme-changer'),
Locale = require('./util/locale');
$(function() {
$(() => {
if (isPopup()) {
return AuthReceiver.receive();
}
@ -23,7 +23,7 @@ $(function() {
ThemeChanger.setBySettings(appModel.settings);
var configParam = getConfigParam();
if (configParam) {
appModel.loadConfig(configParam, function(err) {
appModel.loadConfig(configParam, err => {
if (err) {
showSettingsLoadError();
} else {

View File

@ -47,7 +47,7 @@ AutoTypeObfuscator.prototype.step = function() {
this.stepReal();
}
if (logger.getLevel() >= Logger.Level.Debug) {
logger.debug('value', this.inputChars.map(function(ic) { return ic.ch; }).join(''));
logger.debug('value', this.inputChars.map(ic => ic.ch).join(''));
}
};

View File

@ -164,7 +164,6 @@ AutoTypeRunner.prototype.tryParseCommand = function(op) {
default:
return false;
}
};
AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
@ -173,7 +172,7 @@ AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
}
field = field.toLowerCase();
var value = null;
_.findKey(this.entry.entry.fields, function(val, f) {
_.findKey(this.entry.entry.fields, (val, f) => {
if (f.toLowerCase() === field) {
value = val;
return true;
@ -185,7 +184,7 @@ AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
if (value.isProtected) {
op.type = 'group';
var ops = [];
value.forEachChar(function(ch) {
value.forEachChar(ch => {
if (ch === 10 || ch === 13) {
ops.push({type: 'key', value: 'enter'});
} else {
@ -200,7 +199,7 @@ AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
}
op.type = 'group';
var partsOps = [];
parts.forEach(function(part) {
parts.forEach(part => {
if (partsOps.length) {
partsOps.push({type: 'key', value: 'enter'});
}
@ -256,7 +255,6 @@ AutoTypeRunner.prototype.udt = function(part) {
default:
throw 'Bad part: ' + part;
}
};
AutoTypeRunner.prototype.getOtp = function(op) {
@ -267,9 +265,8 @@ AutoTypeRunner.prototype.getOtp = function(op) {
if (!this.entry.otpGenerator) {
return '';
}
var that = this;
this.entry.otpGenerator.next(function(otp) {
that.pendingResolved(op, otp, otp ? undefined : 'OTP error');
this.entry.otpGenerator.next(otp => {
this.pendingResolved(op, otp, otp ? undefined : 'OTP error');
});
return AutoTypeRunner.PendingResolve;
};
@ -302,7 +299,7 @@ AutoTypeRunner.prototype.obfuscateOps = function(ops) {
if (op.type === 'text') {
this.obfuscateOp(op);
} else if (op.type === 'group') {
var onlyText = op.value.every(function(grOp) { return grOp.type === 'text' && !grOp.mod; });
var onlyText = op.value.every(grOp => grOp.type === 'text' && !grOp.mod);
if (onlyText) {
this.obfuscateOp(op);
} else {
@ -320,7 +317,7 @@ AutoTypeRunner.prototype.obfuscateOp = function(op) {
}
letters = op.value.split('');
} else {
op.value.forEach(function(grOp) { letters.push.apply(letters, grOp.value.split('')); });
op.value.forEach(grOp => letters.push.apply(letters, grOp.value.split('')));
}
if (letters.length <= 1) {
return;

View File

@ -38,7 +38,7 @@ AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
AutoTypeEmitter.prototype.text = function(text) {
text = text.replace(/"/g, '\\"').replace(/\\/g, '\\\\');
this.pendingScript.push('keystroke "' + text + '"'+ this.modString());
this.pendingScript.push('keystroke "' + text + '"' + this.modString());
this.callback();
};

View File

@ -37,19 +37,18 @@ AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
};
AutoTypeEmitter.prototype.text = function(text) {
var that = this;
Object.keys(this.mod).forEach(function (mod) {
that.pendingScript.push('keydown ' + ModMap[mod]);
Object.keys(this.mod).forEach(mod => {
this.pendingScript.push('keydown ' + ModMap[mod]);
});
that.pendingScript.push('type ' + text.split('').map(function(char) {
this.pendingScript.push('type ' + text.split('').map(char => {
return char === '\'' ? '"\'"' : '\'' + char + '\'';
}).join(''));
this.waitComplete(function(err) {
if (err) { return that.callback(err); }
Object.keys(that.mod).forEach(function (mod) {
that.pendingScript.push('keyup ' + ModMap[mod]);
this.waitComplete(err => {
if (err) { return this.callback(err); }
Object.keys(this.mod).forEach(mod => {
this.pendingScript.push('keyup ' + ModMap[mod]);
});
that.callback();
this.callback();
});
};
@ -89,7 +88,7 @@ AutoTypeEmitter.prototype.waitComplete = function(callback) {
AutoTypeEmitter.prototype.modString = function() {
var mod = '';
Object.keys(this.mod).forEach(function (key) {
Object.keys(this.mod).forEach(key => {
mod += key + '+';
});
return mod;

View File

@ -41,7 +41,7 @@ AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
};
AutoTypeEmitter.prototype.text = function(text) {
text = this.addMod(text.replace(TextReplaceRegex, function(match) { return '{' + match + '}'; }));
text = this.addMod(text.replace(TextReplaceRegex, match => '{' + match + '}'));
this.pendingScript.push('text ' + text);
this.callback();
};

View File

@ -21,7 +21,7 @@ var AutoTypeHelper = function() {
};
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
AutoTypeHelper.exec(ForeMostAppScript, function(err, out) {
AutoTypeHelper.exec(ForeMostAppScript, (err, out) => {
if (err) { return callback(err); }
var appName = out.trim();
// getting urls and titles from Chrome or Safari:
@ -29,20 +29,20 @@ AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
// - does not require assistive access
// - allows to get url
if (['Google Chrome', 'Chromium', 'Google Chrome Canary'].indexOf(appName) >= 0) {
AutoTypeHelper.exec(ChromeScript.replace(/\{}/g, appName), function(err, out) {
AutoTypeHelper.exec(ChromeScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
var parts = out.split('\n');
return callback(null, parts[1].trim(), parts[0].trim());
});
} else if (['Safari', 'Webkit'].indexOf(appName) >= 0) {
AutoTypeHelper.exec(SafariScript.replace(/\{}/g, appName), function(err, out) {
AutoTypeHelper.exec(SafariScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
var parts = out.split('\n');
return callback(null, parts[1].trim(), parts[0].trim());
});
} else {
// special cases are not available. this method may ask the user about assistive access
AutoTypeHelper.exec(OtherAppsScript.replace(/\{}/g, appName), function(err, out) {
AutoTypeHelper.exec(OtherAppsScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
return callback(null, out.trim());
});

View File

@ -17,18 +17,17 @@ var AutoType = {
run: function(entry, callback) {
var sequence = entry.getEffectiveAutoTypeSeq();
logger.debug('Start', sequence);
var that = this;
var ts = logger.ts();
try {
var parser = new AutoTypeParser(sequence);
var runner = parser.parse();
logger.debug('Parsed', that.printOps(runner.ops));
runner.resolve(entry, function(err) {
logger.debug('Parsed', this.printOps(runner.ops));
runner.resolve(entry, err => {
if (err) {
logger.error('Resolve error', err);
return callback && callback(err);
}
logger.debug('Resolved', that.printOps(runner.ops));
logger.debug('Resolved', this.printOps(runner.ops));
if (entry.autoTypeObfuscation) {
try {
runner.obfuscate();
@ -38,7 +37,7 @@ var AutoType = {
}
logger.debug('Obfuscated');
}
runner.run(function(err) {
runner.run(err => {
if (err) {
logger.error('Run error', err);
return callback && callback(err);
@ -93,7 +92,7 @@ var AutoType = {
getActiveWindowTitle: function(callback) {
logger.debug('Get window title');
return this.helper.getActiveWindowTitle(function(err, title, url) {
return this.helper.getActiveWindowTitle((err, title, url) => {
if (err) {
logger.error('Error get window title', err);
} else {

View File

@ -7,19 +7,19 @@ var FileCollection = Backbone.Collection.extend({
model: FileModel,
hasOpenFiles: function() {
return this.some(function(file) { return file.get('open'); });
return this.some(file => file.get('open'));
},
hasUnsavedFiles: function() {
return this.some(function(file) { return file.get('modified'); });
return this.some(file => file.get('modified'));
},
hasDirtyFiles: function() {
return this.some(function(file) { return file.get('dirty'); });
return this.some(file => file.get('dirty'));
},
getByName: function(name) {
return this.find(function(file) { return file.get('name').toLowerCase() === name.toLowerCase(); });
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
}
});

View File

@ -26,7 +26,7 @@ var FileInfoCollection = Backbone.Collection.extend({
},
getMatch: function (storage, name, path) {
return this.find(function(fi) {
return this.find(fi => {
return (fi.get('storage') || '') === (storage || '') &&
(fi.get('name') || '') === (name || '') &&
(fi.get('path') || '') === (path || '');
@ -34,7 +34,7 @@ var FileInfoCollection = Backbone.Collection.extend({
},
getByName: function(name) {
return this.find(function(file) { return file.get('name').toLowerCase() === name.toLowerCase(); });
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
}
});

View File

@ -17,7 +17,7 @@ var Alerts = {
Alerts.alertDisplayed = true;
var view = new ModalView({ model: config });
view.render();
view.on('result', function(res, check) {
view.on('result', (res, check) => {
Alerts.alertDisplayed = false;
if (res && config.success) {
config.success(res, check);

View File

@ -16,7 +16,7 @@ var AuthReceiver = {
urlArgsToMessage: function(url) {
var message = {};
url.split(/[\?#&]/g).forEach(function(part) {
url.split(/[\?#&]/g).forEach(part => {
var parts = part.split('=');
if (parts.length === 2) {
message[parts[0]] = parts[1];

View File

@ -12,7 +12,7 @@ var CopyPaste = {
Launcher.setClipboardText(text);
var clipboardSeconds = AppSettingsModel.instance.get('clipboardSeconds');
if (clipboardSeconds > 0) {
setTimeout(function () {
setTimeout(() => {
if (Launcher.getClipboardText() === text) {
Launcher.clearClipboardText();
}
@ -46,7 +46,7 @@ var CopyPaste = {
hiddenInput[0].selectionEnd = text.length;
hiddenInput.focus();
hiddenInput.on({
'copy cut paste': function() { setTimeout(function() { hiddenInput.blur(); }, 0); },
'copy cut paste': function() { setTimeout(() => hiddenInput.blur(), 0); },
blur: function() { hiddenInput.remove(); }
});
}

View File

@ -58,7 +58,7 @@ DropboxChooser.prototype.buildUrl = function() {
iframe: 'false',
version: 2
};
return 'https://www.dropbox.com/chooser?' + Object.keys(urlParams).map(function(key) {
return 'https://www.dropbox.com/chooser?' + Object.keys(urlParams).map(key => {
return key + '=' + urlParams[key];
}).join('&');
};
@ -103,7 +103,6 @@ DropboxChooser.prototype.checkClose = function() {
};
DropboxChooser.prototype.success = function(params) {
/* jshint camelcase:false */
if (!params || !params[0] || !params[0].link || params[0].is_dir) {
return this.callback('bad result');
}
@ -113,9 +112,9 @@ DropboxChooser.prototype.success = function(params) {
DropboxChooser.prototype.readFile = function(url) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', (function() {
xhr.addEventListener('load', () => {
this.callback(null, { name: this.result.name, data: xhr.response });
}).bind(this));
});
xhr.addEventListener('error', this.callback.bind(this, 'download error'));
xhr.addEventListener('abort', this.callback.bind(this, 'download abort'));
xhr.open('GET', url);
@ -143,12 +142,12 @@ var DropboxLink = {
} else {
client.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl: location.href }));
}
client.authenticate((function(error, client) {
client.authenticate((error, client) => {
if (!error) {
this._dropboxClient = client;
}
complete(error, client);
}).bind(this));
});
},
_handleUiError: function(err, alertCallback, callback) {
@ -166,10 +165,10 @@ var DropboxLink = {
header: Locale.dropboxLogin,
body: Locale.dropboxLoginBody,
buttons: [{result: 'yes', title: Locale.alertSignIn}, {result: '', title: Locale.alertCancel}],
success: (function () {
this.authenticate(function (err) { callback(!err); });
}).bind(this),
cancel: function () {
success: () => {
this.authenticate(err => { callback(!err); });
},
cancel: () => {
callback(false);
}
});
@ -221,19 +220,18 @@ var DropboxLink = {
},
_callAndHandleError: function(callName, args, callback, errorAlertCallback) {
var that = this;
this._getClient(function(err, client) {
this._getClient((err, client) => {
if (err) {
return callback(err);
}
var ts = logger.ts();
logger.debug('Call', callName);
client[callName].apply(client, args.concat(function(err) {
client[callName].apply(client, args.concat(err => {
logger.debug('Result', callName, logger.ts(ts), arguments);
if (err) {
that._handleUiError(err, errorAlertCallback, function(repeat) {
this._handleUiError(err, errorAlertCallback, repeat => {
if (repeat) {
that._callAndHandleError(callName, args, callback, errorAlertCallback);
this._callAndHandleError(callName, args, callback, errorAlertCallback);
} else {
callback(err);
}
@ -260,7 +258,7 @@ var DropboxLink = {
},
authenticate: function(complete, overrideAppKey) {
this._getClient(function(err) { complete(err); }, overrideAppKey);
this._getClient(err => { complete(err); }, overrideAppKey);
},
logout: function() {
@ -288,12 +286,12 @@ var DropboxLink = {
this._callAndHandleError('writeFile', [fileName, data, opts], complete, alertCallback);
} else {
var dir = UrlUtil.fileToDir(fileName);
this.list(dir, (function(err, files) {
this.list(dir, (err, files) => {
if (err) { return complete(err); }
var exists = files.some(function(file) { return file.toLowerCase() === fileName.toLowerCase(); });
var exists = files.some(file => file.toLowerCase() === fileName.toLowerCase());
if (exists) { return complete({ exists: true }); }
this._callAndHandleError('writeFile', [fileName, data], complete);
}).bind(this));
});
}
},
@ -306,9 +304,9 @@ var DropboxLink = {
},
list: function(dir, complete) {
this._callAndHandleError('readdir', [dir || ''], function(err, files, dirStat, filesStat) {
this._callAndHandleError('readdir', [dir || ''], (err, files, dirStat, filesStat) => {
if (files) {
files = files.filter(function(f) { return /\.kdbx$/i.test(f); });
files = files.filter(f => /\.kdbx$/i.test(f));
}
complete(err, files, dirStat, filesStat);
});

View File

@ -26,7 +26,7 @@ var KeyHandler = {
},
offKey: function(key, handler, thisArg) {
if (this.shortcuts[key]) {
this.shortcuts[key] = _.reject(this.shortcuts[key], function(sh) {
this.shortcuts[key] = _.reject(this.shortcuts[key], sh => {
return sh.handler === handler && sh.thisArg === thisArg;
});
}

View File

@ -9,7 +9,6 @@ var Launcher;
var logger = new Logger('launcher');
if (window.process && window.process.versions && window.process.versions.electron) {
/* jshint node:true */
Launcher = {
name: 'electron',
version: window.process.versions.electron,
@ -117,7 +116,7 @@ if (window.process && window.process.versions && window.process.versions.electro
resolveProxy: function(url, callback) {
var window = this.remoteApp().getMainWindow();
var session = window.webContents.session;
session.resolveProxy(url, function(proxy) {
session.resolveProxy(url, proxy => {
var match = /^proxy\s+([\w\.]+):(\d+)+\s*/i.exec(proxy);
proxy = match && match[1] ? { host: match[1], port: +match[2] } : null;
callback(proxy);
@ -144,12 +143,12 @@ if (window.process && window.process.versions && window.process.versions.electro
var ts = logger.ts();
var complete = config.complete;
var ps = this.req('child_process').spawn(config.cmd, config.args);
[ps.stdin, ps.stdout, ps.stderr].forEach(function(s) { s.setEncoding('utf-8'); });
[ps.stdin, ps.stdout, ps.stderr].forEach(s => s.setEncoding('utf-8'));
var stderr = '';
var stdout = '';
ps.stderr.on('data', function(d) { stderr += d.toString('utf-8'); });
ps.stdout.on('data', function(d) { stdout += d.toString('utf-8'); });
ps.on('close', function(code) {
ps.stderr.on('data', d => { stderr += d.toString('utf-8'); });
ps.stdout.on('data', d => { stdout += d.toString('utf-8'); });
ps.on('close', code => {
stdout = stdout.trim();
stderr = stderr.trim();
var msg = 'spawn ' + config.cmd + ': ' + code + ', ' + logger.ts(ts);
@ -163,7 +162,7 @@ if (window.process && window.process.versions && window.process.versions.electro
complete = null;
}
});
ps.on('error', function(err) {
ps.on('error', err => {
logger.error('spawn error: ' + config.cmd + ', ' + logger.ts(ts), err);
if (complete) {
complete(err);
@ -180,17 +179,15 @@ if (window.process && window.process.versions && window.process.versions.electro
return process.platform;
}
};
Backbone.on('launcher-exit-request', function() {
setTimeout(function() { Launcher.exit(); }, 0);
});
Backbone.on('launcher-minimize', function() {
setTimeout(function() { Backbone.trigger('app-minimized'); }, 0);
Backbone.on('launcher-exit-request', () => {
setTimeout(() => Launcher.exit(), 0);
});
Backbone.on('launcher-minimize', () => setTimeout(() => Backbone.trigger('app-minimized'), 0));
window.launcherOpen = function(path) {
Backbone.trigger('launcher-open-file', path);
};
if (window.launcherOpenedFile) {
console.log('Open file request', window.launcherOpenedFile);
logger.info('Open file request', window.launcherOpenedFile);
Backbone.trigger('launcher-open-file', window.launcherOpenedFile);
delete window.launcherOpenedFile;
}

View File

@ -20,8 +20,8 @@ var OtpQrReader = {
if (screenshotKey) {
screenshotKey = Locale.detSetupOtpAlertBodyWith.replace('{}', '<code>' + screenshotKey + '</code>');
}
var pasteKey = FeatureDetector.isMobile() ? '' :
Locale.detSetupOtpAlertBodyWith.replace('{}',
var pasteKey = FeatureDetector.isMobile() ? ''
: Locale.detSetupOtpAlertBodyWith.replace('{}',
'<code>' + FeatureDetector.actionShortcutSymbol() + 'V</code>');
OtpQrReader.startListenClipoard();
var buttons = [{result: 'manually', title: Locale.detSetupOtpManualButton, silent: true},
@ -29,8 +29,8 @@ var OtpQrReader = {
if (FeatureDetector.isMobile()) {
buttons.unshift({result: 'select', title: Locale.detSetupOtpScanButton});
}
var line3 = FeatureDetector.isMobile() ? Locale.detSetupOtpAlertBody3Mobile :
Locale.detSetupOtpAlertBody3.replace('{}', pasteKey || '');
var line3 = FeatureDetector.isMobile() ? Locale.detSetupOtpAlertBody3Mobile
: Locale.detSetupOtpAlertBody3.replace('{}', pasteKey || '');
OtpQrReader.alert = Alerts.alert({
icon: 'qrcode',
header: Locale.detSetupOtpAlert,
@ -90,9 +90,7 @@ var OtpQrReader = {
},
pasteEvent: function(e) {
var item = _.find(e.clipboardData.items, function(item) {
return item.kind === 'file' && item.type.indexOf('image') !== -1;
});
var item = _.find(e.clipboardData.items, item => item.kind === 'file' && item.type.indexOf('image') !== -1);
if (!item) {
logger.debug('Paste without file');
return;
@ -131,7 +129,7 @@ var OtpQrReader = {
logger.error('Error parsing QR code', err);
Alerts.error({
header: Locale.detOtpQrWrong,
body: Locale.detOtpQrWrongBody + '<pre class="modal__pre">' + _.escape(err.toString()) +'</pre>'
body: Locale.detOtpQrWrongBody + '<pre class="modal__pre">' + _.escape(err.toString()) + '</pre>'
});
}
} catch (e) {

View File

@ -44,7 +44,7 @@ var PopupNotifier = {
};
if (settings) {
var settingsObj = {};
settings.split(',').forEach(function(part) {
settings.split(',').forEach(part => {
var parts = part.split('=');
settingsObj[parts[0].trim()] = parts[1].trim();
});
@ -54,14 +54,14 @@ var PopupNotifier = {
if (settings.left) { opts.x = settings.left; }
}
var win = Launcher.openWindow(opts);
win.webContents.on('did-get-redirect-request', function(e, fromUrl, toUrl) {
win.webContents.on('did-get-redirect-request', (e, fromUrl, toUrl) => {
if (toUrl.lastIndexOf(Links.WebApp, 0) === 0) {
win.webContents.stop();
win.close();
PopupNotifier.processReturnToApp(toUrl);
}
});
win.webContents.on('will-navigate', function(e, toUrl) {
win.webContents.on('will-navigate', (e, toUrl) => {
if (toUrl.lastIndexOf(Links.WebApp, 0) === 0) {
e.preventDefault();
win.close();
@ -70,7 +70,7 @@ var PopupNotifier = {
});
win.loadURL(url);
win.show();
win.on('closed', function() {
win.on('closed', () => {
setTimeout(PopupNotifier.triggerClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
});
Backbone.trigger('popup-opened', win);

View File

@ -28,7 +28,7 @@ var Transport = {
logger.info('GET ' + config.url);
var opts = Launcher.req('url').parse(config.url);
opts.headers = { 'User-Agent': navigator.userAgent };
Launcher.resolveProxy(config.url, function(proxy) {
Launcher.resolveProxy(config.url, proxy => {
logger.info('Request to ' + config.url + ' ' + (proxy ? 'using proxy ' + proxy.host + ':' + proxy.port : 'without proxy'));
if (proxy) {
opts.headers.Host = opts.host;
@ -36,26 +36,26 @@ var Transport = {
opts.port = proxy.port;
opts.path = config.url;
}
Launcher.req(proto).get(opts, function (res) {
Launcher.req(proto).get(opts, res => {
logger.info('Response from ' + config.url + ': ' + res.statusCode);
if (res.statusCode === 200) {
if (config.file) {
var file = fs.createWriteStream(tmpFile);
res.pipe(file);
file.on('finish', function () {
file.close(function () {
file.on('finish', () => {
file.close(() => {
config.success(tmpFile);
});
});
file.on('error', function (err) {
file.on('error', err => {
config.error(err);
});
} else {
var data = [];
res.on('data', function (chunk) {
res.on('data', chunk => {
data.push(chunk);
});
res.on('end', function () {
res.on('end', () => {
data = window.Buffer.concat(data);
if (config.utf8) {
data = data.toString('utf8');
@ -73,7 +73,7 @@ var Transport = {
} else {
config.error('HTTP status ' + res.statusCode);
}
}).on('error', function (e) {
}).on('error', e => {
logger.error('Cannot GET ' + config.url, e);
if (tmpFile) {
fs.unlink(tmpFile);

View File

@ -13,7 +13,7 @@ var Backbone = require('backbone'),
var logger = new Logger('updater');
var Updater = {
UpdateInterval: 1000*60*60*24,
UpdateInterval: 1000 * 60 * 60 * 24,
MinUpdateTimeout: 500,
MinUpdateSize: 10000,
UpdateCheckFiles: ['index.html', 'app.js'],
@ -67,13 +67,12 @@ var Updater = {
return;
}
UpdateModel.instance.set('status', 'checking');
var that = this;
if (!startedByUser) {
// additional protection from broken program logic, to ensure that auto-checks are not performed more than once an hour
var diffMs = new Date() - this.updateCheckDate;
if (isNaN(diffMs) || diffMs < 1000 * 60 * 60) {
logger.error('Prevented update check; last check was performed at ' + this.updateCheckDate);
that.scheduleNextCheck();
this.scheduleNextCheck();
return;
}
this.updateCheckDate = new Date();
@ -82,7 +81,7 @@ var Updater = {
Transport.httpGet({
url: Links.Manifest,
utf8: true,
success: function(data) {
success: data => {
var dt = new Date();
var match = data.match(/#\s*(\d+\-\d+\-\d+):v([\d+\.\w]+)/);
logger.info('Update check: ' + (match ? match[0] : 'unknown'));
@ -90,7 +89,7 @@ var Updater = {
var errMsg = 'No version info found';
UpdateModel.instance.set({ status: 'error', lastCheckDate: dt, lastCheckError: errMsg });
UpdateModel.instance.save();
that.scheduleNextCheck();
this.scheduleNextCheck();
return;
}
var updateMinVersionMatch = data.match(/#\s*updmin:v([\d+\.\w]+)/);
@ -105,8 +104,8 @@ var Updater = {
lastCheckUpdMin: updateMinVersionMatch ? updateMinVersionMatch[1] : null
});
UpdateModel.instance.save();
that.scheduleNextCheck();
if (!that.canAutoUpdate()) {
this.scheduleNextCheck();
if (!this.canAutoUpdate()) {
return;
}
if (prevLastVersion === UpdateModel.instance.get('lastVersion') &&
@ -114,13 +113,13 @@ var Updater = {
logger.info('Waiting for the user to apply downloaded update');
return;
}
if (!startedByUser && that.getAutoUpdateType() === 'install') {
that.update(startedByUser);
} else if (that.compareVersions(UpdateModel.instance.get('lastVersion'), RuntimeInfo.version) > 0) {
if (!startedByUser && this.getAutoUpdateType() === 'install') {
this.update(startedByUser);
} else if (this.compareVersions(UpdateModel.instance.get('lastVersion'), RuntimeInfo.version) > 0) {
UpdateModel.instance.set('updateStatus', 'found');
}
},
error: function(e) {
error: e => {
logger.error('Update check error', e);
UpdateModel.instance.set({
status: 'error',
@ -128,7 +127,7 @@ var Updater = {
lastCheckError: 'Error checking last version'
});
UpdateModel.instance.save();
that.scheduleNextCheck();
this.scheduleNextCheck();
}
});
},
@ -172,16 +171,15 @@ var Updater = {
return;
}
UpdateModel.instance.set({ updateStatus: 'downloading', updateError: null });
var that = this;
logger.info('Downloading update', ver);
Transport.httpGet({
url: Links.UpdateDesktop.replace('{ver}', ver),
file: 'KeeWeb-' + ver + '.zip',
cache: !startedByUser,
success: function(filePath) {
success: filePath => {
UpdateModel.instance.set('updateStatus', 'extracting');
logger.info('Extracting update file', that.UpdateCheckFiles, filePath);
that.extractAppUpdate(filePath, function(err) {
logger.info('Extracting update file', this.UpdateCheckFiles, filePath);
this.extractAppUpdate(filePath, err => {
if (err) {
logger.error('Error extracting update', err);
UpdateModel.instance.set({ updateStatus: 'error', updateError: 'Error extracting update' });
@ -207,22 +205,21 @@ var Updater = {
var expectedFiles = this.UpdateCheckFiles;
var appPath = Launcher.getUserDataPath();
var StreamZip = Launcher.req('node-stream-zip');
var that = this;
var zip = new StreamZip({ file: updateFile, storeEntries: true });
zip.on('error', cb);
zip.on('ready', function() {
var containsAll = expectedFiles.every(function(expFile) {
zip.on('ready', () => {
var containsAll = expectedFiles.every(expFile => {
var entry = zip.entry(expFile);
return entry && entry.isFile;
});
if (!containsAll) {
return cb('Bad archive');
}
var validationError = that.validateArchiveSignature(updateFile, zip);
var validationError = this.validateArchiveSignature(updateFile, zip);
if (validationError) {
return cb('Invalid archive: ' + validationError);
}
zip.extract(null, appPath, function(err) {
zip.extract(null, appPath, err => {
zip.close();
if (err) {
return cb(err);

View File

@ -118,4 +118,4 @@ var Keys = {
DOM_VK_META: 224
};
module.exports = Keys;
module.exports = Keys;

View File

@ -14,7 +14,7 @@ Handlebars.registerHelper('res', function(key, options) {
return value;
});
Handlebars.registerHelper('Res', function(key) {
Handlebars.registerHelper('Res', function(key) { // eslint-disable-line prefer-arrow-callback
var value = Locale[key];
if (value) {
value = value[0].toUpperCase() + value.substr(1);

View File

@ -43,7 +43,7 @@ kdbxweb.ProtectedValue.prototype.forEachChar = function(fn) {
Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
get: function() {
var textLength = 0;
this.forEachChar(function() { textLength++; });
this.forEachChar(() => { textLength++; });
return textLength;
}
});
@ -51,9 +51,8 @@ Object.defineProperty(kdbxweb.ProtectedValue.prototype, 'textLength', {
kdbxweb.ProtectedValue.prototype.includesLower = function(findLower) {
var matches = false;
var foundSeqs = [];
var ix = 0;
var len = findLower.length;
this.forEachChar(function(ch) {
this.forEachChar(ch => {
ch = String.fromCharCode(ch).toLowerCase();
if (matches) {
return;
@ -73,7 +72,6 @@ kdbxweb.ProtectedValue.prototype.includesLower = function(findLower) {
if (findLower[0] === ch) {
foundSeqs.push(0);
}
ix++;
});
return matches;
};

View File

@ -43,14 +43,14 @@ var Resizable = {
},
// TODO: check size on window resize
//checkSize: function() {
// if (this.maxWidth) {
// this.fixSize(this.getDragInfo('x'));
// }
// if (this.maxHeight) {
// this.fixSize(this.getDragInfo('y'));
// }
//},
// checkSize: function() {
// if (this.maxWidth) {
// this.fixSize(this.getDragInfo('x'));
// }
// if (this.maxHeight) {
// this.fixSize(this.getDragInfo('y'));
// }
// },
getDragInfo: function(coord) {
var prop = coord === 'x' ? 'Width' : 'Height',

View File

@ -9,7 +9,7 @@ var isEnabled = FeatureDetector.isDesktop();
var Scrollable = {
createScroll: function(opts) {
opts.$ = Backbone.$;
//opts.cssGuru = true;
// opts.cssGuru = true;
if (isEnabled) {
if (this.scroll) {
this.removeScroll();
@ -30,9 +30,9 @@ var Scrollable = {
pageResized: function() {
// TODO: check size on window resize
//if (this.checkSize && (!e || e.source === 'window')) {
// this.checkSize();
//}
// if (this.checkSize && (!e || e.source === 'window')) {
// this.checkSize();
// }
if (this.scroll) {
this.scroll.update();
this.requestAnimationFrame(function() {

View File

@ -71,8 +71,9 @@ _.extend(Backbone.View.prototype, {
this.trigger('remove');
this.removeInnerViews();
if (this.scroll) {
try { this.scroll.dispose(); }
catch (e) { }
try {
this.scroll.dispose();
} catch (e) { }
}
Tip.hideTips(this.$el);
this._parentRemove(arguments);
@ -80,14 +81,12 @@ _.extend(Backbone.View.prototype, {
removeInnerViews: function() {
if (this.views) {
_.each(this.views, function(view) {
_.each(this.views, view => {
if (view) {
if (view instanceof Backbone.View) {
view.remove();
} else if (view.length) {
view.forEach(function (v) {
v.remove();
});
view.forEach(v => v.remove());
}
}
});

View File

@ -48,18 +48,17 @@ var AppModel = Backbone.Model.extend({
xhr.open('GET', configLocation);
xhr.responseType = 'json';
xhr.send();
var that = this;
xhr.addEventListener('load', function() {
xhr.addEventListener('load', () => {
if (!xhr.response) {
that.appLogger.error('Error loading app config', xhr.statusText);
this.appLogger.error('Error loading app config', xhr.statusText);
return callback(true);
}
that.appLogger.info('Loaded app config from', configLocation, that.appLogger.ts(ts));
that.settings.set(xhr.response);
this.appLogger.info('Loaded app config from', configLocation, this.appLogger.ts(ts));
this.settings.set(xhr.response);
callback();
});
xhr.addEventListener('error', function() {
that.appLogger.error('Error loading app config', xhr.statusText, xhr.status);
xhr.addEventListener('error', () => {
this.appLogger.error('Error loading app config', xhr.statusText, xhr.status);
callback(true);
});
},
@ -92,15 +91,14 @@ var AppModel = Backbone.Model.extend({
_addTags: function(file) {
var tagsHash = {};
this.tags.forEach(function(tag) {
this.tags.forEach(tag => {
tagsHash[tag.toLowerCase()] = true;
});
var that = this;
file.forEachEntry({}, function(entry) {
_.forEach(entry.tags, function(tag) {
file.forEachEntry({}, entry => {
_.forEach(entry.tags, tag => {
if (!tagsHash[tag.toLowerCase()]) {
tagsHash[tag.toLowerCase()] = true;
that.tags.push(tag);
this.tags.push(tag);
}
});
});
@ -110,7 +108,7 @@ var AppModel = Backbone.Model.extend({
_tagsChanged: function() {
if (this.tags.length) {
this.menu.tagsSection.set('scrollable', true);
this.menu.tagsSection.setItems(this.tags.map(function (tag) {
this.menu.tagsSection.setItems(this.tags.map(tag => {
return {title: tag, icon: 'tag', filterKey: 'tag', filterValue: tag, editable: true};
}));
} else {
@ -131,17 +129,14 @@ var AppModel = Backbone.Model.extend({
},
renameTag: function(from, to) {
this.files.forEach(function(file) {
file.renameTag(from, to);
});
this.files.forEach(file => file.renameTag(from, to));
this.updateTags();
},
closeAllFiles: function() {
var that = this;
this.files.each(function(file) {
this.files.each(file => {
file.close();
that.fileClosed(file);
this.fileClosed(file);
});
this.files.reset();
this.menu.groupsSection.removeAllItems();
@ -164,9 +159,7 @@ var AppModel = Backbone.Model.extend({
},
emptyTrash: function() {
this.files.forEach(function(file) {
file.emptyTrash();
}, this);
this.files.forEach(file => file.emptyTrash());
this.refresh();
},
@ -198,8 +191,8 @@ var AppModel = Backbone.Model.extend({
getEntries: function() {
var entries = new EntryCollection();
var filter = this.prepareFilter();
this.files.forEach(function(file) {
file.forEachEntry(filter, function(entry) {
this.files.forEach(file => {
file.forEachEntry(filter, (entry) => {
entries.push(entry);
});
});
@ -211,10 +204,10 @@ var AppModel = Backbone.Model.extend({
},
addTrashGroups: function(collection) {
this.files.forEach(function(file) {
this.files.forEach(file => {
var trashGroup = file.getTrashGroup();
if (trashGroup) {
trashGroup.getOwnSubGroups().forEach(function(group) {
trashGroup.getOwnSubGroups().forEach(group => {
collection.unshift(GroupModel.fromGroup(group, file, trashGroup));
});
}
@ -236,13 +229,13 @@ var AppModel = Backbone.Model.extend({
var selGroupId = this.filter.group;
var file, group;
if (selGroupId) {
this.files.forEach(function(f) {
this.files.forEach(f => {
group = f.getGroup(selGroupId);
if (group) {
file = f;
return false;
}
}, this);
});
}
if (!group) {
file = this.files.first();
@ -253,8 +246,8 @@ var AppModel = Backbone.Model.extend({
completeUserNames: function(part) {
var userNames = {};
this.files.forEach(function(file) {
file.forEachEntry({ text: part, textLower: part.toLowerCase(), advanced: { user: true } }, function(entry) {
this.files.forEach(file => {
file.forEachEntry({ text: part, textLower: part.toLowerCase(), advanced: { user: true } }, entry => {
var userName = entry.user;
if (userName) {
userNames[userName] = (userNames[userName] || 0) + 1;
@ -262,12 +255,12 @@ var AppModel = Backbone.Model.extend({
});
});
var matches = _.pairs(userNames);
matches.sort(function(x, y) { return y[1] - x[1]; });
matches.sort((x, y) => y[1] - x[1]);
var maxResults = 5;
if (matches.length > maxResults) {
matches.length = maxResults;
}
return matches.map(function(m) { return m[0]; });
return matches.map(m => m[0]);
},
createNewEntry: function() {
@ -281,11 +274,10 @@ var AppModel = Backbone.Model.extend({
},
createDemoFile: function() {
var that = this;
if (!this.files.getByName('Demo')) {
var demoFile = new FileModel({ id: IdGenerator.uuid() });
demoFile.openDemo(function() {
that.addFile(demoFile);
demoFile.openDemo(() => {
this.addFile(demoFile);
});
return true;
} else {
@ -316,7 +308,7 @@ var AppModel = Backbone.Model.extend({
}
if (fileInfo && fileInfo.get('modified')) {
logger.info('Open file from cache because it is modified');
this.openFileFromCache(params, function(err, file) {
this.openFileFromCache(params, (err, file) => {
if (!err && file) {
logger.info('Sync just opened modified file');
_.defer(that.syncFile.bind(that, file));
@ -338,7 +330,7 @@ var AppModel = Backbone.Model.extend({
var storage = Storage[params.storage];
var storageLoad = function() {
logger.info('Load from storage');
storage.load(params.path, params.opts, function(err, data, stat) {
storage.load(params.path, params.opts, (err, data, stat) => {
if (err) {
if (fileInfo) {
logger.info('Open file from cache because of storage load error', err);
@ -359,7 +351,7 @@ var AppModel = Backbone.Model.extend({
var cacheRev = fileInfo && fileInfo.get('rev') || null;
if (cacheRev && storage.stat) {
logger.info('Stat file');
storage.stat(params.path, params.opts, function(err, stat) {
storage.stat(params.path, params.opts, (err, stat) => {
if (fileInfo && storage.name !== 'file' && (err || stat && stat.rev === cacheRev)) {
logger.info('Open file from cache because ' + (err ? 'stat error' : 'it is latest'), err);
that.openFileFromCache(params, callback, fileInfo);
@ -376,7 +368,7 @@ var AppModel = Backbone.Model.extend({
}
} else {
logger.info('Open file from cache, will sync after load', params.storage);
this.openFileFromCache(params, function(err, file) {
this.openFileFromCache(params, (err, file) => {
if (!err && file) {
logger.info('Sync just opened file');
_.defer(that.syncFile.bind(that, file));
@ -387,13 +379,12 @@ var AppModel = Backbone.Model.extend({
},
openFileFromCache: function(params, callback, fileInfo) {
var that = this;
Storage.cache.load(fileInfo.id, null, function(err, data) {
Storage.cache.load(fileInfo.id, null, (err, data) => {
new Logger('open', params.name).info('Loaded file from cache', err);
if (err) {
callback(err);
} else {
that.openFileWithData(params, callback, fileInfo, data);
this.openFileWithData(params, callback, fileInfo, data);
}
});
},
@ -411,12 +402,11 @@ var AppModel = Backbone.Model.extend({
path: params.path,
keyFileName: params.keyFileName
});
var that = this;
file.open(params.password, data, params.keyFileData, function(err) {
file.open(params.password, data, params.keyFileData, err => {
if (err) {
return callback(err);
}
if (that.files.get(file.id)) {
if (this.files.get(file.id)) {
return callback('Duplicate file id');
}
if (fileInfo && fileInfo.get('modified')) {
@ -435,11 +425,11 @@ var AppModel = Backbone.Model.extend({
Storage.cache.save(file.id, null, params.fileData);
}
var rev = params.rev || fileInfo && fileInfo.get('rev');
that.setFileOpts(file, params.opts);
that.addToLastOpenFiles(file, rev);
that.addFile(file);
this.setFileOpts(file, params.opts);
this.addToLastOpenFiles(file, rev);
this.addFile(file);
callback(null, file);
that.fileOpened(file);
this.fileOpened(file);
});
},
@ -452,14 +442,13 @@ var AppModel = Backbone.Model.extend({
storage: params.storage,
path: params.path
});
var that = this;
file.importWithXml(params.fileXml, function(err) {
file.importWithXml(params.fileXml, err => {
logger.info('Import xml complete ' + (err ? 'with error' : ''), err);
if (err) {
return callback(err);
}
that.addFile(file);
that.fileOpened(file);
this.addFile(file);
this.fileOpened(file);
});
},
@ -491,7 +480,7 @@ var AppModel = Backbone.Model.extend({
getStoreOpts: function(file) {
var opts = file.get('opts'), storage = file.get('storage');
if (Storage[storage]&& Storage[storage].fileOptsToStoreOpts && opts) {
if (Storage[storage] && Storage[storage].fileOptsToStoreOpts && opts) {
return Storage[storage].fileOptsToStoreOpts(opts, file);
}
return null;
@ -499,16 +488,15 @@ var AppModel = Backbone.Model.extend({
setFileOpts: function(file, opts) {
var storage = file.get('storage');
if (Storage[storage]&& Storage[storage].storeOptsToFileOpts && opts) {
if (Storage[storage] && Storage[storage].storeOptsToFileOpts && opts) {
file.set('opts', Storage[storage].storeOptsToFileOpts(opts, file));
}
},
fileOpened: function(file) {
var that = this;
if (file.get('storage') === 'file') {
Storage.file.watch(file.get('path'), _.debounce(function() {
that.syncFile(file);
Storage.file.watch(file.get('path'), _.debounce(() => {
this.syncFile(file);
}, Timeouts.FileChangeSync));
}
if (file.isKeyChangePending(true)) {
@ -601,9 +589,9 @@ var AppModel = Backbone.Model.extend({
return complete();
}
logger.info('Local, save to cache');
file.getData(function(data, err) {
file.getData((data, err) => {
if (err) { return complete(err); }
Storage.cache.save(fileInfo.id, null, data, function(err) {
Storage.cache.save(fileInfo.id, null, data, (err) => {
logger.info('Saved to cache', err || 'no error');
complete(err);
});
@ -615,10 +603,10 @@ var AppModel = Backbone.Model.extend({
return complete('Too many load attempts');
}
logger.info('Load from storage, attempt ' + loadLoops);
Storage[storage].load(path, opts, function(err, data, stat) {
Storage[storage].load(path, opts, (err, data, stat) => {
logger.info('Load from storage', stat, err || 'no error');
if (err) { return complete(err); }
file.mergeOrUpdate(data, options.remoteKey, function(err) {
file.mergeOrUpdate(data, options.remoteKey, (err) => {
logger.info('Merge complete', err || 'no error');
that.refresh();
if (err) {
@ -638,7 +626,7 @@ var AppModel = Backbone.Model.extend({
saveToCacheAndStorage();
} else if (file.get('dirty')) {
logger.info('Saving not modified dirty file to cache');
Storage.cache.save(fileInfo.id, null, data, function (err) {
Storage.cache.save(fileInfo.id, null, data, (err) => {
if (err) { return complete(err); }
file.set('dirty', false);
logger.info('Complete, remove dirty flag');
@ -653,7 +641,7 @@ var AppModel = Backbone.Model.extend({
};
var saveToCacheAndStorage = function() {
logger.info('Getting file data for saving');
file.getData(function(data, err) {
file.getData((data, err) => {
if (err) { return complete(err); }
if (storage === 'file') {
logger.info('Saving to file storage');
@ -663,7 +651,7 @@ var AppModel = Backbone.Model.extend({
saveToStorage(data);
} else {
logger.info('Saving to cache');
Storage.cache.save(fileInfo.id, null, data, function (err) {
Storage.cache.save(fileInfo.id, null, data, (err) => {
if (err) { return complete(err); }
file.set('dirty', false);
logger.info('Saved to cache, saving to storage');
@ -674,7 +662,7 @@ var AppModel = Backbone.Model.extend({
};
var saveToStorage = function(data) {
logger.info('Save data to storage');
Storage[storage].save(path, opts, data, function(err, stat) {
Storage[storage].save(path, opts, data, (err, stat) => {
if (err && err.revConflict) {
logger.info('Save rev conflict, reloading from storage');
loadFromStorageAndMerge();
@ -699,16 +687,16 @@ var AppModel = Backbone.Model.extend({
}, fileInfo.get('rev'));
};
logger.info('Stat file');
Storage[storage].stat(path, opts, function (err, stat) {
Storage[storage].stat(path, opts, (err, stat) => {
if (err) {
if (err.notFound) {
logger.info('File does not exist in storage, creating');
saveToCacheAndStorage();
} else if (file.get('dirty')) {
logger.info('Stat error, dirty, save to cache', err || 'no error');
file.getData(function (data) {
file.getData((data) => {
if (data) {
Storage.cache.save(fileInfo.id, null, data, function (e) {
Storage.cache.save(fileInfo.id, null, data, (e) => {
if (!e) {
file.set('dirty', false);
}
@ -738,7 +726,7 @@ var AppModel = Backbone.Model.extend({
},
clearStoredKeyFiles: function() {
this.fileInfos.each(function(fileInfo) {
this.fileInfos.each(fileInfo => {
fileInfo.set({
keyFileName: null,
keyFileHash: null

View File

@ -26,8 +26,8 @@ var AttachmentModel = Backbone.Model.extend({
case 'txt': case 'log': case 'rtf':
return 'file-text-o';
case 'html': case 'htm': case 'js': case 'css': case 'xml': case 'config': case 'json': case 'yaml':
case 'cpp': case 'c': case 'h': case 'cc': case 'hpp': case 'mm': case 'cs': case 'php': case 'sh':
case 'py': case 'java': case 'rb': case 'cfg': case 'properties': case 'yml': case 'asm': case 'bat':
case 'cpp': case 'c': case 'h': case 'cc': case 'hpp': case 'mm': case 'cs': case 'php': case 'sh':
case 'py': case 'java': case 'rb': case 'cfg': case 'properties': case 'yml': case 'asm': case 'bat':
return 'file-code-o';
case 'pdf':
return 'file-pdf-o';
@ -41,7 +41,7 @@ var AttachmentModel = Backbone.Model.extend({
case 'ppt': case 'pptx':
return 'file-powerpoint-o';
case 'jpeg': case 'jpg': case 'png': case 'gif': case 'bmp': case 'tiff': case 'svg': case 'ico': case 'psd':
return 'file-image-o';
return 'file-image-o';
case 'avi': case 'mp4': case '3gp': case 'm4v': case 'mov': case 'mpeg': case 'mpg': case 'mpe':
return 'file-video-o';
case 'mp3': case 'wav': case 'flac':
@ -54,8 +54,8 @@ var AttachmentModel = Backbone.Model.extend({
switch (ext) {
case 'txt': case 'log':
case 'html': case 'htm': case 'js': case 'css': case 'xml': case 'config': case 'json': case 'yaml':
case 'cpp': case 'c': case 'h': case 'cc': case 'hpp': case 'mm': case 'cs': case 'php': case 'sh':
case 'py': case 'java': case 'rb': case 'cfg': case 'properties': case 'yml': case 'asm':
case 'cpp': case 'c': case 'h': case 'cc': case 'hpp': case 'mm': case 'cs': case 'php': case 'sh':
case 'py': case 'java': case 'rb': case 'cfg': case 'properties': case 'yml': case 'asm':
return 'text/plain';
case 'pdf':
return 'application/pdf';

View File

@ -70,15 +70,15 @@ var EntryModel = Backbone.Model.extend({
_buildSearchText: function() {
var text = '';
_.forEach(this.entry.fields, function(value) {
_.forEach(this.entry.fields, value => {
if (typeof value === 'string') {
text += value.toLowerCase() + '\n';
}
});
this.entry.tags.forEach(function(tag) {
this.entry.tags.forEach(tag => {
text += tag.toLowerCase() + '\n';
});
this.attachments.forEach(function(att) {
this.attachments.forEach(att => {
text += att.title.toLowerCase() + '\n';
});
this.searchText = text;
@ -94,7 +94,7 @@ var EntryModel = Backbone.Model.extend({
},
_buildSearchTags: function() {
this.searchTags = this.entry.tags.map(function(tag) { return tag.toLowerCase(); });
this.searchTags = this.entry.tags.map(tag => tag.toLowerCase());
},
_buildSearchColor: function() {
@ -176,8 +176,9 @@ var EntryModel = Backbone.Model.extend({
var adv = filter.advanced;
var search, match;
if (adv.regex) {
try { search = new RegExp(filter.text, adv.cs ? '' : 'i'); }
catch (e) { return false; }
try {
search = new RegExp(filter.text, adv.cs ? '' : 'i');
} catch (e) { return false; }
match = this.matchRegex;
} else if (adv.cs) {
search = filter.text;
@ -241,7 +242,7 @@ var EntryModel = Backbone.Model.extend({
if (adv.other || adv.protect) {
var builtInFields = this.builtInFields;
var fieldNames = Object.keys(entry.fields);
matches = fieldNames.some(function (field) {
matches = fieldNames.some(field => {
if (builtInFields.indexOf(field) >= 0) {
return false;
}
@ -293,7 +294,7 @@ var EntryModel = Backbone.Model.extend({
},
renameTag: function(from, to) {
var ix = _.findIndex(this.entry.tags, function(tag) { return tag.toLowerCase() === from.toLowerCase(); });
var ix = _.findIndex(this.entry.tags, tag => tag.toLowerCase() === from.toLowerCase());
if (ix < 0) {
return;
}
@ -346,7 +347,7 @@ var EntryModel = Backbone.Model.extend({
return EntryModel.fromEntry(rec, this.group, this.file);
}, this);
history.push(this);
history.sort(function(x, y) { return x.updated - y.updated; });
history.sort((x, y) => x.updated - y.updated);
return history;
},
@ -437,7 +438,7 @@ var EntryModel = Backbone.Model.extend({
} else if (otpUrl.toLowerCase().lastIndexOf('otpauth:', 0) !== 0) {
// KeeOTP plugin format
var args = {};
otpUrl.split('&').forEach(function(part) {
otpUrl.split('&').forEach(part => {
var parts = part.split('=', 2);
args[parts[0]] = decodeURIComponent(parts[1]).replace(/=/g, '');
});

View File

@ -49,7 +49,7 @@ var FileModel = Backbone.Model.extend({
try {
var credentials = new kdbxweb.Credentials(password, keyFileData);
var ts = logger.ts();
kdbxweb.Kdbx.load(fileData, credentials, (function(db, err) {
kdbxweb.Kdbx.load(fileData, credentials, (db, err) => {
if (err) {
if (err.code === kdbxweb.Consts.ErrorCodes.InvalidKey && password && !password.byteLength) {
logger.info('Error opening file with empty password, try to open with null password');
@ -68,7 +68,7 @@ var FileModel = Backbone.Model.extend({
db.header.keyEncryptionRounds + ' rounds, ' + Math.round(fileData.byteLength / 1024) + ' kB');
callback();
}
}).bind(this));
});
} catch (e) {
logger.error('Error opening file', e, e.code, e.message, e);
callback(e);
@ -89,7 +89,7 @@ var FileModel = Backbone.Model.extend({
var ts = logger.ts();
var password = kdbxweb.ProtectedValue.fromString('');
var credentials = new kdbxweb.Credentials(password);
kdbxweb.Kdbx.loadXml(fileXml, credentials, (function(db, err) {
kdbxweb.Kdbx.loadXml(fileXml, credentials, (db, err) => {
if (err) {
logger.error('Error importing file', err.code, err.message, err);
callback(err);
@ -100,7 +100,7 @@ var FileModel = Backbone.Model.extend({
logger.info('Imported file ' + this.get('name') + ': ' + logger.ts(ts));
callback();
}
}).bind(this));
});
} catch (e) {
logger.error('Error importing file', e, e.code, e.message, e);
callback(e);
@ -111,13 +111,13 @@ var FileModel = Backbone.Model.extend({
var password = kdbxweb.ProtectedValue.fromString('demo');
var credentials = new kdbxweb.Credentials(password);
var demoFile = kdbxweb.ByteUtils.arrayToBuffer(kdbxweb.ByteUtils.base64ToBytes(demoFileData));
kdbxweb.Kdbx.load(demoFile, credentials, (function(db) {
kdbxweb.Kdbx.load(demoFile, credentials, db => {
this.db = db;
this.set('name', 'Demo');
this.readModel();
this.setOpenFile({passwordLength: 4, demo: true});
callback();
}).bind(this));
});
},
setOpenFile: function(props) {
@ -165,9 +165,9 @@ var FileModel = Backbone.Model.extend({
buildObjectMap: function() {
var entryMap = {};
var groupMap = {};
this.forEachGroup(function(group) {
this.forEachGroup(group => {
groupMap[group.id] = group;
group.forEachOwnEntry(null, function(entry) {
group.forEachOwnEntry(null, entry => {
entryMap[entry.id] = entry;
});
}, true);
@ -200,7 +200,7 @@ var FileModel = Backbone.Model.extend({
} else {
credentials = this.db.credentials;
}
kdbxweb.Kdbx.load(fileData, credentials, (function(remoteDb, err) {
kdbxweb.Kdbx.load(fileData, credentials, (remoteDb, err) => {
if (err) {
logger.error('Error opening file to merge', err.code, err.message, err);
} else {
@ -225,7 +225,7 @@ var FileModel = Backbone.Model.extend({
this.reload();
}
callback(err);
}).bind(this));
});
},
getLocalEditState: function() {
@ -271,7 +271,7 @@ var FileModel = Backbone.Model.extend({
top.forEachOwnEntry(filter, callback);
}
if (!filter.group || filter.subGroups) {
top.forEachGroup(function (group) {
top.forEachGroup(group => {
group.forEachOwnEntry(filter, callback);
});
}
@ -279,7 +279,7 @@ var FileModel = Backbone.Model.extend({
},
forEachGroup: function(callback, includeDisabled) {
this.get('groups').forEach(function(group) {
this.get('groups').forEach(group => {
if (callback(group) !== false) {
group.forEachGroup(callback, includeDisabled);
}
@ -302,11 +302,10 @@ var FileModel = Backbone.Model.extend({
customIcons: true,
binaries: true
});
var that = this;
this.db.cleanup({ binaries: true });
this.db.save(function(data, err) {
this.db.save((data, err) => {
if (err) {
logger.error('Error saving file', that.get('name'), err);
logger.error('Error saving file', this.get('name'), err);
}
cb(data, err);
});
@ -344,9 +343,7 @@ var FileModel = Backbone.Model.extend({
return;
}
this.setOpenFile({ passwordLength: this.get('passwordLength') });
this.forEachEntry({}, function(entry) {
entry.setSaved();
});
this.forEachEntry({}, entry => entry.setSaved());
},
setPassword: function(password) {
@ -476,9 +473,7 @@ var FileModel = Backbone.Model.extend({
},
getCustomIcons: function() {
return _.mapObject(this.db.meta.customIcons, function(customIcon) {
return IconUrl.toDataUrl(customIcon);
});
return _.mapObject(this.db.meta.customIcons, customIcon => IconUrl.toDataUrl(customIcon));
},
addCustomIcon: function(iconData) {
@ -488,9 +483,7 @@ var FileModel = Backbone.Model.extend({
},
renameTag: function(from, to) {
this.forEachEntry({}, function(entry) {
entry.renameTag(from, to);
});
this.forEachEntry({}, entry => entry.renameTag(from, to));
}
});

View File

@ -109,7 +109,7 @@ var GroupModel = MenuItemModel.extend({
forEachGroup: function(callback, includeDisabled) {
var result = true;
this.get('items').forEach(function(group) {
this.get('items').forEach(group => {
if (includeDisabled || group.group.enableSearching !== false) {
result = callback(group) !== false && group.forEachGroup(callback, includeDisabled) !== false;
}

View File

@ -31,8 +31,10 @@ var MenuModel = Backbone.Model.extend({
this.tagsSection.defaultItems = defTags;
this.trashSection = new MenuSectionModel([{ title: Locale.menuTrash, icon: 'trash', shortcut: Keys.DOM_VK_D,
filterKey: 'trash', filterValue: true, drop: true }]);
Colors.AllColors.forEach(function(color) { this.colorsSection.get('items').models[0]
.addOption({ cls: 'fa ' + color + '-color', value: color, filterValue: color }); }, this);
Colors.AllColors.forEach(color => {
this.colorsSection.get('items').models[0]
.addOption({ cls: 'fa ' + color + '-color', value: color, filterValue: color });
});
this.menus.app = new MenuSectionCollection([
this.allItemsSection,
this.colorsSection,
@ -61,9 +63,7 @@ var MenuModel = Backbone.Model.extend({
var sections = this.get('sections');
sections.forEach(function(section) { this._select(section, sel.item); }, this);
if (sections === this.menus.app) {
this.colorsItem.get('options').forEach(function (opt) {
opt.set('active', opt === sel.option);
});
this.colorsItem.get('options').forEach(opt => opt.set('active', opt === sel.option));
var selColor = sel.item === this.colorsItem && sel.option ? sel.option.get('value') + '-color' : '';
this.colorsItem.set('cls', 'menu__item-colors ' + selColor);
var filterKey = sel.item.get('filterKey'),

View File

@ -29,7 +29,7 @@ var MenuItemModel = Backbone.Model.extend({
removeByFile: function(file) {
var items = this.get('items');
items.find(function(item) {
items.find(item => {
if (item.file === file || item.get('file') === file) {
items.remove(item);
return true;
@ -40,7 +40,7 @@ var MenuItemModel = Backbone.Model.extend({
replaceByFile: function(file, newItem) {
var items = this.get('items');
items.find(function(item, ix) {
items.find((item, ix) => {
if (item.file === file || item.get('file') === file) {
items.remove(item);
items.add(newItem, { at: ix });

View File

@ -24,7 +24,7 @@ var UpdateModel = Backbone.Model.extend({
var data = SettingsStore.load('update-info');
if (data) {
try {
_.each(data, function(val, key) {
_.each(data, (val, key) => {
if (/Date$/.test(key)) {
data[key] = val ? new Date(val) : null;
}
@ -36,7 +36,7 @@ var UpdateModel = Backbone.Model.extend({
save: function() {
var attr = _.clone(this.attributes);
Object.keys(attr).forEach(function(key) {
Object.keys(attr).forEach(key => {
if (key.lastIndexOf('update', 0) === 0) {
delete attr[key];
}

View File

@ -48,7 +48,7 @@ EntryPresenter.prototype = {
case 'updated':
return this.updated;
case 'attachments':
return this.entry.attachments.map(function(a) { return a.title; }).join(', ') || '(' + Locale.listNoAttachments + ')';
return this.entry.attachments.map(a => a.title).join(', ') || '(' + Locale.listNoAttachments + ')';
default:
return this.notes || this.url || this.user;
}

View File

@ -11,8 +11,6 @@ var Storage = {
cache: Launcher ? require('./storage-file-cache') : require('./storage-cache')
};
_.forEach(Storage, function(prv) {
prv.init();
});
_.forEach(Storage, prv => prv.init());
module.exports = Storage;

View File

@ -47,33 +47,32 @@ _.extend(StorageBase.prototype, {
xhr.responseType = config.responseType;
}
var statuses = config.statuses || [200];
var that = this;
xhr.addEventListener('load', function() {
xhr.addEventListener('load', () => {
if (statuses.indexOf(xhr.status) >= 0) {
return config.success && config.success(xhr.response, xhr);
}
if (xhr.status === 401 && that._oauthToken) {
that._oauthRefreshToken(function(err) {
if (xhr.status === 401 && this._oauthToken) {
this._oauthRefreshToken(err => {
if (err) {
return config.error && config.error('unauthorized', xhr);
} else {
config.tryNum = (config.tryNum || 0) + 1;
if (config.tryNum >= MaxRequestRetries) {
that.logger.info('Too many authorize attempts, fail request', config.url);
this.logger.info('Too many authorize attempts, fail request', config.url);
return config.error && config.error('unauthorized', xhr);
}
that.logger.info('Repeat request, try #' + config.tryNum, config.url);
that._xhr(config);
this.logger.info('Repeat request, try #' + config.tryNum, config.url);
this._xhr(config);
}
});
} else {
return config.error && config.error('http status ' + xhr.status, xhr);
}
});
xhr.addEventListener('error', function() {
xhr.addEventListener('error', () => {
return config.error && config.error('network error', xhr);
});
xhr.addEventListener('timeout', function() {
xhr.addEventListener('timeout', () => {
return config.error && config.error('timeout', xhr);
});
xhr.open(config.method || 'GET', config.url);
@ -81,7 +80,7 @@ _.extend(StorageBase.prototype, {
xhr.setRequestHeader('Authorization',
this._oauthToken.tokenType + ' ' + this._oauthToken.accessToken);
}
_.forEach(config.headers, function(value, key) {
_.forEach(config.headers, (value, key) => {
xhr.setRequestHeader(key, value);
});
xhr.send(config.data);
@ -107,7 +106,7 @@ _.extend(StorageBase.prototype, {
scrollbars: 'yes',
location: 'yes'
};
settings = Object.keys(settings).map(function(key) { return key + '=' + settings[key]; }).join(',');
settings = Object.keys(settings).map(key => key + '=' + settings[key]).join(',');
var win = window.open(url, title, settings);
if (win && win.focus) {
@ -125,14 +124,13 @@ _.extend(StorageBase.prototype, {
},
_oauthAuthorize: function(callback) {
var that = this;
if (that._oauthToken && !that._oauthToken.expired) {
if (this._oauthToken && !this._oauthToken.expired) {
return callback();
}
var opts = this._getOAuthConfig();
var oldToken = that.runtimeData.get(that.name + 'OAuthToken');
var oldToken = this.runtimeData.get(this.name + 'OAuthToken');
if (oldToken && !oldToken.expired) {
that._oauthToken = oldToken;
this._oauthToken = oldToken;
callback();
return;
}
@ -140,30 +138,30 @@ _.extend(StorageBase.prototype, {
.replace('{cid}', encodeURIComponent(opts.clientId))
.replace('{scope}', encodeURIComponent(opts.scope))
.replace('{url}', encodeURIComponent(this._getOauthRedirectUrl()));
that.logger.debug('OAuth popup opened');
if (!that._openPopup(url, 'OAuth', opts.width, opts.height)) {
this.logger.debug('OAuth popup opened');
if (!this._openPopup(url, 'OAuth', opts.width, opts.height)) {
callback('cannot open popup');
}
var popupClosed = function() {
var popupClosed = () => {
Backbone.off('popup-closed', popupClosed);
window.removeEventListener('message', windowMessage);
that.logger.error('OAuth error', 'popup closed');
this.logger.error('OAuth error', 'popup closed');
callback('popup closed');
};
var windowMessage = function(e) {
var windowMessage = e => {
if (!e.data) {
return;
}
Backbone.off('popup-closed', popupClosed);
window.removeEventListener('message', windowMessage);
var token = that._oauthMsgToToken(e.data);
var token = this._oauthMsgToToken(e.data);
if (token.error) {
that.logger.error('OAuth error', token.error, token.errorDescription);
this.logger.error('OAuth error', token.error, token.errorDescription);
callback(token.error);
} else {
that._oauthToken = token;
that.runtimeData.set(that.name + 'OAuthToken', token);
that.logger.debug('OAuth success');
this._oauthToken = token;
this.runtimeData.set(this.name + 'OAuthToken', token);
this.logger.debug('OAuth success');
callback();
}
};
@ -172,7 +170,6 @@ _.extend(StorageBase.prototype, {
},
_oauthMsgToToken: function(data) {
// jshint camelcase:false
if (data.error || !data.token_type) {
return { error: data.error || 'no token', errorDescription: data.error_description };
}

View File

@ -16,98 +16,94 @@ var StorageCache = StorageBase.extend({
if (this.db) {
return callback && callback();
}
var that = this;
try {
var req = idb.open('FilesCache');
req.onerror = function (e) {
that.logger.error('Error opening indexed db', e);
that.errorOpening = e;
req.onerror = e => {
this.logger.error('Error opening indexed db', e);
this.errorOpening = e;
if (callback) { callback(e); }
};
req.onsuccess = function (e) {
that.db = e.target.result;
req.onsuccess = e => {
this.db = e.target.result;
if (callback) { callback(); }
};
req.onupgradeneeded = function (e) {
req.onupgradeneeded = e => {
var db = e.target.result;
db.createObjectStore('files');
};
} catch (e) {
that.logger.error('Error opening indexed db', e);
this.logger.error('Error opening indexed db', e);
if (callback) { callback(e); }
}
},
save: function(id, opts, data, callback) {
var that = this;
that.logger.debug('Save', id);
that.initDb(function(err) {
this.logger.debug('Save', id);
this.initDb(err => {
if (err) {
return callback && callback(err);
}
try {
var ts = that.logger.ts();
var req = that.db.transaction(['files'], 'readwrite').objectStore('files').put(data, id);
req.onsuccess = function () {
that.logger.debug('Saved', id, that.logger.ts(ts));
var ts = this.logger.ts();
var req = this.db.transaction(['files'], 'readwrite').objectStore('files').put(data, id);
req.onsuccess = () => {
this.logger.debug('Saved', id, this.logger.ts(ts));
if (callback) { callback(); }
};
req.onerror = function () {
that.logger.error('Error saving to cache', id, req.error);
req.onerror = () => {
this.logger.error('Error saving to cache', id, req.error);
if (callback) { callback(req.error); }
};
} catch (e) {
that.logger.error('Error saving to cache', id, e);
this.logger.error('Error saving to cache', id, e);
if (callback) { callback(e); }
}
});
},
load: function(id, opts, callback) {
var that = this;
that.logger.debug('Load', id);
that.initDb(function(err) {
this.logger.debug('Load', id);
this.initDb(err => {
if (err) {
return callback && callback(err, null);
}
try {
var ts = that.logger.ts();
var req = that.db.transaction(['files'], 'readonly').objectStore('files').get(id);
req.onsuccess = function () {
that.logger.debug('Loaded', id, that.logger.ts(ts));
var ts = this.logger.ts();
var req = this.db.transaction(['files'], 'readonly').objectStore('files').get(id);
req.onsuccess = () => {
this.logger.debug('Loaded', id, this.logger.ts(ts));
if (callback) { callback(null, req.result); }
};
req.onerror = function () {
that.logger.error('Error loading from cache', id, req.error);
req.onerror = () => {
this.logger.error('Error loading from cache', id, req.error);
if (callback) { callback(req.error); }
};
} catch (e) {
that.logger.error('Error loading from cache', id, e);
this.logger.error('Error loading from cache', id, e);
if (callback) { callback(e, null); }
}
});
},
remove: function(id, opts, callback) {
var that = this;
that.logger.debug('Remove', id);
that.initDb(function(err) {
this.logger.debug('Remove', id);
this.initDb(err => {
if (err) {
return callback && callback(err);
}
try {
var ts = that.logger.ts();
var req = that.db.transaction(['files'], 'readwrite').objectStore('files').delete(id);
req.onsuccess = function () {
that.logger.debug('Removed', id, that.logger.ts(ts));
var ts = this.logger.ts();
var req = this.db.transaction(['files'], 'readwrite').objectStore('files').delete(id);
req.onsuccess = () => {
this.logger.debug('Removed', id, this.logger.ts(ts));
if (callback) { callback(); }
};
req.onerror = function () {
that.logger.error('Error removing from cache', id, req.error);
req.onerror = () => {
this.logger.error('Error removing from cache', id, req.error);
if (callback) { callback(req.error); }
};
} catch(e) {
that.logger.error('Error removing from cache', id, e);
} catch (e) {
this.logger.error('Error removing from cache', id, e);
if (callback) { callback(e); }
}
});

View File

@ -97,13 +97,12 @@ var StorageDropbox = StorageBase.extend({
},
applyConfig: function(config, callback) {
var that = this;
DropboxLink.authenticate(function(err) {
DropboxLink.authenticate(err => {
if (!err) {
if (config.folder) {
config.folder = that._fixConfigFolder(config.folder);
config.folder = this._fixConfigFolder(config.folder);
}
that.appSettings.set({
this.appSettings.set({
dropboxAppKey: config.key,
dropboxFolder: config.folder
});
@ -150,77 +149,68 @@ var StorageDropbox = StorageBase.extend({
},
load: function(path, opts, callback) {
var that = this;
that.logger.debug('Load', path);
var ts = that.logger.ts();
path = that._toFullPath(path);
DropboxLink.openFile(path, function(err, data, stat) {
that.logger.debug('Loaded', path, stat ? stat.versionTag : null, that.logger.ts(ts));
err = that._convertError(err);
this.logger.debug('Load', path);
var ts = this.logger.ts();
path = this._toFullPath(path);
DropboxLink.openFile(path, (err, data, stat) => {
this.logger.debug('Loaded', path, stat ? stat.versionTag : null, this.logger.ts(ts));
err = this._convertError(err);
if (callback) { callback(err, data, stat ? { rev: stat.versionTag } : null); }
}, _.noop);
},
stat: function(path, opts, callback) {
var that = this;
that.logger.debug('Stat', path);
var ts = that.logger.ts();
path = that._toFullPath(path);
DropboxLink.stat(path, function(err, stat) {
this.logger.debug('Stat', path);
var ts = this.logger.ts();
path = this._toFullPath(path);
DropboxLink.stat(path, (err, stat) => {
if (stat && stat.isRemoved) {
err = new Error('File removed');
err.notFound = true;
}
that.logger.debug('Stated', path, stat ? stat.versionTag : null, that.logger.ts(ts));
err = that._convertError(err);
this.logger.debug('Stated', path, stat ? stat.versionTag : null, this.logger.ts(ts));
err = this._convertError(err);
if (callback) { callback(err, stat ? { rev: stat.versionTag } : null); }
}, _.noop);
},
save: function(path, opts, data, callback, rev) {
var that = this;
that.logger.debug('Save', path, rev);
var ts = that.logger.ts();
path = that._toFullPath(path);
DropboxLink.saveFile(path, data, rev, function(err, stat) {
that.logger.debug('Saved', path, that.logger.ts(ts));
this.logger.debug('Save', path, rev);
var ts = this.logger.ts();
path = this._toFullPath(path);
DropboxLink.saveFile(path, data, rev, (err, stat) => {
this.logger.debug('Saved', path, this.logger.ts(ts));
if (!callback) { return; }
err = that._convertError(err);
err = this._convertError(err);
callback(err, stat ? { rev: stat.versionTag } : null);
}, _.noop);
},
list: function(callback) {
var that = this;
DropboxLink.authenticate(function(err) {
DropboxLink.authenticate((err) => {
if (err) { return callback(err); }
DropboxLink.list(that._toFullPath(''), function(err, files, dirStat, filesStat) {
DropboxLink.list(this._toFullPath(''), (err, files, dirStat, filesStat) => {
if (err) { return callback(err); }
var fileList = filesStat
.filter(function(f) {
return !f.isFolder && !f.isRemoved && UrlUtil.isKdbx(f.name);
})
.map(function(f) {
return {
name: f.name,
path: that._toRelPath(f.path),
rev: f.versionTag
};
});
var dir = dirStat.inAppFolder ? Locale.openAppFolder :
(UrlUtil.trimStartSlash(dirStat.path) || Locale.openRootFolder);
.filter(f => !f.isFolder && !f.isRemoved && UrlUtil.isKdbx(f.name))
.map(f => ({
name: f.name,
path: this._toRelPath(f.path),
rev: f.versionTag
}));
var dir = dirStat.inAppFolder ? Locale.openAppFolder
: (UrlUtil.trimStartSlash(dirStat.path) || Locale.openRootFolder);
callback(null, fileList, dir);
});
});
},
remove: function(path, callback) {
var that = this;
that.logger.debug('Remove', path);
var ts = that.logger.ts();
path = that._toFullPath(path);
DropboxLink.deleteFile(path, function(err) {
that.logger.debug('Removed', path, that.logger.ts(ts));
this.logger.debug('Remove', path);
var ts = this.logger.ts();
path = this._toFullPath(path);
DropboxLink.deleteFile(path, err => {
this.logger.debug('Removed', path, this.logger.ts(ts));
return callback && callback(err);
}, _.noop);
},

View File

@ -33,60 +33,57 @@ var StorageFileCache = StorageBase.extend({
},
save: function(id, opts, data, callback) {
var that = this;
that.logger.debug('Save', id);
that.initFs(function(err) {
this.logger.debug('Save', id);
this.initFs(err => {
if (err) {
return callback && callback(err);
}
var ts = that.logger.ts();
var ts = this.logger.ts();
try {
Launcher.writeFile(that.getPath(id), data);
that.logger.debug('Saved', id, that.logger.ts(ts));
Launcher.writeFile(this.getPath(id), data);
this.logger.debug('Saved', id, this.logger.ts(ts));
if (callback) { callback(); }
} catch (e) {
that.logger.error('Error saving to cache', id, e);
this.logger.error('Error saving to cache', id, e);
if (callback) { callback(e); }
}
});
},
load: function(id, opts, callback) {
var that = this;
that.logger.debug('Load', id);
that.initFs(function(err) {
this.logger.debug('Load', id);
this.initFs(err => {
if (err) {
return callback && callback(null, err);
}
var ts = that.logger.ts();
var ts = this.logger.ts();
try {
var data = Launcher.readFile(that.getPath(id));
that.logger.debug('Loaded', id, that.logger.ts(ts));
var data = Launcher.readFile(this.getPath(id));
this.logger.debug('Loaded', id, this.logger.ts(ts));
if (callback) { callback(null, data.buffer); }
} catch (e) {
that.logger.error('Error loading from cache', id, e);
this.logger.error('Error loading from cache', id, e);
if (callback) { callback(e, null); }
}
});
},
remove: function(id, opts, callback) {
var that = this;
that.logger.debug('Remove', id);
that.initFs(function(err) {
this.logger.debug('Remove', id);
this.initFs(err => {
if (err) {
return callback && callback(err);
}
var ts = that.logger.ts();
var ts = this.logger.ts();
try {
var path = that.getPath(id);
var path = this.getPath(id);
if (Launcher.fileExists(path)) {
Launcher.deleteFile(path);
}
that.logger.debug('Removed', id, that.logger.ts(ts));
this.logger.debug('Removed', id, this.logger.ts(ts));
if (callback) { callback(); }
} catch(e) {
that.logger.error('Error removing from cache', id, e);
} catch (e) {
this.logger.error('Error removing from cache', id, e);
if (callback) { callback(e); }
}
});

View File

@ -83,7 +83,7 @@ var StorageFile = StorageBase.extend({
var names = Launcher.parsePath(path);
var watcher = fileWatchers[names.dir];
if (watcher) {
var ix = watcher.callbacks.findIndex(function(cb) { return cb.file === names.file; });
var ix = watcher.callbacks.findIndex(cb => cb.file === names.file);
if (ix >= 0) {
watcher.callbacks.splice(ix, 1);
}
@ -97,11 +97,10 @@ var StorageFile = StorageBase.extend({
fsWatcherChange: function(dirname, evt, fileName) {
var watcher = fileWatchers[dirname];
var that = this;
if (watcher) {
watcher.callbacks.forEach(function(cb) {
watcher.callbacks.forEach(cb => {
if (cb.file === fileName && typeof cb.callback === 'function') {
that.logger.debug('File changed', dirname, evt, fileName);
this.logger.debug('File changed', dirname, evt, fileName);
cb.callback();
}
});

View File

@ -21,7 +21,7 @@ var StorageGDrive = StorageBase.extend({
load: function(path, opts, callback) {
var that = this;
that.stat(path, opts, function(err, stat) {
that.stat(path, opts, (err, stat) => {
if (err) { return callback && callback(err); }
that.logger.debug('Load', path);
var ts = that.logger.ts();
@ -48,7 +48,7 @@ var StorageGDrive = StorageBase.extend({
if (path.lastIndexOf(NewFileIdPrefix, 0) === 0) {
return callback && callback({ notFound: true });
}
this._oauthAuthorize(function(err) {
this._oauthAuthorize(err => {
if (err) {
return callback && callback(err);
}
@ -74,7 +74,7 @@ var StorageGDrive = StorageBase.extend({
save: function(path, opts, data, callback, rev) {
var that = this;
that.stat(path, opts, function(err, stat) {
that.stat(path, opts, (err, stat) => {
if (rev) {
if (err) { return callback && callback(err); }
if (stat.rev !== rev) {
@ -126,7 +126,7 @@ var StorageGDrive = StorageBase.extend({
list: function(callback) {
var that = this;
this._oauthAuthorize(function(err) {
this._oauthAuthorize((err) => {
if (err) { return callback && callback(err); }
that.logger.debug('List');
var url = that._baseUrl + '/files?fields={fields}&q={q}'
@ -142,13 +142,11 @@ var StorageGDrive = StorageBase.extend({
return callback && callback('list error');
}
that.logger.debug('Listed', that.logger.ts(ts));
var fileList = response.files.map(function(f) {
return {
name: f.name,
path: f.id,
rev: f.headRevisionId
};
});
var fileList = response.files.map(f => ({
name: f.name,
path: f.id,
rev: f.headRevisionId
}));
return callback && callback(null, fileList);
},
error: function(err) {

View File

@ -32,7 +32,7 @@ var StorageOneDrive = StorageBase.extend({
load: function(path, opts, callback) {
var that = this;
this._oauthAuthorize(function(err) {
this._oauthAuthorize(err => {
if (err) {
return callback && callback(err);
}
@ -73,7 +73,7 @@ var StorageOneDrive = StorageBase.extend({
stat: function(path, opts, callback) {
var that = this;
this._oauthAuthorize(function(err) {
this._oauthAuthorize(err => {
if (err) {
return callback && callback(err);
}
@ -106,7 +106,7 @@ var StorageOneDrive = StorageBase.extend({
save: function(path, opts, data, callback, rev) {
var that = this;
this._oauthAuthorize(function(err) {
this._oauthAuthorize(err => {
if (err) {
return callback && callback(err);
}
@ -143,7 +143,7 @@ var StorageOneDrive = StorageBase.extend({
list: function(callback) {
var that = this;
this._oauthAuthorize(function(err) {
this._oauthAuthorize(err => {
if (err) { return callback && callback(err); }
that.logger.debug('List');
var ts = that.logger.ts();
@ -158,14 +158,12 @@ var StorageOneDrive = StorageBase.extend({
}
that.logger.debug('Listed', that.logger.ts(ts));
var fileList = response.value
.filter(function(f) { return f.name && UrlUtil.isKdbx(f.name); })
.map(function(f) {
return {
name: f.name,
path: f.parentReference.path + '/' + f.name,
rev: f.eTag
};
});
.filter(f => f.name && UrlUtil.isKdbx(f.name))
.map(f => ({
name: f.name,
path: f.parentReference.path + '/' + f.name,
rev: f.eTag
}));
return callback && callback(null, fileList);
},
error: function(err) {

View File

@ -29,7 +29,7 @@ var StorageWebDav = StorageBase.extend({
path: path,
user: opts ? opts.user : null,
password: opts ? opts.password : null
}, callback ? function(err, xhr, stat) {
}, callback ? (err, xhr, stat) => {
callback(err, xhr.response, stat);
} : null);
},
@ -41,7 +41,7 @@ var StorageWebDav = StorageBase.extend({
path: path,
user: opts ? opts.user : null,
password: opts ? opts.password : null
}, callback ? function(err, xhr, stat) {
}, callback ? (err, xhr, stat) => {
callback(err, stat);
} : null);
},
@ -53,7 +53,7 @@ var StorageWebDav = StorageBase.extend({
callback = null;
}
};
var tmpPath = path.replace(/[^\/]+$/, function(m) { return '.' + m; }) + '.' + Date.now();
var tmpPath = path.replace(/[^\/]+$/, m => '.' + m) + '.' + Date.now();
var saveOpts = {
path: path,
user: opts ? opts.user : null,
@ -62,7 +62,7 @@ var StorageWebDav = StorageBase.extend({
var that = this;
this._request(_.defaults({
op: 'Save:stat', method: 'HEAD'
}, saveOpts), function(err, xhr, stat) {
}, saveOpts), (err, xhr, stat) => {
if (err) { return cb(err); }
if (stat.rev !== rev) {
that.logger.debug('Save error', path, 'rev conflict', stat.rev, rev);
@ -70,11 +70,11 @@ var StorageWebDav = StorageBase.extend({
}
that._request(_.defaults({
op: 'Save:put', method: 'PUT', path: tmpPath, data: data, nostat: true
}, saveOpts), function(err) {
}, saveOpts), (err) => {
if (err) { return cb(err); }
that._request(_.defaults({
op: 'Save:stat', method: 'HEAD'
}, saveOpts), function(err, xhr, stat) {
}, saveOpts), (err, xhr, stat) => {
if (err) {
that._request(_.defaults({ op: 'Save:delete', method: 'DELETE', path: tmpPath }, saveOpts));
return cb(err, xhr, stat);
@ -91,11 +91,11 @@ var StorageWebDav = StorageBase.extend({
that._request(_.defaults({
op: 'Save:move', method: 'MOVE', path: tmpPath, nostat: true,
headers: { Destination: movePath, 'Overwrite': 'T' }
}, saveOpts), function(err) {
}, saveOpts), (err) => {
if (err) { return cb(err); }
that._request(_.defaults({
op: 'Save:stat', method: 'HEAD'
}, saveOpts), function(err, xhr, stat) {
}, saveOpts), (err, xhr, stat) => {
cb(err, xhr, stat);
});
});
@ -141,7 +141,7 @@ var StorageWebDav = StorageBase.extend({
}
var ts = that.logger.ts();
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {
xhr.addEventListener('load', () => {
if ([200, 201, 204].indexOf(xhr.status) < 0) {
that.logger.debug(config.op + ' error', config.path, xhr.status, that.logger.ts(ts));
var err;
@ -169,11 +169,11 @@ var StorageWebDav = StorageBase.extend({
that.logger.debug(completedOpName, config.path, rev, that.logger.ts(ts));
if (callback) { callback(null, xhr, rev ? { rev: rev } : null); callback = null; }
});
xhr.addEventListener('error', function() {
xhr.addEventListener('error', () => {
that.logger.debug(config.op + ' error', config.path, that.logger.ts(ts));
if (callback) { callback('network error', xhr); callback = null; }
});
xhr.addEventListener('abort', function() {
xhr.addEventListener('abort', () => {
that.logger.debug(config.op + ' error', config.path, 'aborted', that.logger.ts(ts));
if (callback) { callback('aborted', xhr); callback = null; }
});
@ -183,7 +183,7 @@ var StorageWebDav = StorageBase.extend({
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(config.user + ':' + config.password));
}
if (config.headers) {
_.forEach(config.headers, function(value, header) {
_.forEach(config.headers, (value, header) => {
xhr.setRequestHeader(header, value);
});
}

View File

@ -54,7 +54,7 @@ Color.getNearest = function(colorStr) {
return null;
}
var selected = null, minDistance = Number.MAX_VALUE;
_.forEach(KnownColors, function(col, name) {
_.forEach(KnownColors, (col, name) => {
var distance = color.distanceTo(col);
if (distance < minDistance) {
minDistance = distance;
@ -68,7 +68,7 @@ Color.getKnownBgColor = function(knownColor) {
return Colors.BgColors[knownColor] ? '#' + Colors.BgColors[knownColor] : undefined;
};
_.forEach(Colors.ColorsValues, function(val, name) {
_.forEach(Colors.ColorsValues, (val, name) => {
KnownColors[name] = new Color(val);
});

View File

@ -2,10 +2,9 @@
var LastChar = String.fromCharCode(0xffffffff);
var ciCompare = (window.Intl && window.Intl.Collator) ?
new Intl.Collator(undefined, { sensitivity: 'base' }).compare : function(x, y) {
return x.toLocaleLowerCase().localeCompare(y.toLocaleLowerCase());
};
var ciCompare = (window.Intl && window.Intl.Collator)
? new Intl.Collator(undefined, { sensitivity: 'base' }).compare
: (x, y) => x.toLocaleLowerCase().localeCompare(y.toLocaleLowerCase());
var Comparators = {
stringComparator: function(field, asc) {

View File

@ -1,10 +1,10 @@
'use strict';
var Locale = {
months: ['January','February','March','April','May','June','July','August','September','October','November','December'],
monthsShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
weekdays: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
weekdaysShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
retToApp: 'return to app',
name: 'name',

View File

@ -1,8 +1,5 @@
'use strict';
/* globals console */
/* globals performance */
var Level = {
Off: 0,
Error: 1,
@ -37,7 +34,7 @@ Logger.prototype.debug = function() {
arguments[0] = this.getPrefix() + arguments[0];
if (this.level > Level.Debug) {
Logger.saveLast('debug', arguments);
console.debug.apply(console, arguments);
console.debug.apply(console, arguments); // eslint-disable-line no-console
}
};
@ -45,7 +42,7 @@ Logger.prototype.info = function() {
arguments[0] = this.getPrefix() + arguments[0];
if (this.level > Level.Info) {
Logger.saveLast('info', arguments);
console.log.apply(console, arguments);
console.log.apply(console, arguments); // eslint-disable-line no-console
}
};
@ -53,7 +50,7 @@ Logger.prototype.warn = function() {
arguments[0] = this.getPrefix() + arguments[0];
if (this.level > Level.Warn) {
Logger.saveLast('warn', arguments);
console.warn.apply(console, arguments);
console.warn.apply(console, arguments); // eslint-disable-line no-console
}
};
@ -61,7 +58,7 @@ Logger.prototype.error = function() {
arguments[0] = this.getPrefix() + arguments[0];
if (this.level > Level.Error) {
Logger.saveLast('error', arguments);
console.error.apply(console, arguments);
console.error.apply(console, arguments); // eslint-disable-line no-console
}
};

View File

@ -56,8 +56,7 @@ Otp.prototype.next = function(callback) {
}
var data = new Uint8Array(8).buffer;
new DataView(data).setUint32(4, valueForHashing);
var that = this;
this.hmac(data, function(sig, err) {
this.hmac(data, (sig, err) => {
if (!sig) {
logger.error('OTP calculation error', err);
return callback();
@ -65,7 +64,7 @@ Otp.prototype.next = function(callback) {
sig = new DataView(sig);
var offset = sig.getInt8(sig.byteLength - 1) & 0xf;
var pass = (sig.getUint32(offset) & 0x7fffffff).toString();
pass = Otp.leftPad(pass.substr(pass.length - that.digits), that.digits);
pass = Otp.leftPad(pass.substr(pass.length - this.digits), this.digits);
callback(pass, timeLeft);
});
};
@ -77,12 +76,12 @@ Otp.prototype.hmac = function(data, callback) {
var subtle = window.crypto.subtle || window.crypto.webkitSubtle;
var algo = { name: 'HMAC', hash: { name: this.algorithm.replace('SHA', 'SHA-') } };
subtle.importKey('raw', this.key, algo, false, ['sign'])
.then(function(key) {
.then(key => {
subtle.sign(algo, key, data)
.then(function(sig) { callback(sig); })
.catch(function(err) { callback(null, err); });
.then(sig => { callback(sig); })
.catch(err => { callback(null, err); });
})
.catch(function(err) { callback(null, err); });
.catch(err => { callback(null, err); });
};
Otp.prototype.hmacMsCrypto = function(data, callback) {
@ -138,7 +137,7 @@ Otp.parseUrl = function(url) {
}
}
params.type = match[1].toLowerCase();
match[3].split('&').forEach(function(part) {
match[3].split('&').forEach(part => {
var parts = part.split('=', 2);
params[parts[0].toLowerCase()] = decodeURIComponent(parts[1]);
});

View File

@ -29,7 +29,7 @@ var PasswordGenerator = {
return this.generateMac();
}
var ranges = Object.keys(this.charRanges)
.filter(function(r) { return opts[r]; })
.filter(r => opts[r])
.map(function(r) { return this.charRanges[r]; }, this);
if (!ranges.length) {
return '';
@ -92,10 +92,10 @@ var PasswordGenerator = {
var length = 0;
if (password) {
var charRanges = this.charRanges;
password.forEachChar(function(ch) {
password.forEachChar(ch => {
length++;
ch = String.fromCharCode(ch);
_.forEach(charRanges, function(chars, range) {
_.forEach(charRanges, (chars, range) => {
if (chars.indexOf(ch) >= 0) {
opts[range] = true;
}

View File

@ -167,10 +167,8 @@ function getOptions(overrides) {
overrides = overrides || {};
options.length = overrides.length || 16;
options.seed = overrides.seed || Math.random();
options.phoneticSimplicity = overrides.phoneticSimplicity ?
Math.max(overrides.phoneticSimplicity, 1) : 5;
options.compoundSimplicity = overrides.compoundSimplicity ?
Math.max(overrides.compoundSimplicity, 1) : 5;
options.phoneticSimplicity = overrides.phoneticSimplicity ? Math.max(overrides.phoneticSimplicity, 1) : 5;
options.compoundSimplicity = overrides.compoundSimplicity ? Math.max(overrides.compoundSimplicity, 1) : 5;
return options;
}

View File

@ -4,7 +4,7 @@ var StringUtil = {
camelCaseRegex: /\-./g,
camelCase: function(str) {
return str.replace(this.camelCaseRegex, function(match) { return match[1].toUpperCase(); });
return str.replace(this.camelCaseRegex, match => match[1].toUpperCase());
}
};

View File

@ -11,7 +11,7 @@ var ThemeChanger = {
},
setTheme: function(theme) {
_.forEach(document.body.classList, function(cls) {
_.forEach(document.body.classList, cls => {
if (/^th\-/.test(cls)) {
document.body.classList.remove(cls);
}

View File

@ -83,23 +83,21 @@ Tip.prototype.hide = function() {
};
Tip.prototype.mouseenter = function() {
var that = this;
if (this.showTimeout) {
return;
}
this.showTimeout = setTimeout(function() {
that.showTimeout = null;
that.show();
this.showTimeout = setTimeout(() => {
this.showTimeout = null;
this.show();
}, 200);
};
Tip.prototype.mouseleave = function() {
var that = this;
if (this.tipEl) {
that.tipEl.addClass('tip--hide');
this.hideTimeout = setTimeout(function () {
that.hideTimeout = null;
that.hide();
this.tipEl.addClass('tip--hide');
this.hideTimeout = setTimeout(() => {
this.hideTimeout = null;
this.hide();
}, 500);
}
if (this.showTimeout) {
@ -138,7 +136,7 @@ Tip.createTips = function(container) {
if (!Tip.enabled) {
return;
}
container.find('[title]').each(function(ix, el) {
container.find('[title]').each((ix, el) => {
Tip.createTip(el);
});
};
@ -156,7 +154,7 @@ Tip.hideTips = function(container) {
if (!Tip.enabled) {
return;
}
container.find('[data-title]').each(function(ix, el) {
container.find('[data-title]').each((ix, el) => {
Tip.hideTip(el);
});
};

View File

@ -252,9 +252,7 @@ var AppView = Backbone.View.extend({
},
showFileSettings: function(e) {
var menuItem = this.model.menu.filesSection.get('items').find(function(item) {
return item.get('file').cid === e.fileId;
});
var menuItem = this.model.menu.filesSection.get('items').find(item => item.get('file').cid === e.fileId);
if (this.views.settings) {
if (this.views.settings.file === menuItem.get('file')) {
this.showEntries();
@ -280,12 +278,11 @@ var AppView = Backbone.View.extend({
if (this.model.files.hasDirtyFiles()) {
if (Launcher && !Launcher.exitRequested) {
if (!this.exitAlertShown) {
var that = this;
if (this.model.settings.get('autoSave')) {
that.saveAndExit();
this.saveAndExit();
return Launcher.preventExit(e);
}
that.exitAlertShown = true;
this.exitAlertShown = true;
Alerts.yesno({
header: Locale.appUnsavedWarn,
body: Locale.appUnsavedWarnBody,
@ -294,18 +291,18 @@ var AppView = Backbone.View.extend({
{result: 'exit', title: Locale.appExitBtn, error: true},
{result: '', title: Locale.appDontExitBtn}
],
success: function (result) {
success: result => {
if (result === 'save') {
that.saveAndExit();
this.saveAndExit();
} else {
Launcher.exit();
}
},
cancel: function() {
cancel: () => {
Launcher.cancelRestart(false);
},
complete: function () {
that.exitAlertShown = false;
complete: () => {
this.exitAlertShown = false;
}
});
}
@ -363,7 +360,6 @@ var AppView = Backbone.View.extend({
},
lockWorkspace: function(autoInit) {
var that = this;
if (Alerts.alertDisplayed) {
return;
}
@ -382,14 +378,14 @@ var AppView = Backbone.View.extend({
{ result: '', title: Locale.alertCancel }
],
checkbox: Locale.appAutoSave,
success: function(result, autoSaveChecked) {
success: (result, autoSaveChecked) => {
if (result === 'save') {
if (autoSaveChecked) {
that.model.settings.set('autoSave', autoSaveChecked);
this.model.settings.set('autoSave', autoSaveChecked);
}
that.saveAndLock();
this.saveAndLock();
} else if (result === 'discard') {
that.model.closeAllFiles();
this.model.closeAllFiles();
}
}
});
@ -436,7 +432,7 @@ var AppView = Backbone.View.extend({
},
saveAndExit: function() {
this.saveAndLock(function(result) {
this.saveAndLock(result => {
if (result) {
Launcher.exit();
}
@ -444,7 +440,7 @@ var AppView = Backbone.View.extend({
},
closeAllFilesAndShowFirst: function() {
var fileToShow = this.model.files.find(function(file) { return !file.get('demo') && !file.get('created'); });
var fileToShow = this.model.files.find(file => !file.get('demo') && !file.get('created'));
this.model.closeAllFiles();
if (!fileToShow) {
fileToShow = this.model.fileInfos.getLast();

View File

@ -19,10 +19,10 @@ var DetailsAttachmentView = Backbone.View.extend({
switch ((this.model.mimeType || '').split('/')[0]) {
case 'text':
var reader = new FileReader();
reader.addEventListener('loadend', (function() {
reader.addEventListener('loadend', () => {
$('<pre/>').text(reader.result).appendTo(dataEl);
complete();
}).bind(this));
});
reader.readAsText(blob);
return this;
case 'image':

View File

@ -39,13 +39,12 @@ var DetailsAutoTypeView = Backbone.View.extend({
},
seqInput: function(e) {
var that = this;
var el = e.target;
var seq = $.trim(el.value);
AutoType.validate(this.model, seq, function(err) {
AutoType.validate(this.model, seq, err => {
$(el).toggleClass('input--error', !!err);
if (!err) {
that.model.setAutoTypeSeq(seq);
this.model.setAutoTypeSeq(seq);
}
});
},
@ -61,7 +60,7 @@ var DetailsAutoTypeView = Backbone.View.extend({
seqFocus: function(e) {
if (!this.views.hint) {
this.views.hint = new AutoTypeHintView({input: e.target}).render();
this.views.hint.on('remove', (function() {delete this.views.hint; }).bind(this));
this.views.hint.on('remove', () => { delete this.views.hint; });
}
},

View File

@ -25,11 +25,11 @@ var DetailsHistoryView = Backbone.View.extend({
formats: [
{ name: 'ms', round: 1, format: function(d) { return Format.dtStr(d); } },
{ name: 'sec', round: 1000, format: function(d) { return Format.dtStr(d); } },
{ name: 'min', round: 1000*60, format: function(d) { return Format.dtStr(d).replace(':00 ', ' '); } },
{ name: 'hour', round: 1000*60*60, format: function(d) { return Format.dtStr(d).replace(':00', ''); } },
{ name: 'day', round: 1000*60*60*24, format: function(d) { return Format.dStr(d); } },
{ name: 'month', round: 1000*60*60*24*31, format: function(d) { return Format.dStr(d); } },
{ name: 'year', round: 1000*60*60*24*365, format: function(d) { return d.getFullYear(); } }
{ name: 'min', round: 1000 * 60, format: function(d) { return Format.dtStr(d).replace(':00 ', ' '); } },
{ name: 'hour', round: 1000 * 60 * 60, format: function(d) { return Format.dtStr(d).replace(':00', ''); } },
{ name: 'day', round: 1000 * 60 * 60 * 24, format: function(d) { return Format.dStr(d); } },
{ name: 'month', round: 1000 * 60 * 60 * 24 * 31, format: function(d) { return Format.dStr(d); } },
{ name: 'year', round: 1000 * 60 * 60 * 24 * 365, format: function(d) { return d.getFullYear(); } }
],
fieldViews: null,
@ -71,7 +71,7 @@ var DetailsHistoryView = Backbone.View.extend({
},
removeFieldViews: function() {
this.fieldViews.forEach(function(fieldView) { fieldView.remove(); });
this.fieldViews.forEach(fieldView => fieldView.remove());
this.fieldViews = [];
},
@ -103,7 +103,7 @@ var DetailsHistoryView = Backbone.View.extend({
}, this);
if (this.record.attachments.length) {
this.fieldViews.push(new FieldViewReadOnly({ model: { name: 'Attachments', title: Locale.detAttachments,
value: this.record.attachments.map(function(att) { return att.title; }).join(', ') } }));
value: this.record.attachments.map(att => att.title).join(', ') } }));
}
this.fieldViews.forEach(function(fieldView) {
fieldView.setElement(this.bodyEl).render();
@ -135,22 +135,18 @@ var DetailsHistoryView = Backbone.View.extend({
buildTimeline: function() {
var firstRec = this.history[0],
lastRec = this.history[this.history.length - 1];
this.timeline = this.history.map(function(rec) {
return {
pos: (rec.updated - firstRec.updated) / (lastRec.updated - firstRec.updated),
rec: rec
};
}, this);
this.timeline = this.history.map(rec => ({
pos: (rec.updated - firstRec.updated) / (lastRec.updated - firstRec.updated),
rec: rec
}));
var period = lastRec.updated - firstRec.updated;
var format = this.getDateFormat(period);
this.labels = this.getLabels(firstRec.updated.getTime(), lastRec.updated.getTime(), format.round)
.map(function(label) {
return {
pos: (label - firstRec.updated) / (lastRec.updated - firstRec.updated),
val: label,
text: format.format(new Date(label))
};
});
.map(label => ({
pos: (label - firstRec.updated) / (lastRec.updated - firstRec.updated),
val: label,
text: format.format(new Date(label))
}));
},
getDateFormat: function(period) {
@ -187,10 +183,10 @@ var DetailsHistoryView = Backbone.View.extend({
Alerts.yesno({
header: 'Revert to this history state?',
body: 'Your current state will be saved to history.',
success: (function() {
success: () => {
this.model.revertToHistoryState(this.record.entry);
this.closeHistory(true);
}).bind(this)
}
});
},
@ -198,10 +194,10 @@ var DetailsHistoryView = Backbone.View.extend({
Alerts.yesno({
header: 'Delete this history state?',
body: 'You will not be able to restore it.',
success: (function() {
success: () => {
this.model.deleteHistory(this.record.entry);
this.render(this.activeIx);
}).bind(this)
}
});
},
@ -209,10 +205,10 @@ var DetailsHistoryView = Backbone.View.extend({
Alerts.yesno({
header: 'Discard changed made to entry?',
body: 'Unsaved changed will by lost, there will be no way back.',
success: (function() {
success: () => {
this.model.discardUnsaved();
this.closeHistory(true);
}).bind(this)
}
});
}
});

View File

@ -92,7 +92,7 @@ var DetailsView = Backbone.View.extend({
},
removeFieldViews: function() {
this.fieldViews.forEach(function(fieldView) { fieldView.remove(); });
this.fieldViews.forEach(fieldView => fieldView.remove());
this.fieldViews = [];
this.hideFieldCopyTip();
},
@ -235,7 +235,7 @@ var DetailsView = Backbone.View.extend({
var hideEmptyFields = AppSettingsModel.instance.get('hideEmptyFields');
var moreOptions = [];
if (hideEmptyFields) {
this.fieldViews.forEach(function(fieldView) {
this.fieldViews.forEach(fieldView => {
if (fieldView.isHidden()) {
moreOptions.push({value: 'add:' + fieldView.model.name, icon: 'pencil',
text: Locale.detMenuAddField.replace('{}', fieldView.model.title)});
@ -282,7 +282,7 @@ var DetailsView = Backbone.View.extend({
default:
if (e.item.lastIndexOf('add:', 0) === 0) {
var fieldName = e.item.substr(4);
var fieldView = _.find(this.fieldViews, function(f) { return f.model.name === fieldName; });
var fieldView = _.find(this.fieldViews, f => f.model.name === fieldName);
fieldView.show();
fieldView.edit();
}
@ -296,7 +296,7 @@ var DetailsView = Backbone.View.extend({
setSelectedColor: function(color) {
this.$el.find('.details__colors-popup > .details__colors-popup-item').removeClass('details__colors-popup-item--active');
var colorEl = this.$el.find('.details__header-color')[0];
_.forEach(colorEl.classList, function(cls) {
_.forEach(colorEl.classList, cls => {
if (cls.indexOf('color') > 0 && cls.lastIndexOf('details', 0) !== 0) {
colorEl.classList.remove(cls);
}
@ -444,7 +444,7 @@ var DetailsView = Backbone.View.extend({
var tip = new Tip(label, { title: Locale.detCopyHint, placement: 'right' });
tip.show();
this.fieldCopyTip = tip;
setTimeout(function() { tip.hide(); }, Timeouts.AutoHideHint);
setTimeout(() => { tip.hide(); }, Timeouts.AutoHideHint);
},
hideFieldCopyTip: function() {
@ -546,14 +546,13 @@ var DetailsView = Backbone.View.extend({
this.fieldCopyTip = tip;
tip.show();
}
var that = this;
setTimeout(function() {
setTimeout(() => {
if (tip) {
tip.hide();
}
that.fieldCopyTip = null;
this.fieldCopyTip = null;
if (e.source.model.name === '$Password' && AppSettingsModel.instance.get('lockOnCopy')) {
setTimeout(function() {
setTimeout(() => {
Backbone.trigger('lock-workspace');
}, Timeouts.BeforeAutoLock);
}
@ -575,10 +574,10 @@ var DetailsView = Backbone.View.extend({
if (this.dragTimeout) {
clearTimeout(this.dragTimeout);
}
this.dragTimeout = setTimeout((function() {
this.dragTimeout = setTimeout(() => {
this.$el.find('.details').removeClass('details--drag');
this.dragging = false;
}).bind(this), 100);
}, 100);
},
drop: function(e) {
@ -606,9 +605,9 @@ var DetailsView = Backbone.View.extend({
addAttachedFiles: function(files) {
_.forEach(files, function(file) {
var reader = new FileReader();
reader.onload = (function() {
reader.onload = () => {
this.addAttachment(file.name, reader.result);
}).bind(this);
};
reader.readAsArrayBuffer(file);
}, this);
},
@ -742,10 +741,10 @@ var DetailsView = Backbone.View.extend({
header: Locale.detDelFromTrash,
body: Locale.detDelFromTrashBody + ' <p class="muted-color">' + Locale.detDelFromTrashBodyHint + '</p>',
icon: 'minus-circle',
success: (function() {
success: () => {
this.model.deleteFromTrash();
Backbone.trigger('refresh');
}).bind(this)
}
});
},
@ -764,7 +763,7 @@ var DetailsView = Backbone.View.extend({
otpEnterManually: function() {
if (this.model.fields.otp) {
var otpField = this.fieldViews.find(function(f) { return f.model.name === '$otp'; });
var otpField = this.fieldViews.find(f => f.model.name === '$otp');
if (otpField) {
otpField.edit();
}
@ -799,7 +798,7 @@ var DetailsView = Backbone.View.extend({
// AutoType.getActiveWindowTitle(function() {
// console.log(arguments);
// });
AutoType.hideWindow(function() {
AutoType.hideWindow(() => {
AutoType.run(entry);
});
},

View File

@ -36,7 +36,7 @@ var FieldViewAutocomplete = FieldViewText.extend({
updateAutocomplete: function() {
var completions = this.model.getCompletions(this.input.val());
var completionsHtml = completions.map(function(item) {
var completionsHtml = completions.map(item => {
return '<div class="details__field-autocomplete-item">' + _.escape(item) + '</div>';
}).join('');
this.autocomplete.html(completionsHtml);

View File

@ -4,10 +4,10 @@ var FieldView = require('./field-view');
var FieldViewSelect = FieldView.extend({
readonly: true,
renderValue: function(value) {
return '<select>' +
value.map(function(opt) {
value.map(opt => {
return '<option ' + 'value="' + _.escape(opt.id) + '" ' + (opt.selected ? 'selected ' : '') + '>' +
_.escape(opt.value) +
'</option>';
@ -16,11 +16,10 @@ var FieldViewSelect = FieldView.extend({
},
render: function() {
var that = this;
FieldView.prototype.render.call(this);
this.valueEl.addClass('details__field-value--select');
this.valueEl.find('select:first').change(function(e) {
that.triggerChange({ val: e.target.value, field: that.model.name });
this.valueEl.find('select:first').change(e => {
this.triggerChange({ val: e.target.value, field: this.model.name });
});
},

View File

@ -13,10 +13,10 @@ var FieldViewTags = FieldViewText.extend({
valueToTags: function(val) {
var allTags = {};
this.model.tags.forEach(function(tag) {
this.model.tags.forEach(tag => {
allTags[tag.toLowerCase()] = tag;
});
return _.unique(val.split(/\s*[;,:]\s*/).filter(_.identity).map(function (tag) {
return _.unique(val.split(/\s*[;,:]\s*/).filter(_.identity).map(tag => {
return allTags[tag.toLowerCase()] || tag;
}));
},
@ -55,14 +55,14 @@ var FieldViewTags = FieldViewText.extend({
var tags = this.valueToTags(this.input.val());
var last = tags[tags.length - 1];
var isLastPart = last && this.model.tags.indexOf(last) < 0;
return this.model.tags.filter(function(tag) {
return this.model.tags.filter(tag => {
return tags.indexOf(tag) < 0 && (!isLastPart || tag.toLowerCase().indexOf(last.toLowerCase()) >= 0);
});
},
setTags: function() {
var availableTags = this.getAvailableTags();
var tagsHtml = availableTags.map(function(tag) {
var tagsHtml = availableTags.map(tag => {
return '<div class="details__field-autocomplete-item">' + _.escape(tag) + '</div>';
}).join('');
this.tagsAutocomplete.html(tagsHtml);

View File

@ -10,8 +10,8 @@ var Backbone = require('backbone'),
var FieldViewText = FieldView.extend({
renderValue: function(value) {
return value && value.isProtected ? PasswordGenerator.present(value.textLength) :
_.escape(value || '').replace(/\n/g, '<br/>');
return value && value.isProtected ? PasswordGenerator.present(value.textLength)
: _.escape(value || '').replace(/\n/g, '<br/>');
},
getEditValue: function(value) {

View File

@ -56,7 +56,7 @@ var FieldView = Backbone.View.extend({
return;
}
CopyPaste.createHiddenInput(textValue, box);
//CopyPaste.copy(); // maybe Apple will ever support this?
// CopyPaste.copy(); // maybe Apple will ever support this?
return;
}
var copyRes;

View File

@ -62,8 +62,8 @@ var FooterView = Backbone.View.extend({
bodyRect = document.body.getBoundingClientRect(),
right = bodyRect.right - rect.right,
bottom = bodyRect.bottom - rect.top;
var generator = new GeneratorView({ model: { copy: true, pos: { right: right, bottom: bottom } }}).render();
generator.once('remove', (function() { delete this.views.gen; }).bind(this));
var generator = new GeneratorView({ model: { copy: true, pos: { right: right, bottom: bottom } } }).render();
generator.once('remove', () => { delete this.views.gen; });
this.views.gen = generator;
},

View File

@ -21,7 +21,7 @@ var GeneratorView = Backbone.View.extend({
'click .gen__btn-refresh': 'newPass'
},
valuesMap: [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28,30,32,48,64],
valuesMap: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 48, 64],
presets: null,
preset: null,
@ -29,7 +29,7 @@ var GeneratorView = Backbone.View.extend({
initialize: function () {
this.createPresets();
var preset = this.preset;
this.gen = _.clone(_.find(this.presets, function(pr) { return pr.name === preset; }));
this.gen = _.clone(_.find(this.presets, pr => pr.name === preset));
$('body').one('click', this.remove.bind(this));
this.listenTo(Backbone, 'lock-workspace', this.remove.bind(this));
},
@ -131,7 +131,7 @@ var GeneratorView = Backbone.View.extend({
templateChange: function(e) {
var name = e.target.value;
this.preset = name;
var preset = _.find(this.presets, function(t) { return t.name === name; });
var preset = _.find(this.presets, t => t.name === name);
this.gen = _.clone(preset);
this.render();
},

View File

@ -78,13 +78,12 @@ var GrpView = Backbone.View.extend({
},
changeAutoTypeSeq: function(e) {
var that = this;
var el = e.target;
var seq = $.trim(el.value);
AutoType.validate(null, seq, function(err) {
AutoType.validate(null, seq, err => {
$(e.target).toggleClass('input--error', !!err);
if (!err) {
that.model.setAutoTypeSeq(seq);
this.model.setAutoTypeSeq(seq);
}
});
},
@ -92,7 +91,7 @@ var GrpView = Backbone.View.extend({
focusAutoTypeSeq: function(e) {
if (!this.views.hint) {
this.views.hint = new AutoTypeHintView({input: e.target}).render();
this.views.hint.on('remove', (function() {delete this.views.hint; }).bind(this));
this.views.hint.on('remove', () => { delete this.views.hint; });
}
},

View File

@ -58,25 +58,24 @@ var IconSelectView = Backbone.View.extend({
this.downloadingFavicon = true;
this.$el.find('.icon-select__icon-download>i').addClass('fa-spinner fa-spin');
this.$el.find('.icon-select__icon-download').removeClass('icon-select__icon--download-error');
var that = this;
var url = this.getIconUrl(!Launcher); // inside launcher we can load images without CORS
var img = document.createElement('img');
img.crossOrigin = 'Anonymous';
img.src = url;
img.onload = function () {
that.setSpecialImage(img, 'download');
that.$el.find('.icon-select__icon-download img').remove();
that.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
that.$el.find('.icon-select__icon-download').addClass('icon-select__icon--custom-selected').append(img);
that.downloadingFavicon = false;
img.onload = () => {
this.setSpecialImage(img, 'download');
this.$el.find('.icon-select__icon-download img').remove();
this.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
this.$el.find('.icon-select__icon-download').addClass('icon-select__icon--custom-selected').append(img);
this.downloadingFavicon = false;
};
img.onerror = function (e) {
img.onerror = e => {
logger.error('Favicon download error: ' + url, e);
that.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
that.$el.find('.icon-select__icon-download')
this.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
this.$el.find('.icon-select__icon-download')
.removeClass('icon-select__icon--custom-selected')
.addClass('icon-select__icon--download-error');
that.downloadingFavicon = false;
this.downloadingFavicon = false;
};
},
@ -84,7 +83,7 @@ var IconSelectView = Backbone.View.extend({
if (!this.model.url) {
return null;
}
var url = this.model.url.replace(/([^\/:]\/.*)?$/, function(match) { return (match && match[0]) + '/favicon.ico'; });
var url = this.model.url.replace(/([^\/:]\/.*)?$/, match => (match && match[0]) + '/favicon.ico');
if (url.indexOf('://') < 0) {
url = 'http://' + url;
}
@ -99,23 +98,22 @@ var IconSelectView = Backbone.View.extend({
},
iconSelected: function(e) {
var that = this;
var file = e.target.files[0];
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
reader.onload = e => {
var img = document.createElement('img');
img.onload = function() {
that.setSpecialImage(img, 'select');
that.$el.find('.icon-select__icon-select img').remove();
that.$el.find('.icon-select__icon-select').addClass('icon-select__icon--custom-selected').append(img);
img.onload = () => {
this.setSpecialImage(img, 'select');
this.$el.find('.icon-select__icon-select img').remove();
this.$el.find('.icon-select__icon-select').addClass('icon-select__icon--custom-selected').append(img);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
} else {
that.$el.find('.icon-select__icon-select img').remove();
that.$el.find('.icon-select__icon-select').removeClass('icon-select__icon--custom-selected');
this.$el.find('.icon-select__icon-select img').remove();
this.$el.find('.icon-select__icon-select').removeClass('icon-select__icon--custom-selected');
}
},

View File

@ -66,12 +66,12 @@ var KeyChangeView = Backbone.View.extend({
var file = e.target.files[0];
if (file) {
var reader = new FileReader();
reader.onload = (function(e) {
reader.onload = e => {
this.keyFileName = file.name;
this.keyFileData = e.target.result;
this.$el.find('.key-change__keyfile-name').text(': ' + this.keyFileName);
}).bind(this);
reader.onerror = function() {
};
reader.onerror = () => {
Alerts.error({ header: Locale.openFailedRead });
};
reader.readAsArrayBuffer(file);

View File

@ -30,7 +30,6 @@ var ListView = Backbone.View.extend({
itemsEl: null,
tableColumns: [
{ val: 'title', name: 'title', enabled: true },
{ val: 'user', name: 'user', enabled: true },
@ -80,14 +79,14 @@ var ListView = Backbone.View.extend({
var noColor = AppSettingsModel.instance.get('colorfulIcons') ? '' : 'grayscale';
var presenter = new EntryPresenter(this.getDescField(), noColor, this.model.activeEntryId);
var columns = {};
this.tableColumns.forEach(function(col) {
this.tableColumns.forEach(col => {
if (col.enabled) {
columns[col.val] = true;
}
});
presenter.columns = columns;
var itemsHtml = '';
this.items.forEach(function (item) {
this.items.forEach(item => {
presenter.present(item);
itemsHtml += itemTemplate(presenter);
}, this);
@ -207,7 +206,7 @@ var ListView = Backbone.View.extend({
this.throttleSetViewSizeSetting(size);
},
throttleSetViewSizeSetting: _.throttle(function(size) {
throttleSetViewSizeSetting: _.throttle(size => {
AppSettingsModel.instance.set('listViewWidth', size);
}, 1000),
@ -240,13 +239,11 @@ var ListView = Backbone.View.extend({
this.listenTo(view, 'cancel', this.hideOptionsDropdown);
this.listenTo(view, 'select', this.optionsDropdownSelect);
var targetElRect = this.$el.find('.list__table-options')[0].getBoundingClientRect();
var options = this.tableColumns.map(function(col) {
return {
value: col.val,
icon: col.enabled ? 'check-square-o' : 'square-o',
text: Format.capFirst(Locale[col.name])
};
});
var options = this.tableColumns.map(col => ({
value: col.val,
icon: col.enabled ? 'check-square-o' : 'square-o',
text: Format.capFirst(Locale[col.name])
}));
view.render({
position: {
top: targetElRect.bottom,
@ -265,7 +262,7 @@ var ListView = Backbone.View.extend({
},
optionsDropdownSelect: function(e) {
var col = _.find(this.tableColumns, function(c) { return c.val === e.item; });
var col = _.find(this.tableColumns, c => c.val === e.item);
col.enabled = !col.enabled;
e.el.find('i:first').toggleClass('fa-check-square-o fa-square-o');
this.render();

View File

@ -21,7 +21,7 @@ var MenuItemView = Backbone.View.extend({
'dragstart': 'dragstart',
'dragover': 'dragover',
'dragleave': 'dragleave',
'drop' : 'drop'
'drop': 'drop'
},
iconEl: null,
@ -66,7 +66,7 @@ var MenuItemView = Backbone.View.extend({
this.itemViews.push(new MenuItemView({el: this.$el, model: item}).render());
},
remove : function() {
remove: function() {
this.removeInnerViews();
var shortcut = this.model.get('shortcut');
if (shortcut) {
@ -79,7 +79,7 @@ var MenuItemView = Backbone.View.extend({
},
removeInnerViews: function() {
this.itemViews.forEach(function(itemView) { itemView.remove(); });
this.itemViews.forEach(itemView => itemView.remove());
this.itemViews = [];
},
@ -137,7 +137,7 @@ var MenuItemView = Backbone.View.extend({
var options = this.model.get('options');
var value = $(e.target).data('value');
if (options && options.length) {
var option = options.find(function(op) { return op.get('value') === value; });
var option = options.find(op => op.get('value') === value);
if (option) {
Backbone.trigger('menu-select', { item: this.model, option: option });
}

View File

@ -53,7 +53,7 @@ var MenuSectionView = Backbone.View.extend({
this.pageResized();
},
remove : function() {
remove: function() {
if (this.scroll) {
this.scroll.dispose();
}
@ -62,7 +62,7 @@ var MenuSectionView = Backbone.View.extend({
},
removeInnerViews: function() {
this.itemViews.forEach(function(itemView) { itemView.remove(); });
this.itemViews.forEach(itemView => itemView.remove());
this.itemViews = [];
},
@ -75,7 +75,7 @@ var MenuSectionView = Backbone.View.extend({
this.saveViewHeight(size);
},
saveViewHeight: _.throttle(function(size) {
saveViewHeight: _.throttle(size => {
AppSettingsModel.instance.set('tagsViewHeight', size);
}, 1000)
});

View File

@ -22,7 +22,7 @@ var MenuView = Backbone.View.extend({
},
remove: function() {
this.sectionViews.forEach(function(sectionView) { sectionView.remove(); });
this.sectionViews.forEach(sectionView => sectionView.remove());
this.sectionViews = [];
Backbone.View.prototype.remove.apply(this, arguments);
},
@ -52,7 +52,7 @@ var MenuView = Backbone.View.extend({
this.render();
},
viewResized: _.throttle(function(size) {
viewResized: _.throttle(size => {
AppSettingsModel.instance.set('menuViewWidth', size);
}, 1000),

View File

@ -24,7 +24,7 @@ var ModalView = Backbone.View.extend({
KeyHandler.setModal(true);
},
remove : function() {
remove: function() {
KeyHandler.offKey(Keys.DOM_VK_ESCAPE, this.escPressed, this);
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.enterPressed, this);
KeyHandler.setModal(false);
@ -37,7 +37,7 @@ var ModalView = Backbone.View.extend({
parent.append(this.$el);
var el = this.$el;
el.addClass('modal--hidden');
setTimeout(function() {
setTimeout(() => {
el.removeClass('modal--hidden');
}, 20);
return this;

View File

@ -65,13 +65,13 @@ var OpenView = Backbone.View.extend({
clearTimeout(this.dragTimeout);
}
var storageProviders = [];
Object.keys(Storage).forEach(function(name) {
Object.keys(Storage).forEach(name => {
var prv = Storage[name];
if (!prv.system && prv.enabled) {
storageProviders.push(prv);
}
});
storageProviders.sort(function(x, y) { return (x.uipos || Infinity) - (y.uipos || Infinity); });
storageProviders.sort((x, y) => (x.uipos || Infinity) - (y.uipos || Infinity));
this.renderTemplate({
lastOpenFiles: this.getLastOpenFiles(),
canOpenKeyFromDropbox: DropboxLink.canChooseFile() && Storage.dropbox.enabled,
@ -90,7 +90,7 @@ var OpenView = Backbone.View.extend({
},
getLastOpenFiles: function() {
return this.model.fileInfos.map(function(f) {
return this.model.fileInfos.map(f => {
var icon = 'file-text';
var storage = Storage[f.get('storage')];
if (storage && storage.icon) {
@ -117,7 +117,6 @@ var OpenView = Backbone.View.extend({
if (this.model.settings.get('skipOpenLocalWarn')) {
return;
}
var that = this;
Alerts.alert({
header: Locale.openLocalFile,
body: Locale.openLocalFileBody,
@ -129,10 +128,10 @@ var OpenView = Backbone.View.extend({
click: '',
esc: '',
enter: '',
success: function(res) {
that.focusInput();
success: res => {
this.focusInput();
if (res === 'skip') {
that.model.settings.set('skipOpenLocalWarn', true);
this.model.settings.set('skipOpenLocalWarn', true);
}
}
});
@ -141,17 +140,17 @@ var OpenView = Backbone.View.extend({
fileSelected: function(e) {
var file = e.target.files[0];
if (file) {
this.processFile(file, (function(success) {
this.processFile(file, success => {
if (success && !file.path && this.reading === 'fileData') {
this.showLocalFileAlert();
}
}).bind(this));
});
}
},
processFile: function(file, complete) {
var reader = new FileReader();
reader.onload = (function(e) {
reader.onload = e => {
var success = false;
switch (this.reading) {
case 'fileData':
@ -191,13 +190,13 @@ var OpenView = Backbone.View.extend({
if (complete) {
complete(success);
}
}).bind(this);
reader.onerror = (function() {
};
reader.onerror = () => {
Alerts.error({ header: Locale.openFailedRead });
if (complete) {
complete(false);
}
}).bind(this);
};
if (this.reading === 'fileXml') {
reader.readAsText(file);
} else {
@ -238,7 +237,7 @@ var OpenView = Backbone.View.extend({
setFile: function(file, keyFile, fileReadyCallback) {
this.reading = 'fileData';
this.processFile(file, (function(success) {
this.processFile(file, success => {
if (success && keyFile) {
this.reading = 'keyFileData';
this.processFile(keyFile);
@ -246,7 +245,7 @@ var OpenView = Backbone.View.extend({
if (success && typeof fileReadyCallback === 'function') {
fileReadyCallback();
}
}).bind(this));
});
},
openFile: function() {
@ -280,14 +279,14 @@ var OpenView = Backbone.View.extend({
openKeyFileFromDropbox: function() {
if (!this.busy) {
DropboxLink.chooseFile((function(err, res) {
DropboxLink.chooseFile((err, res) => {
if (err) {
return;
}
this.params.keyFileData = res.data;
this.params.keyFileName = res.name;
this.displayOpenKeyFile();
}).bind(this));
});
}
},
@ -305,7 +304,6 @@ var OpenView = Backbone.View.extend({
if ($(e.target).is('.open__last-item-icon-del')) {
var fileInfo = this.model.fileInfos.get(id);
if (!fileInfo.get('storage') || fileInfo.get('modified')) {
var that = this;
Alerts.yesno({
header: Locale.openRemoveLastQuestion,
body: fileInfo.get('modified') ? Locale.openRemoveLastQuestionModBody : Locale.openRemoveLastQuestionBody,
@ -313,8 +311,8 @@ var OpenView = Backbone.View.extend({
{result: 'yes', title: Locale.alertYes},
{result: '', title: Locale.alertNo}
],
success: function() {
that.removeFile(id);
success: () => {
this.removeFile(id);
}
});
return;
@ -378,9 +376,9 @@ var OpenView = Backbone.View.extend({
if (this.dragTimeout) {
clearTimeout(this.dragTimeout);
}
this.dragTimeout = setTimeout((function() {
this.dragTimeout = setTimeout(() => {
this.$el.removeClass('open--drag');
}).bind(this), 100);
}, 100);
},
drop: function(e) {
@ -394,8 +392,8 @@ var OpenView = Backbone.View.extend({
this.closeConfig();
this.$el.removeClass('open--drag');
var files = e.target.files || e.originalEvent.dataTransfer.files;
var dataFile = _.find(files, function(file) { return file.name.split('.').pop().toLowerCase() === 'kdbx'; });
var keyFile = _.find(files, function(file) { return file.name.split('.').pop().toLowerCase() === 'key'; });
var dataFile = _.find(files, file => file.name.split('.').pop().toLowerCase() === 'kdbx');
var keyFile = _.find(files, file => file.name.split('.').pop().toLowerCase() === 'key');
if (dataFile) {
this.setFile(dataFile, keyFile,
dataFile.path ? null : this.showLocalFileAlert.bind(this));
@ -475,7 +473,7 @@ var OpenView = Backbone.View.extend({
if (err.code !== 'InvalidKey') {
Alerts.error({
header: Locale.openError,
body: Locale.openErrorDescription + '<pre class="modal__pre">' + _.escape(err.toString()) +'</pre>'
body: Locale.openErrorDescription + '<pre class="modal__pre">' + _.escape(err.toString()) + '</pre>'
});
}
} else {
@ -528,19 +526,18 @@ var OpenView = Backbone.View.extend({
}
this.closeConfig();
var icon = this.$el.find('.open__icon-storage[data-storage=' + storage.name + ']');
var that = this;
that.busy = true;
this.busy = true;
icon.toggleClass('flip3d', true);
storage.list(function(err, files, dir) {
storage.list((err, files, dir) => {
icon.toggleClass('flip3d', false);
that.busy = false;
this.busy = false;
if (err || !files) {
return;
}
var buttons = [];
var allStorageFiles = {};
files.forEach(function (file) {
files.forEach(file => {
var fileName = UrlUtil.getDataFileName(file.name);
buttons.push({result: file.path, title: fileName});
allStorageFiles[file.path] = file;
@ -564,8 +561,8 @@ var OpenView = Backbone.View.extend({
buttons: buttons,
esc: '',
click: '',
success: function (file) {
that.openStorageFile(storage, allStorageFiles[file]);
success: file => {
this.openStorageFile(storage, allStorageFiles[file]);
}
});
});

View File

@ -47,13 +47,13 @@ var SettingsFileView = Backbone.View.extend({
render: function() {
var storageProviders = [];
var fileStorage = this.model.get('storage');
Object.keys(Storage).forEach(function(name) {
Object.keys(Storage).forEach(name => {
var prv = Storage[name];
if (!prv.system && prv.enabled && name !== fileStorage) {
storageProviders.push(prv);
}
});
storageProviders.sort(function(x, y) { return (x.uipos || Infinity) - (y.uipos || Infinity); });
storageProviders.sort((x, y) => (x.uipos || Infinity) - (y.uipos || Infinity));
this.renderTemplate({
cmd: FeatureDetector.actionShortcutSymbol(true),
supportFiles: !!Launcher,
@ -106,15 +106,14 @@ var SettingsFileView = Backbone.View.extend({
validatePassword: function(continueCallback) {
if (!this.model.get('passwordLength')) {
var that = this;
Alerts.yesno({
header: Locale.setFileEmptyPass,
body: Locale.setFileEmptyPassBody,
success: function() {
success: () => {
continueCallback();
},
cancel: function() {
that.$el.find('#settings__file-master-pass').focus();
cancel: () => {
this.$el.find('#settings__file-master-pass').focus();
}
});
return false;
@ -123,15 +122,14 @@ var SettingsFileView = Backbone.View.extend({
},
save: function(arg) {
var that = this;
if (!arg) {
arg = {};
}
arg.startedByUser = true;
if (!arg.skipValidation) {
var isValid = this.validatePassword(function() {
var isValid = this.validatePassword(() => {
arg.skipValidation = true;
that.save(arg);
this.save(arg);
});
if (!isValid) {
return;
@ -153,19 +151,18 @@ var SettingsFileView = Backbone.View.extend({
return;
}
var fileName = this.model.get('name') + '.kdbx';
var that = this;
if (Launcher && !this.model.get('storage')) {
Launcher.getSaveFileName(fileName, function (path) {
Launcher.getSaveFileName(fileName, path => {
if (path) {
that.save({storage: 'file', path: path});
this.save({storage: 'file', path: path});
}
});
} else {
this.model.getData(function (data) {
this.model.getData(data => {
if (Launcher) {
Launcher.getSaveFileName(fileName, function (path) {
Launcher.getSaveFileName(fileName, path => {
if (path) {
Storage.file.save(path, data, function (err) {
Storage.file.save(path, data, err => {
if (err) {
Alerts.error({
header: Locale.setFileSaveError,
@ -184,10 +181,10 @@ var SettingsFileView = Backbone.View.extend({
},
saveToXml: function() {
this.model.getXml((function(xml) {
this.model.getXml(xml => {
var blob = new Blob([xml], {type: 'text/xml'});
FileSaver.saveAs(blob, this.model.get('name') + '.xml');
}).bind(this));
});
},
saveToStorage: function(e) {
@ -199,9 +196,8 @@ var SettingsFileView = Backbone.View.extend({
if (!storage) {
return;
}
var that = this;
if (that.model.get('storage') === storageName) {
that.save();
if (this.model.get('storage') === storageName) {
this.save();
} else {
if (!storage.list) {
if (storage.name === 'webdav') {
@ -215,32 +211,32 @@ var SettingsFileView = Backbone.View.extend({
}
return;
}
that.model.set('syncing', true);
storage.list(function(err, files) {
that.model.set('syncing', false);
this.model.set('syncing', true);
storage.list((err, files) => {
this.model.set('syncing', false);
if (err) {
return;
}
var expName = that.model.get('name').toLowerCase();
var existingFile = _.find(files, function(file) {
var expName = this.model.get('name').toLowerCase();
var existingFile = _.find(files, file => {
return UrlUtil.getDataFileName(file.name).toLowerCase() === expName;
});
if (existingFile) {
Alerts.yesno({
header: Locale.setFileAlreadyExists,
body: Locale.setFileAlreadyExistsBody.replace('{}', that.model.escape('name')),
success: function() {
that.model.set('syncing', true);
storage.remove(existingFile.path, function(err) {
that.model.set('syncing', false);
body: Locale.setFileAlreadyExistsBody.replace('{}', this.model.escape('name')),
success: () => {
this.model.set('syncing', true);
storage.remove(existingFile.path, err => {
this.model.set('syncing', false);
if (!err) {
that.save({storage: storageName});
this.save({storage: storageName});
}
});
}
});
} else {
that.save({storage: storageName});
this.save({storage: storageName});
}
});
}
@ -248,7 +244,6 @@ var SettingsFileView = Backbone.View.extend({
closeFile: function() {
if (this.model.get('modified')) {
var that = this;
Alerts.yesno({
header: Locale.setFileUnsaved,
body: Locale.setFileUnsavedBody,
@ -256,9 +251,9 @@ var SettingsFileView = Backbone.View.extend({
{result: 'close', title: Locale.setFileCloseNoSave, error: true},
{result: '', title: Locale.setFileDontClose}
],
success: function(result) {
success: result => {
if (result === 'close') {
that.closeFileNoCheck();
this.closeFileNoCheck();
}
}
});
@ -309,11 +304,11 @@ var SettingsFileView = Backbone.View.extend({
fileSelected: function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = (function(e) {
reader.onload = e => {
var res = e.target.result;
this.model.setKeyFile(res, file.name);
this.renderKeyFileSelect();
}).bind(this);
};
reader.readAsArrayBuffer(file);
},

View File

@ -51,7 +51,7 @@ var SettingsGeneralView = Backbone.View.extend({
sd: Locale.setGenThemeSd,
sl: Locale.setGenThemeSl,
wh: Locale.setGenThemeWh,
hc: Locale.setGenThemeHc,
hc: Locale.setGenThemeHc
},
initialize: function() {
@ -151,20 +151,18 @@ var SettingsGeneralView = Backbone.View.extend({
getStorageProviders: function() {
var storageProviders = [];
Object.keys(Storage).forEach(function(name) {
Object.keys(Storage).forEach(name => {
var prv = Storage[name];
if (!prv.system) {
storageProviders.push(prv);
}
});
storageProviders.sort(function(x, y) { return (x.uipos || Infinity) - (y.uipos || Infinity); });
return storageProviders.map(function(sp) {
return {
name: sp.name,
enabled: sp.enabled,
hasConfig: sp.getSettingsConfig
};
});
storageProviders.sort((x, y) => (x.uipos || Infinity) - (y.uipos || Infinity));
return storageProviders.map(sp => ({
name: sp.name,
enabled: sp.enabled,
hasConfig: sp.getSettingsConfig
}));
},
changeTheme: function(e) {
@ -252,7 +250,7 @@ var SettingsGeneralView = Backbone.View.extend({
},
installFoundUpdate: function() {
Updater.update(true, function() {
Updater.update(true, () => {
Launcher.requestRestart();
});
},

View File

@ -8,12 +8,10 @@ var SettingsLogView = Backbone.View.extend({
template: require('templates/settings/settings-logs-view.hbs'),
render: function() {
var logs = Logger.getLast().map(function(item) {
return {
level: item.level,
msg: '[' + Format.padStr(item.level.toUpperCase(), 5) + '] ' + item.args.join(' ')
};
});
var logs = Logger.getLast().map(item => ({
level: item.level,
msg: '[' + Format.padStr(item.level.toUpperCase(), 5) + '] ' + item.args.join(' ')
}));
this.renderTemplate({ logs: logs });
return this;
}

View File

@ -16,7 +16,7 @@ var SettingsView = Backbone.View.extend({
initialize: function () {
this.listenTo(Backbone, 'set-page', this.setPage);
this.views = { };
this.views = { };
KeyHandler.onKey(Keys.DOM_VK_ESCAPE, this.returnToApp, this);
},

View File

@ -40,7 +40,7 @@ var TagView = Backbone.View.extend({
Alerts.error({ header: Locale.tagBadName, body: Locale.tagBadNameBody });
return;
}
if (this.appModel.tags.some(function(t) { return t.toLowerCase() === title.toLowerCase(); })) {
if (this.appModel.tags.some(t => t.toLowerCase() === title.toLowerCase())) {
Alerts.error({ header: Locale.tagExists, body: Locale.tagExistsBody });
return;
}
@ -50,12 +50,11 @@ var TagView = Backbone.View.extend({
moveToTrash: function() {
this.title = null;
var that = this;
Alerts.yesno({
header: Locale.tagTrashQuestion,
body: Locale.tagTrashQuestionBody,
success: function() {
that.appModel.renameTag(that.model.get('title'), undefined);
success: () => {
this.appModel.renameTag(this.model.get('title'), undefined);
Backbone.trigger('select-all');
}
});

View File

@ -1,8 +1,5 @@
'use strict';
/* jshint node:true */
/* jshint browser:false */
var electron = require('electron'),
app = electron.app,
path = require('path'),
@ -10,7 +7,7 @@ var electron = require('electron'),
var mainWindow = null,
appIcon = null,
openFile = process.argv.filter(function (arg) { return /\.kdbx$/i.test(arg); })[0],
openFile = process.argv.filter(arg => /\.kdbx$/i.test(arg))[0],
ready = false,
restartPending = false,
htmlPath = path.join(__dirname, 'index.html'),
@ -18,13 +15,13 @@ var mainWindow = null,
updateMainWindowPositionTimeout = null,
windowPositionFileName = path.join(app.getPath('userData'), 'window-position.json');
process.argv.forEach(function (arg) {
process.argv.forEach(arg => {
if (arg.lastIndexOf('--htmlpath=', 0) === 0) {
htmlPath = path.resolve(arg.replace('--htmlpath=', ''), 'index.html');
}
});
app.on('window-all-closed', function () {
app.on('window-all-closed', () => {
if (restartPending) {
// unbind all handlers, load new app.js module and pass control to it
electron.globalShortcut.unregisterAll();
@ -42,32 +39,32 @@ app.on('window-all-closed', function () {
}
}
});
app.on('ready', function () {
app.on('ready', () => {
if (!checkSingleInstance()) {
setAppOptions();
createMainWindow();
setGlobalShortcuts();
}
});
app.on('open-file', function (e, path) {
app.on('open-file', (e, path) => {
e.preventDefault();
openFile = path;
notifyOpenFile();
});
app.on('activate', function () {
app.on('activate', () => {
if (process.platform === 'darwin') {
if (!mainWindow) {
createMainWindow();
}
}
});
app.on('will-quit', function () {
app.on('will-quit', () => {
electron.globalShortcut.unregisterAll();
});
app.restartApp = function () {
restartPending = true;
mainWindow.close();
setTimeout(function () {
setTimeout(() => {
restartPending = false;
}, 1000);
};
@ -93,7 +90,7 @@ app.getMainWindow = function () {
};
function checkSingleInstance() {
var shouldQuit = app.makeSingleInstance(function(/*commandLine, workingDirectory*/) {
var shouldQuit = app.makeSingleInstance((/* commandLine, workingDirectory */) => {
restoreMainWindow();
});
@ -115,8 +112,8 @@ function createMainWindow() {
});
setMenu();
mainWindow.loadURL('file://' + htmlPath);
mainWindow.webContents.on('dom-ready', function() {
setTimeout(function() {
mainWindow.webContents.on('dom-ready', () => {
setTimeout(() => {
mainWindow.show();
ready = true;
notifyOpenFile();
@ -125,11 +122,11 @@ function createMainWindow() {
mainWindow.on('resize', delaySaveMainWindowPosition);
mainWindow.on('move', delaySaveMainWindowPosition);
mainWindow.on('close', updateMainWindowPositionIfPending);
mainWindow.on('closed', function() {
mainWindow.on('closed', () => {
mainWindow = null;
saveMainWindowPosition();
});
mainWindow.on('minimize', function() {
mainWindow.on('minimize', () => {
emitBackboneEvent('launcher-minimize');
});
restoreMainWindowPosition();
@ -199,7 +196,7 @@ function saveMainWindowPosition() {
}
function restoreMainWindowPosition() {
fs.readFile(windowPositionFileName, 'utf8', function(err, data) {
fs.readFile(windowPositionFileName, 'utf8', (e, data) => {
if (data) {
mainWindowPosition = JSON.parse(data);
if (mainWindow && mainWindowPosition) {
@ -275,11 +272,11 @@ function setGlobalShortcuts() {
U: 'copy-url',
T: 'auto-type'
};
Object.keys(shortcuts).forEach(function(key) {
Object.keys(shortcuts).forEach(key => {
var shortcut = shortcutModifiers + key;
var eventName = shortcuts[key];
try {
electron.globalShortcut.register(shortcut, function () {
electron.globalShortcut.register(shortcut, () => {
emitBackboneEvent(eventName);
});
} catch (e) {}

View File

@ -8,9 +8,6 @@
'use strict';
/* jshint node:true */
/* jshint browser:false */
var app = require('electron').app,
path = require('path'),
fs = require('fs');
@ -34,9 +31,8 @@ if (fs.existsSync(appPathUserData)) {
break;
}
}
}
catch (e) {
console.error('Error reading user file version', e);
} catch (e) {
console.error('Error reading user file version', e); // eslint-disable-line no-console
}
}

View File

@ -24,7 +24,7 @@ module.exports = function (grunt) {
cmd: executable,
args: args,
opts: {stdio: 'inherit'}
}, function (error, result, code) {
}, (error, result, code) => {
if (error) {
return grunt.warn('NSIS error: ' + error);
}

View File

@ -11,10 +11,10 @@ module.exports = function (grunt) {
var expFiles = this.options().expected;
var publicKey = fs.readFileSync(this.options().publicKey, 'binary');
var zipFileData = fs.readFileSync(this.options().file);
zip.on('error', function(err) {
zip.on('error', err => {
grunt.warn(err);
});
zip.on('ready', function() {
zip.on('ready', () => {
var valid = true;
if (!zip.comment) {
grunt.warn('No comment in ZIP');
@ -24,7 +24,7 @@ module.exports = function (grunt) {
grunt.warn('Bad comment length in ZIP');
return;
}
var verify = crypto.createVerify('RSA-SHA256');
var verify = crypto.createVerify('RSA-SHA256');
verify.write(zipFileData.slice(0, zip.centralDirectory.headerOffset + 22));
verify.end();
var signature = new Buffer(zip.comment, 'hex');
@ -32,7 +32,7 @@ module.exports = function (grunt) {
grunt.warn('Invalid ZIP signature');
return;
}
expFiles.forEach(function(entry) {
expFiles.forEach(entry => {
try {
if (!zip.entryDataSync(entry)) {
grunt.warn('Corrupted entry in desktop update archive: ' + entry);

475
npm-shrinkwrap.json generated
View File

@ -29,6 +29,11 @@
"from": "acorn@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.2.0.tgz"
},
"acorn-jsx": {
"version": "3.0.1",
"from": "acorn-jsx@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz"
},
"align-text": {
"version": "0.1.4",
"from": "align-text@>=0.1.3 <0.2.0",
@ -49,6 +54,11 @@
"from": "ansi@>=0.3.1 <0.4.0",
"resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz"
},
"ansi-escapes": {
"version": "1.4.0",
"from": "ansi-escapes@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz"
},
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@>=2.0.0 <3.0.0",
@ -718,6 +728,16 @@
"from": "bytes@2.2.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz"
},
"caller-path": {
"version": "0.1.0",
"from": "caller-path@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz"
},
"callsites": {
"version": "0.2.0",
"from": "callsites@>=0.2.0 <0.3.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz"
},
"camel-case": {
"version": "3.0.0",
"from": "camel-case@>=3.0.0 <4.0.0",
@ -814,22 +834,15 @@
}
}
},
"cli": {
"version": "0.6.6",
"from": "cli@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/cli/-/cli-0.6.6.tgz",
"dependencies": {
"glob": {
"version": "3.2.11",
"from": "glob@>=3.2.1 <3.3.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz"
},
"minimatch": {
"version": "0.3.0",
"from": "minimatch@>=0.3.0 <0.4.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz"
}
}
"cli-cursor": {
"version": "1.0.2",
"from": "cli-cursor@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz"
},
"cli-width": {
"version": "2.1.0",
"from": "cli-width@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz"
},
"cliui": {
"version": "3.2.0",
@ -1155,11 +1168,21 @@
"from": "deep-extend@>=0.4.1 <0.5.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz"
},
"deep-is": {
"version": "0.1.3",
"from": "deep-is@>=0.1.3 <0.2.0",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
},
"defined": {
"version": "1.0.0",
"from": "defined@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz"
},
"del": {
"version": "2.2.1",
"from": "del@>=2.0.2 <3.0.0",
"resolved": "https://registry.npmjs.org/del/-/del-2.2.1.tgz"
},
"delayed-stream": {
"version": "0.0.5",
"from": "delayed-stream@0.0.5",
@ -1202,15 +1225,20 @@
"from": "diff@>=2.0.2 <3.0.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-2.2.2.tgz"
},
"dom-serializer": {
"version": "0.1.0",
"from": "dom-serializer@>=0.0.0 <1.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"doctrine": {
"version": "1.2.2",
"from": "doctrine@>=1.2.2 <2.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.2.2.tgz",
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"from": "domelementtype@>=1.1.1 <1.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz"
"esutils": {
"version": "1.1.6",
"from": "esutils@>=1.1.6 <2.0.0",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz"
},
"isarray": {
"version": "1.0.0",
"from": "isarray@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
}
}
},
@ -1219,21 +1247,6 @@
"from": "domain-browser@>=1.1.1 <2.0.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz"
},
"domelementtype": {
"version": "1.3.0",
"from": "domelementtype@>=1.3.0 <2.0.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz"
},
"domhandler": {
"version": "2.3.0",
"from": "domhandler@>=2.3.0 <3.0.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz"
},
"domutils": {
"version": "1.5.1",
"from": "domutils@>=1.5.1 <2.0.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz"
},
"dot-case": {
"version": "2.1.0",
"from": "dot-case@>=2.1.0 <3.0.0",
@ -1320,11 +1333,6 @@
}
}
},
"entities": {
"version": "1.1.1",
"from": "entities@>=1.1.1 <2.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz"
},
"errno": {
"version": "0.1.4",
"from": "errno@>=0.1.3 <0.2.0",
@ -1345,11 +1353,33 @@
"from": "es6-iterator@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz"
},
"es6-map": {
"version": "0.1.4",
"from": "es6-map@>=0.1.3 <0.2.0",
"resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.4.tgz",
"dependencies": {
"es6-symbol": {
"version": "3.1.0",
"from": "es6-symbol@>=3.1.0 <3.2.0",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz"
}
}
},
"es6-set": {
"version": "0.1.4",
"from": "es6-set@>=0.1.3 <0.2.0",
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.4.tgz"
},
"es6-symbol": {
"version": "3.0.2",
"from": "es6-symbol@>=3.0.2 <3.1.0",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.0.2.tgz"
},
"es6-weak-map": {
"version": "2.0.1",
"from": "es6-weak-map@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz"
},
"escape-html": {
"version": "1.0.3",
"from": "escape-html@>=1.0.3 <1.1.0",
@ -1360,16 +1390,115 @@
"from": "escape-string-regexp@>=1.0.2 <2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
},
"escope": {
"version": "3.6.0",
"from": "escope@>=3.6.0 <4.0.0",
"resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz"
},
"eslint": {
"version": "3.1.0",
"from": "eslint@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-3.1.0.tgz",
"dependencies": {
"chalk": {
"version": "1.1.3",
"from": "chalk@>=1.1.3 <2.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
},
"glob": {
"version": "7.0.5",
"from": "glob@>=7.0.3 <8.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz"
},
"globals": {
"version": "9.9.0",
"from": "globals@>=9.2.0 <10.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-9.9.0.tgz"
},
"lodash": {
"version": "4.13.1",
"from": "lodash@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz"
},
"minimatch": {
"version": "3.0.2",
"from": "minimatch@^3.0.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz"
},
"strip-bom": {
"version": "3.0.0",
"from": "strip-bom@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
},
"supports-color": {
"version": "2.0.0",
"from": "supports-color@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
},
"user-home": {
"version": "2.0.0",
"from": "user-home@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz"
}
}
},
"eslint-config-standard": {
"version": "5.3.5",
"from": "eslint-config-standard@latest",
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-5.3.5.tgz"
},
"eslint-plugin-promise": {
"version": "2.0.0",
"from": "eslint-plugin-promise@latest",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-2.0.0.tgz"
},
"eslint-plugin-standard": {
"version": "2.0.0",
"from": "eslint-plugin-standard@latest",
"resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-2.0.0.tgz"
},
"espree": {
"version": "3.1.6",
"from": "espree@>=3.1.6 <4.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.1.6.tgz"
},
"esprima": {
"version": "2.7.2",
"from": "esprima@>=2.6.0 <3.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.2.tgz"
},
"esrecurse": {
"version": "4.1.0",
"from": "esrecurse@>=4.1.0 <5.0.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz",
"dependencies": {
"estraverse": {
"version": "4.1.1",
"from": "estraverse@>=4.1.0 <4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz"
}
}
},
"estraverse": {
"version": "4.2.0",
"from": "estraverse@>=4.2.0 <5.0.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz"
},
"esutils": {
"version": "2.0.2",
"from": "esutils@>=2.0.2 <3.0.0",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"
},
"etag": {
"version": "1.7.0",
"from": "etag@>=1.7.0 <1.8.0",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz"
},
"event-emitter": {
"version": "0.3.4",
"from": "event-emitter@>=0.3.4 <0.4.0",
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz"
},
"eventemitter2": {
"version": "0.4.14",
"from": "eventemitter2@>=0.4.13 <0.5.0",
@ -1400,6 +1529,11 @@
"from": "exit@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
},
"exit-hook": {
"version": "1.1.1",
"from": "exit-hook@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz"
},
"expand-brackets": {
"version": "0.1.5",
"from": "expand-brackets@>=0.1.4 <0.2.0",
@ -1491,6 +1625,11 @@
"from": "extsprintf@1.0.2",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
},
"fast-levenshtein": {
"version": "1.1.3",
"from": "fast-levenshtein@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.3.tgz"
},
"fastparse": {
"version": "1.1.1",
"from": "fastparse@>=1.0.0 <2.0.0",
@ -1511,6 +1650,11 @@
"from": "figures@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.5.0.tgz"
},
"file-entry-cache": {
"version": "1.2.4",
"from": "file-entry-cache@>=1.1.1 <2.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.2.4.tgz"
},
"file-loader": {
"version": "0.8.5",
"from": "file-loader@>=0.8.1 <0.9.0",
@ -1560,6 +1704,11 @@
}
}
},
"flat-cache": {
"version": "1.0.10",
"from": "flat-cache@>=1.0.9 <2.0.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.0.10.tgz"
},
"flatten": {
"version": "1.0.2",
"from": "flatten@1.0.2",
@ -2333,6 +2482,23 @@
"from": "globals@>=8.3.0 <9.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz"
},
"globby": {
"version": "5.0.0",
"from": "globby@>=5.0.0 <6.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"dependencies": {
"glob": {
"version": "7.0.5",
"from": "glob@^7.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz"
},
"minimatch": {
"version": "3.0.2",
"from": "minimatch@>=3.0.2 <4.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz"
}
}
},
"globule": {
"version": "0.2.0",
"from": "globule@>=0.2.0 <0.3.0",
@ -2482,11 +2648,6 @@
}
}
},
"grunt-contrib-jshint": {
"version": "1.0.0",
"from": "grunt-contrib-jshint@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.0.0.tgz"
},
"grunt-contrib-uglify": {
"version": "1.0.1",
"from": "grunt-contrib-uglify@>=1.0.1 <2.0.0",
@ -2531,6 +2692,11 @@
}
}
},
"grunt-eslint": {
"version": "19.0.0",
"from": "grunt-eslint@latest",
"resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-19.0.0.tgz"
},
"grunt-gitinfo": {
"version": "0.1.8",
"from": "grunt-gitinfo@>=0.1.7 <0.2.0",
@ -2829,11 +2995,21 @@
"from": "ieee754@>=1.1.4 <2.0.0",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.6.tgz"
},
"ignore": {
"version": "3.1.3",
"from": "ignore@>=3.1.2 <4.0.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.1.3.tgz"
},
"image-size": {
"version": "0.5.0",
"from": "image-size@>=0.5.0 <0.6.0",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.0.tgz"
},
"imurmurhash": {
"version": "0.1.4",
"from": "imurmurhash@>=0.1.4 <0.2.0",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
},
"in-publish": {
"version": "2.0.0",
"from": "in-publish@>=2.0.0 <3.0.0",
@ -2869,6 +3045,18 @@
"from": "ini@>=1.3.0 <1.4.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz"
},
"inquirer": {
"version": "0.12.0",
"from": "inquirer@>=0.12.0 <0.13.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
"dependencies": {
"lodash": {
"version": "4.13.1",
"from": "lodash@^4.3.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz"
}
}
},
"interpret": {
"version": "0.6.6",
"from": "interpret@>=0.6.4 <0.7.0",
@ -2969,6 +3157,21 @@
"from": "is-number@>=2.1.0 <3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz"
},
"is-path-cwd": {
"version": "1.0.0",
"from": "is-path-cwd@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz"
},
"is-path-in-cwd": {
"version": "1.0.0",
"from": "is-path-in-cwd@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz"
},
"is-path-inside": {
"version": "1.0.0",
"from": "is-path-inside@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz"
},
"is-plain-obj": {
"version": "1.1.0",
"from": "is-plain-obj@>=1.0.0 <2.0.0",
@ -2994,6 +3197,11 @@
"from": "is-relative@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz"
},
"is-resolvable": {
"version": "1.0.0",
"from": "is-resolvable@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz"
},
"is-stream": {
"version": "1.1.0",
"from": "is-stream@>=1.1.0 <2.0.0",
@ -3076,38 +3284,16 @@
"from": "jsesc@>=0.5.0 <0.6.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz"
},
"jshint": {
"version": "2.9.2",
"from": "jshint@>=2.9.1 <2.10.0",
"resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.2.tgz",
"dependencies": {
"entities": {
"version": "1.0.0",
"from": "entities@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz"
},
"htmlparser2": {
"version": "3.8.3",
"from": "htmlparser2@>=3.8.0 <3.9.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz"
},
"lodash": {
"version": "3.7.0",
"from": "lodash@>=3.7.0 <3.8.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz"
},
"minimatch": {
"version": "2.0.10",
"from": "minimatch@>=2.0.0 <2.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz"
}
}
},
"json-schema": {
"version": "0.2.2",
"from": "json-schema@0.2.2",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz"
},
"json-stable-stringify": {
"version": "1.0.1",
"from": "json-stable-stringify@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz"
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@>=5.0.0 <5.1.0",
@ -3128,6 +3314,11 @@
"from": "jsonfile@>=2.1.0 <3.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.3.1.tgz"
},
"jsonify": {
"version": "0.0.0",
"from": "jsonify@>=0.0.0 <0.1.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
},
"jsonpointer": {
"version": "2.0.0",
"from": "jsonpointer@2.0.0",
@ -3175,6 +3366,11 @@
"from": "lcid@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"
},
"levn": {
"version": "0.3.0",
"from": "levn@>=0.3.0 <0.4.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz"
},
"livereload-js": {
"version": "2.2.2",
"from": "livereload-js@>=2.2.0 <3.0.0",
@ -3396,6 +3592,11 @@
"from": "multimatch@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz"
},
"mute-stream": {
"version": "0.0.5",
"from": "mute-stream@0.0.5",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz"
},
"mv": {
"version": "2.1.1",
"from": "mv@>=2.0.3 <3.0.0",
@ -3676,6 +3877,18 @@
"from": "optimist@>=0.3.5 <0.4.0",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz"
},
"optionator": {
"version": "0.8.1",
"from": "optionator@>=0.8.1 <0.9.0",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.1.tgz",
"dependencies": {
"wordwrap": {
"version": "1.0.0",
"from": "wordwrap@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz"
}
}
},
"original": {
"version": "1.0.0",
"from": "original@>=0.0.5",
@ -3800,6 +4013,11 @@
"from": "path-is-absolute@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz"
},
"path-is-inside": {
"version": "1.0.1",
"from": "path-is-inside@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.1.tgz"
},
"path-key": {
"version": "1.0.0",
"from": "path-key@>=1.0.0 <2.0.0",
@ -3855,6 +4073,11 @@
"from": "plur@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz"
},
"pluralize": {
"version": "1.2.1",
"from": "pluralize@>=1.2.1 <2.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz"
},
"postcss": {
"version": "5.0.21",
"from": "postcss@>=5.0.14 <6.0.0",
@ -4000,6 +4223,11 @@
"from": "postcss-zindex@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.1.1.tgz"
},
"prelude-ls": {
"version": "1.1.2",
"from": "prelude-ls@>=1.1.2 <1.2.0",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
},
"prepend-http": {
"version": "1.0.4",
"from": "prepend-http@>=1.0.0 <2.0.0",
@ -4035,6 +4263,11 @@
"from": "process-nextick-args@>=1.0.6 <1.1.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
},
"progress": {
"version": "1.1.8",
"from": "progress@>=1.1.8 <2.0.0",
"resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz"
},
"progress-stream": {
"version": "1.2.0",
"from": "progress-stream@>=1.2.0 <2.0.0",
@ -4149,6 +4382,11 @@
"from": "rcedit@>=0.5.1 <0.6.0",
"resolved": "https://registry.npmjs.org/rcedit/-/rcedit-0.5.1.tgz"
},
"read-json-sync": {
"version": "1.1.1",
"from": "read-json-sync@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/read-json-sync/-/read-json-sync-1.1.1.tgz"
},
"read-pkg": {
"version": "1.1.0",
"from": "read-pkg@>=1.0.0 <2.0.0",
@ -4186,6 +4424,11 @@
}
}
},
"readline2": {
"version": "1.0.1",
"from": "readline2@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz"
},
"redent": {
"version": "1.0.0",
"from": "redent@>=1.0.0 <2.0.0",
@ -4256,6 +4499,18 @@
"from": "request@2.55.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz"
},
"require-uncached": {
"version": "1.0.2",
"from": "require-uncached@>=1.0.2 <2.0.0",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.2.tgz",
"dependencies": {
"resolve-from": {
"version": "1.0.1",
"from": "resolve-from@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz"
}
}
},
"requires-port": {
"version": "1.0.0",
"from": "requires-port@>=1.0.0 <2.0.0",
@ -4276,6 +4531,11 @@
"from": "resolve-pkg@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz"
},
"restore-cursor": {
"version": "1.0.1",
"from": "restore-cursor@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz"
},
"right-align": {
"version": "0.1.3",
"from": "right-align@>=0.1.1 <0.2.0",
@ -4298,11 +4558,21 @@
"from": "ripemd160@0.2.0",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz"
},
"run-async": {
"version": "0.1.0",
"from": "run-async@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz"
},
"run-series": {
"version": "1.1.4",
"from": "run-series@>=1.1.1 <2.0.0",
"resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.4.tgz"
},
"rx-lite": {
"version": "3.1.2",
"from": "rx-lite@>=3.1.2 <4.0.0",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz"
},
"sass-graph": {
"version": "2.1.1",
"from": "sass-graph@>=2.1.1 <3.0.0",
@ -4393,9 +4663,9 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"
},
"shelljs": {
"version": "0.3.0",
"from": "shelljs@>=0.3.0 <0.4.0",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz"
"version": "0.6.0",
"from": "shelljs@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.0.tgz"
},
"sigmund": {
"version": "1.0.1",
@ -4417,6 +4687,11 @@
"from": "slash@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz"
},
"slice-ansi": {
"version": "0.0.4",
"from": "slice-ansi@0.0.4",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz"
},
"snake-case": {
"version": "2.1.0",
"from": "snake-case@>=2.1.0 <3.0.0",
@ -4635,6 +4910,18 @@
"from": "swap-case@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz"
},
"table": {
"version": "3.7.8",
"from": "table@>=3.7.8 <4.0.0",
"resolved": "https://registry.npmjs.org/table/-/table-3.7.8.tgz",
"dependencies": {
"lodash": {
"version": "4.13.1",
"from": "lodash@^4.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz"
}
}
},
"tapable": {
"version": "0.1.10",
"from": "tapable@>=0.1.8 <0.2.0",
@ -4689,6 +4976,11 @@
"from": "throttleit@0.0.2",
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz"
},
"through": {
"version": "2.3.8",
"from": "through@>=2.3.6 <3.0.0",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
},
"through2": {
"version": "0.2.3",
"from": "through2@>=0.2.3 <0.3.0",
@ -4765,6 +5057,11 @@
"from": "trim-newlines@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz"
},
"tryit": {
"version": "1.0.2",
"from": "tryit@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.2.tgz"
},
"tty-browserify": {
"version": "0.0.0",
"from": "tty-browserify@0.0.0",
@ -4775,11 +5072,21 @@
"from": "tunnel-agent@>=0.4.0 <0.5.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
},
"tv4": {
"version": "1.2.7",
"from": "tv4@>=1.2.7 <2.0.0",
"resolved": "https://registry.npmjs.org/tv4/-/tv4-1.2.7.tgz"
},
"tweetnacl": {
"version": "0.13.3",
"from": "tweetnacl@>=0.13.0 <0.14.0",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
},
"type-check": {
"version": "0.3.2",
"from": "type-check@>=0.3.2 <0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz"
},
"type-is": {
"version": "1.6.12",
"from": "type-is@>=1.6.10 <1.7.0",
@ -5039,6 +5346,11 @@
"from": "wrappy@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
},
"write": {
"version": "0.2.1",
"from": "write@>=0.2.1 <0.3.0",
"resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz"
},
"xml-char-classes": {
"version": "1.0.0",
"from": "xml-char-classes@>=1.0.0 <2.0.0",
@ -5054,6 +5366,11 @@
"from": "xmldom@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.22.tgz"
},
"xregexp": {
"version": "3.1.1",
"from": "xregexp@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-3.1.1.tgz"
},
"xtend": {
"version": "4.0.1",
"from": "xtend@>=4.0.0 <5.0.0",

View File

@ -16,6 +16,9 @@
"base64-loader": "1.0.0",
"cssnano": "3.7.3",
"electron-prebuilt": "1.2.6",
"eslint-config-standard": "5.3.5",
"eslint-plugin-promise": "2.0.0",
"eslint-plugin-standard": "2.0.0",
"exports-loader": "0.6.3",
"get-folder-size": "1.0.0",
"grunt": "1.0.1",
@ -26,10 +29,10 @@
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-deb": "github:keeweb/grunt-contrib-deb#45d31f6",
"grunt-contrib-htmlmin": "1.5.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-uglify": "1.0.1",
"grunt-contrib-watch": "1.0.0",
"grunt-electron": "4.0.0",
"grunt-eslint": "19.0.0",
"grunt-gitinfo": "0.1.8",
"grunt-inline-alt": "0.3.10",
"grunt-postcss": "0.8.0",
@ -49,7 +52,7 @@
"webpack-dev-server": "1.14.1"
},
"optionalDependencies": {
"grunt-appdmg": "0.4.0"
"grunt-appdmg": "0.4.0"
},
"scripts": {
"start": "grunt",