-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: control if workbench part content is capable of being moved in …
…the DOM This commit adds the structural component `ContentAsOverlayComponent` which ensures that its content children are not reparented in the DOM when workbench parts are layouted. Technically, content is added to a top-level workbench DOM element and its content projected into that component's bounding box. For instance, an iframe would reload once it is reparented in the DOM. Closes #30 BREAKING CHANGE: Removed content projection from `RemoteSiteComponent` and added it to workbench part level. If using a remote site, wrap entire part content in a `<wb-content-as-overlay>` element, which causes it to be added to a top-level workbench DOM element and projected into that component's bounding box. Removed support to use `RemoteSiteComponent` as a routing component because must be a child of `<wb-content-as-overlay>` element
- Loading branch information
1 parent
f589764
commit 303d29a
Showing
25 changed files
with
302 additions
and
174 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
14 changes: 14 additions & 0 deletions
14
projects/scion/workbench/src/lib/content-projection/content-as-overlay.component.html
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,14 @@ | ||
<!-- define area where to project `ng-content` into --> | ||
<div class="projection-target" | ||
wbTemplateHostOverlay | ||
[wbTemplate]="ng_content_template" | ||
[wbOverlayHost]="contentHost"> | ||
</div> | ||
|
||
<!-- make `ng-content` available in the form of a template --> | ||
<ng-template #ng_content_template> | ||
<!-- wrap `ng-content` in a a single element --> | ||
<div class="content-as-overlay"> | ||
<ng-content></ng-content> | ||
</div> | ||
</ng-template> |
12 changes: 12 additions & 0 deletions
12
projects/scion/workbench/src/lib/content-projection/content-as-overlay.component.scss
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,12 @@ | ||
:host { | ||
display: flex; | ||
|
||
> div.projection-target { | ||
flex: auto; | ||
} | ||
} | ||
|
||
div.content-as-overlay { | ||
display: flex; // public API | ||
flex-direction: column; // public API | ||
} |
92 changes: 92 additions & 0 deletions
92
projects/scion/workbench/src/lib/content-projection/content-as-overlay.component.ts
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,92 @@ | ||
/* | ||
* Copyright (c) 2018 Swiss Federal Railways | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
|
||
import { Component, OnDestroy, Optional, ViewContainerRef } from '@angular/core'; | ||
import { ContentHostRef } from './content-host-ref.service'; | ||
import { ContentProjectionContext } from './content-projection-context.service'; | ||
import { WorkbenchView } from '../workbench.model'; | ||
import { takeUntil } from 'rxjs/operators'; | ||
import { Subject } from 'rxjs'; | ||
import { WorkbenchActivityPartService } from '../activity-part/workbench-activity-part.service'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
|
||
|
||
/** | ||
* Structural component which adds its `ng-content` to a top-level workbench DOM element and projects it into this component's bounding box. | ||
* | ||
* This component ensures that its content children are not reparented in the DOM when workbench views are rearranged or activities toggled. | ||
* For instance, an iframe would reload once it is reparented in the DOM. | ||
* | ||
* Use this component to wrap the entire content of your component, so `<wb-content-as-overlay>` is the only root view child of your component. | ||
* | ||
* `ng-content` is added to a flex-box container with `flex-direction` set to 'column'. | ||
* To style elements of `ng-content`, do not combine CSS selectors with :host CSS pseudo-class because not a child of the host component. | ||
* | ||
* | ||
* --- | ||
* Example HTML template: | ||
* | ||
* <wb-content-as-overlay> | ||
* <wb-remote-site [url]="..."></wb-remote-site> | ||
* </wb-content-as-overlay> | ||
* | ||
* | ||
* Example SCSS styles: | ||
* | ||
* :host { | ||
* display: flex; | ||
* > wb-content-as-overlay { | ||
* flex: auto; | ||
* } | ||
* } | ||
* | ||
* wb-remote-site { | ||
* flex: auto; | ||
* } | ||
*/ | ||
@Component({ | ||
selector: 'wb-content-as-overlay', | ||
templateUrl: './content-as-overlay.component.html', | ||
styleUrls: ['./content-as-overlay.component.scss'] | ||
}) | ||
export class ContentAsOverlayComponent implements OnDestroy { | ||
|
||
private _destroy$ = new Subject<void>(); | ||
public contentHost: ViewContainerRef; | ||
|
||
constructor(contentHostRef: ContentHostRef, | ||
private _contentProjection: ContentProjectionContext, | ||
@Optional() view: WorkbenchView, | ||
activityPartService: WorkbenchActivityPartService, | ||
route: ActivatedRoute) { | ||
this.contentHost = contentHostRef.get(); | ||
|
||
this.installViewActiveListener(view); | ||
this.installActivityActiveListener(activityPartService, route); | ||
} | ||
|
||
private installActivityActiveListener(activityService: WorkbenchActivityPartService, route: ActivatedRoute): void { | ||
const activity = activityService.getActivityFromRoutingContext(route.snapshot); | ||
activity && activity.active$ | ||
.pipe(takeUntil(this._destroy$)) | ||
.subscribe(active => this._contentProjection.setActive(active)); | ||
} | ||
|
||
private installViewActiveListener(view: WorkbenchView): void { | ||
view && view.active$ | ||
.pipe(takeUntil(this._destroy$)) | ||
.subscribe(active => this._contentProjection.setActive(active)); | ||
} | ||
|
||
public ngOnDestroy(): void { | ||
this._destroy$.next(); | ||
this._contentProjection.setActive(false); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
projects/scion/workbench/src/lib/content-projection/content-host-ref.service.ts
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,38 @@ | ||
/* | ||
* Copyright (c) 2018 Swiss Federal Railways | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
|
||
import { Injectable, ViewContainerRef } from '@angular/core'; | ||
|
||
/** | ||
* Represents the location in the DOM where to append content of views or activities, whose DOM elements | ||
* are not allowed to be moved within the DOM or detached/re-attached during their lifecycle. This would | ||
* happen when workbench views are rearranged or activities toggled. | ||
* | ||
* Instead, content is added to a top-level workbench DOM element and its content projected into the container's bounding box. | ||
* To not cover other parts of the workbench (e.g. sashes or view dropdown), they are placed upfront in the DOM. | ||
* | ||
* For instance, an iframe would reload once it is reparented in the DOM. | ||
*/ | ||
@Injectable() | ||
export class ContentHostRef { | ||
|
||
private _vcr: ViewContainerRef; | ||
|
||
public set(vcr: ViewContainerRef): void { | ||
if (this._vcr) { | ||
throw Error('`ViewContainerRef` already set'); | ||
} | ||
this._vcr = vcr; | ||
} | ||
|
||
public get(): ViewContainerRef { | ||
return this._vcr; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
projects/scion/workbench/src/lib/content-projection/content-projection-context.service.ts
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,22 @@ | ||
import { Injectable } from '@angular/core'; | ||
|
||
/** | ||
* Indicates if content projection is used in the current view or activity context. | ||
* | ||
* A separate instance is used for every {ViewComponent} and {ActivityPartComponent}. | ||
*/ | ||
@Injectable() | ||
export class ContentProjectionContext { | ||
|
||
private _active = false; | ||
|
||
public setActive(active: boolean): void { | ||
// Set active flag asynchronously to not run into a `ExpressionChangedAfterItHasBeenCheckedError`, | ||
// e.g. if evaluated by a component which already was change detected. | ||
setTimeout(() => this._active = active); | ||
} | ||
|
||
public isActive(): boolean { | ||
return this._active; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
projects/scion/workbench/src/lib/content-projection/mixins.scss
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,30 @@ | ||
/* | ||
* Copyright (c) 2018 Swiss Federal Railways | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
|
||
/** | ||
* Pointer events are ignored in 'activity part' and 'viewpart-grid' to allow interaction with projected content. | ||
* Projected content is out of the element flow and added to a top-level workbench DOM element. It is projected | ||
* into respective view or activity bounding box. | ||
* | ||
* To not cover other parts of the workbench (e.g. sashes), it is placed upfront in the DOM, which requires projection | ||
* areas to ignore pointer events and not to use a background color. | ||
* | ||
* Use this mixin to allow pointer events in selected areas like sashes, activity header or view tabbar. | ||
*/ | ||
@mixin allowPointerEvents() { | ||
pointer-events: auto; | ||
} | ||
|
||
/** | ||
* See mixin 'allowPointerEvents' | ||
*/ | ||
@mixin preventPointerEvents() { | ||
pointer-events: none; | ||
} |
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
35 changes: 0 additions & 35 deletions
35
projects/scion/workbench/src/lib/remote-site/iframe-host-ref.service.ts
This file was deleted.
Oops, something went wrong.
22 changes: 7 additions & 15 deletions
22
projects/scion/workbench/src/lib/remote-site/remote-site.component.html
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 |
---|---|---|
@@ -1,15 +1,7 @@ | ||
<main wbTemplateHostOverlay | ||
[wbTemplate]="iframe_template" | ||
[wbOverlayHost]="iframeHostRef.get()" | ||
(wbTemplateViewRef)="onIframeViewRef($event)"> | ||
</main> | ||
|
||
<ng-template #iframe_template> | ||
<iframe [src]="siteUrl" | ||
(load)="onSiteLoad($event)" | ||
scrolling="no" | ||
frameborder="0" | ||
marginheight="0" | ||
marginwidth="0"> | ||
</iframe> | ||
</ng-template> | ||
<iframe [src]="siteUrl" | ||
(load)="onSiteLoad($event)" | ||
scrolling="no" | ||
frameborder="0" | ||
marginheight="0" | ||
marginwidth="0"> | ||
</iframe> |
Oops, something went wrong.