Skip to content

feat(projection): Host Projection service #1756

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

Merged
merged 1 commit into from
Nov 16, 2016
Merged

Conversation

hansl
Copy link
Contributor

@hansl hansl commented Nov 7, 2016

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Nov 7, 2016
@jelbourn jelbourn added the in progress This issue is currently in progress label Nov 8, 2016
@hansl hansl force-pushed the projection branch 4 times, most recently from 07f8973 to 75c2693 Compare November 8, 2016 22:34
@hansl hansl added pr: needs review and removed in progress This issue is currently in progress labels Nov 9, 2016
</div>
`,
styles: [`
.outer {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefix class name with demo-
(same for other classes in the demo)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.



@Injectable()
export class MdProjectionService {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about DomProjector?

I'm generally opposed to the Service suffix since it's somewhat meaningless; it's talking about how the class is meant to be consumed rather than what it does. Also, the service is specifically dealing with projection via DOM, hence DomProjector.

Going along this vein, how about calling the directive DomProjectionHost with selector dom-projection-host? I think this makes the API a bit more explicit than <md-host>, which doesn't give a string cue as to what it's for.

(also omitting the md prefix since this would be something not strictly related to material design, similar to the portal and overlay directives).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

let child = childNodes[0];

// Replace ComponentEl by all its children, in place.
this._replaceWith(componentEl, child);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this just an non-exported module function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay.

* Project an element into a host element.
*/
project(ref: ElementRef, host: MdProjectionHostDirective): void {
const componentEl = ref.nativeElement;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can append as Node on these

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.


@Injectable()
export class MdProjectionService {
private _replaceWith(toReplaceEl: HTMLElement, otherEl: HTMLElement) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be Node instead of HTMLElement (less specific)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot replace all nodes by all nodes in the tree. Element is semantically accurate.


// Replace ComponentEl by all its children, in place.
this._replaceWith(componentEl, child);
while (childNodes.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading length on a NodeList is notoriously slow; it's better to cache the length and for loop.
(here and below)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

/**
* Project an element into a host element.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment needs some expansion; the key thing to communicate is that it's only the given element that is projected and not its content (children). Also worth mention when you might want to use this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* Project an element into a host element.
*/
project(ref: ElementRef, host: MdProjectionHostDirective): void {
const componentEl = ref.nativeElement;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

componentEl -> projectedEl? (since it's not necessarily a component)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const childNodes = componentEl.childNodes;
let child = childNodes[0];

// Replace ComponentEl by all its children, in place.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expand comment to something like

// We hoist all of the projected element's children out into the projected elements position
// because we *only* want to move the projected element and not its children.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

`,
styles: [`
.inner {
background-color: blue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: these colors are totally unreadable to me (when I run the demo)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@hansl
Copy link
Contributor Author

hansl commented Nov 11, 2016

@jelbourn please re-review

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Nov 12, 2016
@kara
Copy link
Contributor

kara commented Nov 15, 2016

@hansl I think you need to add MdProjectionHostDirective to the module definition. It's failing presubmit.

@kara kara removed the action: merge The PR is ready for merge by the caretaker label Nov 15, 2016
@hansl
Copy link
Contributor Author

hansl commented Nov 16, 2016

@kara could you rerun the presubmits? It should pass now.

@hansl hansl added the action: merge The PR is ready for merge by the caretaker label Nov 16, 2016
@kara
Copy link
Contributor

kara commented Nov 16, 2016

Absolutely! Momentito.

@kara kara merged commit 522324c into angular:master Nov 16, 2016
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants