chore: rename modules/examples to modules/playground
The directory contains code authored in a style that makes it transpilable to dart. As such, these are not idiomatic examples of Angular 2 usage. The main purpose of this directory is to enable experimentation with Angular within the angular/angular repository. Closes #4342 Closes #4639
This commit is contained in:

committed by
Flavio Corpa Ríos

parent
c3ab20cc87
commit
e4e74ae65c
3
modules/playground/e2e_test/async/async_spec.dart
Normal file
3
modules/playground/e2e_test/async/async_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.async_spec;
|
||||
|
||||
main() {}
|
62
modules/playground/e2e_test/async/async_spec.ts
Normal file
62
modules/playground/e2e_test/async/async_spec.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('async', () => {
|
||||
var URL = 'playground/src/async/index.html';
|
||||
|
||||
beforeEach(() => browser.get(URL));
|
||||
|
||||
it('should work with synchronous actions', () => {
|
||||
var increment = $('#increment');
|
||||
increment.$('.action').click();
|
||||
|
||||
expect(increment.$('.val').getText()).toEqual('1');
|
||||
});
|
||||
|
||||
it('should wait for asynchronous actions', () => {
|
||||
var timeout = $('#delayedIncrement');
|
||||
|
||||
// At this point, the async action is still pending, so the count should
|
||||
// still be 0.
|
||||
expect(timeout.$('.val').getText()).toEqual('0');
|
||||
|
||||
timeout.$('.action').click();
|
||||
|
||||
// whenStable should only be called when the async action finished,
|
||||
// so the count should be 1 at this point.
|
||||
expect(timeout.$('.val').getText()).toEqual('1');
|
||||
});
|
||||
|
||||
it('should notice when asynchronous actions are cancelled', () => {
|
||||
var timeout = $('#delayedIncrement');
|
||||
|
||||
// At this point, the async action is still pending, so the count should
|
||||
// still be 0.
|
||||
expect(timeout.$('.val').getText()).toEqual('0');
|
||||
|
||||
browser.ignoreSynchronization = true;
|
||||
timeout.$('.action').click();
|
||||
|
||||
timeout.$('.cancel').click();
|
||||
browser.ignoreSynchronization = false;
|
||||
|
||||
// whenStable should be called since the async action is cancelled. The
|
||||
// count should still be 0;
|
||||
expect(timeout.$('.val').getText()).toEqual('0');
|
||||
});
|
||||
|
||||
it('should wait for a series of asynchronous actions', () => {
|
||||
var timeout = $('#multiDelayedIncrements');
|
||||
|
||||
// At this point, the async action is still pending, so the count should
|
||||
// still be 0.
|
||||
expect(timeout.$('.val').getText()).toEqual('0');
|
||||
|
||||
timeout.$('.action').click();
|
||||
|
||||
// whenStable should only be called when all the async actions
|
||||
// finished, so the count should be 10 at this point.
|
||||
expect(timeout.$('.val').getText()).toEqual('10');
|
||||
});
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.hello_world.hello_world_spec;
|
||||
|
||||
main() {}
|
34
modules/playground/e2e_test/hello_world/hello_world_spec.ts
Normal file
34
modules/playground/e2e_test/hello_world/hello_world_spec.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('hello world', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('hello world app', function() {
|
||||
var URL = 'playground/src/hello_world/index.html';
|
||||
|
||||
it('should greet', function() {
|
||||
browser.get(URL);
|
||||
|
||||
expect(getComponentText('hello-app', '.greeting')).toEqual('hello world!');
|
||||
});
|
||||
|
||||
it('should change greeting', function() {
|
||||
browser.get(URL);
|
||||
|
||||
clickComponentButton('hello-app', '.changeButton');
|
||||
expect(getComponentText('hello-app', '.greeting')).toEqual('howdy world!');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function getComponentText(selector, innerSelector) {
|
||||
return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' +
|
||||
innerSelector + '").textContent');
|
||||
}
|
||||
|
||||
function clickComponentButton(selector, innerSelector) {
|
||||
return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' +
|
||||
innerSelector + '").click()');
|
||||
}
|
3
modules/playground/e2e_test/http/http_spec.dart
Normal file
3
modules/playground/e2e_test/http/http_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.http.http_spec;
|
||||
|
||||
main() {}
|
22
modules/playground/e2e_test/http/http_spec.ts
Normal file
22
modules/playground/e2e_test/http/http_spec.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/// <reference path="../../../angular2/typings/jasmine/jasmine.d.ts" />
|
||||
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('http', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('fetching', function() {
|
||||
var URL = 'playground/src/http/index.html';
|
||||
|
||||
it('should fetch and display people', function() {
|
||||
browser.get(URL);
|
||||
expect(getComponentText('http-app', '.people')).toEqual('hello, Jeff');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getComponentText(selector, innerSelector) {
|
||||
return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' +
|
||||
innerSelector + '").textContent.trim()');
|
||||
}
|
3
modules/playground/e2e_test/jsonp/jsonp_spec.dart
Normal file
3
modules/playground/e2e_test/jsonp/jsonp_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.jsonp.jsonp_spec;
|
||||
|
||||
main() {}
|
22
modules/playground/e2e_test/jsonp/jsonp_spec.ts
Normal file
22
modules/playground/e2e_test/jsonp/jsonp_spec.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/// <reference path="../../../angular2/typings/jasmine/jasmine.d.ts" />
|
||||
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('jsonp', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('fetching', function() {
|
||||
var URL = 'playground/src/jsonp/index.html';
|
||||
|
||||
it('should fetch and display people', function() {
|
||||
browser.get(URL);
|
||||
expect(getComponentText('jsonp-app', '.people')).toEqual('hello, caitp');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getComponentText(selector, innerSelector) {
|
||||
return browser.executeScript('return document.querySelector("' + selector + '").querySelector("' +
|
||||
innerSelector + '").textContent.trim()');
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.key_events.key_events_spec;
|
||||
|
||||
main() {}
|
70
modules/playground/e2e_test/key_events/key_events_spec.ts
Normal file
70
modules/playground/e2e_test/key_events/key_events_spec.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('key_events', function() {
|
||||
|
||||
var URL = 'playground/src/key_events/index.html';
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
beforeEach(() => { browser.get(URL); });
|
||||
|
||||
it('should display correct key names', function() {
|
||||
var firstArea = element.all(by.css('.sample-area')).get(0);
|
||||
expect(firstArea.getText()).toEqual('(none)');
|
||||
|
||||
// testing different key categories:
|
||||
firstArea.sendKeys(protractor.Key.ENTER);
|
||||
expect(firstArea.getText()).toEqual('enter');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.SHIFT, protractor.Key.ENTER);
|
||||
expect(firstArea.getText()).toEqual('shift.enter');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.CONTROL, protractor.Key.SHIFT, protractor.Key.ENTER);
|
||||
expect(firstArea.getText()).toEqual('control.shift.enter');
|
||||
|
||||
firstArea.sendKeys(' ');
|
||||
expect(firstArea.getText()).toEqual('space');
|
||||
|
||||
// It would not work with a letter which position depends on the keyboard layout (ie AZERTY vs
|
||||
// QWERTY), see https://code.google.com/p/chromedriver/issues/detail?id=553
|
||||
firstArea.sendKeys('u');
|
||||
expect(firstArea.getText()).toEqual('u');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.CONTROL, 'b');
|
||||
expect(firstArea.getText()).toEqual('control.b');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.F1);
|
||||
expect(firstArea.getText()).toEqual('f1');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.ALT, protractor.Key.F1);
|
||||
expect(firstArea.getText()).toEqual('alt.f1');
|
||||
|
||||
firstArea.sendKeys(protractor.Key.CONTROL, protractor.Key.F1);
|
||||
expect(firstArea.getText()).toEqual('control.f1');
|
||||
|
||||
// There is an issue with protractor.Key.NUMPAD0 (and other NUMPADx):
|
||||
// chromedriver does not correctly set the location property on the event to
|
||||
// specify that the key is on the numeric keypad (event.location = 3)
|
||||
// so the following test fails:
|
||||
// firstArea.sendKeys(protractor.Key.NUMPAD0);
|
||||
// expect(firstArea.getText()).toEqual('0');
|
||||
});
|
||||
|
||||
it('should correctly react to the specified key', function() {
|
||||
var secondArea = element.all(by.css('.sample-area')).get(1);
|
||||
secondArea.sendKeys(protractor.Key.SHIFT, protractor.Key.ENTER);
|
||||
expect(secondArea.getText()).toEqual('You pressed shift.enter!');
|
||||
});
|
||||
|
||||
it('should not react to incomplete keys', function() {
|
||||
var secondArea = element.all(by.css('.sample-area')).get(1);
|
||||
secondArea.sendKeys(protractor.Key.ENTER);
|
||||
expect(secondArea.getText()).toEqual('');
|
||||
});
|
||||
|
||||
it('should not react to keys with more modifiers', function() {
|
||||
var secondArea = element.all(by.css('.sample-area')).get(1);
|
||||
secondArea.sendKeys(protractor.Key.CONTROL, protractor.Key.SHIFT, protractor.Key.ENTER);
|
||||
expect(secondArea.getText()).toEqual('');
|
||||
});
|
||||
|
||||
});
|
3
modules/playground/e2e_test/material/button_spec.dart
Normal file
3
modules/playground/e2e_test/material/button_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.button_spec;
|
||||
|
||||
main() {}
|
10
modules/playground/e2e_test/material/button_spec.ts
Normal file
10
modules/playground/e2e_test/material/button_spec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-button', function() {
|
||||
var url = 'playground/src/material/button/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
// Buttons are broken right now, see https://github.com/angular/angular/issues/1602
|
||||
});
|
3
modules/playground/e2e_test/material/checkbox_spec.dart
Normal file
3
modules/playground/e2e_test/material/checkbox_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.checkbox_spec;
|
||||
|
||||
main() {}
|
18
modules/playground/e2e_test/material/checkbox_spec.ts
Normal file
18
modules/playground/e2e_test/material/checkbox_spec.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-checkbox', function() {
|
||||
var url = 'playground/src/material/checkbox/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should toggle a checkbox', function() {
|
||||
var checkbox = element.all(by.css('md-checkbox')).first();
|
||||
|
||||
checkbox.click();
|
||||
expect(checkbox.getAttribute('aria-checked')).toEqual('true');
|
||||
|
||||
checkbox.click();
|
||||
expect(checkbox.getAttribute('aria-checked')).toEqual('false');
|
||||
});
|
||||
});
|
3
modules/playground/e2e_test/material/dialog_spec.dart
Normal file
3
modules/playground/e2e_test/material/dialog_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.dialog_spec;
|
||||
|
||||
main() {}
|
21
modules/playground/e2e_test/material/dialog_spec.ts
Normal file
21
modules/playground/e2e_test/material/dialog_spec.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-dialog', function() {
|
||||
var url = 'playground/src/material/dialog/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should open a dialog', function() {
|
||||
var openButton = element(by.id('open'));
|
||||
openButton.click();
|
||||
|
||||
var dialog = element(by.css('.md-dialog'));
|
||||
|
||||
expect(dialog.isPresent()).toEqual(true);
|
||||
|
||||
dialog.sendKeys(protractor.Key.ESCAPE);
|
||||
|
||||
expect(element(by.css('.md-dialog')).isPresent()).toEqual(false);
|
||||
});
|
||||
});
|
3
modules/playground/e2e_test/material/grid_list_spec.dart
Normal file
3
modules/playground/e2e_test/material/grid_list_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.grid_list_spec;
|
||||
|
||||
main() {}
|
16
modules/playground/e2e_test/material/grid_list_spec.ts
Normal file
16
modules/playground/e2e_test/material/grid_list_spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-grid-list', function() {
|
||||
var url = 'playground/src/material/grid_list/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should set tiles into different positions', () => {
|
||||
var tiles = element.all(by.css('md-grid-list#complex md-grid-tile'));
|
||||
|
||||
// If the grid-list was not doing any layout, all of the tiles would have the same position.
|
||||
// So our smoke test simply checks that any two tiles are in different positions.
|
||||
expect(tiles.first().getLocation()).not.toEqual(tiles.last().getLocation());
|
||||
});
|
||||
});
|
3
modules/playground/e2e_test/material/input_spec.dart
Normal file
3
modules/playground/e2e_test/material/input_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.input_spec;
|
||||
|
||||
main() {}
|
16
modules/playground/e2e_test/material/input_spec.ts
Normal file
16
modules/playground/e2e_test/material/input_spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-input', function() {
|
||||
var url = 'playground/src/material/input/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should enter a value to the input', () => {
|
||||
var input = element.all(by.css('md-input-container input')).first();
|
||||
|
||||
input.sendKeys('Hello');
|
||||
|
||||
expect(input.getAttribute('value')).toEqual('Hello');
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.progress_linear_spec;
|
||||
|
||||
main() {}
|
23
modules/playground/e2e_test/material/progress_linear_spec.ts
Normal file
23
modules/playground/e2e_test/material/progress_linear_spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-progress-linear', function() {
|
||||
var url = 'playground/src/material/progress-linear/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should increment and decrement progress', function() {
|
||||
var progressBar = element.all(by.css('md-progress-linear')).first();
|
||||
var incrementButton = element(by.id('increment'));
|
||||
var decrementButton = element(by.id('decrement'));
|
||||
|
||||
var initialValue = progressBar.getAttribute('aria-valuenow');
|
||||
|
||||
incrementButton.click();
|
||||
expect(progressBar.getAttribute('aria-valuenow')).toBeGreaterThan(initialValue);
|
||||
|
||||
decrementButton.click();
|
||||
decrementButton.click();
|
||||
expect(progressBar.getAttribute('aria-valuenow')).toBeLessThan(initialValue);
|
||||
});
|
||||
});
|
3
modules/playground/e2e_test/material/radio_spec.dart
Normal file
3
modules/playground/e2e_test/material/radio_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.material.radio_spec;
|
||||
|
||||
main() {}
|
21
modules/playground/e2e_test/material/radio_spec.ts
Normal file
21
modules/playground/e2e_test/material/radio_spec.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('md-radio-button', function() {
|
||||
var url = 'playground/src/material/radio/index.html';
|
||||
|
||||
beforeEach(() => { browser.get(url); });
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should check one radio button and then check another', () => {
|
||||
var standaloneRadios = element.all(by.css('[name="element"]'));
|
||||
var firstRadio = standaloneRadios.first();
|
||||
var lastRadio = standaloneRadios.last();
|
||||
|
||||
firstRadio.click();
|
||||
expect(firstRadio.getAttribute('aria-checked')).toEqual('true');
|
||||
|
||||
lastRadio.click();
|
||||
expect(firstRadio.getAttribute('aria-checked')).toEqual('false');
|
||||
expect(lastRadio.getAttribute('aria-checked')).toEqual('true');
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.hello_world.model_driven_forms_spec;
|
||||
|
||||
main() {}
|
@ -0,0 +1,21 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('Model-Driven Forms', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
var URL = 'playground/src/model_driven_forms/index.html';
|
||||
|
||||
it('should display errors', function() {
|
||||
browser.get(URL);
|
||||
|
||||
var form = element.all(by.css('form')).first();
|
||||
var input = element.all(by.css('#creditCard')).first();
|
||||
var firstName = element.all(by.css('#firstName')).first();
|
||||
|
||||
input.sendKeys('invalid');
|
||||
firstName.click();
|
||||
|
||||
expect(form.getInnerHtml()).toContain('is invalid credit card number');
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.order_management_spec;
|
||||
|
||||
main() {}
|
@ -0,0 +1,10 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('Order Management CRUD', function() {
|
||||
var URL = 'playground/src/order_management/index.html';
|
||||
|
||||
it('should work', function() {
|
||||
browser.get(URL);
|
||||
verifyNoBrowserErrors();
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.person_management_spec;
|
||||
|
||||
main() {}
|
@ -0,0 +1,10 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('Person Management CRUD', function() {
|
||||
var URL = 'playground/src/person_management/index.html';
|
||||
|
||||
it('should work', function() {
|
||||
browser.get(URL);
|
||||
verifyNoBrowserErrors();
|
||||
});
|
||||
});
|
3
modules/playground/e2e_test/routing/routing_spec.dart
Normal file
3
modules/playground/e2e_test/routing/routing_spec.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.routing.routing_spec;
|
||||
|
||||
main() {}
|
92
modules/playground/e2e_test/routing/routing_spec.ts
Normal file
92
modules/playground/e2e_test/routing/routing_spec.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/core/facade/async';
|
||||
|
||||
function waitForElement(selector) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
}
|
||||
|
||||
describe('routing inbox-app', () => {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('index view', () => {
|
||||
var URL = 'playground/src/routing/';
|
||||
|
||||
it('should list out the current collection of items', () => {
|
||||
browser.get(URL);
|
||||
waitForElement('.inbox-item-record');
|
||||
expect(element.all(by.css('.inbox-item-record')).count()).toEqual(200);
|
||||
});
|
||||
|
||||
it('should build a link which points to the detail page', () => {
|
||||
browser.get(URL);
|
||||
waitForElement('#item-15');
|
||||
expect(element(by.css('#item-15')).getAttribute('href')).toMatch(/\/detail\/15$/);
|
||||
element(by.css('#item-15')).click();
|
||||
waitForElement('#record-id');
|
||||
expect(browser.getCurrentUrl()).toMatch(/\/detail\/15$/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('drafts view', () => {
|
||||
var URL = 'playground/src/routing/#/drafts';
|
||||
|
||||
it('should navigate to the drafts view when the drafts link is clicked', () => {
|
||||
browser.get(URL);
|
||||
waitForElement('.inbox-item-record');
|
||||
element(by.linkText('Drafts')).click();
|
||||
waitForElement('.page-title');
|
||||
expect(element(by.css('.page-title')).getText()).toEqual('Drafts');
|
||||
});
|
||||
|
||||
it('should navigate to email details', () => {
|
||||
browser.get(URL);
|
||||
element(by.linkText('Drafts')).click();
|
||||
waitForElement('.inbox-item-record');
|
||||
expect(element.all(by.css('.inbox-item-record')).count()).toEqual(2);
|
||||
expect(element(by.css('#item-201')).getAttribute('href')).toMatch(/\/detail\/201$/);
|
||||
element(by.css('#item-201')).click();
|
||||
waitForElement('#record-id');
|
||||
expect(browser.getCurrentUrl()).toMatch(/\/detail\/201$/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('detail view', () => {
|
||||
var URL = 'playground/src/routing/';
|
||||
|
||||
it('should navigate to the detail view when an email is clicked', () => {
|
||||
browser.get(URL);
|
||||
waitForElement('#item-10');
|
||||
element(by.css('#item-10')).click();
|
||||
waitForElement('#record-id');
|
||||
var recordId = element(by.css("#record-id"));
|
||||
browser.wait(protractor.until.elementTextIs(recordId, "ID: 10"), 5000);
|
||||
expect(recordId.getText()).toEqual('ID: 10');
|
||||
});
|
||||
|
||||
it('should navigate back to the email inbox page when the back button is clicked', () => {
|
||||
browser.get(URL);
|
||||
waitForElement('#item-10');
|
||||
element(by.css('#item-10')).click();
|
||||
waitForElement('.back-button');
|
||||
element(by.css('.back-button')).click();
|
||||
expect(browser.getCurrentUrl()).toMatch(/\/$/);
|
||||
});
|
||||
|
||||
it('should navigate back to index and sort the page items based on the provided querystring param',
|
||||
() => {
|
||||
browser.get(URL);
|
||||
waitForElement('#item-10');
|
||||
element(by.css('#item-10')).click();
|
||||
waitForElement('.sort-button');
|
||||
element(by.css('.sort-button')).click();
|
||||
expect(browser.getCurrentUrl()).toMatch(/\/#\?sort=date$/);
|
||||
waitForElement('.inbox-item-record');
|
||||
expect(element(by.css(".inbox-item-record > a")).getAttribute("id")).toEqual("item-137");
|
||||
});
|
||||
})
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.sourcemap.sourcemap_spec;
|
||||
|
||||
main() {}
|
44
modules/playground/e2e_test/sourcemap/sourcemap_spec.ts
Normal file
44
modules/playground/e2e_test/sourcemap/sourcemap_spec.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import * as testUtil from 'angular2/src/testing/e2e_util';
|
||||
|
||||
var fs = require('fs');
|
||||
var sourceMap = require('source-map');
|
||||
|
||||
describe('sourcemaps', function() {
|
||||
var URL = 'playground/src/sourcemap/index.html';
|
||||
|
||||
it('should map sources', function() {
|
||||
browser.get(URL);
|
||||
|
||||
$('error-app .errorButton').click();
|
||||
|
||||
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
|
||||
// so that the browser logs can be read out!
|
||||
browser.executeScript('1+1');
|
||||
browser.manage().logs().get('browser').then(function(logs) {
|
||||
var errorLine = null;
|
||||
var errorColumn = null;
|
||||
logs.forEach(function(log) {
|
||||
var match = /\.createError\s+\(.+:(\d+):(\d+)/m.exec(log.message);
|
||||
if (match) {
|
||||
errorLine = parseInt(match[1]);
|
||||
errorColumn = parseInt(match[2]);
|
||||
}
|
||||
});
|
||||
|
||||
expect(errorLine).not.toBeNull();
|
||||
expect(errorColumn).not.toBeNull();
|
||||
|
||||
|
||||
var sourceMapData = fs.readFileSync('dist/js/prod/es5/playground/src/sourcemap/index.js.map');
|
||||
var decoder = new sourceMap.SourceMapConsumer(JSON.parse(sourceMapData));
|
||||
|
||||
var originalPosition = decoder.originalPositionFor({line: errorLine, column: errorColumn});
|
||||
|
||||
var sourceCodeLines =
|
||||
fs.readFileSync('modules/playground/src/sourcemap/index.ts', {encoding: 'UTF-8'})
|
||||
.split('\n');
|
||||
expect(sourceCodeLines[originalPosition.line - 1])
|
||||
.toMatch(/throw new BaseException\(\'Sourcemap test\'\)/);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.hello_world.template_driven_forms_spec;
|
||||
|
||||
main() {}
|
@ -0,0 +1,21 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('Template-Driven Forms', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
var URL = 'playground/src/template_driven_forms/index.html';
|
||||
|
||||
it('should display errors', function() {
|
||||
browser.get(URL);
|
||||
|
||||
var form = element.all(by.css('form')).first();
|
||||
var input = element.all(by.css('#creditCard')).first();
|
||||
var firstName = element.all(by.css('#firstName')).first();
|
||||
|
||||
input.sendKeys('invalid');
|
||||
firstName.click();
|
||||
|
||||
expect(form.getInnerHtml()).toContain('is invalid credit card number');
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.web_workers.kitchen_sink_spec;
|
||||
|
||||
main() {}
|
@ -0,0 +1,47 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/core/facade/async';
|
||||
|
||||
describe('WebWorkers Kitchen Sink', function() {
|
||||
afterEach(() => {
|
||||
verifyNoBrowserErrors();
|
||||
browser.ignoreSynchronization = false;
|
||||
});
|
||||
var selector = "hello-app .greeting";
|
||||
var URL = "playground/src/web_workers/kitchen_sink/index.html";
|
||||
|
||||
it('should greet', () => {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
|
||||
browser.wait(protractor.until.elementLocated(by.css(selector)), 15000);
|
||||
expect(element.all(by.css(selector)).first().getText()).toEqual("hello world!");
|
||||
|
||||
});
|
||||
|
||||
it('should change greeting', () => {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
|
||||
browser.wait(protractor.until.elementLocated(by.css(selector)), 15000);
|
||||
element(by.css("hello-app .changeButton")).click();
|
||||
var elem = element(by.css(selector));
|
||||
browser.wait(protractor.until.elementTextIs(elem, "howdy world!"), 5000);
|
||||
expect(elem.getText()).toEqual("howdy world!");
|
||||
});
|
||||
|
||||
it("should display correct key names", () => {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
browser.wait(protractor.until.elementLocated(by.css(".sample-area")), 15000);
|
||||
|
||||
var area = element.all(by.css(".sample-area")).first();
|
||||
expect(area.getText()).toEqual('(none)');
|
||||
|
||||
area.sendKeys('u');
|
||||
browser.wait(protractor.until.elementTextIs(area, "U"), 5000);
|
||||
expect(area.getText()).toEqual("U");
|
||||
});
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.message_bus;
|
||||
|
||||
main() {}
|
@ -0,0 +1,39 @@
|
||||
import {verifyNoBrowserErrors} from "angular2/src/testing/e2e_util";
|
||||
import {PromiseWrapper} from "angular2/src/core/facade/async";
|
||||
|
||||
var URL = 'playground/src/web_workers/message_broker/index.html';
|
||||
|
||||
describe("MessageBroker", function() {
|
||||
|
||||
afterEach(() => {
|
||||
verifyNoBrowserErrors();
|
||||
browser.ignoreSynchronization = false;
|
||||
});
|
||||
|
||||
it("should bootstrap", () => {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
waitForBootstrap();
|
||||
expect(element(by.css("app h1")).getText()).toEqual("WebWorker MessageBroker Test");
|
||||
});
|
||||
|
||||
it("should echo messages", () => {
|
||||
const VALUE = "Hi There";
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
waitForBootstrap();
|
||||
|
||||
var input = element.all(by.css("#echo_input")).first();
|
||||
input.sendKeys(VALUE);
|
||||
element(by.css("#send_echo")).click();
|
||||
var area = element(by.css("#echo_result"));
|
||||
browser.wait(protractor.until.elementTextIs(area, VALUE), 5000);
|
||||
expect(area.getText()).toEqual(VALUE);
|
||||
});
|
||||
});
|
||||
|
||||
function waitForBootstrap(): void {
|
||||
browser.wait(protractor.until.elementLocated(by.css("app h1")), 15000);
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.web_workers.todo_spec;
|
||||
|
||||
main() {}
|
25
modules/playground/e2e_test/web_workers/todo/todo_spec.ts
Normal file
25
modules/playground/e2e_test/web_workers/todo/todo_spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/core/facade/async';
|
||||
|
||||
describe('WebWorkers Todo', function() {
|
||||
afterEach(() => {
|
||||
verifyNoBrowserErrors();
|
||||
browser.ignoreSynchronization = false;
|
||||
});
|
||||
|
||||
var URL = "playground/src/web_workers/todo/index.html";
|
||||
|
||||
it('should bootstrap', () => {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
|
||||
waitForBootstrap();
|
||||
expect(element(by.css("#todoapp header")).getText()).toEqual("todos");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function waitForBootstrap(): void {
|
||||
browser.wait(protractor.until.elementLocated(by.css("todo-app #todoapp")), 15000);
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
library playground.e2e_test.zippy_component.zippy_spec;
|
||||
|
||||
main() {}
|
31
modules/playground/e2e_test/zippy_component/zippy_spec.ts
Normal file
31
modules/playground/e2e_test/zippy_component/zippy_spec.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
|
||||
describe('Zippy Component', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('zippy', function() {
|
||||
var URL = 'playground/src/zippy_component/index.html';
|
||||
|
||||
beforeEach(function() { browser.get(URL); });
|
||||
|
||||
it('should change the zippy title depending on it\'s state', function() {
|
||||
var zippyTitle = element(by.css('.zippy__title'));
|
||||
|
||||
expect(zippyTitle.getText()).toEqual('▾ Details');
|
||||
zippyTitle.click();
|
||||
expect(zippyTitle.getText()).toEqual('▸ Details');
|
||||
});
|
||||
|
||||
it('should have zippy content', function() {
|
||||
expect(element(by.css('.zippy__content')).getText()).toEqual('This is some content.');
|
||||
});
|
||||
|
||||
it('should toggle when the zippy title is clicked', function() {
|
||||
element(by.css('.zippy__title')).click();
|
||||
expect(element(by.css('.zippy__content')).isDisplayed()).toEqual(false);
|
||||
element(by.css('.zippy__title')).click();
|
||||
expect(element(by.css('.zippy__content')).isDisplayed()).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
61
modules/playground/pubspec.yaml
Normal file
61
modules/playground/pubspec.yaml
Normal file
@ -0,0 +1,61 @@
|
||||
name: playground
|
||||
environment:
|
||||
sdk: '>=1.10.0 <2.0.0'
|
||||
dependencies:
|
||||
observe: '^0.13.1'
|
||||
angular2: '^<%= packageJson.version %>'
|
||||
angular2_material: '^<%= packageJson.version %>'
|
||||
browser: '^0.10.0'
|
||||
dev_dependencies:
|
||||
guinness: '^0.1.17'
|
||||
benchpress:
|
||||
path: ../benchpress
|
||||
dependency_overrides:
|
||||
angular2:
|
||||
path: ../angular2
|
||||
angular2_material:
|
||||
path: ../angular2_material
|
||||
transformers:
|
||||
- angular2:
|
||||
entry_points:
|
||||
- web/src/gestures/index.dart
|
||||
- web/src/hello_world/index.dart
|
||||
- web/src/key_events/index.dart
|
||||
- web/src/sourcemap/index.dart
|
||||
- web/src/todo/index.dart
|
||||
- web/src/order_management/index.dart
|
||||
- web/src/model_driven_forms/index.dart
|
||||
- web/src/observable_models/index.dart
|
||||
- web/src/person_management/index.dart
|
||||
- web/src/template_driven_forms/index.dart
|
||||
- web/src/zippy_component/index.dart
|
||||
- web/src/material/button/index.dart
|
||||
- web/src/material/checkbox/index.dart
|
||||
- web/src/material/dialog/index.dart
|
||||
- web/src/material/grid_list/index.dart
|
||||
- web/src/material/input/index.dart
|
||||
- web/src/material/progress-linear/index.dart
|
||||
- web/src/material/radio/index.dart
|
||||
- web/src/material/switcher/index.dart
|
||||
|
||||
# These entrypoints are disabled untl the transformer supports UI bootstrap (issue #3971)
|
||||
# - web/src/web_workers/message_broker/index.dart
|
||||
# - web/src/web_workers/kitchen_sink/index.dart
|
||||
# - web/src/web_workers/todo/index.dart
|
||||
# - web/src/web_workers/todo/server_index.dart
|
||||
# - web/src/web_workers/todo/background_index.dart
|
||||
# - web/src/web_workers/message_broker/background_index.dart
|
||||
# - web/src/web_workers/kitchen_sink/background_index.dart
|
||||
#
|
||||
# This entrypoint is not needed:
|
||||
# - web/src/material/demo_common.dart
|
||||
|
||||
- $dart2js:
|
||||
minify: false
|
||||
commandLineOptions:
|
||||
- --show-package-warnings
|
||||
- --trust-type-annotations
|
||||
- --trust-primitives
|
||||
- --enable-experimental-mirrors
|
||||
# Uncomment to generate summaries from dart2js
|
||||
# - --dump-info
|
14
modules/playground/src/animate/animate-app.ts
Normal file
14
modules/playground/src/animate/animate-app.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {Component, View, NgIf} from 'angular2/angular2';
|
||||
|
||||
@Component({selector: 'animate-app'})
|
||||
@View({
|
||||
directives: [NgIf],
|
||||
template: `
|
||||
<h1>The box is {{visible ? 'visible' : 'hidden'}}</h1>
|
||||
<div class="ng-animate box" *ng-if="visible"></div>
|
||||
<button (click)="visible = !visible">Animate</button>
|
||||
`
|
||||
})
|
||||
export class AnimateApp {
|
||||
visible: boolean = false;
|
||||
}
|
25
modules/playground/src/animate/css/app.css
Normal file
25
modules/playground/src/animate/css/app.css
Normal file
@ -0,0 +1,25 @@
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: red;
|
||||
transition: all 0.35s ease-in-out;
|
||||
}
|
||||
.box.blue {
|
||||
background-color: blue;
|
||||
}
|
||||
.box.ng-enter {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
}
|
||||
.box.ng-enter-active {
|
||||
opacity: 1;
|
||||
height: 100px;
|
||||
}
|
||||
.box.ng-leave-active {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
}
|
10
modules/playground/src/animate/index.html
Normal file
10
modules/playground/src/animate/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<title>Animation Example</title>
|
||||
<link rel="stylesheet" type="text/css" href="./css/app.css" />
|
||||
<base href="/playground/src/animate/">
|
||||
<body>
|
||||
<animate-app>Loading...</animate-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
6
modules/playground/src/animate/index.ts
Normal file
6
modules/playground/src/animate/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import {AnimateApp} from './animate-app';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
|
||||
export function main() {
|
||||
bootstrap(AnimateApp);
|
||||
}
|
14
modules/playground/src/async/index.html
Normal file
14
modules/playground/src/async/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Async</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<async-app>
|
||||
Loading...
|
||||
</async-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
96
modules/playground/src/async/index.ts
Normal file
96
modules/playground/src/async/index.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {NgIf, Component, View} from 'angular2/core';
|
||||
import {TimerWrapper} from 'angular2/src/core/facade/async';
|
||||
|
||||
@Component({selector: 'async-app'})
|
||||
@View({
|
||||
template: `
|
||||
<div id='increment'>
|
||||
<span class='val'>{{val1}}</span>
|
||||
<button class='action' (click)="increment()">Increment</button>
|
||||
</div>
|
||||
<div id='delayedIncrement'>
|
||||
<span class='val'>{{val2}}</span>
|
||||
<button class='action' (click)="delayedIncrement()">Delayed Increment</button>
|
||||
<button class='cancel' *ng-if="timeoutId != null" (click)="cancelDelayedIncrement()">Cancel</button>
|
||||
</div>
|
||||
<div id='multiDelayedIncrements'>
|
||||
<span class='val'>{{val3}}</span>
|
||||
<button class='action' (click)="multiDelayedIncrements(10)">10 Delayed Increments</button>
|
||||
<button class='cancel' *ng-if="multiTimeoutId != null" (click)="cancelMultiDelayedIncrements()">Cancel</button>
|
||||
</div>
|
||||
<div id='periodicIncrement'>
|
||||
<span class='val'>{{val4}}</span>
|
||||
<button class='action' (click)="periodicIncrement()">Periodic Increment</button>
|
||||
<button class='cancel' *ng-if="intervalId != null" (click)="cancelPeriodicIncrement()">Cancel</button>
|
||||
</div>
|
||||
`,
|
||||
directives: [NgIf]
|
||||
})
|
||||
class AsyncApplication {
|
||||
val1: number = 0;
|
||||
val2: number = 0;
|
||||
val3: number = 0;
|
||||
val4: number = 0;
|
||||
timeoutId = null;
|
||||
multiTimeoutId = null;
|
||||
intervalId = null;
|
||||
|
||||
increment(): void { this.val1++; };
|
||||
|
||||
delayedIncrement(): void {
|
||||
this.cancelDelayedIncrement();
|
||||
this.timeoutId = TimerWrapper.setTimeout(() => {
|
||||
this.val2++;
|
||||
this.timeoutId = null;
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
multiDelayedIncrements(i: number): void {
|
||||
this.cancelMultiDelayedIncrements();
|
||||
|
||||
var self = this;
|
||||
function helper(_i) {
|
||||
if (_i <= 0) {
|
||||
self.multiTimeoutId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
self.multiTimeoutId = TimerWrapper.setTimeout(() => {
|
||||
self.val3++;
|
||||
helper(_i - 1);
|
||||
}, 500);
|
||||
}
|
||||
helper(i);
|
||||
};
|
||||
|
||||
periodicIncrement(): void {
|
||||
this.cancelPeriodicIncrement();
|
||||
this.intervalId = TimerWrapper.setInterval(() => { this.val4++; }, 2000)
|
||||
};
|
||||
|
||||
cancelDelayedIncrement(): void {
|
||||
if (this.timeoutId != null) {
|
||||
TimerWrapper.clearTimeout(this.timeoutId);
|
||||
this.timeoutId = null;
|
||||
}
|
||||
};
|
||||
|
||||
cancelMultiDelayedIncrements(): void {
|
||||
if (this.multiTimeoutId != null) {
|
||||
TimerWrapper.clearTimeout(this.multiTimeoutId);
|
||||
this.multiTimeoutId = null;
|
||||
}
|
||||
};
|
||||
|
||||
cancelPeriodicIncrement(): void {
|
||||
if (this.intervalId != null) {
|
||||
TimerWrapper.clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function main() {
|
||||
bootstrap(AsyncApplication);
|
||||
}
|
16
modules/playground/src/benchpress/index.html
Normal file
16
modules/playground/src/benchpress/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Benchpress test</title>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="pleaseLog()">Click me</button>
|
||||
<div id="log"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function pleaseLog() {
|
||||
document.getElementById("log").innerHTML = "hi";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
32
modules/playground/src/gestures/index.html
Normal file
32
modules/playground/src/gestures/index.html
Normal file
File diff suppressed because one or more lines are too long
20
modules/playground/src/gestures/index.ts
Normal file
20
modules/playground/src/gestures/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {Component, View} from 'angular2/core';
|
||||
|
||||
@Component({selector: 'gestures-app'})
|
||||
@View({templateUrl: 'template.html'})
|
||||
class GesturesCmp {
|
||||
swipeDirection: string = '-';
|
||||
pinchScale: number = 1;
|
||||
rotateAngle: number = 0;
|
||||
|
||||
onSwipe(event): void { this.swipeDirection = event.deltaX > 0 ? 'right' : 'left'; }
|
||||
|
||||
onPinch(event): void { this.pinchScale = event.scale; }
|
||||
|
||||
onRotate(event): void { this.rotateAngle = event.rotation; }
|
||||
}
|
||||
|
||||
export function main() {
|
||||
bootstrap(GesturesCmp);
|
||||
}
|
15
modules/playground/src/gestures/template.html
Normal file
15
modules/playground/src/gestures/template.html
Normal file
@ -0,0 +1,15 @@
|
||||
<style type="text/css">
|
||||
.row {
|
||||
height: 33%;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid black;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row" (swipe)="onSwipe($event)">Swipe (direction = {{swipeDirection}})</div>
|
||||
<div class="row" (pinch)="onPinch($event)">pinch (scale = {{pinchScale}})</div>
|
||||
<div class="row" (rotate)="onRotate($event)">Rotate (angle = {{rotateAngle}})</div>
|
||||
<div class="row"></div>
|
11
modules/playground/src/hello_world/index.html
Normal file
11
modules/playground/src/hello_world/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<title>Hello Angular 2.0</title>
|
||||
<body>
|
||||
<hello-app>
|
||||
Loading...
|
||||
</hello-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
62
modules/playground/src/hello_world/index.ts
Normal file
62
modules/playground/src/hello_world/index.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {ElementRef, Component, Directive, Injectable} from 'angular2/core';
|
||||
import {Renderer} from 'angular2/render';
|
||||
|
||||
export function main() {
|
||||
// Bootstrapping only requires specifying a root component.
|
||||
// The boundary between the Angular application and the rest of the page is
|
||||
// the shadowDom of this root component.
|
||||
// The selector of the component passed in is used to find where to insert the
|
||||
// application.
|
||||
// You can use the light dom of the <hello-app> tag as temporary content (for
|
||||
// example 'Loading...') before the application is ready.
|
||||
bootstrap(HelloCmp);
|
||||
}
|
||||
|
||||
// A service available to the Injector, used by the HelloCmp component.
|
||||
@Injectable()
|
||||
class GreetingService {
|
||||
greeting: string = 'hello';
|
||||
}
|
||||
|
||||
// Directives are light-weight. They don't allow new
|
||||
// expression contexts (use @Component for those needs).
|
||||
@Directive({selector: '[red]'})
|
||||
class RedDec {
|
||||
// ElementRef is always injectable and it wraps the element on which the
|
||||
// directive was found by the compiler.
|
||||
constructor(el: ElementRef, renderer: Renderer) { renderer.setElementStyle(el, 'color', 'red'); }
|
||||
}
|
||||
|
||||
// Angular 2.0 supports 2 basic types of directives:
|
||||
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
|
||||
// ShadowDom.(http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
|
||||
// - Directive - add behavior to existing elements.
|
||||
|
||||
// @Component is AtScript syntax to annotate the HelloCmp class as an Angular
|
||||
// 2.0 component.
|
||||
@Component({
|
||||
// The Selector prop tells Angular on which elements to instantiate this
|
||||
// class. The syntax supported is a basic subset of CSS selectors, for example
|
||||
// 'element', '[attr]', [attr=foo]', etc.
|
||||
selector: 'hello-app',
|
||||
// These are services that would be created if a class in the component's
|
||||
// template tries to inject them.
|
||||
viewProviders: [GreetingService],
|
||||
// Expressions in the template (like {{greeting}}) are evaluated in the
|
||||
// context of the HelloCmp class below.
|
||||
template: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`,
|
||||
// All directives used in the template need to be specified. This allows for
|
||||
// modularity (RedDec can only be used in this template)
|
||||
// and better tooling (the template can be invalidated if the attribute is
|
||||
// misspelled).
|
||||
directives: [RedDec]
|
||||
})
|
||||
export class HelloCmp {
|
||||
greeting: string;
|
||||
|
||||
constructor(service: GreetingService) { this.greeting = service.greeting; }
|
||||
|
||||
changeGreeting(): void { this.greeting = 'howdy'; }
|
||||
}
|
21
modules/playground/src/http/http_comp.ts
Normal file
21
modules/playground/src/http/http_comp.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import {Component, View, NgFor} from 'angular2/angular2';
|
||||
import {Http} from 'angular2/http';
|
||||
|
||||
@Component({selector: 'http-app'})
|
||||
@View({
|
||||
directives: [NgFor],
|
||||
template: `
|
||||
<h1>people</h1>
|
||||
<ul class="people">
|
||||
<li *ng-for="#person of people">
|
||||
hello, {{person['name']}}
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
})
|
||||
export class HttpCmp {
|
||||
people: Object;
|
||||
constructor(http: Http) {
|
||||
http.get('./people.json').map(res => res.json()).subscribe(res => this.people = res);
|
||||
}
|
||||
}
|
11
modules/playground/src/http/index.html
Normal file
11
modules/playground/src/http/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<title>Hello Http</title>
|
||||
<body>
|
||||
<http-app>
|
||||
Loading...
|
||||
</http-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
7
modules/playground/src/http/index.ts
Normal file
7
modules/playground/src/http/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {HTTP_PROVIDERS} from 'angular2/http';
|
||||
import {HttpCmp} from './http_comp';
|
||||
|
||||
export function main() {
|
||||
bootstrap(HttpCmp, [HTTP_PROVIDERS]);
|
||||
}
|
1
modules/playground/src/http/people.json
Normal file
1
modules/playground/src/http/people.json
Normal file
@ -0,0 +1 @@
|
||||
[{"name":"Jeff"}]
|
11
modules/playground/src/jsonp/index.html
Normal file
11
modules/playground/src/jsonp/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<title>Hello Jsonp</title>
|
||||
<body>
|
||||
<jsonp-app>
|
||||
Loading...
|
||||
</jsonp-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
7
modules/playground/src/jsonp/index.ts
Normal file
7
modules/playground/src/jsonp/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {JSONP_PROVIDERS} from 'angular2/http';
|
||||
import {JsonpCmp} from './jsonp_comp';
|
||||
|
||||
export function main() {
|
||||
bootstrap(JsonpCmp, [JSONP_PROVIDERS]);
|
||||
}
|
22
modules/playground/src/jsonp/jsonp_comp.ts
Normal file
22
modules/playground/src/jsonp/jsonp_comp.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import {Component, View, NgFor} from 'angular2/angular2';
|
||||
import {Jsonp, Response} from 'angular2/http';
|
||||
import {ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||
|
||||
@Component({selector: 'jsonp-app'})
|
||||
@View({
|
||||
directives: [NgFor],
|
||||
template: `
|
||||
<h1>people</h1>
|
||||
<ul class="people">
|
||||
<li *ng-for="#person of people">
|
||||
hello, {{person['name']}}
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
})
|
||||
export class JsonpCmp {
|
||||
people: Object;
|
||||
constructor(jsonp: Jsonp) {
|
||||
jsonp.get('./people.json?callback=JSONP_CALLBACK').subscribe(res => this.people = res.json());
|
||||
}
|
||||
}
|
2
modules/playground/src/jsonp/people.json
Normal file
2
modules/playground/src/jsonp/people.json
Normal file
@ -0,0 +1,2 @@
|
||||
// This can only be requested once due to constant method name :(
|
||||
__ng_jsonp__.__req0.finished([{"name":"caitp"}])
|
26
modules/playground/src/key_events/index.html
Normal file
26
modules/playground/src/key_events/index.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<title>Key events</title>
|
||||
<style>
|
||||
.sample-area {
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #d0d0d0;
|
||||
}
|
||||
.sample-area:focus {
|
||||
border: 1px solid blue;
|
||||
color: blue;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<key-events-app>
|
||||
Loading...
|
||||
</key-events-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
36
modules/playground/src/key_events/index.ts
Normal file
36
modules/playground/src/key_events/index.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {Component, View} from 'angular2/core';
|
||||
import {KeyEventsPlugin} from 'angular2/src/core/render/dom/events/key_events';
|
||||
|
||||
@Component({selector: 'key-events-app'})
|
||||
@View({
|
||||
template: `Click in the following area and press a key to display its name:<br>
|
||||
<div (keydown)="onKeyDown($event)" class="sample-area" tabindex="0">{{lastKey}}</div><br>
|
||||
Click in the following area and press shift.enter:<br>
|
||||
<div
|
||||
(keydown.shift.enter)="onShiftEnter($event)"
|
||||
(click)="resetShiftEnter()"
|
||||
class="sample-area"
|
||||
tabindex="0"
|
||||
>{{shiftEnter ? 'You pressed shift.enter!' : ''}}</div>`
|
||||
})
|
||||
class KeyEventsApp {
|
||||
lastKey: string = '(none)';
|
||||
shiftEnter: boolean = false;
|
||||
|
||||
onKeyDown(event): void {
|
||||
this.lastKey = KeyEventsPlugin.getEventFullKey(event);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
onShiftEnter(event): void {
|
||||
this.shiftEnter = true;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
resetShiftEnter(): void { this.shiftEnter = false; }
|
||||
}
|
||||
|
||||
export function main() {
|
||||
bootstrap(KeyEventsApp);
|
||||
}
|
12
modules/playground/src/material/.clang-format
Normal file
12
modules/playground/src/material/.clang-format
Normal file
@ -0,0 +1,12 @@
|
||||
Language: JavaScript
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 100
|
||||
|
||||
TabWidth: 2
|
||||
ContinuationIndentWidth: 4
|
||||
MaxEmptyLinesToKeep : 2
|
||||
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
88
modules/playground/src/material/button/demo_app.html
Normal file
88
modules/playground/src/material/button/demo_app.html
Normal file
@ -0,0 +1,88 @@
|
||||
<style>
|
||||
section {
|
||||
background: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
position: relative !important;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.label {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 7px;
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.custom {
|
||||
background-color: #ae0001;
|
||||
color: #eeba30;
|
||||
}
|
||||
|
||||
.custom:hover, .custom.md-button-focus {
|
||||
background-color: #740001;
|
||||
color: #d3a625;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Button demo</h1>
|
||||
|
||||
<p>
|
||||
You just clicked: <span>{{previousClick}}</span>
|
||||
</p>
|
||||
|
||||
<section>
|
||||
<form (submit)="submit('form submit')">
|
||||
<button md-button>SUBMIT</button>
|
||||
<button>Native button</button>
|
||||
</form>
|
||||
|
||||
<span class="label">form submit</span>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<span class="label">Regular button</span>
|
||||
|
||||
<button md-button (click)="click('button')">BUTTON</button>
|
||||
|
||||
<button md-button class="md-primary" (click)="click('primary')">PRIMARY</button>
|
||||
<button md-button disabled="disabled" (click)="click('disabled')">DISABLED</button>
|
||||
<button md-button class="md-accent" (click)="click('accent')">ACCENT</button>
|
||||
<button md-button class="md-warn" (click)="click('warn')">WARN</button>
|
||||
<button md-button class="custom" (click)="click('custom')">CUSTOM</button>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<span class="label">Raised button</span>
|
||||
<button md-raised-button (click)="click('raised')">BUTTON</button>
|
||||
<button md-raised-button class="md-primary" (click)="click('raised primary')">PRIMARY</button>
|
||||
<button md-raised-button disabled="disabled" (click)="click('raised disabled')">DISABLED</button>
|
||||
<button md-raised-button class="md-accent" (click)="click('raised accent')">ACCENT</button>
|
||||
<button md-raised-button class="md-warn" (click)="click('raised warn')">WARN</button>
|
||||
<button md-raised-button class="custom" (click)="click('custom raised')">CUSTOM</button>
|
||||
</section>
|
||||
<section>
|
||||
<span class="label">Fab button</span>
|
||||
<button md-fab (click)="click('fab')">BTN</button>
|
||||
<button md-fab class="md-primary" (click)="click('fab primary')">PRMY</button>
|
||||
<button md-fab disabled="disabled" (click)="click('fab disabled')">DIS</button>
|
||||
<button md-fab class="md-accent" (click)="click('fab accent')">ACC</button>
|
||||
<button md-fab class="md-warn" (click)="click('fab warn')">WRN</button>
|
||||
<button md-fab class="custom" (click)="click('custom fab')">CSTM</button>
|
||||
</section>
|
||||
<section>
|
||||
<span class="label">Anchor / hyperlink</span>
|
||||
<a md-button href="http://google.com" target="_blank">HREF</a>
|
||||
<a md-button href="http://google.com" disabled>DISABLED HREF</a>
|
||||
<a md-raised-button target="_blank" href="http://google.com">RAISED HREF</a>
|
||||
</section>
|
||||
|
||||
<section dir="rtl">
|
||||
<span class="label" dir="ltr">Right-to-left</span>
|
||||
<button md-button (click)="click('Hebrew button')">לחצן</button>
|
||||
<button md-raised-button (click)="click('Hebrew raised button')">העלה</button>
|
||||
<a md-button href="http://translate.google.com">עוגן</a>
|
||||
</section>
|
||||
|
13
modules/playground/src/material/button/index.html
Normal file
13
modules/playground/src/material/button/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material button demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif; } </style>
|
||||
</head>
|
||||
<body>
|
||||
<demo-app>Loading...</demo-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
44
modules/playground/src/material/button/index.ts
Normal file
44
modules/playground/src/material/button/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, NgFor, UrlResolver, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdButton, MdAnchor} from 'angular2_material/src/components/button/button';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdButton, MdAnchor, NgFor],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
class DemoApp {
|
||||
previousClick: string;
|
||||
action: string;
|
||||
clickCount: number;
|
||||
items: number[];
|
||||
|
||||
constructor() {
|
||||
this.previousClick = 'Nothing';
|
||||
this.action = "ACTIVATE";
|
||||
this.clickCount = 0;
|
||||
this.items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
||||
}
|
||||
|
||||
click(msg: string) {
|
||||
this.previousClick = msg;
|
||||
}
|
||||
|
||||
submit(msg: string, event) {
|
||||
event.preventDefault();
|
||||
this.previousClick = msg;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.clickCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
9
modules/playground/src/material/checkbox/demo_app.html
Normal file
9
modules/playground/src/material/checkbox/demo_app.html
Normal file
@ -0,0 +1,9 @@
|
||||
<div md-theme="default">
|
||||
<h2>Checkbox demo</h2>
|
||||
|
||||
<md-checkbox (click)="increment()">Normal checkbox</md-checkbox>
|
||||
<md-checkbox class="md-primary" (click)="increment()">Primary checkbox</md-checkbox>
|
||||
<md-checkbox disabled (click)="increment()">Disabled checkbox</md-checkbox>
|
||||
|
||||
<p>Toggle count: {{toggleCount}}</p>
|
||||
</div>
|
13
modules/playground/src/material/checkbox/index.html
Normal file
13
modules/playground/src/material/checkbox/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material checkbox demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; } </style>
|
||||
</head>
|
||||
<body>
|
||||
<demo-app>Loading...</demo-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
38
modules/playground/src/material/checkbox/index.ts
Normal file
38
modules/playground/src/material/checkbox/index.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {
|
||||
bind,
|
||||
provide,
|
||||
Component,
|
||||
Directive,
|
||||
UrlResolver,
|
||||
View,
|
||||
ViewEncapsulation
|
||||
} from 'angular2/core';
|
||||
import {MdCheckbox} from 'angular2_material/src/components/checkbox/checkbox';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdCheckbox],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
class DemoApp {
|
||||
toggleCount: number;
|
||||
|
||||
constructor() {
|
||||
this.toggleCount = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.toggleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
23
modules/playground/src/material/demo_common.dart
Normal file
23
modules/playground/src/material/demo_common.dart
Normal file
@ -0,0 +1,23 @@
|
||||
library angular2_examples.material.demo_common;
|
||||
|
||||
import 'package:angular2/src/core/dom/browser_adapter.dart';
|
||||
import 'package:angular2/src/core/compiler/url_resolver.dart';
|
||||
|
||||
void commonDemoSetup() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
}
|
||||
|
||||
class DemoUrlResolver extends UrlResolver {
|
||||
@override
|
||||
String resolve(String baseUrl, String url) {
|
||||
const MATERIAL_PKG = 'package:angular2_material/';
|
||||
|
||||
// We run a proxy server in front of pub serve that prepends "example" to
|
||||
// paths
|
||||
if (url.startsWith(MATERIAL_PKG)) {
|
||||
return '/examples/packages/angular2_material/' +
|
||||
url.substring(MATERIAL_PKG.length);
|
||||
}
|
||||
return super.resolve(baseUrl, url);
|
||||
}
|
||||
}
|
27
modules/playground/src/material/demo_common.ts
Normal file
27
modules/playground/src/material/demo_common.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {print} from 'angular2/src/core/facade/lang';
|
||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||
import {isPresent, isBlank, RegExpWrapper, StringWrapper} from 'angular2/src/core/facade/lang';
|
||||
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {BrowserDomAdapter} from 'angular2/src/core/dom/browser_adapter';
|
||||
|
||||
|
||||
export function commonDemoSetup(): void {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DemoUrlResolver extends UrlResolver {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
resolve(baseUrl: string, url: string): string {
|
||||
// The standard UrlResolver looks for "package:" templateUrls in
|
||||
// node_modules, however in our repo we host material widgets at the root.
|
||||
if (url.startsWith('package:angular2_material/')) {
|
||||
return '/' + url.substring(8);
|
||||
}
|
||||
return super.resolve(baseUrl, url);
|
||||
}
|
||||
}
|
32
modules/playground/src/material/dialog/demo_app.html
Normal file
32
modules/playground/src/material/dialog/demo_app.html
Normal file
@ -0,0 +1,32 @@
|
||||
<div>
|
||||
<h2>Dialog demo</h2>
|
||||
|
||||
<button id="open" type="button" (click)="open()" [disabled]="!!dialogRef">
|
||||
Open a dialog
|
||||
</button>
|
||||
|
||||
<button type="button" (click)="close()" [disabled]="!dialogRef">
|
||||
Close the dialog
|
||||
</button>
|
||||
|
||||
<p>
|
||||
Last result: {{lastResult}}
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
<p> Here are some paragaphs to make the page scrollable</p>
|
||||
|
||||
</div>
|
13
modules/playground/src/material/dialog/index.html
Normal file
13
modules/playground/src/material/dialog/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material dialog demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; } </style>
|
||||
</head>
|
||||
<body class="dialog-demo">
|
||||
<demo-app>Loading...</demo-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
106
modules/playground/src/material/dialog/index.ts
Normal file
106
modules/playground/src/material/dialog/index.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {
|
||||
bind,
|
||||
provide,
|
||||
ElementRef,
|
||||
ComponentRef,
|
||||
Component,
|
||||
UrlResolver,
|
||||
View,
|
||||
ViewEncapsulation
|
||||
} from 'angular2/core';
|
||||
import {
|
||||
MdDialog,
|
||||
MdDialogRef,
|
||||
MdDialogConfig
|
||||
} from 'angular2_material/src/components/dialog/dialog';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
import {isPresent} from 'angular2/src/core/facade/lang';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
viewProviders: [MdDialog],
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class DemoApp {
|
||||
dialog: MdDialog;
|
||||
elementRef: ElementRef;
|
||||
dialogRef: MdDialogRef;
|
||||
dialogConfig: MdDialogConfig;
|
||||
lastResult: string;
|
||||
|
||||
constructor(mdDialog: MdDialog, elementRef: ElementRef) {
|
||||
this.dialog = mdDialog;
|
||||
this.elementRef = elementRef;
|
||||
this.dialogConfig = new MdDialogConfig();
|
||||
|
||||
this.dialogConfig.width = '60%';
|
||||
this.dialogConfig.height = '60%';
|
||||
this.lastResult = '';
|
||||
}
|
||||
|
||||
open() {
|
||||
if (isPresent(this.dialogRef)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialog.open(SimpleDialogComponent, this.elementRef, this.dialogConfig)
|
||||
.then(ref => {
|
||||
this.dialogRef = ref;
|
||||
ref.instance.numCoconuts = 777;
|
||||
|
||||
ref.whenClosed.then(result => {
|
||||
this.dialogRef = null;
|
||||
this.lastResult = result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'simple-dialog',
|
||||
inputs: ['numCoconuts'],
|
||||
})
|
||||
@View({
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
template: `
|
||||
<h2>This is the dialog content</h2>
|
||||
<p>There are {{numCoconuts}} coconuts.</p>
|
||||
<p>Return: <input (input)="updateValue($event)"></p>
|
||||
<button type="button" (click)="done()">Done</button>
|
||||
`
|
||||
})
|
||||
class SimpleDialogComponent {
|
||||
numCoconuts: number;
|
||||
dialogRef: MdDialogRef;
|
||||
toReturn: string;
|
||||
|
||||
constructor(dialogRef: MdDialogRef) {
|
||||
this.numCoconuts = 0;
|
||||
this.dialogRef = dialogRef;
|
||||
this.toReturn = '';
|
||||
}
|
||||
|
||||
updateValue(event) {
|
||||
this.toReturn = event.target.value;
|
||||
}
|
||||
|
||||
done() {
|
||||
this.dialogRef.close(this.toReturn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
41
modules/playground/src/material/grid_list/demo_app.html
Normal file
41
modules/playground/src/material/grid_list/demo_app.html
Normal file
@ -0,0 +1,41 @@
|
||||
<style>
|
||||
md-grid-tile {
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
md-grid-list {
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
|
||||
<h2>grid-list demo</h2>
|
||||
|
||||
<md-grid-list cols="4" row-height="50px" gutter-size="2em" id="complex">
|
||||
|
||||
<md-grid-tile rowspan="1" colspan="2"> Tile #1 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
|
||||
<md-grid-tile rowspan="3" colspan="1"> Tile #3 </md-grid-tile>
|
||||
<md-grid-tile rowspan="2" colspan="2"> Tile #4 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="3"> Tile #5 </md-grid-tile>
|
||||
|
||||
</md-grid-list>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
<md-grid-list cols="4" row-height="50px" gutter-size="2em" id="simple">
|
||||
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #1 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #3 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #4 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #5 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #6 </md-grid-tile>
|
||||
<md-grid-tile rowspan="1" colspan="1"> Tile #7 </md-grid-tile>
|
||||
|
||||
</md-grid-list>
|
||||
|
||||
</div>
|
13
modules/playground/src/material/grid_list/index.html
Normal file
13
modules/playground/src/material/grid_list/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material grid-list demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; } </style>
|
||||
</head>
|
||||
<body>
|
||||
<demo-app>Loading...</demo-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
28
modules/playground/src/material/grid_list/index.ts
Normal file
28
modules/playground/src/material/grid_list/index.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, UrlResolver, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdGridList, MdGridTile} from 'angular2_material/src/components/grid_list/grid_list';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdGridList, MdGridTile],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class DemoApp {
|
||||
tile3RowSpan: number;
|
||||
tile3ColSpan: number;
|
||||
|
||||
constructor() {
|
||||
this.tile3RowSpan = 3;
|
||||
this.tile3ColSpan = 3;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
43
modules/playground/src/material/input/demo_app.html
Normal file
43
modules/playground/src/material/input/demo_app.html
Normal file
@ -0,0 +1,43 @@
|
||||
<style>@import "package:angular2_material/src/components/input/input.css";</style>
|
||||
|
||||
<style>
|
||||
body {
|
||||
max-width: 500px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<h2>input demo</h2>
|
||||
|
||||
|
||||
<h3>Normal input</h3>
|
||||
<md-input-container>
|
||||
<label>Name</label>
|
||||
<input md-input>
|
||||
</md-input-container>
|
||||
|
||||
<h3>Pre-filled value</h3>
|
||||
<md-input-container>
|
||||
<label>Favorite Framework</label>
|
||||
<input value="Angular">
|
||||
</md-input-container>
|
||||
|
||||
<h3>Disabled input</h3>
|
||||
<md-input-container>
|
||||
<label>ID Number</label>
|
||||
<input disabled>
|
||||
</md-input-container>
|
||||
|
||||
<h3>Disabled, pre-filled input</h3>
|
||||
<md-input-container>
|
||||
<label>Best TV show</label>
|
||||
<input disabled value="Firefly">
|
||||
</md-input-container>
|
||||
|
||||
<!--<h3>textarea</h3>
|
||||
<md-input-container>
|
||||
<label>What I did on my summer vaccation</label>
|
||||
<textarea></textarea>
|
||||
</md-input-container>-->
|
||||
|
||||
</div>
|
14
modules/playground/src/material/input/index.html
Normal file
14
modules/playground/src/material/input/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material input demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<demo-app>Loading...</demo-app>
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
19
modules/playground/src/material/input/index.ts
Normal file
19
modules/playground/src/material/input/index.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, UrlResolver, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdInputContainer, MdInput} from 'angular2_material/src/components/input/input';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
@Component({selector: 'demo-app'})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdInputContainer, MdInput],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
class DemoApp {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<div style="width: 500px;">
|
||||
<h2>Progress-linear demo</h2>
|
||||
|
||||
<p>
|
||||
Determinate: primary
|
||||
<md-progress-linear mode="determinate" [value]="progress" class="md-accent">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Determinate: accent
|
||||
<md-progress-linear mode="determinate" [value]="progress" class="md-primary">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Buffer
|
||||
<md-progress-linear mode="buffer"
|
||||
[value]="progress" [buffer-value]="progress + (200 / progress)" class="md-warn">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Indeterminate
|
||||
<md-progress-linear mode="indeterminate" class="md-primary">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Query
|
||||
<md-progress-linear mode="query" class="md-accent">
|
||||
</md-progress-linear>
|
||||
</p>
|
||||
|
||||
<!--<md-progress-linear></md-progress-linear>-->
|
||||
|
||||
<p>Progress: {{progress}}</p>
|
||||
<button type="button" (click)="step(10)" id="increment">Increment</button>
|
||||
<button type="button" (click)="step(-10)" id="decrement">Decrement</button>
|
||||
</div>
|
15
modules/playground/src/material/progress-linear/index.html
Normal file
15
modules/playground/src/material/progress-linear/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material progress-linear demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; } </style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
30
modules/playground/src/material/progress-linear/index.ts
Normal file
30
modules/playground/src/material/progress-linear/index.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdProgressLinear} from 'angular2_material/src/components/progress-linear/progress_linear';
|
||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdProgressLinear],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class DemoApp {
|
||||
progress: number;
|
||||
|
||||
constructor() {
|
||||
this.progress = 40;
|
||||
}
|
||||
|
||||
step(s: number) {
|
||||
this.progress += s;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
41
modules/playground/src/material/radio/demo_app.html
Normal file
41
modules/playground/src/material/radio/demo_app.html
Normal file
@ -0,0 +1,41 @@
|
||||
<style>
|
||||
md-radio-button {
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<h2>Radio buttons</h2>
|
||||
<h3>Inside of a radiogroup</h3>
|
||||
|
||||
<md-radio-group #scifi (change)="onGroupChange()" id="scifi-group">
|
||||
<md-radio-button value="star-wars">Star Wars</md-radio-button>
|
||||
<md-radio-button value="star-trek" id="special-radio">Star Trek</md-radio-button>
|
||||
<md-radio-button value="bsg" disabled>Battlestar Galactica</md-radio-button>
|
||||
<md-radio-button [value]="thirdValue">Dr. Who</md-radio-button>
|
||||
</md-radio-group>
|
||||
|
||||
<p>Your selection: {{scifi.value}}</p>
|
||||
<p>radio group value change count: {{groupValueChangeCount}}</p>
|
||||
|
||||
<hr>
|
||||
<h3>Standalone</h3>
|
||||
|
||||
<md-radio-button name="element" (click)="onIndividualClick()">Earth</md-radio-button>
|
||||
<md-radio-button name="element" (click)="onIndividualClick()">Fire</md-radio-button>
|
||||
<md-radio-button name="element" (click)="onIndividualClick()" disabled>Wind (disabled)</md-radio-button>
|
||||
<md-radio-button name="element" (click)="onIndividualClick()">Heart</md-radio-button>
|
||||
|
||||
<p>individual radio value change count: {{individualValueChanges}}</p>
|
||||
|
||||
<hr>
|
||||
<h3>Disabled radio group</h3>
|
||||
<p>Chosen: {{pokemon}}</p>
|
||||
<md-radio-group disabled [value]="pokemon">
|
||||
<md-radio-button value="fire">Charmander</md-radio-button>
|
||||
<md-radio-button value="leaf">Bulbasaur</md-radio-button>
|
||||
<md-radio-button value="water">Squirtle</md-radio-button>
|
||||
</md-radio-group>
|
||||
|
||||
<button type="button" (click)="chooseCharmander()">Choose Charmander</button>
|
||||
</div>
|
15
modules/playground/src/material/radio/index.html
Normal file
15
modules/playground/src/material/radio/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material radio demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style> * { font-family: RobotoDraft, Roboto; } </style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
47
modules/playground/src/material/radio/index.ts
Normal file
47
modules/playground/src/material/radio/index.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, UrlResolver, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdRadioButton, MdRadioGroup} from 'angular2_material/src/components/radio/radio_button';
|
||||
import {MdRadioDispatcher} from 'angular2_material/src/components/radio/radio_dispatcher';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
viewProviders: [MdRadioDispatcher],
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdRadioGroup, MdRadioButton],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class DemoApp {
|
||||
thirdValue;
|
||||
groupValueChangeCount;
|
||||
individualValueChanges;
|
||||
pokemon;
|
||||
someTabindex;
|
||||
|
||||
constructor() {
|
||||
this.thirdValue = 'dr-who';
|
||||
this.groupValueChangeCount = 0;
|
||||
this.individualValueChanges = 0;
|
||||
this.pokemon = '';
|
||||
this.someTabindex = 888;
|
||||
}
|
||||
|
||||
chooseCharmander() {
|
||||
this.pokemon = 'fire';
|
||||
}
|
||||
|
||||
onGroupChange() {
|
||||
this.groupValueChangeCount++;
|
||||
}
|
||||
|
||||
onIndividualClick() {
|
||||
this.individualValueChanges++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
9
modules/playground/src/material/switcher/demo_app.html
Normal file
9
modules/playground/src/material/switcher/demo_app.html
Normal file
@ -0,0 +1,9 @@
|
||||
<div md-theme="default">
|
||||
<h2>NgSwitch demo</h2>
|
||||
|
||||
<md-switch (click)="increment()">Normal switch</md-switch>
|
||||
<md-switch class="md-primary" (click)="increment()">Primary switch</md-switch>
|
||||
<md-switch disabled (click)="increment()">Disabled switch</md-switch>
|
||||
|
||||
<p>Toggle count: {{toggleCount}}</p>
|
||||
</div>
|
19
modules/playground/src/material/switcher/index.html
Normal file
19
modules/playground/src/material/switcher/index.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>ng-material switch demo</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=RobotoDraft:400,500,700,400italic">
|
||||
<style>
|
||||
* {
|
||||
font-family: RobotoDraft, Roboto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<demo-app>Loading...</demo-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
30
modules/playground/src/material/switcher/index.ts
Normal file
30
modules/playground/src/material/switcher/index.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bind, provide, Component, View, ViewEncapsulation} from 'angular2/core';
|
||||
import {MdSwitch} from 'angular2_material/src/components/switcher/switch';
|
||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||
import {commonDemoSetup, DemoUrlResolver} from '../demo_common';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: './demo_app.html',
|
||||
directives: [MdSwitch],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
class DemoApp {
|
||||
toggleCount: number;
|
||||
|
||||
constructor() {
|
||||
this.toggleCount = 0;
|
||||
}
|
||||
|
||||
increment() {
|
||||
this.toggleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
commonDemoSetup();
|
||||
bootstrap(DemoApp, [provide(UrlResolver, {useValue: new DemoUrlResolver()})]);
|
||||
}
|
19
modules/playground/src/model_driven_forms/index.html
Normal file
19
modules/playground/src/model_driven_forms/index.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Model Driven Forms</title>
|
||||
<style>
|
||||
.ng-touched.ng-invalid {
|
||||
border-color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<model-driven-forms>
|
||||
Loading...
|
||||
</model-driven-forms>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
161
modules/playground/src/model_driven_forms/index.ts
Normal file
161
modules/playground/src/model_driven_forms/index.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {
|
||||
FORM_DIRECTIVES,
|
||||
NgControl,
|
||||
Validators,
|
||||
NgFormModel,
|
||||
FormBuilder,
|
||||
NgIf,
|
||||
NgFor,
|
||||
Component,
|
||||
Directive,
|
||||
View,
|
||||
Host
|
||||
} from 'angular2/core';
|
||||
|
||||
import {RegExpWrapper, print, isPresent} from 'angular2/src/core/facade/lang';
|
||||
|
||||
/**
|
||||
* Custom validator.
|
||||
*/
|
||||
function creditCardValidator(c): {[key: string]: boolean} {
|
||||
if (isPresent(c.value) && RegExpWrapper.test(/^\d{16}$/g, c.value)) {
|
||||
return null;
|
||||
} else {
|
||||
return {"invalidCreditCard": true};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a component that displays an error message.
|
||||
*
|
||||
* For instance,
|
||||
*
|
||||
* <show-error control="creditCard" [errors]="['required', 'invalidCreditCard']"></show-error>
|
||||
*
|
||||
* Will display the "is required" error if the control is empty, and "invalid credit card" if the
|
||||
* control is not empty
|
||||
* but not valid.
|
||||
*
|
||||
* In a real application, this component would receive a service that would map an error code to an
|
||||
* actual error message.
|
||||
* To make it simple, we are using a simple map here.
|
||||
*/
|
||||
@Component({selector: 'show-error', inputs: ['controlPath: control', 'errorTypes: errors']})
|
||||
@View({
|
||||
template: `
|
||||
<span *ng-if="errorMessage !== null">{{errorMessage}}</span>
|
||||
`,
|
||||
directives: [NgIf]
|
||||
})
|
||||
class ShowError {
|
||||
formDir;
|
||||
controlPath: string;
|
||||
errorTypes: string[];
|
||||
|
||||
constructor(@Host() formDir: NgFormModel) { this.formDir = formDir; }
|
||||
|
||||
get errorMessage(): string {
|
||||
var control = this.formDir.form.find(this.controlPath);
|
||||
if (isPresent(control) && control.touched) {
|
||||
for (var i = 0; i < this.errorTypes.length; ++i) {
|
||||
if (control.hasError(this.errorTypes[i])) {
|
||||
return this._errorMessage(this.errorTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_errorMessage(code: string): string {
|
||||
var config = {'required': 'is required', 'invalidCreditCard': 'is invalid credit card number'};
|
||||
return config[code];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'model-driven-forms', viewProviders: [FormBuilder]})
|
||||
@View({
|
||||
template: `
|
||||
<h1>Checkout Form (Model Driven)</h1>
|
||||
|
||||
<form (ng-submit)="onSubmit()" [ng-form-model]="form" #f="form">
|
||||
<p>
|
||||
<label for="firstName">First Name</label>
|
||||
<input type="text" id="firstName" ng-control="firstName">
|
||||
<show-error control="firstName" [errors]="['required']"></show-error>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="middleName">Middle Name</label>
|
||||
<input type="text" id="middleName" ng-control="middleName">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="lastName">Last Name</label>
|
||||
<input type="text" id="lastName" ng-control="lastName">
|
||||
<show-error control="lastName" [errors]="['required']"></show-error>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="country">Country</label>
|
||||
<select id="country" ng-control="country">
|
||||
<option *ng-for="#c of countries" [value]="c">{{c}}</option>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="creditCard">Credit Card</label>
|
||||
<input type="text" id="creditCard" ng-control="creditCard">
|
||||
<show-error control="creditCard" [errors]="['required', 'invalidCreditCard']"></show-error>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="amount">Amount</label>
|
||||
<input type="number" id="amount" ng-control="amount">
|
||||
<show-error control="amount" [errors]="['required']"></show-error>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" ng-control="email">
|
||||
<show-error control="email" [errors]="['required']"></show-error>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="comments">Comments</label>
|
||||
<textarea id="comments" ng-control="comments">
|
||||
</textarea>
|
||||
</p>
|
||||
|
||||
<button type="submit" [disabled]="!f.form.valid">Submit</button>
|
||||
</form>
|
||||
`,
|
||||
directives: [FORM_DIRECTIVES, NgFor, ShowError]
|
||||
})
|
||||
class ModelDrivenForms {
|
||||
form;
|
||||
countries = ['US', 'Canada'];
|
||||
|
||||
constructor(fb: FormBuilder) {
|
||||
this.form = fb.group({
|
||||
"firstName": ["", Validators.required],
|
||||
"middleName": [""],
|
||||
"lastName": ["", Validators.required],
|
||||
"country": ["Canada", Validators.required],
|
||||
"creditCard": ["", Validators.compose([Validators.required, creditCardValidator])],
|
||||
"amount": [0, Validators.required],
|
||||
"email": ["", Validators.required],
|
||||
"comments": [""]
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
print("Submitting:");
|
||||
print(this.form.value);
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
bootstrap(ModelDrivenForms);
|
||||
}
|
39
modules/playground/src/observable_models/app.dart
Normal file
39
modules/playground/src/observable_models/app.dart
Normal file
@ -0,0 +1,39 @@
|
||||
library benchmarks.src.naive_infinite_scroll.app;
|
||||
|
||||
import "package:angular2/src/core/facade/collection.dart" show List, ListWrapper;
|
||||
import "scroll_area.dart" show ScrollAreaComponent;
|
||||
import "package:angular2/angular2.dart" show Component, Directive, View, IterableDiffers, SkipSelf, Binding;
|
||||
import "package:angular2/core.dart" show ObservableListDiffFactory, NgIf, NgFor;
|
||||
import 'package:observe/observe.dart' show ObservableList;
|
||||
|
||||
createDiffers(IterableDiffers parent) {
|
||||
return IterableDiffers.create([const ObservableListDiffFactory()], parent);
|
||||
}
|
||||
|
||||
const binding = const Binding(IterableDiffers,
|
||||
toFactory: createDiffers, deps: const [ const[IterableDiffers, const SkipSelf()]]);
|
||||
|
||||
@Component(
|
||||
selector: "scroll-app",
|
||||
bindings: const [binding]
|
||||
)
|
||||
@View(directives: const [ScrollAreaComponent, NgIf, NgFor], template: '''
|
||||
<div>
|
||||
<div style="display: flex">
|
||||
<scroll-area id="testArea"></scroll-area>
|
||||
</div>
|
||||
<div template="ng-if scrollAreas.length > 0">
|
||||
<p>Following tables are only here to add weight to the UI:</p>
|
||||
<scroll-area template="ng-for #scrollArea of scrollAreas"></scroll-area>
|
||||
</div>
|
||||
</div>''')
|
||||
class App {
|
||||
List<int> scrollAreas;
|
||||
App() {
|
||||
var scrollAreas = [];
|
||||
for (var i = 0; i < 300; i++) {
|
||||
scrollAreas.add(i);
|
||||
}
|
||||
this.scrollAreas = new ObservableList.from(scrollAreas);
|
||||
}
|
||||
}
|
135
modules/playground/src/observable_models/cells.dart
Normal file
135
modules/playground/src/observable_models/cells.dart
Normal file
@ -0,0 +1,135 @@
|
||||
library benchmarks.src.naive_infinite_scroll.cells;
|
||||
|
||||
import "package:angular2/src/core/facade/collection.dart"
|
||||
show List, ListWrapper, Map;
|
||||
import "common.dart"
|
||||
show Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST;
|
||||
import "package:angular2/core.dart" show NgFor;
|
||||
import "package:angular2/angular2.dart" show Component, Directive, View, ChangeDetectionStrategy;
|
||||
|
||||
class HasStyle {
|
||||
int cellWidth;
|
||||
HasStyle() {}
|
||||
set width(int w) {
|
||||
this.cellWidth = w;
|
||||
}
|
||||
}
|
||||
@Component(
|
||||
selector: "company-name",
|
||||
inputs: const ["width: cell-width", "company"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
template: '''<div [style.width.px]="cellWidth">{{company.name}}</div>'''
|
||||
)
|
||||
class CompanyNameComponent extends HasStyle {
|
||||
Company company;
|
||||
}
|
||||
@Component(
|
||||
selector: "opportunity-name",
|
||||
inputs: const ["width: cell-width", "opportunity"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
template: '''<div [style.width.px]="cellWidth">{{opportunity.name}}</div>'''
|
||||
)
|
||||
class OpportunityNameComponent extends HasStyle {
|
||||
Opportunity opportunity;
|
||||
}
|
||||
@Component(
|
||||
selector: "offering-name",
|
||||
inputs: const ["width: cell-width", "offering"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
template: '''<div [style.width.px]="cellWidth">{{offering.name}}</div>'''
|
||||
)
|
||||
class OfferingNameComponent extends HasStyle {
|
||||
Offering offering;
|
||||
}
|
||||
class Stage {
|
||||
String name;
|
||||
bool isDisabled;
|
||||
String backgroundColor;
|
||||
Function apply;
|
||||
}
|
||||
@Component(
|
||||
selector: "stage-buttons",
|
||||
inputs: const ["width: cell-width", "offering"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(directives: const [NgFor], template: '''
|
||||
<div [style.width.px]="cellWidth">
|
||||
<button template="ng-for #stage of stages"
|
||||
[disabled]="stage.isDisabled"
|
||||
[style.background-color]="stage.backgroundColor"
|
||||
on-click="setStage(stage)">
|
||||
{{stage.name}}
|
||||
</button>
|
||||
</div>''')
|
||||
class StageButtonsComponent extends HasStyle {
|
||||
Offering _offering;
|
||||
List<Stage> stages;
|
||||
Offering get offering {
|
||||
return this._offering;
|
||||
}
|
||||
set offering(Offering offering) {
|
||||
this._offering = offering;
|
||||
this._computeStageButtons();
|
||||
}
|
||||
setStage(Stage stage) {
|
||||
this._offering.status = stage.name;
|
||||
this._offering.name = this._offering.name + "!";
|
||||
this._computeStageButtons();
|
||||
}
|
||||
_computeStageButtons() {
|
||||
var disabled = true;
|
||||
this.stages = ListWrapper.clone(STATUS_LIST.map((status) {
|
||||
var isCurrent = this._offering.status == status;
|
||||
var stage = new Stage();
|
||||
stage.name = status;
|
||||
stage.isDisabled = disabled;
|
||||
stage.backgroundColor = disabled ? "#DDD" : isCurrent ? "#DDF" : "#FDD";
|
||||
if (isCurrent) {
|
||||
disabled = false;
|
||||
}
|
||||
return stage;
|
||||
}).toList());
|
||||
}
|
||||
}
|
||||
@Component(
|
||||
selector: "account-cell",
|
||||
inputs: const ["width: cell-width", "account"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(directives: const [], template: '''
|
||||
<div [style.width.px]="cellWidth">
|
||||
<a href="/account/{{account.accountId}}">
|
||||
{{account.accountId}}
|
||||
</a>
|
||||
</div>''')
|
||||
class AccountCellComponent extends HasStyle {
|
||||
Account account;
|
||||
}
|
||||
@Component(
|
||||
selector: "formatted-cell",
|
||||
inputs: const ["width: cell-width", "value"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPushObserve
|
||||
)
|
||||
@View(
|
||||
directives: const [],
|
||||
template: '''<div [style.width.px]="cellWidth">{{formattedValue}}</div>''')
|
||||
class FormattedCellComponent extends HasStyle {
|
||||
String formattedValue;
|
||||
set value(value) {
|
||||
if (value is CustomDate) {
|
||||
this.formattedValue =
|
||||
'''${ value . month}/${ value . day}/${ value . year}''';
|
||||
} else {
|
||||
this.formattedValue = value.toString();
|
||||
}
|
||||
}
|
||||
}
|
241
modules/playground/src/observable_models/common.dart
Normal file
241
modules/playground/src/observable_models/common.dart
Normal file
@ -0,0 +1,241 @@
|
||||
library benchmarks.src.naive_infinite_scroll.common;
|
||||
|
||||
import "package:angular2/src/core/facade/math.dart" show Math;
|
||||
import "package:angular2/src/core/facade/collection.dart";
|
||||
import 'package:observe/observe.dart';
|
||||
import 'dart:collection';
|
||||
import 'dart:async';
|
||||
|
||||
var ITEMS = 1000;
|
||||
var ITEM_HEIGHT = 40;
|
||||
var VISIBLE_ITEMS = 17;
|
||||
var HEIGHT = ITEMS * ITEM_HEIGHT;
|
||||
var VIEW_PORT_HEIGHT = ITEM_HEIGHT * VISIBLE_ITEMS;
|
||||
var COMPANY_NAME_WIDTH = 100;
|
||||
var OPPORTUNITY_NAME_WIDTH = 100;
|
||||
var OFFERING_NAME_WIDTH = 100;
|
||||
var ACCOUNT_CELL_WIDTH = 50;
|
||||
var BASE_POINTS_WIDTH = 50;
|
||||
var KICKER_POINTS_WIDTH = 50;
|
||||
var STAGE_BUTTONS_WIDTH = 220;
|
||||
var BUNDLES_WIDTH = 120;
|
||||
var DUE_DATE_WIDTH = 100;
|
||||
var END_DATE_WIDTH = 100;
|
||||
var AAT_STATUS_WIDTH = 100;
|
||||
var ROW_WIDTH = COMPANY_NAME_WIDTH +
|
||||
OPPORTUNITY_NAME_WIDTH +
|
||||
OFFERING_NAME_WIDTH +
|
||||
ACCOUNT_CELL_WIDTH +
|
||||
BASE_POINTS_WIDTH +
|
||||
KICKER_POINTS_WIDTH +
|
||||
STAGE_BUTTONS_WIDTH +
|
||||
BUNDLES_WIDTH +
|
||||
DUE_DATE_WIDTH +
|
||||
END_DATE_WIDTH +
|
||||
AAT_STATUS_WIDTH;
|
||||
var STATUS_LIST = ["Planned", "Pitched", "Won", "Lost"];
|
||||
var AAT_STATUS_LIST = ["Active", "Passive", "Abandoned"];
|
||||
// Imitate Streamy entities.
|
||||
|
||||
// Just a non-trivial object. Nothing fancy or correct.
|
||||
class CustomDate {
|
||||
num year;
|
||||
num month;
|
||||
num day;
|
||||
CustomDate(num y, num m, num d) {
|
||||
this.year = y;
|
||||
this.month = m;
|
||||
this.day = d;
|
||||
}
|
||||
CustomDate addDays(num days) {
|
||||
var newDay = this.day + days;
|
||||
var newMonth = this.month + Math.floor(newDay / 30);
|
||||
newDay = newDay % 30;
|
||||
var newYear = this.year + Math.floor(newMonth / 12);
|
||||
return new CustomDate(newYear, newMonth, newDay);
|
||||
}
|
||||
static CustomDate now() {
|
||||
return new CustomDate(2014, 1, 28);
|
||||
}
|
||||
}
|
||||
class RawEntity extends Object
|
||||
with MapMixin<String, dynamic>
|
||||
implements ObservableMap<String, dynamic> {
|
||||
ObservableMap _data = new ObservableMap();
|
||||
|
||||
@override
|
||||
Iterable<String> get keys => _data.keys;
|
||||
|
||||
@override
|
||||
void clear() {
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
operator [](String key) {
|
||||
if (!key.contains('.')) {
|
||||
return _data[key];
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = pieces.removeLast();
|
||||
var target = _resolve(pieces, this);
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
return target[last];
|
||||
}
|
||||
|
||||
@override
|
||||
operator []=(String key, value) {
|
||||
if (!key.contains('.')) {
|
||||
_data[key] = value;
|
||||
return;
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = pieces.removeLast();
|
||||
var target = _resolve(pieces, this);
|
||||
target[last] = value;
|
||||
}
|
||||
|
||||
dynamic get(String name) { return this[name]; }
|
||||
|
||||
set(String name, dynamic value) { this[name] = value; }
|
||||
|
||||
@override
|
||||
remove(String key) {
|
||||
if (!key.contains('.')) {
|
||||
return _data.remove(key);
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = pieces.removeLast();
|
||||
var target = _resolve(pieces, this);
|
||||
return target.remove(last);
|
||||
}
|
||||
|
||||
_resolve(List<String> pieces, start) {
|
||||
var cur = start;
|
||||
for (var i = 0; i < pieces.length; i++) {
|
||||
cur = cur[pieces[i]];
|
||||
if (cur == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<List<ChangeRecord>> get changes => _data.changes;
|
||||
@override
|
||||
bool get hasObservers => _data.hasObservers;
|
||||
@override
|
||||
bool deliverChanges() => _data.deliverChanges();
|
||||
@override
|
||||
notifyPropertyChange(Symbol field, Object oldValue, Object newValue) =>
|
||||
_data.notifyPropertyChange(field, oldValue, newValue);
|
||||
@override
|
||||
void notifyChange(ChangeRecord record) {
|
||||
_data.notifyChange(record);
|
||||
}
|
||||
|
||||
@override
|
||||
void observed() {
|
||||
_data.observed();
|
||||
}
|
||||
|
||||
@override
|
||||
void unobserved() {
|
||||
_data.observed();
|
||||
}
|
||||
}
|
||||
class Company extends RawEntity {
|
||||
String get name {
|
||||
return this.get("name");
|
||||
}
|
||||
set name(String val) {
|
||||
this.set("name", val);
|
||||
}
|
||||
}
|
||||
class Offering extends RawEntity {
|
||||
String get name {
|
||||
return this.get("name");
|
||||
}
|
||||
set name(String val) {
|
||||
this.set("name", val);
|
||||
}
|
||||
Company get company {
|
||||
return this.get("company");
|
||||
}
|
||||
set company(Company val) {
|
||||
this.set("company", val);
|
||||
}
|
||||
Opportunity get opportunity {
|
||||
return this.get("opportunity");
|
||||
}
|
||||
set opportunity(Opportunity val) {
|
||||
this.set("opportunity", val);
|
||||
}
|
||||
Account get account {
|
||||
return this.get("account");
|
||||
}
|
||||
set account(Account val) {
|
||||
this.set("account", val);
|
||||
}
|
||||
num get basePoints {
|
||||
return this.get("basePoints");
|
||||
}
|
||||
set basePoints(num val) {
|
||||
this.set("basePoints", val);
|
||||
}
|
||||
num get kickerPoints {
|
||||
return this.get("kickerPoints");
|
||||
}
|
||||
set kickerPoints(num val) {
|
||||
this.set("kickerPoints", val);
|
||||
}
|
||||
String get status {
|
||||
return this.get("status");
|
||||
}
|
||||
set status(String val) {
|
||||
this.set("status", val);
|
||||
}
|
||||
String get bundles {
|
||||
return this.get("bundles");
|
||||
}
|
||||
set bundles(String val) {
|
||||
this.set("bundles", val);
|
||||
}
|
||||
CustomDate get dueDate {
|
||||
return this.get("dueDate");
|
||||
}
|
||||
set dueDate(CustomDate val) {
|
||||
this.set("dueDate", val);
|
||||
}
|
||||
CustomDate get endDate {
|
||||
return this.get("endDate");
|
||||
}
|
||||
set endDate(CustomDate val) {
|
||||
this.set("endDate", val);
|
||||
}
|
||||
String get aatStatus {
|
||||
return this.get("aatStatus");
|
||||
}
|
||||
set aatStatus(String val) {
|
||||
this.set("aatStatus", val);
|
||||
}
|
||||
}
|
||||
class Opportunity extends RawEntity {
|
||||
String get name {
|
||||
return this.get("name");
|
||||
}
|
||||
set name(String val) {
|
||||
this.set("name", val);
|
||||
}
|
||||
}
|
||||
class Account extends RawEntity {
|
||||
num get accountId {
|
||||
return this.get("accountId");
|
||||
}
|
||||
set accountId(num val) {
|
||||
this.set("accountId", val);
|
||||
}
|
||||
}
|
14
modules/playground/src/observable_models/index.dart
Normal file
14
modules/playground/src/observable_models/index.dart
Normal file
@ -0,0 +1,14 @@
|
||||
library benchmarks.src.naive_infinite_scroll.index;
|
||||
|
||||
import "package:angular2/bootstrap.dart" show bootstrap;
|
||||
import "app.dart" show App;
|
||||
import "package:angular2/src/core/linker/view_pool.dart"
|
||||
show APP_VIEW_POOL_CAPACITY;
|
||||
import "package:angular2/core.dart" show bind;
|
||||
|
||||
main() {
|
||||
bootstrap(App, createBindings());
|
||||
}
|
||||
List<dynamic> createBindings() {
|
||||
return [bind(APP_VIEW_POOL_CAPACITY).toValue(100000)];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user