mirror of https://github.com/moparisthebest/mail
[WO-598] Replace contentEditable in writer with textarea
This commit is contained in:
parent
f3ad08b066
commit
74f6b3312e
|
@ -5,7 +5,6 @@ define(function(require) {
|
||||||
_ = require('underscore'),
|
_ = require('underscore'),
|
||||||
appController = require('js/app-controller'),
|
appController = require('js/app-controller'),
|
||||||
axe = require('axe'),
|
axe = require('axe'),
|
||||||
aes = require('js/crypto/aes-gcm'),
|
|
||||||
util = require('js/crypto/util'),
|
util = require('js/crypto/util'),
|
||||||
str = require('js/app-config').string,
|
str = require('js/app-config').string,
|
||||||
pgp, emailDao, outbox, keychainDao, auth;
|
pgp, emailDao, outbox, keychainDao, auth;
|
||||||
|
@ -37,7 +36,6 @@ define(function(require) {
|
||||||
|
|
||||||
// fill fields depending on replyTo
|
// fill fields depending on replyTo
|
||||||
fillFields(replyTo, replyAll, forward);
|
fillFields(replyTo, replyAll, forward);
|
||||||
$scope.updatePreview();
|
|
||||||
|
|
||||||
$scope.verify($scope.to[0]);
|
$scope.verify($scope.to[0]);
|
||||||
},
|
},
|
||||||
|
@ -61,7 +59,6 @@ define(function(require) {
|
||||||
$scope.bcc = [];
|
$scope.bcc = [];
|
||||||
$scope.subject = '';
|
$scope.subject = '';
|
||||||
$scope.body = '';
|
$scope.body = '';
|
||||||
$scope.ciphertextPreview = '';
|
|
||||||
$scope.attachments = [];
|
$scope.attachments = [];
|
||||||
$scope.addressBookCache = undefined;
|
$scope.addressBookCache = undefined;
|
||||||
}
|
}
|
||||||
|
@ -321,21 +318,6 @@ define(function(require) {
|
||||||
// Editing email body
|
// Editing email body
|
||||||
//
|
//
|
||||||
|
|
||||||
// generate key,iv for encryption preview
|
|
||||||
var key = util.random(128),
|
|
||||||
iv = util.random(128);
|
|
||||||
|
|
||||||
$scope.updatePreview = function() {
|
|
||||||
if (!$scope.sendBtnSecure || !$scope.body.trim()) {
|
|
||||||
$scope.ciphertextPreview = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Although this does encrypt live using AES, this is just for show. The plaintext is encrypted seperately before sending the email.
|
|
||||||
$scope.ciphertextPreview = aes.encrypt($scope.body, key, iv);
|
|
||||||
};
|
|
||||||
$scope.$watch('sendBtnSecure', $scope.updatePreview);
|
|
||||||
|
|
||||||
$scope.sendToOutbox = function() {
|
$scope.sendToOutbox = function() {
|
||||||
var email;
|
var email;
|
||||||
|
|
||||||
|
@ -466,27 +448,6 @@ define(function(require) {
|
||||||
//
|
//
|
||||||
|
|
||||||
var ngModule = angular.module('write', []);
|
var ngModule = angular.module('write', []);
|
||||||
ngModule.directive('contenteditable', function() {
|
|
||||||
return {
|
|
||||||
require: 'ngModel',
|
|
||||||
link: function(scope, elm, attrs, ctrl) {
|
|
||||||
// view -> model
|
|
||||||
elm.on('keyup keydown', function() {
|
|
||||||
// set model
|
|
||||||
ctrl.$setViewValue(elm[0].innerText);
|
|
||||||
scope.$digest();
|
|
||||||
});
|
|
||||||
|
|
||||||
// model -> view
|
|
||||||
ctrl.$render = function() {
|
|
||||||
elm[0].innerText = ctrl.$viewValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// load init value from DOM
|
|
||||||
ctrl.$setViewValue(elm[0].innerText);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
ngModule.directive('focusMe', function($timeout, $parse) {
|
ngModule.directive('focusMe', function($timeout, $parse) {
|
||||||
return {
|
return {
|
||||||
|
@ -496,7 +457,12 @@ define(function(require) {
|
||||||
scope.$watch(model, function(value) {
|
scope.$watch(model, function(value) {
|
||||||
if (value === true) {
|
if (value === true) {
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
element[0].focus();
|
var el = element[0];
|
||||||
|
el.focus();
|
||||||
|
if (typeof el.selectionStart !== 'undefined' && typeof el.selectionEnd !== 'undefined') {
|
||||||
|
el.selectionStart = 0;
|
||||||
|
el.selectionEnd = 0;
|
||||||
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -504,17 +470,6 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
ngModule.directive('focusChild', function() {
|
|
||||||
return {
|
|
||||||
//scope: true, // optionally create a child scope
|
|
||||||
link: function(scope, element) {
|
|
||||||
element.on('click', function() {
|
|
||||||
element[0].children[0].focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
ngModule.directive('focusInput', function($timeout, $parse) {
|
ngModule.directive('focusInput', function($timeout, $parse) {
|
||||||
return {
|
return {
|
||||||
//scope: true, // optionally create a child scope
|
//scope: true, // optionally create a child scope
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
.subject-box {
|
.subject-box {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 20px 0 7px 0;
|
margin: 20px 0;
|
||||||
|
|
||||||
input[type=file] {
|
input[type=file] {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
@ -146,33 +146,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
textarea {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
color: $color-grey-dark;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
user-select: text;
|
overflow-y: auto;
|
||||||
overflow-y: scroll;
|
|
||||||
// allow scrolling on iOS
|
// allow scrolling on iOS
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
// put layer on GPU
|
// put layer on GPU
|
||||||
transform: translatez(0);
|
transform: translatez(0);
|
||||||
|
|
||||||
*[contentEditable] {
|
|
||||||
outline: 0px;
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.encrypt-preview {
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin-top: 3em;
|
|
||||||
font-family: monospace;
|
|
||||||
color: $color-grey-light;
|
|
||||||
word-wrap: break-word;
|
|
||||||
transition: opacity 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invisible {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-control {
|
.send-control {
|
||||||
|
|
|
@ -58,13 +58,7 @@
|
||||||
</span><!--/.attachment-->
|
</span><!--/.attachment-->
|
||||||
</div><!--/.attachments-box-->
|
</div><!--/.attachments-box-->
|
||||||
|
|
||||||
<div class="body" focus-child>
|
<textarea ng-model="body" spellcheck="true" focus-me="state.lightbox === 'write' && writerTitle === 'Reply'" tabindex="3"></textarea>
|
||||||
<p ng-model="body" contentEditable="true" ng-change="updatePreview()" tabindex="3" focus-me="state.lightbox === 'write' && writerTitle === 'Reply'"></p>
|
|
||||||
|
|
||||||
<div class="encrypt-preview" ng-show="ciphertextPreview && sendBtnSecure">
|
|
||||||
<p>-----BEGIN ENCRYPTED PREVIEW-----<br>{{ciphertextPreview}}<br>-----END ENCRYPTED PREVIEW-----</p>
|
|
||||||
</div><!--/.encrypt-preview-->
|
|
||||||
</div><!--/.body-->
|
|
||||||
|
|
||||||
<div class="send-control">
|
<div class="send-control">
|
||||||
<button wo-touch="sendToOutbox()" class="btn" ng-class="{'btn-primary': sendBtnSecure === false}" ng-disabled="!okToSend" tabindex="4">{{sendBtnText || 'Send'}}</button>
|
<button wo-touch="sendToOutbox()" class="btn" ng-class="{'btn-primary': sendBtnSecure === false}" ng-disabled="!okToSend" tabindex="4">{{sendBtnText || 'Send'}}</button>
|
||||||
|
|
|
@ -64,7 +64,6 @@ define(function(require) {
|
||||||
expect(scope.state.writer.close).to.exist;
|
expect(scope.state.writer.close).to.exist;
|
||||||
expect(scope.verify).to.exist;
|
expect(scope.verify).to.exist;
|
||||||
expect(scope.checkSendStatus).to.exist;
|
expect(scope.checkSendStatus).to.exist;
|
||||||
expect(scope.updatePreview).to.exist;
|
|
||||||
expect(scope.sendToOutbox).to.exist;
|
expect(scope.sendToOutbox).to.exist;
|
||||||
expect(scope.tagStyle).to.exist;
|
expect(scope.tagStyle).to.exist;
|
||||||
expect(scope.lookupAddressBook).to.exist;
|
expect(scope.lookupAddressBook).to.exist;
|
||||||
|
@ -91,7 +90,6 @@ define(function(require) {
|
||||||
expect(scope.to).to.deep.equal([]);
|
expect(scope.to).to.deep.equal([]);
|
||||||
expect(scope.subject).to.equal('');
|
expect(scope.subject).to.equal('');
|
||||||
expect(scope.body).to.equal('');
|
expect(scope.body).to.equal('');
|
||||||
expect(scope.ciphertextPreview).to.equal(undefined);
|
|
||||||
expect(verifyMock.calledOnce).to.be.true;
|
expect(verifyMock.calledOnce).to.be.true;
|
||||||
|
|
||||||
scope.verify.restore();
|
scope.verify.restore();
|
||||||
|
@ -124,7 +122,6 @@ define(function(require) {
|
||||||
expect(scope.subject).to.equal('Re: ' + subject);
|
expect(scope.subject).to.equal('Re: ' + subject);
|
||||||
expect(scope.body).to.contain(body);
|
expect(scope.body).to.contain(body);
|
||||||
expect(scope.references).to.deep.equal(['ghi', 'def', 'abc']);
|
expect(scope.references).to.deep.equal(['ghi', 'def', 'abc']);
|
||||||
expect(scope.ciphertextPreview).to.not.be.empty;
|
|
||||||
expect(verifyMock.called).to.be.true;
|
expect(verifyMock.called).to.be.true;
|
||||||
|
|
||||||
scope.verify.restore();
|
scope.verify.restore();
|
||||||
|
@ -156,7 +153,6 @@ define(function(require) {
|
||||||
expect(scope.to).to.deep.equal([]);
|
expect(scope.to).to.deep.equal([]);
|
||||||
expect(scope.subject).to.equal('Fwd: ' + subject);
|
expect(scope.subject).to.equal('Fwd: ' + subject);
|
||||||
expect(scope.body).to.contain(body);
|
expect(scope.body).to.contain(body);
|
||||||
expect(scope.ciphertextPreview).to.be.undefined;
|
|
||||||
expect(verifyMock.called).to.be.true;
|
expect(verifyMock.called).to.be.true;
|
||||||
expect(scope.attachments).to.not.equal(re.attachments); // not the same reference
|
expect(scope.attachments).to.not.equal(re.attachments); // not the same reference
|
||||||
expect(scope.attachments).to.deep.equal(re.attachments); // but the same content
|
expect(scope.attachments).to.deep.equal(re.attachments); // but the same content
|
||||||
|
|
Loading…
Reference in New Issue