diff options
author | Sami Vänttinen <sami.vanttinen@protonmail.com> | 2022-05-29 20:25:33 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-29 20:25:33 +0300 |
commit | 1a7975df9372b06797868fcf0349a9faf6a4bcc1 (patch) | |
tree | 294ca2b87d9a6aa0e3c1afb3dc17e7703119640b | |
parent | 9af37d688aafa0df3eadebbe66b79c9791878275 (diff) |
Add support for traversing child elements (#1547)
Add support for traversing child elements
-rw-r--r-- | keepassxc-browser/content/observer-helper.js | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/keepassxc-browser/content/observer-helper.js b/keepassxc-browser/content/observer-helper.js index 08e3adc..2b45fd5 100644 --- a/keepassxc-browser/content/observer-helper.js +++ b/keepassxc-browser/content/observer-helper.js @@ -1,5 +1,6 @@ 'use strict'; +const MAX_CHILDREN = 50; const MAX_INPUTS = 100; const MAX_MUTATIONS = 200; @@ -149,6 +150,12 @@ kpxcObserverHelper.getInputs = function(target, ignoreVisibility = false) { inputFields.push(target); } + // Traverse children + const traversedChildren = kpxcObserverHelper.findInputsFromChildren(target); + for (const child of traversedChildren) { + inputFields.push(child); + } + // Append any input fields in Shadow DOM if (target.shadowRoot && typeof target.shadowSelectorAll === 'function') { target.shadowSelectorAll('input').forEach(e => { @@ -162,9 +169,9 @@ kpxcObserverHelper.getInputs = function(target, ignoreVisibility = false) { return []; } - // Do not allow more visible inputs than _maximumInputs (default value: 100) -> return the first 100 + // Do not allow more visible inputs than MAX_INPUTS (default value: 100) -> return the first 100 if (inputFields.length > MAX_INPUTS) { - return inputFields.slice(0, MAX_INPUTS); + inputFields = inputFields.slice(0, MAX_INPUTS); } // Only include input fields that match with kpxcObserverHelper.inputTypes @@ -190,6 +197,12 @@ kpxcObserverHelper.alreadyIdentified = function(target) { return kpxc.inputs.some(e => e === target); }; +kpxcObserverHelper.findInputsFromChildren = function(target) { + const children = []; + traverseChildren(target, children); + return children; +}; + // Adds elements to a monitor array. Identifies the input fields. kpxcObserverHelper.handleObserverAdd = async function(target) { if (kpxcObserverHelper.ignoredElement(target)) { @@ -270,3 +283,28 @@ kpxcObserverHelper.ignoredNode = function(target) { return false; }; + +// Traverses all children, including Shadow DOM elements +const traverseChildren = function(target, children, depth = 1) { + depth++; + + // Children can be scripts etc. so ignoredElement() is needed here + if (depth >= MAX_CHILDREN || kpxcObserverHelper.ignoredElement(target)) { + return; + } + + for (const child of target.childNodes) { + if (child.type === 'hidden' || child.disabled) { + continue; + } + + if (child.nodeName === 'INPUT') { + children.push(child); + } + + traverseChildren(child, children, depth); + if (child.shadowRoot) { + traverseChildren(child.shadowRoot, children, depth); + } + } +}; |