New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elements shadow dom fix #24861
Elements shadow dom fix #24861
Conversation
You can preview 1eec884 at https://pr24861-1eec884.ngbuilds.io/. |
458cf2f
to
525ca3e
Compare
You can preview 458cf2f at https://pr24861-458cf2f.ngbuilds.io/. |
throw new Error(`The selector "${selectorOrNode}" did not match any elements`); | ||
} | ||
el.textContent = ''; | ||
; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
too many ;
let el: any = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) : | ||
selectorOrNode; | ||
if (!el) { | ||
throw new Error(`The selector "${selectorOrNode}" did not match any elements`); | ||
} | ||
el.textContent = ''; | ||
if (preserveContent) { | ||
return el; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of early returns. Makes the code hard to follow. Rewrite as:
if (!preserveContent) {
el.textContent = '';
}
@@ -271,6 +274,20 @@ class ShadowDomRenderer extends DefaultDomRenderer2 { | |||
} | |||
} | |||
|
|||
selectRootElement(selectorOrNode: string|any): any { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there an extra method here?
You can preview 525ca3e at https://pr24861-525ca3e.ngbuilds.io/. |
7a08d69
to
8617d87
Compare
You can preview 7a08d69 at https://pr24861-7a08d69.ngbuilds.io/. |
You can preview 8617d87 at https://pr24861-8617d87.ngbuilds.io/. |
You can preview 8d290e2 at https://pr24861-8d290e2.ngbuilds.io/. |
You can preview 8cafe35 at https://pr24861-8cafe35.ngbuilds.io/. |
8cafe35
to
1f5de46
Compare
You can preview 1f5de46 at https://pr24861-1f5de46.ngbuilds.io/. |
You can preview f9b7adc at https://pr24861-f9b7adc.ngbuilds.io/. |
|
||
get supportsCustomElements() { return (typeof(<any>global).customElements !== 'undefined'); } | ||
|
||
get supportsDeprecatedCustomCustomElementsV0() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used anywhere. Is it necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to add a number of new integration tests for native stuff, so I added it here, also to make clear that both of these APIs are DEPRECATED
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robwormald it's better to add these helper methods when we need them, otherwise lots of them go unused. Please use that rule in the future.
|
||
get supportsShadowDom() { | ||
const testEl = document.createElement('div'); | ||
return (typeof customElements !== 'undefined') && (typeof testEl.attachShadow !== 'undefined'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof customElements !== 'undefined'
could be replaced with this.supportsCustomElements
(here and below).
packages/elements/test/slots_spec.ts
Outdated
barBar: string | ||
}; | ||
// we only run these tests in browsers that support Shadom DOM slots natively | ||
if (browserDetection.supportsCustomElements && browserDetection.supportsShadowDom) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: supportsShadowDom
implies supportsCustomElements
afaict.
packages/elements/test/slots_spec.ts
Outdated
template: '<div class="slotparent"><slot name="header"></slot><slot name="body"></slot></div>', | ||
encapsulation: ViewEncapsulation.ShadowDom | ||
}) | ||
class DefaultSlotsComponent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component is not used afaict.
packages/elements/test/slots_spec.ts
Outdated
const content = testContainer.querySelector('span.projected') !; | ||
const slot = testEl.shadowRoot !.querySelector('slot') !; | ||
const assignedNodes = slot.assignedNodes(); | ||
expect(assignedNodes[0]).toEqual(content); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be toBe()
, instead of toEqual()
, (here and below) to be sure the node is not duplicated or something.
packages/elements/test/slots_spec.ts
Outdated
import {NgElement, NgElementConstructor, createCustomElement} from '../src/create-custom-element'; | ||
import {NgElementStrategy, NgElementStrategyEvent, NgElementStrategyFactory} from '../src/element-strategy'; | ||
|
||
type WithFooBar = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused.
packages/elements/test/slots_spec.ts
Outdated
templateEl.innerHTML = tpl; | ||
const template = templateEl.content.cloneNode(true) as DocumentFragment; | ||
const testEl = template.querySelector('slot-events-el') !as NgElement & SlotEventsComponent; | ||
const content = template.querySelector('span.projected'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused.
1afc17b
to
41e0914
Compare
You can preview 41e0914 at https://pr24861-41e0914.ngbuilds.io/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this pr has many of unresolved review comments from @gkalpak please address.
packages/core/src/render/api.ts
Outdated
@@ -267,7 +267,7 @@ export abstract class Renderer2 { | |||
* @param selectorOrNode The DOM element. | |||
* @returns The root element. | |||
*/ | |||
abstract selectRootElement(selectorOrNode: string|any): any; | |||
abstract selectRootElement(selectorOrNode: string|any, preserveContent?: boolean): any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please document the new param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also please document the default value.
41e0914
to
0f88a25
Compare
You can preview a81d30f at https://pr24861-a81d30f.ngbuilds.io/. |
When using ViewEncapsulation.ShadowDom, Angular will not remove the child nodes of the DOM node a root Component is bootstrapped into. This enables developers building Angular Elements to use the `<slot>` element to do native content projection. PR Close #24861
When using ViewEncapsulation.ShadowDom, Angular will not remove the child nodes of the DOM node a root Component is bootstrapped into. This enables developers building Angular Elements to use the `<slot>` element to do native content projection. PR Close angular#24861
When using ViewEncapsulation.ShadowDom, Angular will not remove the child nodes of the DOM node a root Component is bootstrapped into. This enables developers building Angular Elements to use the `<slot>` element to do native content projection. PR Close angular#24861
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Adds a new optional parameter to the renderer.selectRootElement method:
Before:
preserveContents
defaults tofalse
to preserve existing renderer behavior. If set to true, the renderer will not remove the existing contents of a root element when bootstrapping a component.This is primarily useful when combined with the
ViewEncapsulation.ShadowDom
Renderer - the nodes are preserved, and developers can use<slot>
elements to re-project the light DOM nodes.This change had to be made to the Renderer API itself, rather than an in a specific renderer as the method is called on the default renderer, inside the view engine, rather than a renderer specific to the component: https://github.com/angular/angular/blob/master/packages/core/src/view/services.ts#L756
Fixes #24859