-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add inject-css-in-shadow-dom scriplet
- Loading branch information
1 parent
59528ff
commit c8808ba
Showing
4 changed files
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Function to make arbitrary operations on shadow root element, | ||
* to be passed as callback to hijackAttachShadow | ||
* | ||
* @callback attachShadowCallback | ||
* @param {HTMLElement} shadowRoot | ||
* @returns {void} | ||
*/ | ||
|
||
/** | ||
* Overrides attachShadow method of Element API on a given context | ||
* to pass retrieved shadowRoots to callback | ||
* | ||
* @param {Object} context e.g global window object or contentWindow of an iframe | ||
* @param {attachShadowCallback} callback callback to call on shadow root | ||
*/ | ||
export const hijackAttachShadow = (context, callback) => { | ||
const originalAttachShadow = context.Element.prototype.attachShadow; | ||
// eslint-disable-next-line func-names, no-param-reassign | ||
context.Element.prototype.attachShadow = function (originalArgs) { | ||
const shadowRoot = originalAttachShadow.call(this, originalArgs); | ||
callback(shadowRoot); | ||
return shadowRoot; | ||
}; | ||
|
||
const handlerWrapper = (target, thisArg, args) => { | ||
const shadowRoot = Reflect.apply(target, thisArg, args); | ||
callback(shadowRoot); | ||
return shadowRoot; | ||
}; | ||
|
||
const attachShadowHandler = { | ||
apply: handlerWrapper, | ||
}; | ||
|
||
context.Element.prototype.attachShadow = new Proxy(context.Element.prototype.attachShadow, attachShadowHandler); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { | ||
hit, | ||
hijackAttachShadow, | ||
} from '../helpers/index'; | ||
|
||
/* eslint-disable max-len */ | ||
/** | ||
* @scriptlet inject-css-in-shadow-dom | ||
* @description | ||
* Injects css rules into all Shadow DOM subtrees on a page | ||
* | ||
* **Syntax** | ||
* ``` | ||
* example.org#%#//scriptlet('inject-css-in-shadow-dom', cssRule) | ||
* ``` | ||
* | ||
* - `cssRule` - required, string of comma-separated css rules | ||
* | ||
* **Examples** | ||
* ``` | ||
* ! apply single style | ||
* example.org#%#//scriptlet('inject-css-in-shadow-dom', '#advertisement { display: none !important; }') | ||
* | ||
* ! apply multiple css rules | ||
* example.org#%#//scriptlet('inject-css-in-shadow-dom', '#advertisement { display: none !important; }, #content { margin-top: 0 !important; }') | ||
* ``` | ||
*/ | ||
/* eslint-enable max-len */ | ||
|
||
export function injectCssInShadowDom(source, cssRule) { | ||
// do nothing if browser does not support ShadowRoot | ||
// https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot | ||
if (!Element.prototype.attachShadow) { | ||
return; | ||
} | ||
|
||
const parsedStyleRules = cssRule.split(','); | ||
const callback = (shadowRoot) => { | ||
const stylesheet = new CSSStyleSheet(); | ||
|
||
// fill stylesheet with rules | ||
parsedStyleRules.forEach((rule) => stylesheet.insertRule(rule)); | ||
|
||
// attach stylesheet to shadow root so the whole subtree would be affected | ||
// https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptedStyleSheets | ||
shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, stylesheet]; | ||
}; | ||
|
||
hijackAttachShadow(window, callback); | ||
} | ||
|
||
injectCssInShadowDom.names = [ | ||
'inject-css-in-shadow-dom', | ||
]; | ||
|
||
injectCssInShadowDom.injections = [ | ||
hit, | ||
hijackAttachShadow, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters