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

chore(*): stackblitz conversion #331

Merged
merged 3 commits into from
Nov 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/tmp
/src/assets/documents
/src/assets/examples
/src/assets/plunker/examples
/src/assets/stackblitz/examples
/src/assets/*.css
/src/assets/*.html

Expand Down
4 changes: 2 additions & 2 deletions src/app/app-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {ComponentHeaderModule} from './pages/component-page-header/component-pag
import {StyleManager} from './shared/style-manager/style-manager';
import {SvgViewerModule} from './shared/svg-viewer/svg-viewer';
import {ThemePickerModule} from './shared/theme-picker/theme-picker';
import {PlunkerButtonModule} from './shared/plunker/plunker-button';
import {StackblitzButtonModule} from './shared/stackblitz/stackblitz-button';
import {NavBarModule} from './shared/navbar/navbar';
import {ThemeStorage} from './shared/theme-picker/theme-storage/theme-storage';
import {GuideItems} from './shared/guide-items/guide-items';
Expand Down Expand Up @@ -56,7 +56,7 @@ import {HttpClientModule} from '@angular/common/http';
GuideViewerModule,
HomepageModule,
NavBarModule,
PlunkerButtonModule,
StackblitzButtonModule,
SvgViewerModule,
ThemePickerModule,
],
Expand Down
4 changes: 2 additions & 2 deletions src/app/shared/doc-viewer/doc-viewer-module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {DocViewer} from './doc-viewer';
import {ExampleViewer} from '../example-viewer/example-viewer';
import {PlunkerButtonModule} from '../plunker/plunker-button';
import {StackblitzButtonModule} from '../stackblitz/stackblitz-button';
import {
MatButtonModule,
MatIconModule,
Expand All @@ -25,7 +25,7 @@ import {CopierService} from '../copier/copier.service';
MatTabsModule,
CommonModule,
PortalModule,
PlunkerButtonModule
StackblitzButtonModule
],
providers: [CopierService],
declarations: [DocViewer, ExampleViewer, HeaderLink],
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/example-viewer/example-viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</mat-icon>
</button>

<plunker-button [example]="example"></plunker-button>
<stackblitz-button [example]="example"></stackblitz-button>
</div>

<div class="docs-example-viewer-source" *ngIf="showSource">
Expand Down
1 change: 0 additions & 1 deletion src/app/shared/plunker/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/app/shared/stackblitz/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './stackblitz-button';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- TODO: change the template to be plunker icon -->
<div [matTooltip]="isDisabled ? 'Building Plunker example...' : 'Edit in Plunker'">
<!-- TODO: change the template to be stackblitz icon -->
<div [matTooltip]="isDisabled ? 'Building StackBlitz example...' : 'Edit in StackBlitz'">
<button mat-icon-button type="button"
(click)="openPlunker()"
(click)="openStackblitz()"
[disabled]="isDisabled">
<mat-icon>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
import {Component, Input, NgModule} from '@angular/core';
import {PlunkerWriter} from './plunker-writer';
import {StackblitzWriter} from './stackblitz-writer';
import {ExampleData} from '@angular/material-examples';
import {MatButtonModule, MatIconModule, MatTooltipModule} from '@angular/material';

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

@Input()
set example(example: string) {
const exampleData = new ExampleData(example);

this.plunkerWriter.constructPlunkerForm(exampleData).then(plunkerForm => {
this.plunkerForm = plunkerForm;
this.stackblitzWriter.constructStackblitzForm(exampleData).then(stackblitzForm => {
this.stackblitzForm = stackblitzForm;
this.isDisabled = false;
});
}

constructor(private plunkerWriter: PlunkerWriter) {}
constructor(private stackblitzWriter: StackblitzWriter) {}

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

@NgModule({
imports: [MatTooltipModule, MatButtonModule, MatIconModule],
exports: [PlunkerButton],
declarations: [PlunkerButton],
providers: [PlunkerWriter],
exports: [StackblitzButton],
declarations: [StackblitzButton],
providers: [StackblitzWriter],
})
export class PlunkerButtonModule {}
export class StackblitzButtonModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import {
BaseRequestOptions, Http, HttpModule, Response, ResponseOptions,
XHRBackend
} from '@angular/http';
import {PlunkerWriter} from './plunker-writer';
import {StackblitzWriter} from './stackblitz-writer';
import {ExampleData} from '@angular/material-examples';


describe('PlunkerWriter', () => {
let plunkerWriter: PlunkerWriter;
describe('StackblitzWriter', () => {
let stackblitzWriter: StackblitzWriter;
let data: ExampleData;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
declarations: [],
providers: [
PlunkerWriter,
StackblitzWriter,
BaseRequestOptions,
MockBackend,
{provide: XHRBackend, useExisting: MockBackend},
Expand All @@ -30,20 +30,20 @@ describe('PlunkerWriter', () => {
connection.mockRespond(getFakeDocResponse(url));
});

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

it('should append correct copyright', () => {
expect(plunkerWriter._appendCopyright('test.ts', 'NoContent')).toBe(`NoContent
expect(stackblitzWriter._appendCopyright('test.ts', 'NoContent')).toBe(`NoContent

/** Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license */`);

expect(plunkerWriter._appendCopyright('test.html', 'NoContent')).toBe(`NoContent
expect(stackblitzWriter._appendCopyright('test.html', 'NoContent')).toBe(`NoContent

<!-- Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
Expand All @@ -52,26 +52,26 @@ describe('PlunkerWriter', () => {
});

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

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

plunkerWriter._addFileToForm(form, data, 'NoContent', 'test.ts', 'path/to/file');
plunkerWriter._addFileToForm(form, data, 'Test', 'test.html', 'path/to/file');
plunkerWriter._addFileToForm(form, data, 'Detail', 'src/detail.ts', 'path/to/file');
stackblitzWriter._addFileToForm(form, data, 'NoContent', 'test.ts', 'path/to/file');
stackblitzWriter._addFileToForm(form, data, 'Test', 'test.html', 'path/to/file');
stackblitzWriter._addFileToForm(form, data, 'Detail', 'src/detail.ts', 'path/to/file');

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

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

expect(form.elements.length).toBe(11);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,82 @@ import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import {ExampleData} from '@angular/material-examples';
import 'rxjs/add/operator/toPromise';
import {VERSION} from '@angular/material';

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

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

const TEMPLATE_PATH = '/assets/plunker/';
const TEMPLATE_FILES = ['index.html', 'systemjs.config.js', 'main.ts'];
const TEMPLATE_PATH = '/assets/stackblitz/';
const TEMPLATE_FILES = [
'index.html',
'styles.scss',
'polyfills.ts',
'.angular-cli.json',
'main.ts'
];

const TAGS: string[] = ['angular', 'material', 'example'];
const angularVersion = '^5.0.0';
const materialVersion = '^5.0.0-rc.1';

const dependencies = {
'@angular/cdk': materialVersion,
'@angular/material': materialVersion,
'@angular/animations': angularVersion,
'@angular/common': angularVersion,
'@angular/compiler': angularVersion,
'@angular/core': angularVersion,
'@angular/forms': angularVersion,
'@angular/http': angularVersion,
'@angular/platform-browser': angularVersion,
'@angular/platform-browser-dynamic': angularVersion,
'@angular/router': angularVersion,
'angular-in-memory-web-api': '~0.5.0',
'core-js': '^2.4.1',
'rxjs': '^5.5.2',
'web-animations-js': '^2.3.1',
'zone.js': '^0.8.14',
'hammerjs': '^2.0.8'
};

/**
* Plunker writer, write example files to Plunker
* Stackblitz writer, write example files to stackblitz
*
* Plunker API
* URL: http://plnkr.co/edit/?p=preview
* StackBlitz API
* URL: https://run.stackblitz.com/api/aio/v1/
* data: {
* // File name, directory and content of files
* files[file-name1]: file-content1,
* files[directory-name/file-name2]: file-content2,
* // Can add multiple tags
* tags[0]: tag-0,
* // Description of plunker
* // Description of stackblitz
* description: description,
* // Private or not
* private: true
* // Dependencies
* dependencies: dependencies
* }
*/
@Injectable()
export class PlunkerWriter {
export class StackblitzWriter {
constructor(private _http: Http) {}

/**
* Returns an HTMLFormElement that will open a new plunker template with the example data when
* Returns an HTMLFormElement that will open a new stackblitz template with the example data when
* called with submit().
*/
constructPlunkerForm(data: ExampleData): Promise<HTMLFormElement> {
constructStackblitzForm(data: ExampleData): Promise<HTMLFormElement> {
let form = this._createFormElement();

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

return new Promise(resolve => {
let templateContents = TEMPLATE_FILES
Expand All @@ -65,10 +97,10 @@ export class PlunkerWriter {
});
}

/** Constructs a new form element that will navigate to the plunker url. */
/** Constructs a new form element that will navigate to the stackblitz url. */
_createFormElement(): HTMLFormElement {
const form = document.createElement('form');
form.action = PLUNKER_URL;
form.action = STACKBLITZ_URL;
form.method = 'post';
form.target = '_blank';
return form;
Expand Down Expand Up @@ -98,12 +130,14 @@ export class PlunkerWriter {
path: string) {
if (path == TEMPLATE_PATH) {
content = this._replaceExamplePlaceholderNames(data, filename, content);
} else {
filename = 'app/' + filename;
}
this._appendFormInput(form, `files[${filename}]`, this._appendCopyright(filename, content));
}

/**
* The Plunker template assets contain placeholder names for the examples:
* The stackblitz template assets contain placeholder names for the examples:
* "<material-docs-example>" and "MaterialDocsExample".
* This will replace those placeholders with the names from the example metadata,
* e.g. "<basic-button-example>" and "BasicButtonExample"
Expand All @@ -116,6 +150,7 @@ export class PlunkerWriter {
// For example, <material-docs-example></material-docs-example> will be replaced as
// <button-demo></button-demo>
fileContent = fileContent.replace(/material-docs-example/g, data.selectorName);
fileContent = fileContent.replace(/{{version}}/g, VERSION.full);
} else if (fileName == 'main.ts') {
// Replace the component name in `main.ts`.
// For example, `import {MaterialDocsExample} from 'material-docs-example'`
Expand Down
32 changes: 0 additions & 32 deletions src/assets/plunker/index.html

This file was deleted.

Loading