mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Merge pull request #2483 from keepassxreboot/feature/allow_table_editing
Allow editing Site Preferences table
This commit is contained in:
commit
e37f1f1dc7
4 changed files with 146 additions and 5 deletions
|
|
@ -7,6 +7,10 @@
|
|||
"message": "Add Site Preferences for this URL.",
|
||||
"description": "Add button title text on Site Preferences tab."
|
||||
},
|
||||
"editSitePreferenceButtonTitle": {
|
||||
"message": "Edit URL for this Site Preferences.",
|
||||
"description": "Edit button title text on Site Preferences tab."
|
||||
},
|
||||
"allowIframeButtonTitle": {
|
||||
"message": "Allows Cross-Origin iframes for the current page.",
|
||||
"description": "Allow Cross-Origin iframes button title text."
|
||||
|
|
@ -686,6 +690,10 @@
|
|||
"message": "Add",
|
||||
"description": "Add button text."
|
||||
},
|
||||
"optionsButtonEdit": {
|
||||
"message": "Edit",
|
||||
"description": "Edit button text."
|
||||
},
|
||||
"optionsButtonUpdate": {
|
||||
"message": "Check for updates",
|
||||
"description": "Check for updates button text."
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ input:invalid {
|
|||
border: 2px solid red;
|
||||
}
|
||||
|
||||
input[disabled] {
|
||||
input:disabled {
|
||||
opacity: .3!important;
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +112,18 @@ tbody {
|
|||
background-color: var(--kpxc-checkbox-background-color) !important;
|
||||
}
|
||||
|
||||
.table-striped > tbody > tr:nth-of-type(even) input[type="url"] {
|
||||
--bs-table-bg-type: var(--kpxc-card-background-color) !important;
|
||||
background-color: var(--kpxc-card-background-color) !important;
|
||||
color: var(--kpxc-text-color) !important;
|
||||
}
|
||||
|
||||
.table-striped > tbody > tr:nth-of-type(odd) input[type="url"] {
|
||||
--bs-table-bg-type: var(--kpxc-table-odd-color) !important;
|
||||
background-color: var(--kpxc-table-odd-color) !important;
|
||||
color: var(--kpxc-text-color) !important;
|
||||
}
|
||||
|
||||
.table tbody td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
|
@ -213,6 +225,29 @@ table td:last-of-type {
|
|||
color: var(--kpxc-text-color);
|
||||
}
|
||||
|
||||
.site-preferences-input {
|
||||
border: 0;
|
||||
border-bottom-right-radius: 4px !important;
|
||||
border-top-right-radius: 4px !important;
|
||||
}
|
||||
|
||||
.site-preferences-input:disabled {
|
||||
opacity: 1 !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
button#sitePreferencesEditUrl {
|
||||
border-bottom-left-radius: 4px !important;
|
||||
border-bottom-right-radius: 4px !important;
|
||||
border-top-left-radius: 4px !important;
|
||||
border-top-right-radius: 4px !important;
|
||||
}
|
||||
|
||||
button#sitePreferencesCancelEdit {
|
||||
border-bottom-left-radius: 4px !important;
|
||||
border-top-left-radius: 4px !important;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.sidebar {
|
||||
height: auto;
|
||||
|
|
|
|||
|
|
@ -760,7 +760,23 @@
|
|||
<td colspan="5"><span data-i18n="optionsSitePreferencesNotFound"></span></td>
|
||||
</tr>
|
||||
<tr class="clone d-none">
|
||||
<td class="text-nowrap"></td>
|
||||
<td class="text-nowrap">
|
||||
<div class="input-group was-validated" id="manualUrlGroup">
|
||||
<input class="form-control form-control-sm site-preferences-input" type="url" id="editUrl" aria-label="Edit URL" pattern="file://.*|ftp://.*|http://.*|https://.*" minlength="5" maxlength="2000" required disabled>
|
||||
<button class="btn btn-sm btn-primary" type="button" id="sitePreferencesEditUrl" data-i18n="[title]editSitePreferenceButtonTitle">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
<span data-i18n="optionsButtonEdit"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger" type="button" id="sitePreferencesCancelEdit" data-i18n="[title]editSitePreferenceButtonTitle" style="display: none;">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
<span data-i18n="optionsButtonCancel"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-primary" type="button" id="sitePreferencesSaveEdit" data-i18n="[title]editSitePreferenceButtonTitle" style="display: none;">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
<span data-i18n="optionsButtonSave"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-select form-select-sm" name="ignore" data-i18n="[title]optionsSitePreferencesSelect">
|
||||
<option value="ignoreNothing" data-i18n="optionsSelectionNothing"></option>
|
||||
|
|
|
|||
|
|
@ -521,14 +521,68 @@ options.initSitePreferences = function() {
|
|||
const removeButtonClicked = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const closestTr = this.closest('tr');
|
||||
const closestTr = e.target.closest('tr');
|
||||
$('#dialogDeleteSite').setAttribute('url', closestTr.getAttribute('url'));
|
||||
$('#dialogDeleteSite').setAttribute('tr-id', closestTr.getAttribute('id'));
|
||||
$('#dialogDeleteSite .modal-body strong').textContent = closestTr.children[0].textContent;
|
||||
$('#dialogDeleteSite .modal-body strong').textContent = closestTr.getAttribute('url');
|
||||
|
||||
dialogDeleteSiteModal.show();
|
||||
};
|
||||
|
||||
// Shows or hides Cancel / Save buttons on row
|
||||
const enterEditMode = function(e, row, inputField, editButton, cancelButton, saveButton) {
|
||||
e.preventDefault();
|
||||
if (!row || !inputField) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputField.disabled) {
|
||||
inputField.disabled = false;
|
||||
cancelButton.show();
|
||||
saveButton.show();
|
||||
saveButton.disabled = true;
|
||||
editButton.hide();
|
||||
inputField.focus();
|
||||
inputField.setSelectionRange(inputField.value?.length || 0, inputField.value?.length || 0);
|
||||
}
|
||||
};
|
||||
|
||||
const exitEditMode = function(e, row, inputField, editButton, cancelButton, saveButton) {
|
||||
e.preventDefault();
|
||||
if (!row || !inputField) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inputField.disabled) {
|
||||
inputField.disabled = true;
|
||||
inputField.value = row.getAttribute('url');
|
||||
cancelButton.hide();
|
||||
saveButton.hide();
|
||||
editButton.show();
|
||||
}
|
||||
};
|
||||
|
||||
const saveModifiedUrl = function(e, row, inputField, editButton, cancelButton, saveButton) {
|
||||
e.preventDefault();
|
||||
if (!row || !inputField) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentUrl = row.getAttribute('url');
|
||||
for (const site of options.settings['sitePreferences']) {
|
||||
if (site.url === currentUrl && inputField.validity.valid && inputField.value !== currentUrl) {
|
||||
if (slashNeededForUrl(inputField.value)) {
|
||||
inputField.value += '/';
|
||||
}
|
||||
site.url = inputField.value;
|
||||
row.setAttribute('url', inputField.value);
|
||||
exitEditMode(e, row, inputField, editButton, cancelButton, saveButton);
|
||||
options.saveSettings();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const checkboxClicked = function() {
|
||||
const closestTr = this.closest('tr');
|
||||
const url = closestTr.getAttribute('url');
|
||||
|
|
@ -565,7 +619,35 @@ options.initSitePreferences = function() {
|
|||
const row = rowClone.cloneNode(true);
|
||||
row.setAttribute('url', url);
|
||||
row.setAttribute('id', 'tr-scf' + newIndex);
|
||||
row.children[0].textContent = url;
|
||||
|
||||
// Handle listeners for Edit/Cancel/Save buttons
|
||||
const inputField = row?.querySelector('input#editUrl');
|
||||
const editButton = row?.querySelector('button#sitePreferencesEditUrl');
|
||||
const cancelButton = row?.querySelector('button#sitePreferencesCancelEdit');
|
||||
const saveButton = row?.querySelector('button#sitePreferencesSaveEdit');
|
||||
inputField?.addEventListener('keyup', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
saveModifiedUrl(e, row, inputField, editButton, cancelButton, saveButton);
|
||||
} else if (e.key === 'Escape') {
|
||||
exitEditMode(e, row, inputField, editButton, cancelButton, saveButton);
|
||||
} else {
|
||||
saveButton.disabled = !inputField.validity.valid || inputField.value === url;
|
||||
}
|
||||
});
|
||||
editButton?.addEventListener('click', (e) =>
|
||||
enterEditMode(e, row, inputField, editButton, cancelButton, saveButton)
|
||||
);
|
||||
cancelButton?.addEventListener('click', (e) =>
|
||||
exitEditMode(e, row, inputField, editButton, cancelButton, saveButton)
|
||||
);
|
||||
saveButton?.addEventListener('click', (e) =>
|
||||
saveModifiedUrl(e, row, inputField, editButton, cancelButton, saveButton)
|
||||
);
|
||||
|
||||
row.children[0].children[0].children[0].value = url;
|
||||
row.children[0].children[0]?.addEventListener('dblclick', (e) =>
|
||||
enterEditMode(e, row, inputField, editButton, cancelButton, saveButton)
|
||||
);
|
||||
row.children[1].children[0].value = ignore;
|
||||
row.children[1].children[0].addEventListener('change', selectionChanged);
|
||||
row.children[2].children['usernameOnly'].checked = usernameOnly;
|
||||
|
|
|
|||
Loading…
Reference in a new issue