Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit f775248

Browse files
amcdnljelbourn
authored andcommitted
Convert external example write to StackBlitz (#331)
1 parent f42d5f4 commit f775248

21 files changed

+137
-166
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/tmp
66
/src/assets/documents
77
/src/assets/examples
8-
/src/assets/plunker/examples
8+
/src/assets/stackblitz/examples
99
/src/assets/*.css
1010
/src/assets/*.html
1111

src/app/app-module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {ComponentHeaderModule} from './pages/component-page-header/component-pag
2121
import {StyleManager} from './shared/style-manager/style-manager';
2222
import {SvgViewerModule} from './shared/svg-viewer/svg-viewer';
2323
import {ThemePickerModule} from './shared/theme-picker/theme-picker';
24-
import {PlunkerButtonModule} from './shared/plunker/plunker-button';
24+
import {StackblitzButtonModule} from './shared/stackblitz/stackblitz-button';
2525
import {NavBarModule} from './shared/navbar/navbar';
2626
import {ThemeStorage} from './shared/theme-picker/theme-storage/theme-storage';
2727
import {GuideItems} from './shared/guide-items/guide-items';
@@ -56,7 +56,7 @@ import {HttpClientModule} from '@angular/common/http';
5656
GuideViewerModule,
5757
HomepageModule,
5858
NavBarModule,
59-
PlunkerButtonModule,
59+
StackblitzButtonModule,
6060
SvgViewerModule,
6161
ThemePickerModule,
6262
],

src/app/shared/doc-viewer/doc-viewer-module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {DocViewer} from './doc-viewer';
22
import {ExampleViewer} from '../example-viewer/example-viewer';
3-
import {PlunkerButtonModule} from '../plunker/plunker-button';
3+
import {StackblitzButtonModule} from '../stackblitz/stackblitz-button';
44
import {
55
MatButtonModule,
66
MatIconModule,
@@ -25,7 +25,7 @@ import {CopierService} from '../copier/copier.service';
2525
MatTabsModule,
2626
CommonModule,
2727
PortalModule,
28-
PlunkerButtonModule
28+
StackblitzButtonModule
2929
],
3030
providers: [CopierService],
3131
declarations: [DocViewer, ExampleViewer, HeaderLink],

src/app/shared/example-viewer/example-viewer.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</mat-icon>
1313
</button>
1414

15-
<plunker-button [example]="example"></plunker-button>
15+
<stackblitz-button [example]="example"></stackblitz-button>
1616
</div>
1717

1818
<div class="docs-example-viewer-source" *ngIf="showSource">

src/app/shared/plunker/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/app/shared/stackblitz/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './stackblitz-button';

src/app/shared/plunker/plunker-button.html renamed to src/app/shared/stackblitz/stackblitz-button.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<!-- TODO: change the template to be plunker icon -->
2-
<div [matTooltip]="isDisabled ? 'Building Plunker example...' : 'Edit in Plunker'">
1+
<!-- TODO: change the template to be stackblitz icon -->
2+
<div [matTooltip]="isDisabled ? 'Building StackBlitz example...' : 'Edit in StackBlitz'">
33
<button mat-icon-button type="button"
4-
(click)="openPlunker()"
4+
(click)="openStackblitz()"
55
[disabled]="isDisabled">
66
<mat-icon>
77
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
11
import {Component, Input, NgModule} from '@angular/core';
2-
import {PlunkerWriter} from './plunker-writer';
2+
import {StackblitzWriter} from './stackblitz-writer';
33
import {ExampleData} from '@angular/material-examples';
44
import {MatButtonModule, MatIconModule, MatTooltipModule} from '@angular/material';
55

66
@Component({
7-
selector: 'plunker-button',
8-
templateUrl: './plunker-button.html',
9-
providers: [PlunkerWriter],
7+
selector: 'stackblitz-button',
8+
templateUrl: './stackblitz-button.html',
9+
providers: [StackblitzWriter],
1010
host: {
11-
'(mouseover)': 'isDisabled = !plunkerForm'
11+
'(mouseover)': 'isDisabled = !stackblitzForm'
1212
}
1313
})
14-
export class PlunkerButton {
14+
export class StackblitzButton {
1515
/**
16-
* The button becomes disabled if the user hovers over the button before the plunker form
16+
* The button becomes disabled if the user hovers over the button before the stackblitz form
1717
* is created. After the form is created, the button becomes enabled again.
1818
* The form creation usually happens extremely quickly, but we handle the case of the
19-
* plunker not yet being ready for people will poor network connections or slow devices.
19+
* stackblitz not yet being ready for people will poor network connections or slow devices.
2020
*/
2121
isDisabled = false;
22-
plunkerForm: HTMLFormElement;
22+
stackblitzForm: HTMLFormElement;
2323

2424
@Input()
2525
set example(example: string) {
2626
const exampleData = new ExampleData(example);
2727

28-
this.plunkerWriter.constructPlunkerForm(exampleData).then(plunkerForm => {
29-
this.plunkerForm = plunkerForm;
28+
this.stackblitzWriter.constructStackblitzForm(exampleData).then(stackblitzForm => {
29+
this.stackblitzForm = stackblitzForm;
3030
this.isDisabled = false;
3131
});
3232
}
3333

34-
constructor(private plunkerWriter: PlunkerWriter) {}
34+
constructor(private stackblitzWriter: StackblitzWriter) {}
3535

36-
openPlunker(): void {
36+
openStackblitz(): void {
3737
// When the form is submitted, it must be in the document body. The standard of forms is not
3838
// to submit if it is detached from the document. See the following chromium commit for
3939
// more details:
4040
// https://chromium.googlesource.com/chromium/src/+/962c2a22ddc474255c776aefc7abeba00edc7470%5E!
41-
document.body.appendChild(this.plunkerForm);
42-
this.plunkerForm.submit();
43-
document.body.removeChild(this.plunkerForm);
41+
document.body.appendChild(this.stackblitzForm);
42+
this.stackblitzForm.submit();
43+
document.body.removeChild(this.stackblitzForm);
4444
}
4545
}
4646

4747
@NgModule({
4848
imports: [MatTooltipModule, MatButtonModule, MatIconModule],
49-
exports: [PlunkerButton],
50-
declarations: [PlunkerButton],
51-
providers: [PlunkerWriter],
49+
exports: [StackblitzButton],
50+
declarations: [StackblitzButton],
51+
providers: [StackblitzWriter],
5252
})
53-
export class PlunkerButtonModule {}
53+
export class StackblitzButtonModule {}

src/app/shared/plunker/plunker-writer.spec.ts renamed to src/app/shared/stackblitz/stackblitz-writer.spec.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ import {
44
BaseRequestOptions, Http, HttpModule, Response, ResponseOptions,
55
XHRBackend
66
} from '@angular/http';
7-
import {PlunkerWriter} from './plunker-writer';
7+
import {StackblitzWriter} from './stackblitz-writer';
88
import {ExampleData} from '@angular/material-examples';
99

1010

11-
describe('PlunkerWriter', () => {
12-
let plunkerWriter: PlunkerWriter;
11+
describe('StackblitzWriter', () => {
12+
let stackblitzWriter: StackblitzWriter;
1313
let data: ExampleData;
1414
beforeEach(async(() => {
1515
TestBed.configureTestingModule({
1616
imports: [HttpModule],
1717
declarations: [],
1818
providers: [
19-
PlunkerWriter,
19+
StackblitzWriter,
2020
BaseRequestOptions,
2121
MockBackend,
2222
{provide: XHRBackend, useExisting: MockBackend},
@@ -30,20 +30,20 @@ describe('PlunkerWriter', () => {
3030
connection.mockRespond(getFakeDocResponse(url));
3131
});
3232

33-
plunkerWriter = TestBed.get(PlunkerWriter);
33+
stackblitzWriter = TestBed.get(StackblitzWriter);
3434
data = new ExampleData('');
3535
data.examplePath = 'http://material.angular.io/';
3636
data.exampleFiles = ['test.ts', 'test.html', 'src/detail.ts'];
3737
}));
3838

3939
it('should append correct copyright', () => {
40-
expect(plunkerWriter._appendCopyright('test.ts', 'NoContent')).toBe(`NoContent
40+
expect(stackblitzWriter._appendCopyright('test.ts', 'NoContent')).toBe(`NoContent
4141
4242
/** Copyright 2017 Google Inc. All Rights Reserved.
4343
Use of this source code is governed by an MIT-style license that
4444
can be found in the LICENSE file at http://angular.io/license */`);
4545

46-
expect(plunkerWriter._appendCopyright('test.html', 'NoContent')).toBe(`NoContent
46+
expect(stackblitzWriter._appendCopyright('test.html', 'NoContent')).toBe(`NoContent
4747
4848
<!-- Copyright 2017 Google Inc. All Rights Reserved.
4949
Use of this source code is governed by an MIT-style license that
@@ -52,26 +52,26 @@ describe('PlunkerWriter', () => {
5252
});
5353

5454
it('should create form element', () => {
55-
expect(plunkerWriter._createFormElement().outerHTML).toBe(
55+
expect(stackblitzWriter._createFormElement().outerHTML).toBe(
5656
`<form action="https://plnkr.co/edit/?p=preview" method="post" target="_blank"></form>`);
5757
});
5858

5959
it('should add files to form input', () => {
60-
let form = plunkerWriter._createFormElement();
60+
let form = stackblitzWriter._createFormElement();
6161

62-
plunkerWriter._addFileToForm(form, data, 'NoContent', 'test.ts', 'path/to/file');
63-
plunkerWriter._addFileToForm(form, data, 'Test', 'test.html', 'path/to/file');
64-
plunkerWriter._addFileToForm(form, data, 'Detail', 'src/detail.ts', 'path/to/file');
62+
stackblitzWriter._addFileToForm(form, data, 'NoContent', 'test.ts', 'path/to/file');
63+
stackblitzWriter._addFileToForm(form, data, 'Test', 'test.html', 'path/to/file');
64+
stackblitzWriter._addFileToForm(form, data, 'Detail', 'src/detail.ts', 'path/to/file');
6565

6666
expect(form.elements.length).toBe(3);
6767
expect(form.elements[0].getAttribute('name')).toBe('files[test.ts]');
6868
expect(form.elements[1].getAttribute('name')).toBe('files[test.html]');
6969
expect(form.elements[2].getAttribute('name')).toBe('files[src/detail.ts]');
7070
});
7171

72-
it('should open a new window with plunker url', fakeAsync(() => {
72+
it('should open a new window with stackblitz url', fakeAsync(() => {
7373
let form;
74-
plunkerWriter.constructPlunkerForm(data).then(result => form = result);
74+
stackblitzWriter.constructStackblitzForm(data).then(result => form = result);
7575
flushMicrotasks();
7676

7777
expect(form.elements.length).toBe(11);

src/app/shared/plunker/plunker-writer.ts renamed to src/app/shared/stackblitz/stackblitz-writer.ts

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,82 @@ import {Injectable} from '@angular/core';
22
import {Http} from '@angular/http';
33
import {ExampleData} from '@angular/material-examples';
44
import 'rxjs/add/operator/toPromise';
5+
import {VERSION} from '@angular/material';
56

6-
const PLUNKER_URL = 'https://plnkr.co/edit/?p=preview';
7+
const STACKBLITZ_URL = 'https://run.stackblitz.com/api/angular/v1/';
78

89
const COPYRIGHT =
910
`Copyright 2017 Google Inc. All Rights Reserved.
1011
Use of this source code is governed by an MIT-style license that
1112
can be found in the LICENSE file at http://angular.io/license`;
1213

13-
const TEMPLATE_PATH = '/assets/plunker/';
14-
const TEMPLATE_FILES = ['index.html', 'systemjs.config.js', 'main.ts'];
14+
const TEMPLATE_PATH = '/assets/stackblitz/';
15+
const TEMPLATE_FILES = [
16+
'index.html',
17+
'styles.scss',
18+
'polyfills.ts',
19+
'.angular-cli.json',
20+
'main.ts'
21+
];
1522

1623
const TAGS: string[] = ['angular', 'material', 'example'];
24+
const angularVersion = '^5.0.0';
25+
const materialVersion = '^5.0.0-rc.1';
26+
27+
const dependencies = {
28+
'@angular/cdk': materialVersion,
29+
'@angular/material': materialVersion,
30+
'@angular/animations': angularVersion,
31+
'@angular/common': angularVersion,
32+
'@angular/compiler': angularVersion,
33+
'@angular/core': angularVersion,
34+
'@angular/forms': angularVersion,
35+
'@angular/http': angularVersion,
36+
'@angular/platform-browser': angularVersion,
37+
'@angular/platform-browser-dynamic': angularVersion,
38+
'@angular/router': angularVersion,
39+
'angular-in-memory-web-api': '~0.5.0',
40+
'core-js': '^2.4.1',
41+
'rxjs': '^5.5.2',
42+
'web-animations-js': '^2.3.1',
43+
'zone.js': '^0.8.14',
44+
'hammerjs': '^2.0.8'
45+
};
1746

1847
/**
19-
* Plunker writer, write example files to Plunker
48+
* Stackblitz writer, write example files to stackblitz
2049
*
21-
* Plunker API
22-
* URL: http://plnkr.co/edit/?p=preview
50+
* StackBlitz API
51+
* URL: https://run.stackblitz.com/api/aio/v1/
2352
* data: {
2453
* // File name, directory and content of files
2554
* files[file-name1]: file-content1,
2655
* files[directory-name/file-name2]: file-content2,
2756
* // Can add multiple tags
2857
* tags[0]: tag-0,
29-
* // Description of plunker
58+
* // Description of stackblitz
3059
* description: description,
3160
* // Private or not
3261
* private: true
62+
* // Dependencies
63+
* dependencies: dependencies
3364
* }
3465
*/
3566
@Injectable()
36-
export class PlunkerWriter {
67+
export class StackblitzWriter {
3768
constructor(private _http: Http) {}
3869

3970
/**
40-
* Returns an HTMLFormElement that will open a new plunker template with the example data when
71+
* Returns an HTMLFormElement that will open a new stackblitz template with the example data when
4172
* called with submit().
4273
*/
43-
constructPlunkerForm(data: ExampleData): Promise<HTMLFormElement> {
74+
constructStackblitzForm(data: ExampleData): Promise<HTMLFormElement> {
4475
let form = this._createFormElement();
4576

4677
TAGS.forEach((tag, i) => this._appendFormInput(form, `tags[${i}]`, tag));
4778
this._appendFormInput(form, 'private', 'true');
4879
this._appendFormInput(form, 'description', data.description);
80+
this._appendFormInput(form, 'dependencies', JSON.stringify(dependencies));
4981

5082
return new Promise(resolve => {
5183
let templateContents = TEMPLATE_FILES
@@ -65,10 +97,10 @@ export class PlunkerWriter {
6597
});
6698
}
6799

68-
/** Constructs a new form element that will navigate to the plunker url. */
100+
/** Constructs a new form element that will navigate to the stackblitz url. */
69101
_createFormElement(): HTMLFormElement {
70102
const form = document.createElement('form');
71-
form.action = PLUNKER_URL;
103+
form.action = STACKBLITZ_URL;
72104
form.method = 'post';
73105
form.target = '_blank';
74106
return form;
@@ -98,12 +130,14 @@ export class PlunkerWriter {
98130
path: string) {
99131
if (path == TEMPLATE_PATH) {
100132
content = this._replaceExamplePlaceholderNames(data, filename, content);
133+
} else {
134+
filename = 'app/' + filename;
101135
}
102136
this._appendFormInput(form, `files[${filename}]`, this._appendCopyright(filename, content));
103137
}
104138

105139
/**
106-
* The Plunker template assets contain placeholder names for the examples:
140+
* The stackblitz template assets contain placeholder names for the examples:
107141
* "<material-docs-example>" and "MaterialDocsExample".
108142
* This will replace those placeholders with the names from the example metadata,
109143
* e.g. "<basic-button-example>" and "BasicButtonExample"
@@ -116,6 +150,7 @@ export class PlunkerWriter {
116150
// For example, <material-docs-example></material-docs-example> will be replaced as
117151
// <button-demo></button-demo>
118152
fileContent = fileContent.replace(/material-docs-example/g, data.selectorName);
153+
fileContent = fileContent.replace(/{{version}}/g, VERSION.full);
119154
} else if (fileName == 'main.ts') {
120155
// Replace the component name in `main.ts`.
121156
// For example, `import {MaterialDocsExample} from 'material-docs-example'`

src/assets/plunker/index.html

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)