summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2026-02-10 22:57:48 +0000
committerGreg Roach <greg@subaqua.co.uk>2026-02-10 23:04:42 +0000
commit52e8ff16768e6e8a565b1fa9fb835e61029a4e3f (patch)
tree7b70c7a5de6eff06d2879b3f722a8ac6282e9241 /resources
parent5a0bb1e11278476738760bcc35065187fc1a22bb (diff)
downloadwebtrees-52e8ff16768e6e8a565b1fa9fb835e61029a4e3f.tar.gz
webtrees-52e8ff16768e6e8a565b1fa9fb835e61029a4e3f.tar.bz2
webtrees-52e8ff16768e6e8a565b1fa9fb835e61029a4e3f.zip
Fix: #5313 - replace hideshowpassword plugin with vanillaJS
Diffstat (limited to 'resources')
-rw-r--r--resources/js/vendor.js2
-rw-r--r--resources/js/webtrees.js26
-rw-r--r--resources/views/admin/site-mail.phtml9
-rw-r--r--resources/views/admin/users-create.phtml2
-rw-r--r--resources/views/admin/users-edit.phtml2
-rw-r--r--resources/views/edit-account-page.phtml2
-rw-r--r--resources/views/edit/password.phtml58
-rw-r--r--resources/views/login-page.phtml2
-rw-r--r--resources/views/modules/login_block/sign-in.phtml2
-rw-r--r--resources/views/password-reset-page.phtml2
-rw-r--r--resources/views/register-page.phtml8
-rw-r--r--resources/views/setup/step-4-database-mysql.phtml2
-rw-r--r--resources/views/setup/step-4-database-pgsql.phtml2
-rw-r--r--resources/views/setup/step-4-database-sqlsrv.phtml2
-rw-r--r--resources/views/setup/step-5-administrator.phtml8
15 files changed, 76 insertions, 53 deletions
diff --git a/resources/js/vendor.js b/resources/js/vendor.js
index 32d3e4698c..e6996a475d 100644
--- a/resources/js/vendor.js
+++ b/resources/js/vendor.js
@@ -65,8 +65,6 @@ TomSelect.define('virtual_scroll', require('tom-select/dist/js/plugins/virtual_s
window.TomSelect = TomSelect;
-import 'hideshowpassword';
-
import 'moment';
import 'jquery-colorbox';
diff --git a/resources/js/webtrees.js b/resources/js/webtrees.js
index 01e6cfb536..e566b5e57d 100644
--- a/resources/js/webtrees.js
+++ b/resources/js/webtrees.js
@@ -983,32 +983,6 @@ $(function () {
$('.wt-osk-close').on('click', function () {
$('.wt-osk').hide();
});
-
- // Hide/Show password fields
- $('input[type=password]').each(function () {
- $(this).hideShowPassword('infer', true, {
- states: {
- shown: {
- toggle: {
- content: this.dataset.wtHidePasswordText,
- attr: {
- title: this.dataset.wtHidePasswordTitle,
- 'aria-label': this.dataset.wtHidePasswordTitle,
- }
- }
- },
- hidden: {
- toggle: {
- content: this.dataset.wtShowPasswordText,
- attr: {
- title: this.dataset.wtShowPasswordTitle,
- 'aria-label': this.dataset.wtShowPasswordTitle,
- }
- }
- }
- }
- });
- });
});
// Prevent form re-submission via accidental double-click.
diff --git a/resources/views/admin/site-mail.phtml b/resources/views/admin/site-mail.phtml
index 9b733dd863..b026a0d885 100644
--- a/resources/views/admin/site-mail.phtml
+++ b/resources/views/admin/site-mail.phtml
@@ -93,7 +93,7 @@ use Fisharebest\Webtrees\Webtrees;
I18N::translate('Server name') ?>
</label>
<div class="col-sm-9">
- <input type="text" class="form-control" id="SMTP_HOST" name="SMTP_HOST" value="<?= e($SMTP_HOST) ?>" placeholder="smtp.example.com" maxlength="255" pattern="[a-z0-9-]+(\.[a-z0-9-]+)*">
+ <input type="text" class="form-control" id="SMTP_HOST" name="SMTP_HOST" value="<?= e($SMTP_HOST) ?>" placeholder="smtp.example.com" maxlength="255" pattern="[a-z0-9\-]+(\.[a-z0-9\-]+)*">
<div class="form-text">
<?= /* I18N: Help text for the “Server name” site configuration setting */
I18N::translate('This is the name of the SMTP server. “localhost” means that the mail service is running on the same computer as your web server.') ?>
@@ -149,10 +149,9 @@ use Fisharebest\Webtrees\Webtrees;
I18N::translate('Password') ?>
</label>
<div class="col-sm-9">
- <input type="password" class="form-control" id="SMTP_AUTH_PASS" name="SMTP_AUTH_PASS" value="" autocomplete="new-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'SMTP_AUTH_PASS']) ?>
<div class="form-text">
- <?= /* I18N: Help text for the "Password" site configuration setting */
- I18N::translate('The password required for authentication with the SMTP server.') ?>
+ <?= I18N::translate('The password required for authentication with the SMTP server.') ?>
</div>
</div>
</div>
@@ -177,7 +176,7 @@ use Fisharebest\Webtrees\Webtrees;
I18N::translate('Sending server name') ?>
</label>
<div class="col-sm-9">
- <input type="text" class="form-control" id="SMTP_HELO" name="SMTP_HELO" value="<?= e($SMTP_HELO) ?>" maxlength="255" pattern="[a-z0-9-]+(\.[a-z0-9-]+)*">
+ <input type="text" class="form-control" id="SMTP_HELO" name="SMTP_HELO" value="<?= e($SMTP_HELO) ?>" maxlength="255" pattern="[a-z0-9\-]+(\.[a-z0-9\-]+)*">
<div class="form-text">
<?= /* I18N: Help text for the "Sending server name" site configuration setting */
I18N::translate('Most mail servers require that the sending server identifies itself correctly, using a valid domain name.') ?>
diff --git a/resources/views/admin/users-create.phtml b/resources/views/admin/users-create.phtml
index a80e09c0da..1c56db1caf 100644
--- a/resources/views/admin/users-create.phtml
+++ b/resources/views/admin/users-create.phtml
@@ -58,7 +58,7 @@ use Fisharebest\Webtrees\View;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" type="password" id="password" name="password" pattern = ".{8,}" placeholder="<?= I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8)) ?>" required="required" autocomplete="new-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'required' => true, 'autocomplete' => 'new-password', 'pattern' => '.{8,}', 'placeholder' => /* I18N: placeholder text for new-password field */ I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8))]) ?>
<div class="form-text">
<?= I18N::translate('Passwords must be at least 8 characters long and are case-sensitive, so that “secret” is different from “SECRET”.') ?>
</div>
diff --git a/resources/views/admin/users-edit.phtml b/resources/views/admin/users-edit.phtml
index 02c5aad101..78b45a800a 100644
--- a/resources/views/admin/users-edit.phtml
+++ b/resources/views/admin/users-edit.phtml
@@ -68,7 +68,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" type="password" id="password" name="password" pattern = ".{8,}" placeholder="<?= I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8)) ?>" <?= $user->id() ? '' : 'required' ?> autocomplete="new-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'autocomplete' => 'new-password', 'pattern' => '.{8,}', 'placeholder' => /* I18N: placeholder text for new-password field */ I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8))]) ?>
<div class="form-text">
<?= I18N::translate('Passwords must be at least 8 characters long and are case-sensitive, so that “secret” is different from “SECRET”.') ?>
</div>
diff --git a/resources/views/edit-account-page.phtml b/resources/views/edit-account-page.phtml
index 2b9d1e0552..4a7e1cc525 100644
--- a/resources/views/edit-account-page.phtml
+++ b/resources/views/edit-account-page.phtml
@@ -88,7 +88,7 @@ use Fisharebest\Webtrees\Tree;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9 wt-page-options-value">
- <input class="form-control" type="password" id="password" name="password" aria-describedby="password-description" autocomplete="new-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'autocomplete' => 'new-password']) ?>
<div class="form-text" id="password-description">
<?= I18N::translate('Passwords must be at least 8 characters long and are case-sensitive, so that “secret” is different from “SECRET”.') ?>
<br>
diff --git a/resources/views/edit/password.phtml b/resources/views/edit/password.phtml
new file mode 100644
index 0000000000..150f46dbf9
--- /dev/null
+++ b/resources/views/edit/password.phtml
@@ -0,0 +1,58 @@
+<?php
+
+use Fisharebest\Webtrees\I18N;
+
+/**
+ * @var string $id
+ * @var string|null $name
+ * @var bool|null $required
+ * @var string|null $autocomplete
+ * @var string|null $pattern
+ * @var string|null $placeholder
+ * @var string|null $value
+ */
+
+?>
+<div class="input-group">
+ <input
+ autocomplete="<?= ($autocomplete ?? 'one-time-code') ?>"
+ class="form-control"
+ id="<?= e($id) ?>"
+ name="<?= e($name ?? $id) ?>"
+ <?= ($pattern ?? '') !== '' ? 'pattern="' . e($pattern) . '"' : '' ?>
+ placeholder="<?= e($placeholder ?? '') ?>"
+ <?= ($required ?? false) ? 'required="required"' : '' ?>
+ type="password"
+ <?= ($value ?? '') !== '' ? 'value="' . e($value) . '"' : '' ?>
+ >
+ <button
+ id="<?= e($id) ?>-toggle"
+ class="btn btn-outline-secondary"
+ type="button"
+ data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>"
+ data-wt-show-password-text="<?= e(I18N::translate('show')) ?>"
+ data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>"
+ data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>"
+ title="<?= e(I18N::translate('Show password')) ?>"
+ >
+ <?= e(I18N::translate('show')) ?>
+ </button>
+</div>
+
+<script>
+ document.getElementById('<?= e($id) ?>-toggle')
+ .addEventListener('click', function (event) {
+ const element = event.target;
+ const password_field = document.getElementById('<?= e($id) ?>');
+ if (password_field.type === 'password') {
+ password_field.type = 'text';
+ element.title = element.dataset.wtHidePasswordTitle;
+ element.innerHTML = element.dataset.wtHidePasswordText;
+ } else {
+ password_field.type = 'password';
+ element.title = element.dataset.wtShowPasswordTitle;
+ element.innerHTML = element.dataset.wtShowPasswordText;
+ }
+ password_field.focus();
+ });
+</script>
diff --git a/resources/views/login-page.phtml b/resources/views/login-page.phtml
index 8ea5a68eb0..46ea6a0711 100644
--- a/resources/views/login-page.phtml
+++ b/resources/views/login-page.phtml
@@ -44,7 +44,7 @@ use Fisharebest\Webtrees\Tree;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9 wt-page-options-value">
- <input autocomplete="current-password" class="form-control" id="password" name="password" required="required" type="password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'required' => true, 'autocomplete' => 'current-password']) ?>
</div>
</div>
diff --git a/resources/views/modules/login_block/sign-in.phtml b/resources/views/modules/login_block/sign-in.phtml
index a46e76919a..bb17c147d5 100644
--- a/resources/views/modules/login_block/sign-in.phtml
+++ b/resources/views/modules/login_block/sign-in.phtml
@@ -30,7 +30,7 @@ use Fisharebest\Webtrees\Tree;
<label for="password">
<?= I18N::translate('Password') ?>
</label>
- <input type="password" id="password" name="password" class="form-control" autocomplete="current-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'required' => true, 'autocomplete' => 'current-password']) ?>
</div>
<div>
diff --git a/resources/views/password-reset-page.phtml b/resources/views/password-reset-page.phtml
index 3f873f8774..e199dd33ca 100644
--- a/resources/views/password-reset-page.phtml
+++ b/resources/views/password-reset-page.phtml
@@ -34,7 +34,7 @@ use Fisharebest\Webtrees\User;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9 wt-page-options-value">
- <input class="form-control" type="password" id="password" name="password" autocomplete="new-password" pattern=".{8,}" required="required" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'required' => true, 'autocomplete' => 'new-password', 'pattern' => '.{8,}', 'placeholder' => /* I18N: placeholder text for new-password field */ I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8))]) ?>
<div class="form-text" id="password-description">
<?= I18N::translate('Passwords must be at least 8 characters long and are case-sensitive, so that “secret” is different from “SECRET”.') ?>
</div>
diff --git a/resources/views/register-page.phtml b/resources/views/register-page.phtml
index bce82867e5..5f2500461b 100644
--- a/resources/views/register-page.phtml
+++ b/resources/views/register-page.phtml
@@ -73,7 +73,7 @@ use Fisharebest\Webtrees\View;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9 wt-page-options-value">
- <input class="form-control" type="password" id="password" name="password" placeholder="<?= /* I18N: placeholder text for new-password field */ I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8)) ?>" pattern=".{8,}" required="required" autocomplete="new-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'password', 'required' => true, 'autocomplete' => 'new-password', 'pattern' => '.{8,}', 'placeholder' => /* I18N: placeholder text for new-password field */ I18N::plural('Use at least %s character.', 'Use at least %s characters.', 8, I18N::number(8))]) ?>
<div class="form-text">
<?= I18N::translate('Passwords must be at least 8 characters long and are case-sensitive, so that “secret” is different from “SECRET”.') ?>
</div>
@@ -104,9 +104,3 @@ use Fisharebest\Webtrees\View;
<?= csrf_field() ?>
</form>
-
-<?php View::push('javascript') ?>
-<script>
- $("#password").hideShowPassword("infer", true);
-</script>
-<?php View::endpush() ?>
diff --git a/resources/views/setup/step-4-database-mysql.phtml b/resources/views/setup/step-4-database-mysql.phtml
index c6289bb07b..bb3c9c7412 100644
--- a/resources/views/setup/step-4-database-mysql.phtml
+++ b/resources/views/setup/step-4-database-mysql.phtml
@@ -117,7 +117,7 @@ use Illuminate\Support\Collection;
</label>
<div class="col-sm-9">
- <input class="form-control" id="dbpass" name="dbpass" type="password" value="<?= e($dbpass) ?>" dir="ltr" autocomplete="off" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'dbpass', 'value' => $dbpass]) ?>
</div>
</div>
diff --git a/resources/views/setup/step-4-database-pgsql.phtml b/resources/views/setup/step-4-database-pgsql.phtml
index cf4f30623a..e6102c6244 100644
--- a/resources/views/setup/step-4-database-pgsql.phtml
+++ b/resources/views/setup/step-4-database-pgsql.phtml
@@ -82,7 +82,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Database password') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" id="dbpass" name="dbpass" type="password" value="<?= e($dbpass) ?>" dir="ltr" autocomplete="off" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'dbpass', 'value' => $dbpass]) ?>
</div>
</div>
diff --git a/resources/views/setup/step-4-database-sqlsrv.phtml b/resources/views/setup/step-4-database-sqlsrv.phtml
index 09c898cae5..d48e8c256e 100644
--- a/resources/views/setup/step-4-database-sqlsrv.phtml
+++ b/resources/views/setup/step-4-database-sqlsrv.phtml
@@ -82,7 +82,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Database password') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" id="dbpass" name="dbpass" type="password" value="<?= e($dbpass) ?>" dir="ltr" autocomplete="off" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'dbpass', 'value' => $dbpass]) ?>
</div>
</div>
diff --git a/resources/views/setup/step-5-administrator.phtml b/resources/views/setup/step-5-administrator.phtml
index 4bf78b137a..6d37131f52 100644
--- a/resources/views/setup/step-5-administrator.phtml
+++ b/resources/views/setup/step-5-administrator.phtml
@@ -56,7 +56,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Your name') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" dir="ltr" id="wtname" name="wtname" type="text" value="<?= e($wtname) ?>" autocomplete="name">
+ <input class="form-control" dir="ltr" id="wtname" name="wtname" type="text" value="<?= e($wtname) ?>" autocomplete="name" required="required">
<div class="form-text">
<?= I18N::translate('This is your real name, as you would like it displayed on screen.') ?>
</div>
@@ -68,7 +68,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Username') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" dir="ltr" id="wtuser" name="wtuser" type="text" value="<?= e($wtuser) ?>" autocomplete="username">
+ <input class="form-control" dir="ltr" id="wtuser" name="wtuser" type="text" value="<?= e($wtuser) ?>" autocomplete="username" required="required">
<div class="form-text">
<?= I18N::translate('You will use this to sign in to webtrees.') ?>
</div>
@@ -80,7 +80,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Password') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" dir="ltr" id="wtpass" name="wtpass" pattern=".{6,}" type="password" value="<?= e($wtpass) ?>" autocomplete="current-password" data-wt-show-password-text="<?= e(I18N::translate('show')) ?>" data-wt-show-password-title="<?= e(I18N::translate('Show password')) ?>" data-wt-hide-password-text="<?= e(I18N::translate('hide')) ?>" data-wt-hide-password-title="<?= e(I18N::translate('Hide password')) ?>">
+ <?= view('edit/password', ['id' => 'wtpass', 'required' => true, 'autocomplete' => 'current-password', 'pattern' => '.{6,}', 'value' => $wtpass]) ?>
<div class="form-text">
<?= I18N::translate('This must be at least six characters long. It is case-sensitive.') ?>
</div>
@@ -92,7 +92,7 @@ use Illuminate\Support\Collection;
<?= I18N::translate('Email address') ?>
</label>
<div class="col-sm-9">
- <input class="form-control" dir="ltr" id="wtemail" name="wtemail" type="email" value="<?= e($wtemail) ?>" autocomplete="email">
+ <input class="form-control" dir="ltr" id="wtemail" name="wtemail" type="email" value="<?= e($wtemail) ?>" autocomplete="email" required="required">
<div class="form-text">
<?= I18N::translate('This email address will be used to send password reminders, website notifications, and messages from other family members who are registered on the website.') ?>
</div>