mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Removed: KnockoutJS 'hasFocus:' because HTML5 has autofocus=""
Knoin.js now searches for [autofocus] and handles it
This commit is contained in:
parent
226f77e392
commit
996723a486
18 changed files with 60 additions and 113 deletions
|
|
@ -51,4 +51,9 @@ export class AbstractViewNext {
|
|||
|
||||
cancelCommand() {} // eslint-disable-line no-empty-function
|
||||
closeCommand() {} // eslint-disable-line no-empty-function
|
||||
|
||||
querySelector(selectors) {
|
||||
return this.viewModelDom[0].querySelector(selectors);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,6 +246,9 @@ export function showScreenPopup(ViewModelClassToShow, params = []) {
|
|||
|
||||
ModalView.__vm.onShow && ModalView.__vm.onShow(...params);
|
||||
|
||||
const af = ModalView.__dom[0].querySelector('[autofocus]');
|
||||
af && af.focus();
|
||||
|
||||
vmRunHook('view-model-on-show', ModalView, params || []);
|
||||
}
|
||||
}
|
||||
|
|
@ -374,6 +377,9 @@ export function screenOnRoute(screenName, subPart) {
|
|||
ViewModelClass.__vm.onShowTrigger(!ViewModelClass.__vm.onShowTrigger());
|
||||
}
|
||||
|
||||
const af = ViewModelClass.__dom[0].querySelector('[autofocus]');
|
||||
af && af.focus();
|
||||
|
||||
ViewModelClass.__vm.onShowWithDelay && setTimeout(()=>ViewModelClass.__vm.onShowWithDelay, 200);
|
||||
|
||||
vmRunHook('view-model-on-show', ViewModelClass);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@
|
|||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.inputEmail, .inputPassword {
|
||||
padding-right: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.languageLabel {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class LoginAdminView extends AbstractViewNext {
|
|||
this.loginErrorAnimation = ko.observable(false).extend({ 'falseTimeout': 500 });
|
||||
this.passwordErrorAnimation = ko.observable(false).extend({ 'falseTimeout': 500 });
|
||||
|
||||
this.loginFocus = ko.observable(false);
|
||||
// this.loginFocus = ko.observable(false);
|
||||
|
||||
this.formHidden = ko.observable(false);
|
||||
|
||||
|
|
@ -96,14 +96,9 @@ class LoginAdminView extends AbstractViewNext {
|
|||
|
||||
onShow() {
|
||||
routeOff();
|
||||
|
||||
setTimeout(() => {
|
||||
this.loginFocus(true);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
onHide() {
|
||||
this.loginFocus(false);
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ class AddOpenPgpKeyPopupView extends AbstractViewNext {
|
|||
super();
|
||||
|
||||
this.key = ko.observable('');
|
||||
this.key.focus = ko.observable(false);
|
||||
this.key.error = ko.observable(false);
|
||||
this.key.errorMessage = ko.observable('');
|
||||
|
||||
|
|
@ -95,10 +94,6 @@ class AddOpenPgpKeyPopupView extends AbstractViewNext {
|
|||
onShow() {
|
||||
this.clearPopup();
|
||||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
this.key.focus(true);
|
||||
}
|
||||
}
|
||||
|
||||
export { AddOpenPgpKeyPopupView, AddOpenPgpKeyPopupView as default };
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ class AskPopupView extends AbstractViewNext {
|
|||
this.yesButton = ko.observable('');
|
||||
this.noButton = ko.observable('');
|
||||
|
||||
this.yesFocus = ko.observable(false);
|
||||
this.noFocus = ko.observable(false);
|
||||
|
||||
this.fYesAction = null;
|
||||
this.fNoAction = null;
|
||||
|
||||
|
|
@ -34,9 +31,6 @@ class AskPopupView extends AbstractViewNext {
|
|||
this.yesButton(i18n('POPUPS_ASK/BUTTON_YES'));
|
||||
this.noButton(i18n('POPUPS_ASK/BUTTON_NO'));
|
||||
|
||||
this.yesFocus(false);
|
||||
this.noFocus(false);
|
||||
|
||||
this.fYesAction = null;
|
||||
this.fNoAction = null;
|
||||
}
|
||||
|
|
@ -87,17 +81,17 @@ class AskPopupView extends AbstractViewNext {
|
|||
|
||||
onShowWithDelay() {
|
||||
if (this.bFocusYesOnShow) {
|
||||
this.yesFocus(true);
|
||||
this.querySelector('.buttonYes').focus();
|
||||
}
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
key('tab, shift+tab, right, left', KeyState.PopupAsk, () => {
|
||||
if (this.yesFocus()) {
|
||||
this.noFocus(true);
|
||||
} else {
|
||||
this.yesFocus(true);
|
||||
let btn = this.querySelector('.buttonYes');
|
||||
if (btn.matches(':focus')) {
|
||||
btn = this.querySelector('.buttonNo');
|
||||
}
|
||||
btn.focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class DomainPopupView extends AbstractViewNext {
|
|||
this.smtpServerFocus = ko.observable(false);
|
||||
|
||||
this.name = ko.observable('');
|
||||
this.name.focused = ko.observable(false);
|
||||
|
||||
this.imapServer = ko.observable('');
|
||||
this.imapPort = ko.observable('' + IMAP_DEFAULT_PORT);
|
||||
|
|
@ -379,12 +378,6 @@ class DomainPopupView extends AbstractViewNext {
|
|||
}
|
||||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
if (!this.name() && !bMobileDevice) {
|
||||
this.name.focused(true);
|
||||
}
|
||||
}
|
||||
|
||||
clearForm() {
|
||||
this.edit(false);
|
||||
|
||||
|
|
@ -396,7 +389,6 @@ class DomainPopupView extends AbstractViewNext {
|
|||
this.savingError('');
|
||||
|
||||
this.name('');
|
||||
this.name.focused(false);
|
||||
|
||||
this.imapServer('');
|
||||
this.imapPort('' + IMAP_DEFAULT_PORT);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ class DomainAliasPopupView extends AbstractViewNext {
|
|||
this.savingError = ko.observable('');
|
||||
|
||||
this.name = ko.observable('');
|
||||
this.name.focused = ko.observable(false);
|
||||
|
||||
this.alias = ko.observable('');
|
||||
|
||||
|
|
@ -64,18 +63,11 @@ class DomainAliasPopupView extends AbstractViewNext {
|
|||
this.clearForm();
|
||||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
if (!this.name() && !bMobileDevice) {
|
||||
this.name.focused(true);
|
||||
}
|
||||
}
|
||||
|
||||
clearForm() {
|
||||
this.saving(false);
|
||||
this.savingError('');
|
||||
|
||||
this.name('');
|
||||
this.name.focused(false);
|
||||
|
||||
this.alias('');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ class IdentityPopupView extends AbstractViewNext {
|
|||
this.email = ko.observable('').validateEmail();
|
||||
this.email.focused = ko.observable(false);
|
||||
this.name = ko.observable('');
|
||||
this.name.focused = ko.observable(false);
|
||||
this.replyTo = ko.observable('').validateSimpleEmail();
|
||||
this.replyTo.focused = ko.observable(false);
|
||||
this.bcc = ko.observable('').validateSimpleEmail();
|
||||
|
|
|
|||
|
|
@ -14,13 +14,10 @@ class WelcomePagePopupView extends AbstractViewNext {
|
|||
super();
|
||||
|
||||
this.welcomePageURL = ko.observable('');
|
||||
|
||||
this.closeFocused = ko.observable(false);
|
||||
}
|
||||
|
||||
clearPopup() {
|
||||
this.welcomePageURL('');
|
||||
this.closeFocused(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -33,10 +30,6 @@ class WelcomePagePopupView extends AbstractViewNext {
|
|||
this.welcomePageURL(sUrl);
|
||||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
this.closeFocused(true);
|
||||
}
|
||||
|
||||
onHide() {
|
||||
Promises.welcomeClose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ class LoginUserView extends AbstractViewNext {
|
|||
this.additionalCode = ko.observable('');
|
||||
this.additionalCode.error = ko.observable(false);
|
||||
this.additionalCode.errorAnimation = ko.observable(false).extend({ falseTimeout: 500 });
|
||||
this.additionalCode.focused = ko.observable(false);
|
||||
this.additionalCode.visibility = ko.observable(false);
|
||||
this.additionalCodeSignMe = ko.observable(false);
|
||||
|
||||
|
|
@ -75,8 +74,8 @@ class LoginUserView extends AbstractViewNext {
|
|||
(this.additionalCode.visibility() && this.additionalCode.errorAnimation())
|
||||
);
|
||||
|
||||
this.emailFocus = ko.observable(false);
|
||||
this.passwordFocus = ko.observable(false);
|
||||
// this.emailFocus = ko.observable(false);
|
||||
// this.passwordFocus = ko.observable(false);
|
||||
|
||||
this.email.subscribe(() => {
|
||||
this.emailError(false);
|
||||
|
|
@ -152,32 +151,24 @@ class LoginUserView extends AbstractViewNext {
|
|||
this.emailError(false);
|
||||
this.passwordError(false);
|
||||
|
||||
this.emailError(!this.email().trim());
|
||||
this.passwordError(!this.password().trim());
|
||||
|
||||
let error;
|
||||
if (this.additionalCode.visibility()) {
|
||||
this.additionalCode.error(false);
|
||||
this.additionalCode.error(!this.additionalCode().trim());
|
||||
}
|
||||
|
||||
if (
|
||||
this.emailError() ||
|
||||
this.passwordError() ||
|
||||
(this.additionalCode.visibility() && this.additionalCode.error())
|
||||
) {
|
||||
switch (true) {
|
||||
case this.emailError():
|
||||
this.emailFocus(true);
|
||||
break;
|
||||
case this.passwordError():
|
||||
this.passwordFocus(true);
|
||||
break;
|
||||
case this.additionalCode.visibility() && this.additionalCode.error():
|
||||
this.additionalCode.focused(true);
|
||||
break;
|
||||
// no default
|
||||
if (!this.additionalCode().trim()) {
|
||||
this.additionalCode.error(true);
|
||||
error = '.inputAdditionalCode';
|
||||
}
|
||||
|
||||
}
|
||||
if (!this.password().trim()) {
|
||||
this.passwordError(true);
|
||||
error = '#RainLoopPassword';
|
||||
}
|
||||
if (!this.email().trim()) {
|
||||
this.emailError(true);
|
||||
error = '#RainLoopEmail';
|
||||
}
|
||||
if (error) {
|
||||
this.querySelector(error).focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +201,7 @@ class LoginUserView extends AbstractViewNext {
|
|||
this.additionalCode.visibility(true);
|
||||
this.submitRequest(false);
|
||||
|
||||
setTimeout(() => this.additionalCode.focused(true), 100);
|
||||
setTimeout(() => this.querySelector('.inputAdditionalCode').focus(), 100);
|
||||
} else if (oData.Admin) {
|
||||
getApp().redirectToAdminPanel();
|
||||
} else {
|
||||
|
|
@ -262,23 +253,6 @@ class LoginUserView extends AbstractViewNext {
|
|||
routeOff();
|
||||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
if (this.email() && this.password()) {
|
||||
this.passwordFocus(true);
|
||||
} else if (!this.email()) {
|
||||
this.emailFocus(true);
|
||||
} else if (!this.password()) {
|
||||
this.passwordFocus(true);
|
||||
} else {
|
||||
this.emailFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
onHide() {
|
||||
this.emailFocus(false);
|
||||
this.passwordFocus(false);
|
||||
}
|
||||
|
||||
onBuild() {
|
||||
const signMeLocal = Local.get(ClientSideKeyName.LastSignMe),
|
||||
signMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase();
|
||||
|
|
@ -339,9 +313,7 @@ class LoginUserView extends AbstractViewNext {
|
|||
|
||||
selectLanguageOnTab(bShift) {
|
||||
if (!bShift) {
|
||||
setTimeout(() => {
|
||||
this.emailFocus(true);
|
||||
}, 50);
|
||||
// setTimeout(() => this.emailFocus(true), 50);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
<div class="input-append">
|
||||
<input type="text" class="input-block-level inputLogin checkAutocomplete"
|
||||
name="RainLoopAdminLogin" id="RainLoopAdminLogin"
|
||||
style="padding-right: 35px;"
|
||||
autofocus=""
|
||||
autocomplete="username" autocorrect="off" autocapitalize="off" spellcheck="false" data-i18n="[placeholder]LOGIN/LABEL_LOGIN"
|
||||
data-bind="textInput: login, hasFocus: loginFocus, disable: submitRequest" />
|
||||
data-bind="textInput: login, disable: submitRequest" />
|
||||
<span class="add-on">
|
||||
<i class="icon-user"></i>
|
||||
</span>
|
||||
|
|
@ -23,7 +23,6 @@
|
|||
<div class="input-append">
|
||||
<input type="password" class="input-block-level inputPassword checkAutocomplete"
|
||||
placeholder="Password" name="RainLoopAdminPassword" id="RainLoopAdminPassword"
|
||||
style="padding-right: 35px;"
|
||||
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false" data-i18n="[placeholder]LOGIN/LABEL_PASSWORD"
|
||||
data-bind="textInput: password, disable: submitRequest" />
|
||||
<span class="add-on" tabindex="-1" data-tooltip-join="left" data-bind="command: submitCommand, tooltip: 'LOGIN/BUTTON_LOGIN'">
|
||||
|
|
@ -44,4 +43,5 @@
|
|||
</center>
|
||||
</div>
|
||||
<div class="loginAfter"></div>
|
||||
<div>
|
||||
<div>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
<span style="color: #aaa">(<span data-i18n="POPUPS_DOMAIN/NAME_HELPER"></span>)</span>
|
||||
<br />
|
||||
<input type="text" class="span4" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: name, hasfocus: name.focused" />
|
||||
<input type="text" class="span4" autofocus="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: name" />
|
||||
<div data-bind="visible: '' !== savingError()">
|
||||
<span class="error-desc" data-bind="text: savingError"></span>
|
||||
</div>
|
||||
|
|
@ -268,4 +268,4 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@
|
|||
<br />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn buttonYes" data-bind="click: yesClick, hasFocus: yesFocus">
|
||||
<button class="btn buttonYes" data-bind="click: yesClick">
|
||||
<i class="icon-ok"></i>
|
||||
|
||||
<span data-bind="text: yesButton"></span>
|
||||
</button>
|
||||
<button class="btn buttonNo" data-bind="click: noClick, hasFocus: noFocus">
|
||||
<button class="btn buttonNo" data-bind="click: noClick">
|
||||
<i class=" icon-remove"></i>
|
||||
|
||||
<span data-bind="text: noButton"></span>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-bind="command: cancelCommand, hasFocus: closeFocused">
|
||||
<button class="btn" autofocus="" data-bind="command: cancelCommand">
|
||||
<i class="icon-remove"></i>
|
||||
|
||||
<span class="i18n" data-i18n="POPUPS_WELCOME_PAGE/BUTTON_CLOSE"></span>
|
||||
|
|
@ -19,4 +19,4 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,9 +32,10 @@
|
|||
data-bind="css: {'error': emailError, 'animated': emailErrorAnimation}">
|
||||
<div class="input-append">
|
||||
<input type="email" class="i18n input-block-level inputEmail checkAutocomplete"
|
||||
name="RainLoopEmail" id="RainLoopEmail" style="padding-right: 35px;" autocomplete="email"
|
||||
autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: email, hasFocus: emailFocus, disable: submitRequest"
|
||||
name="RainLoopEmail" id="RainLoopEmail"
|
||||
autofocus=""
|
||||
autocomplete="email" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: email, disable: submitRequest"
|
||||
data-i18n="[placeholder]LOGIN/LABEL_EMAIL" />
|
||||
<span class="add-on">
|
||||
<i class="icon-mail"></i>
|
||||
|
|
@ -44,9 +45,9 @@
|
|||
<div class="controls" data-bind="css: {'error': passwordError, 'animated': passwordErrorAnimation}">
|
||||
<div class="input-append">
|
||||
<input type="password" class="i18n input-block-level inputPassword checkAutocomplete"
|
||||
name="RainLoopPassword" id="RainLoopPassword" style="padding-right: 35px;"
|
||||
name="RainLoopPassword" id="RainLoopPassword"
|
||||
autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: password, hasFocus: passwordFocus, disable: submitRequest"
|
||||
data-bind="textInput: password, disable: submitRequest"
|
||||
data-i18n="[placeholder]LOGIN/LABEL_PASSWORD" />
|
||||
<span class="add-on" tabindex="-1" data-tooltip-join="left"
|
||||
data-bind="command: submitCommand, tooltip: 'LOGIN/BUTTON_SIGN_IN'">
|
||||
|
|
@ -62,7 +63,7 @@
|
|||
<div class="input-append">
|
||||
<input type="text" class="i18n input-block-level inputAdditionalCode" autocomplete="off"
|
||||
autocorrect="off" autocapitalize="off" spellcheck="false" style="padding-right: 35px;"
|
||||
data-bind="textInput: additionalCode, hasFocus: additionalCode.focused, disable: submitRequest"
|
||||
data-bind="textInput: additionalCode, disable: submitRequest"
|
||||
data-i18n="[placeholder]LOGIN/LABEL_VERIFICATION_CODE" />
|
||||
<span class="add-on">
|
||||
<i class="icon-key"></i>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="alert" data-bind="visible: key.error() && key.errorMessage(), text: key.errorMessage"></div>
|
||||
<div class="form-horizontal">
|
||||
<div class="control-group" data-bind="css: {'error': key.error}">
|
||||
<textarea class="inputKey input-xxlarge" rows="14" autocomplete="off" data-bind="value: key, hasfocus: key.focus"></textarea>
|
||||
<textarea class="inputKey input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: key"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<div class="control-group" data-bind="visible: !owner(), css: {'error': email.hasError}">
|
||||
<label class="i18n control-label" data-i18n="POPUPS_IDENTITY/LABEL_EMAIL"></label>
|
||||
<div class="controls">
|
||||
<input type="email" class="inputEmail input-xlarge"
|
||||
<input type="email" class="inputEmail input-xlarge" autofocus=""
|
||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: email, onEnter: addOrEditIdentityCommand, hasfocus: email.focused" />
|
||||
</div>
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
<div class="controls">
|
||||
<input type="text" class="inputName input-xlarge"
|
||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: name, onEnter: addOrEditIdentityCommand, hasfocus: name.focused" />
|
||||
data-bind="value: name, onEnter: addOrEditIdentityCommand" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="visible: showReplyTo, css: {'error': replyTo.hasError}">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue