[WO-598] Replace contentEditable in writer with textarea

This commit is contained in:
Tankred Hase 2014-09-22 15:28:22 +02:00
parent f3ad08b066
commit 74f6b3312e
4 changed files with 14 additions and 84 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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>

View File

@ -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