1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-27915] Add additional global styling collision defenses for pseudo-elements (#17340)

* add additional global styling collision defenses for pseudo-elements

* move internal stylesheet into closed shadow root
This commit is contained in:
Jonathan Prusik
2025-11-18 14:49:12 -05:00
committed by GitHub
parent b952e6ea44
commit df03664827
2 changed files with 49 additions and 26 deletions

View File

@@ -240,8 +240,6 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
this.buttonElement = globalThis.document.createElement(customElementName);
this.buttonElement.setAttribute("popover", "manual");
this.createInternalStyleNode(this.buttonElement);
}
/**
@@ -270,30 +268,6 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
this.listElement = globalThis.document.createElement(customElementName);
this.listElement.setAttribute("popover", "manual");
this.createInternalStyleNode(this.listElement);
}
/**
* Builds and prepends an internal stylesheet to the container node with rules
* to prevent targeting by the host's global styling rules. This should only be
* used for pseudo elements such as `::backdrop` or `::before`. All other
* styles should be applied inline upon the parent container itself.
*/
private createInternalStyleNode(parent: HTMLElement) {
const css = document.createTextNode(`
${parent.tagName}::backdrop {
background: none !important;
pointer-events: none !important;
}
${parent.tagName}::before, ${parent.tagName}::after {
content:"" !important;
}
`);
const style = globalThis.document.createElement("style");
style.setAttribute("type", "text/css");
style.appendChild(css);
parent.prepend(style);
}
/**

View File

@@ -8,7 +8,10 @@ export class AutofillInlineMenuIframeElement {
iframeTitle: string,
ariaAlert?: string,
) {
const style = this.createInternalStyleNode();
const shadow: ShadowRoot = element.attachShadow({ mode: "closed" });
shadow.prepend(style);
const autofillInlineMenuIframeService = new AutofillInlineMenuIframeService(
shadow,
portName,
@@ -18,4 +21,50 @@ export class AutofillInlineMenuIframeElement {
);
autofillInlineMenuIframeService.initMenuIframe();
}
/**
* Builds and prepends an internal stylesheet to the container node with rules
* to prevent targeting by the host's global styling rules. This should only be
* used for pseudo elements such as `::backdrop` or `::before`. All other
* styles should be applied inline upon the parent container itself for improved
* specificity priority.
*/
private createInternalStyleNode() {
const css = document.createTextNode(`
:host::backdrop,
:host::before,
:host::after {
all: initial !important;
backdrop-filter: none !important;
filter: none !important;
inset: auto !important;
touch-action: auto !important;
user-select: text !important;
display: none !important;
position: relative !important;
top: auto !important;
right: auto !important;
bottom: auto !important;
left: auto !important;
transform: none !important;
transform-origin: 50% 50% !important;
opacity: 1 !important;
mix-blend-mode: normal !important;
isolation: isolate !important;
z-index: 0 !important;
background: none !important;
background-color: transparent !important;
background-image: none !important;
width: 0 !important;
height: 0 !important;
content: "" !important;
pointer-events: all !important;
}
`);
const style = globalThis.document.createElement("style");
style.setAttribute("type", "text/css");
style.appendChild(css);
return style;
}
}