mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Add the new selector for submit button
This commit is contained in:
parent
b1b6581d50
commit
8bc00cf194
4 changed files with 114 additions and 35 deletions
|
|
@ -319,9 +319,13 @@
|
|||
"description": "Clear save data button text when choosing Custom Login Fields."
|
||||
},
|
||||
"defineStringField": {
|
||||
"message": "String field",
|
||||
"message": "String Field",
|
||||
"description": "Text for string field."
|
||||
},
|
||||
"defineSubmitButton": {
|
||||
"message": "Submit Button",
|
||||
"description": "Text for Submit Button."
|
||||
},
|
||||
"defineChooseUsername": {
|
||||
"message": "Choose a username field",
|
||||
"description": "Choosing a username field text when choosing Custom Login Fields."
|
||||
|
|
@ -338,9 +342,13 @@
|
|||
"message": "Choose String Fields",
|
||||
"description": "Choose String Fields a selection text when choosing Custom Login Fields."
|
||||
},
|
||||
"defineChooseSubmitButton": {
|
||||
"message": "Choose submit button",
|
||||
"description": "Choose submit button selection text when choosing Custom Login Fields."
|
||||
},
|
||||
"defineHelpText": {
|
||||
"message": "Please confirm your selection or choose more fields as String fields.",
|
||||
"description": "Confirm a selection text when choosing Custom Login Fields which contains string fields."
|
||||
"message": "Please confirm your selection or choose more fields as String Fields.",
|
||||
"description": "Confirm a selection text when choosing Custom Login Fields which contains String Fields."
|
||||
},
|
||||
"defineKeyboardText": {
|
||||
"message": "You can also use the numbers to choose the input fields from keyboard.",
|
||||
|
|
@ -362,6 +370,10 @@
|
|||
"message": "String Fields",
|
||||
"description": "General text for a String Fields."
|
||||
},
|
||||
"submitButton": {
|
||||
"message": "Submit Button",
|
||||
"description": "Custom Submit Button text."
|
||||
},
|
||||
"credentialsNoUsername": {
|
||||
"message": "- no username -",
|
||||
"description": "Shown when no username is set in the credentials."
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const STEP_SELECT_USERNAME = 1;
|
|||
const STEP_SELECT_PASSWORD = 2;
|
||||
const STEP_SELECT_TOTP = 3;
|
||||
const STEP_SELECT_STRING_FIELDS = 4;
|
||||
const STEP_SELECT_SUBMIT_BUTTON = 5;
|
||||
|
||||
const CHECKBOX_OVERLAY_SIZE = 20;
|
||||
|
||||
|
|
@ -18,9 +19,10 @@ const PASSWORD_FIELD_CLASS = 'kpxcDefine-fixed-password-field';
|
|||
const TOTP_FIELD_CLASS = 'kpxcDefine-fixed-totp-field';
|
||||
const STRING_FIELD_CLASS = 'kpxcDefine-fixed-string-field';
|
||||
|
||||
const inputQueryPatternStart = 'input';
|
||||
const inputQueryPatternNotCheckbox = ':not([type=checkbox])';
|
||||
const inputQueryPattern = ':not([disabled]):not([type=button]):not([type=radio]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=file]):not([type=hidden]):not([type=image]):not([type=month]):not([type=range]):not([type=reset]):not([type=submit]):not([type=time]):not([type=week]), select, textarea';
|
||||
const INPUT_BUTTON_QUERY_PATTERN = 'button, input[type=submit]';
|
||||
const INPUT_QUERY_PATTERNS_START = 'input';
|
||||
const INPUT_QUERY_PATTERN_NOT_CHECKBOX = ':not([type=checkbox])';
|
||||
const INPUT_QUERY_PATTERN = ':not([disabled]):not([type=button]):not([type=radio]):not([type=color]):not([type=date]):not([type=datetime-local]):not([type=file]):not([type=hidden]):not([type=image]):not([type=month]):not([type=range]):not([type=reset]):not([type=submit]):not([type=time]):not([type=week]), select, textarea';
|
||||
|
||||
const kpxcCustomLoginFieldsBanner = {};
|
||||
kpxcCustomLoginFieldsBanner.banner = undefined;
|
||||
|
|
@ -29,8 +31,9 @@ kpxcCustomLoginFieldsBanner.created = false;
|
|||
kpxcCustomLoginFieldsBanner.dataStep = STEP_NONE;
|
||||
kpxcCustomLoginFieldsBanner.infoText = undefined;
|
||||
kpxcCustomLoginFieldsBanner.wrapper = undefined;
|
||||
kpxcCustomLoginFieldsBanner.inputQueryPatternNormal = inputQueryPatternStart + inputQueryPatternNotCheckbox + inputQueryPattern;
|
||||
kpxcCustomLoginFieldsBanner.inputQueryPatternStringFields = inputQueryPatternStart + inputQueryPattern;
|
||||
kpxcCustomLoginFieldsBanner.inputQueryPatternNormal =
|
||||
INPUT_QUERY_PATTERNS_START + INPUT_QUERY_PATTERN_NOT_CHECKBOX + INPUT_QUERY_PATTERN;
|
||||
kpxcCustomLoginFieldsBanner.inputQueryPatternStringFields = INPUT_QUERY_PATTERNS_START + INPUT_QUERY_PATTERN;
|
||||
kpxcCustomLoginFieldsBanner.markedFields = [];
|
||||
kpxcCustomLoginFieldsBanner.nonSelectedElementsPattern = `div.${FIXED_FIELD_CLASS}:not(.${USERNAME_FIELD_CLASS}):not(.${PASSWORD_FIELD_CLASS}):not(.${TOTP_FIELD_CLASS}):not(.${STRING_FIELD_CLASS})`;
|
||||
|
||||
|
|
@ -43,6 +46,7 @@ kpxcCustomLoginFieldsBanner.selection = {
|
|||
totpElement: undefined,
|
||||
fields: [],
|
||||
fieldElements: [],
|
||||
submitButton: undefined,
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.buttons = {
|
||||
|
|
@ -100,6 +104,7 @@ kpxcCustomLoginFieldsBanner.create = async function() {
|
|||
const passwordButton = kpxcUI.createButton(RED_BUTTON, tr('password'), kpxcCustomLoginFieldsBanner.passwordButtonClicked);
|
||||
const totpButton = kpxcUI.createButton(GREEN_BUTTON, 'TOTP', kpxcCustomLoginFieldsBanner.totpButtonClicked);
|
||||
const stringFieldsButton = kpxcUI.createButton(BLUE_BUTTON, tr('stringFields'), kpxcCustomLoginFieldsBanner.stringFieldsButtonClicked);
|
||||
const submitButton = kpxcUI.createButton(BLUE_BUTTON, tr('submitButton'), kpxcCustomLoginFieldsBanner.submitButtonClicked);
|
||||
const clearDataButton = kpxcUI.createButton(RED_BUTTON, tr('defineClearData'), kpxcCustomLoginFieldsBanner.clearData);
|
||||
const confirmButton = kpxcUI.createButton(GREEN_BUTTON, tr('defineConfirm'), kpxcCustomLoginFieldsBanner.confirm);
|
||||
const closeButton = kpxcUI.createButton(RED_BUTTON, tr('defineClose'), kpxcCustomLoginFieldsBanner.closeButtonClicked);
|
||||
|
|
@ -116,10 +121,11 @@ kpxcCustomLoginFieldsBanner.create = async function() {
|
|||
kpxcCustomLoginFieldsBanner.buttons.password = passwordButton;
|
||||
kpxcCustomLoginFieldsBanner.buttons.totp = totpButton;
|
||||
kpxcCustomLoginFieldsBanner.buttons.stringFields = stringFieldsButton;
|
||||
kpxcCustomLoginFieldsBanner.buttons.submitButton = submitButton;
|
||||
|
||||
bannerInfo.appendMultiple(icon, infoText);
|
||||
bannerButtons.appendMultiple(resetButton, separator, usernameButton,
|
||||
passwordButton, totpButton, stringFieldsButton, secondSeparator, clearDataButton, confirmButton, closeButton);
|
||||
bannerButtons.appendMultiple(resetButton, separator, usernameButton, passwordButton, totpButton,
|
||||
stringFieldsButton, submitButton, secondSeparator, clearDataButton, confirmButton, closeButton);
|
||||
banner.appendMultiple(bannerInfo, bannerButtons);
|
||||
kpxcUI.makeBannerDraggable(banner);
|
||||
|
||||
|
|
@ -189,7 +195,8 @@ kpxcCustomLoginFieldsBanner.usernameButtonClicked = function(e) {
|
|||
|
||||
// Reset username field selection if already set
|
||||
if (kpxcCustomLoginFieldsBanner.selection.username) {
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.username, `div.${USERNAME_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.username,
|
||||
`div.${USERNAME_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.selection.username = undefined;
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +214,8 @@ kpxcCustomLoginFieldsBanner.passwordButtonClicked = function(e) {
|
|||
|
||||
// Reset password field selection if already set
|
||||
if (kpxcCustomLoginFieldsBanner.selection.password) {
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.password, `div.${PASSWORD_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.password,
|
||||
`div.${PASSWORD_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.selection.password = undefined;
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +233,8 @@ kpxcCustomLoginFieldsBanner.totpButtonClicked = function(e) {
|
|||
|
||||
// Reset TOTP field selection if already set
|
||||
if (kpxcCustomLoginFieldsBanner.selection.totp) {
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.totp, `div.${TOTP_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.totp,
|
||||
`div.${TOTP_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.selection.totp = undefined;
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +265,25 @@ kpxcCustomLoginFieldsBanner.stringFieldsButtonClicked = function(e) {
|
|||
sendMessageToFrames(e, 'string_field_button_clicked');
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.submitButtonClicked = function(e) {
|
||||
if (!e.isTrusted || kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_SUBMIT_BUTTON) {
|
||||
kpxcCustomLoginFieldsBanner.backToStart();
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset TOTP field selection if already set
|
||||
if (kpxcCustomLoginFieldsBanner.selection.submitButton) {
|
||||
kpxcCustomLoginFieldsBanner.removeSelection(kpxcCustomLoginFieldsBanner.selection.submitButton,
|
||||
`div.${STRING_FIELD_CLASS}`);
|
||||
kpxcCustomLoginFieldsBanner.selection.submitButton = undefined;
|
||||
}
|
||||
|
||||
kpxcCustomLoginFieldsBanner.prepareSubmitButtonSelection();
|
||||
kpxcCustomLoginFieldsBanner.buttons.confirm.disabled = true;
|
||||
|
||||
sendMessageToFrames(e, 'submit_button_clicked');
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.closeButtonClicked = function(e) {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
|
|
@ -282,6 +310,8 @@ kpxcCustomLoginFieldsBanner.updateFieldSelections = function() {
|
|||
kpxcCustomLoginFieldsBanner.prepareTOTPSelection();
|
||||
} else if (kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_STRING_FIELDS) {
|
||||
kpxcCustomLoginFieldsBanner.prepareStringFieldSelection();
|
||||
} else if (kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_SUBMIT_BUTTON) {
|
||||
kpxcCustomLoginFieldsBanner.prepareSubmitButtonSelection();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -314,6 +344,8 @@ kpxcCustomLoginFieldsBanner.confirm = async function(e) {
|
|||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location].password = undefined;
|
||||
} else if (currentSite.totp?.[0] === path[0]) {
|
||||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location].totp = undefined;
|
||||
} else if (currentSite.submitButton?.[0] === path[0]) {
|
||||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location].submitButton = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -321,10 +353,11 @@ kpxcCustomLoginFieldsBanner.confirm = async function(e) {
|
|||
const passwordPath = kpxcCustomLoginFieldsBanner.selection.password;
|
||||
const totpPath = kpxcCustomLoginFieldsBanner.selection.totp;
|
||||
const stringFieldsPaths = kpxcCustomLoginFieldsBanner.selection.fields;
|
||||
const submitButtonPath = kpxcCustomLoginFieldsBanner.selection.submitButton;
|
||||
const location = kpxc.getDocumentLocation();
|
||||
const currentSettings = kpxc.settings[DEFINED_CUSTOM_FIELDS][location];
|
||||
|
||||
if (usernamePath || passwordPath || totpPath || stringFieldsPaths.length > 0) {
|
||||
if (usernamePath || passwordPath || totpPath || stringFieldsPaths.length > 0 || submitButtonPath) {
|
||||
if (currentSettings) {
|
||||
// Update the single selection to current settings
|
||||
if (usernamePath) {
|
||||
|
|
@ -345,13 +378,19 @@ kpxcCustomLoginFieldsBanner.confirm = async function(e) {
|
|||
if (stringFieldsPaths.length > 0) {
|
||||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location].fields = stringFieldsPaths;
|
||||
}
|
||||
|
||||
if (submitButtonPath) {
|
||||
clearIdenticalField(submitButtonPath, location);
|
||||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location].submitButton = submitButtonPath;
|
||||
}
|
||||
} else {
|
||||
// Override all fields (default, because there's no currentSettings available)
|
||||
kpxc.settings[DEFINED_CUSTOM_FIELDS][location] = {
|
||||
username: usernamePath,
|
||||
password: passwordPath,
|
||||
totp: totpPath,
|
||||
fields: stringFieldsPaths
|
||||
fields: stringFieldsPaths,
|
||||
submitButton: submitButtonPath,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +420,8 @@ kpxcCustomLoginFieldsBanner.resetSelection = function() {
|
|||
username: undefined,
|
||||
password: undefined,
|
||||
totp: undefined,
|
||||
fields: []
|
||||
fields: [],
|
||||
submitButton: undefined,
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.removeMarkedFields();
|
||||
|
|
@ -423,15 +463,24 @@ kpxcCustomLoginFieldsBanner.prepareStringFieldSelection = function() {
|
|||
kpxcCustomLoginFieldsBanner.selectStringFields();
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.prepareSubmitButtonSelection = function() {
|
||||
kpxcCustomLoginFieldsBanner.infoText.textContent = tr('defineChooseSubmitButton');
|
||||
kpxcCustomLoginFieldsBanner.dataStep = STEP_SELECT_SUBMIT_BUTTON;
|
||||
kpxcCustomLoginFieldsBanner.buttons.submitButton.classList.remove(GRAY_BUTTON_CLASS);
|
||||
kpxcCustomLoginFieldsBanner.selectField('submitButton');
|
||||
};
|
||||
|
||||
kpxcCustomLoginFieldsBanner.isFieldSelected = function(field) {
|
||||
const currentFieldId = kpxcFields.setId(field);
|
||||
const selection = kpxcCustomLoginFieldsBanner.selection;
|
||||
|
||||
if (kpxcCustomLoginFieldsBanner.markedFields.some(f => f === field)) {
|
||||
return (
|
||||
(kpxcCustomLoginFieldsBanner.selection.username && kpxcCustomLoginFieldsBanner.selection.usernameElement === field)
|
||||
|| (kpxcCustomLoginFieldsBanner.selection.password && kpxcCustomLoginFieldsBanner.selection.passwordElement === field)
|
||||
|| (kpxcCustomLoginFieldsBanner.selection.totp && kpxcCustomLoginFieldsBanner.selection.totpElement === field)
|
||||
|| kpxcCustomLoginFieldsBanner.selection.fields.some(f => f[0] === currentFieldId[0])
|
||||
(selection.username && selection.usernameElement === field)
|
||||
|| (selection.password && selection.passwordElement === field)
|
||||
|| (selection.totp && selection.totpElement === field)
|
||||
|| (selection.submitButton && selection.submitButton === field)
|
||||
|| selection.fields.some(f => f[0] === currentFieldId[0])
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -460,7 +509,7 @@ kpxcCustomLoginFieldsBanner.setSelectedField = function(elem) {
|
|||
kpxcCustomLoginFieldsBanner.buttons.close.textContent = tr('optionsButtonCancel');
|
||||
};
|
||||
|
||||
// Expects 'username', 'password' or 'totp'
|
||||
// Expects 'username', 'password', 'totp' or 'submitButton'
|
||||
kpxcCustomLoginFieldsBanner.selectField = function(fieldType) {
|
||||
kpxcCustomLoginFieldsBanner.eventFieldClick = function(e) {
|
||||
const field = kpxcCustomLoginFieldsBanner.getSelectedField(e);
|
||||
|
|
@ -516,9 +565,10 @@ kpxcCustomLoginFieldsBanner.selectStringFields = function() {
|
|||
kpxcCustomLoginFieldsBanner.markFields = function() {
|
||||
let firstInput;
|
||||
const inputs = document.querySelectorAll(
|
||||
kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_STRING_FIELDS
|
||||
? kpxcCustomLoginFieldsBanner.inputQueryPatternStringFields
|
||||
: kpxcCustomLoginFieldsBanner.inputQueryPatternNormal);
|
||||
kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_SUBMIT_BUTTON ? INPUT_BUTTON_QUERY_PATTERN :
|
||||
(STEP_SELECT_STRING_FIELDS
|
||||
? kpxcCustomLoginFieldsBanner.inputQueryPatternStringFields
|
||||
: kpxcCustomLoginFieldsBanner.inputQueryPatternNormal));
|
||||
const zoom = kpxcUI.bodyStyle.zoom || 1;
|
||||
|
||||
for (const i of inputs) {
|
||||
|
|
@ -676,6 +726,9 @@ kpxcCustomLoginFieldsBanner.handleTopWindowMessage = function(args) {
|
|||
} else if (message === 'string_field_selected') {
|
||||
kpxcCustomLoginFieldsBanner.selection.fields = selection;
|
||||
kpxcCustomLoginFieldsBanner.setSelectedField();
|
||||
} else if (message === 'submitButton_selected') {
|
||||
kpxcCustomLoginFieldsBanner.selection.submitButton = selection;
|
||||
kpxcCustomLoginFieldsBanner.setSelectedField();
|
||||
} else if (message === 'enable_clear_data_button') {
|
||||
kpxcCustomLoginFieldsBanner.buttons.clearData.style.display = 'inline-block';
|
||||
}
|
||||
|
|
@ -699,6 +752,8 @@ kpxcCustomLoginFieldsBanner.handleParentWindowMessage = function(args) {
|
|||
kpxcCustomLoginFieldsBanner.totpButtonClicked(e);
|
||||
} else if (message === 'string_field_button_clicked') {
|
||||
kpxcCustomLoginFieldsBanner.stringFieldsButtonClicked(e);
|
||||
} else if (message === 'submit_button_clicked') {
|
||||
kpxcCustomLoginFieldsBanner.submitButtonClicked(e);
|
||||
} else if (message === 'reset_button_clicked') {
|
||||
kpxcCustomLoginFieldsBanner.reset();
|
||||
} else if (message === 'close_button_clicked') {
|
||||
|
|
@ -766,5 +821,7 @@ const dataStepToString = function() {
|
|||
return tr('totp');
|
||||
} else if (kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_STRING_FIELDS) {
|
||||
return tr('defineStringField');
|
||||
} else if (kpxcCustomLoginFieldsBanner.dataStep === STEP_SELECT_SUBMIT_BUTTON) {
|
||||
return tr('defineSubmitButton');
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -588,14 +588,14 @@ kpxcFields.traverseParents = function(element, predicate, resultFn = () => true,
|
|||
kpxcFields.useCustomLoginFields = async function() {
|
||||
const location = kpxc.getDocumentLocation();
|
||||
const creds = kpxc.settings['defined-custom-fields'][location];
|
||||
if (!creds.username && !creds.password && !creds.totp && creds.fields.length === 0) {
|
||||
if (!creds.username && !creds.password && !creds.totp && creds.fields.length === 0 && !creds.submitButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Finds the input field based on the stored ID
|
||||
const findInputField = async function(inputFields, idArray) {
|
||||
// Finds the element based on the stored ID
|
||||
const findElement = async function(fields, idArray) {
|
||||
if (idArray) {
|
||||
const input = inputFields.find(e => e === kpxcFields.getId(idArray, e));
|
||||
const input = fields.find(e => e === kpxcFields.getId(idArray, e));
|
||||
if (input) {
|
||||
return input;
|
||||
}
|
||||
|
|
@ -612,16 +612,24 @@ kpxcFields.useCustomLoginFields = async function() {
|
|||
}
|
||||
});
|
||||
|
||||
const [ username, password, totp ] = await Promise.all([
|
||||
await findInputField(inputFields, creds.username),
|
||||
await findInputField(inputFields, creds.password),
|
||||
await findInputField(inputFields, creds.totp)
|
||||
const buttons = [];
|
||||
document.body.querySelectorAll('button, input[type=submit]').forEach(e => {
|
||||
if (e.type !== 'hidden' && !e.disabled) {
|
||||
buttons.push(e);
|
||||
}
|
||||
});
|
||||
|
||||
const [ username, password, totp, submitButton ] = await Promise.all([
|
||||
await findElement(inputFields, creds.username),
|
||||
await findElement(inputFields, creds.password),
|
||||
await findElement(inputFields, creds.totp),
|
||||
await findElement(buttons, creds.submitButton),
|
||||
]);
|
||||
|
||||
// Handle StringFields
|
||||
const stringFields = [];
|
||||
for (const sf of creds.fields) {
|
||||
const field = await findInputField(inputFields, sf);
|
||||
const field = await findElement(inputFields, sf);
|
||||
if (field) {
|
||||
stringFields.push(field);
|
||||
}
|
||||
|
|
@ -639,7 +647,8 @@ kpxcFields.useCustomLoginFields = async function() {
|
|||
password: password,
|
||||
passwordInputs: [ password ],
|
||||
totp: totp,
|
||||
fields: stringFields
|
||||
fields: stringFields,
|
||||
submitButton: submitButton
|
||||
});
|
||||
|
||||
return combinations;
|
||||
|
|
|
|||
|
|
@ -340,7 +340,8 @@ kpxcFill.performAutoSubmit = async function(combination, skipAutoSubmit) {
|
|||
if (!skipAutoSubmit && !autoSubmitIgnoredForSite) {
|
||||
await sendMessage('page_set_autosubmit_performed');
|
||||
|
||||
const submitButton = kpxcForm.getFormSubmitButton(combination.form);
|
||||
// Use submit button from Custom Login Fields or detect it from the form
|
||||
const submitButton = combination?.submitButton ?? kpxcForm.getFormSubmitButton(combination.form);
|
||||
if (submitButton !== undefined) {
|
||||
submitButton.click();
|
||||
} else if (combination.form) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue