mirror of https://github.com/keeweb/keeweb
finished password generator
parent
4934a0506d
commit
5ef8028aea
2
TODO.md
2
TODO.md
|
@ -2,7 +2,6 @@
|
|||
|
||||
- [ ] add/edit groups
|
||||
- [ ] dropbox
|
||||
- [ ] generate
|
||||
- [ ] file settings
|
||||
|
||||
# FUTURE
|
||||
|
@ -17,3 +16,4 @@
|
|||
- [ ] secure fields
|
||||
- [ ] app settings
|
||||
- [ ] trash: groups/empty/untrash
|
||||
- [ ] generation templates
|
||||
|
|
|
@ -236,7 +236,7 @@ var DetailsView = Backbone.View.extend({
|
|||
showEntry: function(entry) {
|
||||
this.model = entry;
|
||||
this.render();
|
||||
if (!entry.title && entry.isNew) {
|
||||
if (entry && !entry.title && entry.isNew) {
|
||||
this.editTitle();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var FieldView = require('./field-view'),
|
||||
GeneratorView = require('../generator-view'),
|
||||
Keys = require('../../const/keys'),
|
||||
kdbxweb = require('kdbxweb');
|
||||
|
||||
|
@ -24,11 +25,57 @@ var FieldViewText = FieldView.extend({
|
|||
blur: this.fieldValueBlur.bind(this),
|
||||
input: this.fieldValueInput.bind(this),
|
||||
keydown: this.fieldValueKeydown.bind(this),
|
||||
keypress: this.fieldValueInput.bind(this)
|
||||
keypress: this.fieldValueInput.bind(this),
|
||||
click: this.fieldValueInputClick.bind(this)
|
||||
});
|
||||
if (this.model.multiline) {
|
||||
this.setInputHeight();
|
||||
}
|
||||
if (this.value && this.value.byteLength) {
|
||||
$('<div/>').addClass('details__field-value-gen-btn').appendTo(this.valueEl)
|
||||
.click(this.showGeneratorClick.bind(this))
|
||||
.mousedown(this.showGenerator.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
showGeneratorClick: function(e) {
|
||||
e.stopPropagation();
|
||||
if (!this.gen) {
|
||||
this.input.focus();
|
||||
}
|
||||
},
|
||||
|
||||
showGenerator: function() {
|
||||
if (this.gen) {
|
||||
this.hideGenerator();
|
||||
} else {
|
||||
var fieldRect = this.input[0].getBoundingClientRect();
|
||||
this.gen = new GeneratorView({model: {pos: {left: fieldRect.left, top: fieldRect.bottom}}}).render();
|
||||
this.gen.once('remove', this.generatorClosed.bind(this));
|
||||
this.gen.once('result', this.generatorResult.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
hideGenerator: function() {
|
||||
if (this.gen) {
|
||||
var gen = this.gen;
|
||||
delete this.gen;
|
||||
gen.remove();
|
||||
}
|
||||
},
|
||||
|
||||
generatorClosed: function() {
|
||||
if (this.gen) {
|
||||
delete this.gen;
|
||||
this.endEdit();
|
||||
}
|
||||
},
|
||||
|
||||
generatorResult: function(password) {
|
||||
if (this.gen) {
|
||||
delete this.gen;
|
||||
this.endEdit(password);
|
||||
}
|
||||
},
|
||||
|
||||
setInputHeight: function() {
|
||||
|
@ -44,7 +91,9 @@ var FieldViewText = FieldView.extend({
|
|||
},
|
||||
|
||||
fieldValueBlur: function(e) {
|
||||
this.endEdit(e.target.value);
|
||||
if (!this.gen) {
|
||||
this.endEdit(e.target.value);
|
||||
}
|
||||
},
|
||||
|
||||
fieldValueInput: function(e) {
|
||||
|
@ -54,6 +103,12 @@ var FieldViewText = FieldView.extend({
|
|||
}
|
||||
},
|
||||
|
||||
fieldValueInputClick: function() {
|
||||
if (this.gen) {
|
||||
this.hideGenerator();
|
||||
}
|
||||
},
|
||||
|
||||
fieldValueKeydown: function(e) {
|
||||
e.stopPropagation();
|
||||
var code = e.keyCode || e.which;
|
||||
|
@ -73,6 +128,9 @@ var FieldViewText = FieldView.extend({
|
|||
},
|
||||
|
||||
endEdit: function(newVal, extra) {
|
||||
if (this.gen) {
|
||||
this.hideGenerator();
|
||||
}
|
||||
if (!this.editing) {
|
||||
return;
|
||||
}
|
||||
|
@ -84,6 +142,10 @@ var FieldViewText = FieldView.extend({
|
|||
newVal = $.trim(newVal);
|
||||
}
|
||||
FieldView.prototype.endEdit.call(this, newVal, extra);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
FieldView.prototype.render.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -49,11 +49,7 @@ var FooterView = Backbone.View.extend({
|
|||
bodyRect = document.body.getBoundingClientRect(),
|
||||
right = bodyRect.right - rect.right,
|
||||
bottom = bodyRect.bottom - rect.top;
|
||||
var generator = new GeneratorView({ model: {
|
||||
pos: { right: right, bottom: bottom },
|
||||
genOpts: this.model.settings.get('genOpts')
|
||||
}});
|
||||
generator.render();
|
||||
var generator = new GeneratorView({ model: { copy: true, pos: { right: right, bottom: bottom } }}).render();
|
||||
generator.once('remove', (function() { delete this.views.gen; }).bind(this));
|
||||
this.views.gen = generator;
|
||||
},
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
var Backbone = require('backbone'),
|
||||
PasswordGenerator = require('../util/password-generator');
|
||||
PasswordGenerator = require('../util/password-generator'),
|
||||
AppSettingsModel = require('../models/app-settings-model'),
|
||||
CopyPaste = require('../util/copy-paste');
|
||||
|
||||
var GeneratorView = Backbone.View.extend({
|
||||
el: 'body',
|
||||
|
@ -13,18 +15,22 @@ var GeneratorView = Backbone.View.extend({
|
|||
'mousedown .gen__length-range': 'generate',
|
||||
'mousemove .gen__length-range': 'lengthChange',
|
||||
'change .gen__length-range': 'lengthChange',
|
||||
'change .gen__check input[type=checkbox]': 'checkChange'
|
||||
'change .gen__check input[type=checkbox]': 'checkChange',
|
||||
'click .gen__btn-ok': 'btnOkClick'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
$('body').one('click', this.remove.bind(this));
|
||||
this.gen = _.clone(this.model.genOpts);
|
||||
this.gen = _.clone(AppSettingsModel.instance.get('genOpts'));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.renderTemplate(this.gen);
|
||||
var canCopy = document.queryCommandSupported('copy');
|
||||
this.renderTemplate({ btnTitle: this.model.copy && canCopy ? 'Copy' : 'OK', opt: this.gen });
|
||||
this.resultEl = this.$el.find('.gen__result');
|
||||
this.$el.css(this.model.pos);
|
||||
this.generate();
|
||||
return this;
|
||||
},
|
||||
|
||||
click: function(e) {
|
||||
|
@ -49,7 +55,19 @@ var GeneratorView = Backbone.View.extend({
|
|||
},
|
||||
|
||||
generate: function() {
|
||||
this.$el.find('.gen__result').text(PasswordGenerator.generate(this.gen));
|
||||
this.password = PasswordGenerator.generate(this.gen);
|
||||
this.resultEl.text(this.password);
|
||||
},
|
||||
|
||||
btnOkClick: function() {
|
||||
var selection = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(this.resultEl[0]);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
CopyPaste.tryCopy();
|
||||
this.trigger('result', this.password);
|
||||
this.remove();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@
|
|||
@include flex(1);
|
||||
@include user-select(text);
|
||||
@include align-self(flex-start);
|
||||
position: relative;
|
||||
cursor: text;
|
||||
padding: 0 $base-padding-h;
|
||||
border: 1px solid transparent;
|
||||
|
@ -210,6 +211,21 @@
|
|||
width: 12em;
|
||||
@include flex(0 0 auto);
|
||||
}
|
||||
&-gen-btn {
|
||||
@include position(absolute, 0 0 null null);
|
||||
@include th { color: muted-color(); }
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
@include th { color: medium-color(); }
|
||||
}
|
||||
&:before {
|
||||
@include position(absolute, 0 0 null null);
|
||||
@include fa-icon();
|
||||
cursor: pointer;
|
||||
padding: $base-padding;
|
||||
content: $fa-var-bolt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
@include user-select(text);
|
||||
font-family: $monospace-font-family;
|
||||
margin-top: $base-padding-v;
|
||||
height: 2.5em;
|
||||
height: 4em;
|
||||
text-align: center;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
&__btn-wrap {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
.hide-by-pos {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<div class="gen">
|
||||
<div>Length: <span class="gen__length-range-val"><%= length %></span></div>
|
||||
<div>Length: <span class="gen__length-range-val"><%= opt.length %></span></div>
|
||||
<input type="range" class="gen__length-range" value="16" min="2" max="32" />
|
||||
<div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-upper"
|
||||
data-id="upper" <%= upper ? 'checked' : '' %>><label for="gen__check-upper">ABC</label></div>
|
||||
data-id="upper" <%= opt.upper ? 'checked' : '' %>><label for="gen__check-upper">ABC</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-lower"
|
||||
data-id="lower" <%= lower ? 'checked' : '' %>><label for="gen__check-lower">abc</label></div>
|
||||
data-id="lower" <%= opt.lower ? 'checked' : '' %>><label for="gen__check-lower">abc</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-digits"
|
||||
data-id="digits" <%= digits ? 'checked' : '' %>><label for="gen__check-digits">123</label></div>
|
||||
data-id="digits" <%= opt.digits ? 'checked' : '' %>><label for="gen__check-digits">123</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-special"
|
||||
data-id="special" <%= special ? 'checked' : '' %>><label for="gen__check-special">!@#</label></div>
|
||||
data-id="special" <%= opt.special ? 'checked' : '' %>><label for="gen__check-special">!@#</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-brackets"
|
||||
data-id="brackets" <%= brackets ? 'checked' : '' %>><label for="gen__check-brackets">({<</label></div>
|
||||
data-id="brackets" <%= opt.brackets ? 'checked' : '' %>><label for="gen__check-brackets">({<</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-high"
|
||||
data-id="high" <%= high ? 'checked' : '' %>><label for="gen__check-high">äæ±</label></div>
|
||||
data-id="high" <%= opt.high ? 'checked' : '' %>><label for="gen__check-high">äæ±</label></div>
|
||||
<div class="gen__check"><input type="checkbox" id="gen__check-ambiguous"
|
||||
data-id="ambiguous" <%= ambiguous ? 'checked' : '' %>><label for="gen__check-ambiguous">0Oo</label></div>
|
||||
data-id="ambiguous" <%= opt.ambiguous ? 'checked' : '' %>><label for="gen__check-ambiguous">0Oo</label></div>
|
||||
</div>
|
||||
<div class="gen__result">password</div>
|
||||
<div class="gen__btn-wrap"><button class="gen__btn-ok"><%= btnTitle %></button></div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue