Open intervalia opened 5 years ago
@intervalia Thanks for raising this - I consider the lack of deep selection inside shadow roots to be a bug, and will work to add it.
Do you guys have an example page where this can be reproduced?
I will send something later today.
On Thu, Feb 14, 2019, 14:50 Maxim Baz <notifications@github.com wrote:
Do you guys have an example page where this can be reproduced?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/browserpass/browserpass/issues/319#issuecomment-463813389, or mute the thread https://github.com/notifications/unsubscribe-auth/ABg64fgzKbBZZ6jx-uWDPpHKUkll_ljyks5vNdo9gaJpZM4a8crH .
Sorry. I was in meeting until late. Here is some code that should work for your testing:
<!doctype html>
<html>
<head>
<title>Form in shadowDOM example</title>
</head>
<body>
<script>
(function() {
function getTemplate() {
var templateEl = document.createElement('template');
templateEl.innerHTML = `
<style>
:host, form{width:300px}
label{display:block;}
form input{display:block;margin-bottom:20px;padding: 4px 8px;width:100%;}
button{padding: 4px 8px;}
</style>
<form id="login">
<label for="username">Username:</label>
<input type="text" id="username"/>
<label for="password">Password:</label>
<input type="password" id="password"/>
<button class="btn btn-sm" id="signin">Login</button>
<div class="error-message"></div>
</form>`;
return templateEl.content;
}
function performLogin(evt) {
evt.preventDefault();
evt.stopPropagation();
const username = this.querySelector('#username').value;
const password = this.querySelector('#password').value;
console.log('Username', username);
console.log('Password', password);
}
// Class for `<sd-login>`
class LoginForm extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode:'open'});
shadow.appendChild(getTemplate());
const formEl = shadow.querySelector('form');
formEl.addEventListener('submit', performLogin.bind(shadow));
}
connectedCallback() {
this.shadowRoot.querySelector('input').focus();
}
}
// Define our web component
customElements.define('sd-login', LoginForm);
})();
</script>
<sd-login></sd-login>
<hr/>
<p>It would be great if we could just add an attribute to the element >sd-login<
that would let your system know where the form is located. But that would put the
burden on every developer and every webpage that uses shadowDOM</p>
</body>
</html>
General information
Your app does not support a form that exists in shadowDom and provides no way to let the app know that a form is held within the shadowDom of a particular element. As more Web Components are created there is a larger likelihood of this app not functioning since the
<form>
may be held within the shadowDOM of the Web Component. And, you can use shadowDOM without a Web Component. Several frameworks are not using shadowDOM for much of their DOM creation. We need some way to indicate that the login<form>
is held inside the element's shadowDOM so the appropriate parent can be used for the call toquerySelectorAll
.Exact steps to reproduce the problem
What should happen?
There should be a way to indicate that the shadowDOM of a given element contains the login form.
What happened instead?
The app can not see the shadowDOM.
document.querySelectorAll
does not penetrate into shadowDOM and, thus, can not find a<form>
that is contained in shadowDOM. There is no way to indicate that a particular element has a login<form>
held within its shadowDOM.