Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
},
// non-standard but important accessor
srcElement: {
get: targetGetter,
enumerable: true,
configurable: true,
},
path: {
get: composedPathValue,
enumerable: true,
configurable: true,
},
});
// not all events implement the relatedTarget getter, that's why we need to extract it from the instance
// Note: we can't really use the super here because of issues with the typescript transpilation for accessors
const originalRelatedTargetDescriptor = getPropertyDescriptor(event, 'relatedTarget');
if (!isUndefined(originalRelatedTargetDescriptor)) {
const relatedTargetGetter: (
this: Event
) => EventTarget | null = originalRelatedTargetDescriptor.get!;
defineProperty(event, 'relatedTarget', {
get(this: Event): EventTarget | null | undefined {
const eventContext = eventToContextMap.get(this);
const originalCurrentTarget = eventCurrentTargetGetter.call(this);
const relatedTarget = relatedTargetGetter.call(this);
if (isNull(relatedTarget)) {
return null;
}
const currentTarget =
eventContext === EventListenerContext.SHADOW_ROOT_LISTENER
? getShadowRoot(
originalCurrentTarget as HTMLElement
function getShadowRootRestrictionsDescriptors(
sr: ShadowRoot,
options: RestrictionsOptions
): PropertyDescriptorMap {
if (process.env.NODE_ENV === 'production') {
// this method should never leak to prod
throw new ReferenceError();
}
// blacklisting properties in dev mode only to avoid people doing the wrong
// thing when using the real shadow root, because if that's the case,
// the component will not work when running with synthetic shadow.
const originalQuerySelector = sr.querySelector;
const originalQuerySelectorAll = sr.querySelectorAll;
const originalAddEventListener = sr.addEventListener;
const descriptors: PropertyDescriptorMap = getNodeRestrictionsDescriptors(sr, options);
const originalInnerHTMLDescriptor = getPropertyDescriptor(sr, 'innerHTML')!;
const originalTextContentDescriptor = getPropertyDescriptor(sr, 'textContent')!;
assign(descriptors, {
innerHTML: generateAccessorDescriptor({
get(this: ShadowRoot): string {
return originalInnerHTMLDescriptor.get!.call(this);
},
set(this: ShadowRoot, _value: string) {
throw new TypeError(`Invalid attempt to set innerHTML on ShadowRoot.`);
},
}),
textContent: generateAccessorDescriptor({
get(this: ShadowRoot): string {
return originalTextContentDescriptor.get!.call(this);
},
set(this: ShadowRoot, _value: string) {
throw new TypeError(`Invalid attempt to set textContent on ShadowRoot.`);
function getElementRestrictionsDescriptors(
elm: HTMLElement,
options: RestrictionsOptions
): PropertyDescriptorMap {
if (process.env.NODE_ENV === 'production') {
// this method should never leak to prod
throw new ReferenceError();
}
const descriptors: PropertyDescriptorMap = getNodeRestrictionsDescriptors(elm, options);
const originalInnerHTMLDescriptor = getPropertyDescriptor(elm, 'innerHTML')!;
const originalOuterHTMLDescriptor = getPropertyDescriptor(elm, 'outerHTML')!;
assign(descriptors, {
innerHTML: generateAccessorDescriptor({
get(): string {
return originalInnerHTMLDescriptor.get!.call(this);
},
set(this: HTMLElement, value: string) {
if (isFalse(options.isPortal)) {
logError(
portalRestrictionErrorMessage('innerHTML', 'property'),
getAssociatedVMIfPresent(this)
);
}
return originalInnerHTMLDescriptor.set!.call(this, value);
},
}),
outerHTML: generateAccessorDescriptor({
sr: ShadowRoot,
options: RestrictionsOptions
): PropertyDescriptorMap {
if (process.env.NODE_ENV === 'production') {
// this method should never leak to prod
throw new ReferenceError();
}
// blacklisting properties in dev mode only to avoid people doing the wrong
// thing when using the real shadow root, because if that's the case,
// the component will not work when running with synthetic shadow.
const originalQuerySelector = sr.querySelector;
const originalQuerySelectorAll = sr.querySelectorAll;
const originalAddEventListener = sr.addEventListener;
const descriptors: PropertyDescriptorMap = getNodeRestrictionsDescriptors(sr, options);
const originalInnerHTMLDescriptor = getPropertyDescriptor(sr, 'innerHTML')!;
const originalTextContentDescriptor = getPropertyDescriptor(sr, 'textContent')!;
assign(descriptors, {
innerHTML: generateAccessorDescriptor({
get(this: ShadowRoot): string {
return originalInnerHTMLDescriptor.get!.call(this);
},
set(this: ShadowRoot, _value: string) {
throw new TypeError(`Invalid attempt to set innerHTML on ShadowRoot.`);
},
}),
textContent: generateAccessorDescriptor({
get(this: ShadowRoot): string {
return originalTextContentDescriptor.get!.call(this);
},
set(this: ShadowRoot, _value: string) {
throw new TypeError(`Invalid attempt to set textContent on ShadowRoot.`);
},
function getNodeRestrictionsDescriptors(
node: Node,
options: RestrictionsOptions
): PropertyDescriptorMap {
if (process.env.NODE_ENV === 'production') {
// this method should never leak to prod
throw new ReferenceError();
}
// getPropertyDescriptor here recursively looks up the prototype chain
// and returns the first descriptor for the property
const originalTextContentDescriptor = getPropertyDescriptor(node, 'textContent')!;
const originalNodeValueDescriptor = getPropertyDescriptor(node, 'nodeValue')!;
const { appendChild, insertBefore, removeChild, replaceChild } = node;
return {
appendChild: generateDataDescriptor({
value(this: Node, aChild: Node) {
if (this instanceof Element && isFalse(options.isPortal)) {
logError(portalRestrictionErrorMessage('appendChild', 'method'));
}
return appendChild.call(this, aChild);
},
}),
insertBefore: generateDataDescriptor({
value(this: Node, newNode: Node, referenceNode: Node) {
if (!isDomMutationAllowed && this instanceof Element && isFalse(options.isPortal)) {
logError(portalRestrictionErrorMessage('insertBefore', 'method'));
}
function getNodeRestrictionsDescriptors(
node: Node,
options: RestrictionsOptions
): PropertyDescriptorMap {
if (process.env.NODE_ENV === 'production') {
// this method should never leak to prod
throw new ReferenceError();
}
// getPropertyDescriptor here recursively looks up the prototype chain
// and returns the first descriptor for the property
const originalTextContentDescriptor = getPropertyDescriptor(node, 'textContent')!;
const originalNodeValueDescriptor = getPropertyDescriptor(node, 'nodeValue')!;
const { appendChild, insertBefore, removeChild, replaceChild } = node;
return {
appendChild: generateDataDescriptor({
value(this: Node, aChild: Node) {
if (this instanceof Element && isFalse(options.isPortal)) {
logError(portalRestrictionErrorMessage('appendChild', 'method'));
}
return appendChild.call(this, aChild);
},
}),
insertBefore: generateDataDescriptor({
value(this: Node, newNode: Node, referenceNode: Node) {
if (!isDomMutationAllowed && this instanceof Element && isFalse(options.isPortal)) {
logError(portalRestrictionErrorMessage('insertBefore', 'method'));
}
return insertBefore.call(this, newNode, referenceNode);
forEach.call(defaultDefHTMLPropertyNames, propName => {
// Note: intentionally using our in-house getPropertyDescriptor instead of getOwnPropertyDescriptor here because
// in IE11, id property is on Element.prototype instead of HTMLElement, and we suspect that more will fall into
// this category, so, better to be sure.
const descriptor = getPropertyDescriptor(HTMLElement.prototype, propName);
if (!isUndefined(descriptor)) {
HTMLElementOriginalDescriptors[propName] = descriptor;
}
});