Skip to content

Commit 9090ce4

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents e130dbf + b2471f2 commit 9090ce4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+854
-56
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ env:
3737
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
3838
- MODE=lint
3939
- MODE=circular_deps
40+
- MODE=extract_metadata
4041
- MODE=e2e
4142
- MODE=saucelabs_required
4243
- MODE=browserstack_required

scripts/ci/build-and-test.sh

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ source scripts/ci/sources/mode.sh
1111
source scripts/ci/sources/tunnel.sh
1212

1313
start_tunnel
14-
npm run build
15-
npm run inline-resources
1614

1715
wait_for_tunnel
1816
if is_lint; then
1917
npm run tslint
2018
npm run ci:forbidden-identifiers
2119
npm run stylelint
2220
elif is_circular_deps_check; then
21+
# Build first because madge needs the JavaScript output.
22+
ng build
2323
npm run check-circular-deps
2424
elif is_e2e; then
2525
# Start up the e2e app. This will take some time.
@@ -32,12 +32,24 @@ elif is_e2e; then
3232
echo "Waiting for e2e app to start"
3333
while [ ! -f ./dist/components/button/button.js ]; do
3434
sleep 2
35+
echo -n ".."
3536
done
3637

38+
echo "\nInlining resources"
39+
npm run inline-resources
40+
3741
# Run the e2e tests on the served e2e app.
3842
echo "Starting e2e tests"
3943
ng e2e
44+
elif is_extract_metadata; then
45+
# Run `tsc` first so that the directory structure in dist/ matches what ngc expects.
46+
./node_modules/.bin/tsc -p ./src/demo-app/
47+
./node_modules/.bin/ngc -p ./src/demo-app/
4048
else
49+
# Unit tests
50+
npm run build
51+
npm run inline-resources
52+
4153
karma start test/karma.conf.js --single-run --no-auto-watch --reporters='dots'
4254
fi
4355
teardown_tunnel

scripts/ci/sources/mode.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ is_lint() {
1212
is_circular_deps_check() {
1313
[[ "$MODE" = circular_deps ]]
1414
}
15+
16+
is_extract_metadata() {
17+
[[ "$MODE" = extract_metadata ]]
18+
}

src/components/button/_button-base.scss

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
@import 'variables';
33
@import 'elevation';
4+
@import 'button-mixins';
45

56
// TODO(jelbourn): This goes away.
67
@import 'default-theme';
@@ -34,12 +35,7 @@ $md-mini-fab-padding: 8px !default;
3435
position: relative;
3536

3637
// Reset browser <button> styles.
37-
background: transparent;
38-
text-align: center;
39-
cursor: pointer;
40-
user-select: none;
41-
outline: none;
42-
border: none;
38+
@include md-button-reset();
4339

4440
// Make anchors render like buttons.
4541
display: inline-block;
@@ -52,6 +48,7 @@ $md-mini-fab-padding: 8px !default;
5248
font-family: $md-font-family;
5349
font-weight: 500;
5450
color: currentColor;
51+
text-align: center;
5552

5653
// Sizing.
5754
margin: $md-button-margin;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {ViewContainerRef} from '@angular/core';
2+
3+
/** Valid ARIA roles for a dialog element. */
4+
export type DialogRole = 'dialog' | 'alertdialog'
5+
6+
7+
8+
/**
9+
* Configuration for opening a modal dialog with the MdDialog service.
10+
*/
11+
export class MdDialogConfig {
12+
viewContainerRef: ViewContainerRef;
13+
14+
/** The ARIA role of the dialog element. */
15+
role: DialogRole = 'dialog';
16+
17+
// TODO(jelbourn): add configuration for size, clickOutsideToClose, lifecycle hooks,
18+
// ARIA labelling.
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<template portalHost></template>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@import 'elevation';
2+
3+
:host {
4+
// TODO(jelbourn): add real Material Design dialog styles.
5+
display: block;
6+
background: deeppink;
7+
@include md-elevation(2);
8+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {Component, ComponentRef, ViewChild, AfterViewInit} from '@angular/core';
2+
import {
3+
BasePortalHost,
4+
ComponentPortal,
5+
TemplatePortal
6+
} from '@angular2-material/core/portal/portal';
7+
import {PortalHostDirective} from '@angular2-material/core/portal/portal-directives';
8+
import {PromiseCompleter} from '@angular2-material/core/async/promise-completer';
9+
import {MdDialogConfig} from './dialog-config';
10+
import {MdDialogContentAlreadyAttachedError} from './dialog-errors';
11+
12+
13+
/**
14+
* Internal component that wraps user-provided dialog content.
15+
*/
16+
@Component({
17+
moduleId: module.id,
18+
selector: 'md-dialog-container',
19+
templateUrl: 'dialog-container.html',
20+
styleUrls: ['dialog-container.css'],
21+
directives: [PortalHostDirective],
22+
host: {
23+
'class': 'md-dialog-container',
24+
'[attr.role]': 'dialogConfig?.role'
25+
}
26+
})
27+
export class MdDialogContainer extends BasePortalHost implements AfterViewInit {
28+
/** The portal host inside of this container into which the dialog content will be loaded. */
29+
@ViewChild(PortalHostDirective) private _portalHost: PortalHostDirective;
30+
31+
/**
32+
* Completer used to resolve the promise for cases when a portal is attempted to be attached,
33+
* but AfterViewInit has not yet occured.
34+
*/
35+
private _deferredAttachCompleter: PromiseCompleter<ComponentRef<any>>;
36+
37+
/** Portal to be attached upon AfterViewInit. */
38+
private _deferredAttachPortal: ComponentPortal<any>;
39+
40+
/** The dialog configuration. */
41+
dialogConfig: MdDialogConfig;
42+
43+
/** TODO: internal */
44+
ngAfterViewInit() {
45+
// If there was an attempted call to `attachComponentPortal` before this lifecycle stage,
46+
// we actually perform the attachment now that the `@ViewChild` is resolved.
47+
if (this._deferredAttachCompleter) {
48+
this.attachComponentPortal(this._deferredAttachPortal).then(componentRef => {
49+
this._deferredAttachCompleter.resolve(componentRef);
50+
51+
this._deferredAttachPortal = null;
52+
this._deferredAttachCompleter = null;
53+
}, () => {
54+
this._deferredAttachCompleter.reject();
55+
this._deferredAttachCompleter = null;
56+
this._deferredAttachPortal = null;
57+
});
58+
}
59+
}
60+
61+
/** Attach a portal as content to this dialog container. */
62+
attachComponentPortal<T>(portal: ComponentPortal<T>): Promise<ComponentRef<T>> {
63+
if (this._portalHost) {
64+
if (this._portalHost.hasAttached()) {
65+
throw new MdDialogContentAlreadyAttachedError();
66+
}
67+
68+
return this._portalHost.attachComponentPortal(portal);
69+
} else {
70+
// The @ViewChild query for the portalHost is not resolved until AfterViewInit, but this
71+
// function may be called before this lifecycle event. As such, we defer the attachment of
72+
// the portal until AfterViewInit.
73+
if (this._deferredAttachCompleter) {
74+
throw new MdDialogContentAlreadyAttachedError();
75+
}
76+
77+
this._deferredAttachPortal = portal;
78+
this._deferredAttachCompleter = new PromiseCompleter();
79+
return this._deferredAttachCompleter.promise;
80+
}
81+
}
82+
83+
attachTemplatePortal(portal: TemplatePortal): Promise<Map<string, any>> {
84+
throw Error('Not yet implemented');
85+
}
86+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {MdError} from '@angular2-material/core/errors/error';
2+
3+
/** Exception thrown when a ComponentPortal is attached to a DomPortalHost without an origin. */
4+
export class MdDialogContentAlreadyAttachedError extends MdError {
5+
constructor() {
6+
super('Attempting to attach dialog content after content is already attached');
7+
}
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {Injector} from '@angular/core';
2+
import {MdDialogRef} from './dialog-ref';
3+
4+
5+
/** Custom injector type specifically for instantiating components with a dialog. */
6+
export class DialogInjector implements Injector {
7+
constructor(private _dialogRef: MdDialogRef<any>, private _parentInjector: Injector) { }
8+
9+
get(token: any, notFoundValue?: any): any {
10+
if (token === MdDialogRef) {
11+
return this._dialogRef;
12+
}
13+
14+
return this._parentInjector.get(token, notFoundValue);
15+
}
16+
}

0 commit comments

Comments
 (0)