feat(core): remove the (^ syntax and make all DOM events bubbling

BREAKING CHANGE

Before
<div (^click)="onEventHandler()">
  <button></button>
</div>

After
<div (click)="onEventHandler()">
  <button></button>
</div>

Closes #3864
This commit is contained in:
vsavkin 2015-09-01 08:52:54 -07:00 committed by Victor Savkin
parent 9934b3ec7f
commit 60ce884671
22 changed files with 113 additions and 243 deletions

View File

@ -130,33 +130,6 @@ Example:
Example:
`<div on-click="doX()">`
</td>
</tr>
<tr>
<th>Event binding (bubbling)</th>
<td>
`<div (^event)="statement">`
Example:
`<div (^mouseover)="hlite()">`
</td>
<td>
`<div on-bubble-event="statement">`
Example:
`<div on-bubble-mouseover="hlite()">`
</td>
</tr>
<tr>
<th>Declare reference</th>
<td>
`<div #symbol>`
Example:
<pre>
```
<video #player>
@ -420,7 +393,7 @@ of the templates occurs. One such example is `ng-for`.
Where:
* `[ng-for]` triggers the for directive.
* `#person` exports the implicit `ng-for` item.
* `#person` exports the implicit `ng-for` item.
* `[ng-for-of]="people"` binds an iterable object to the `ng-for` controller.
* `#i=index` exports item index as `i`.
@ -515,18 +488,16 @@ Where:
* `statement` is a valid statement (as defined in section below).
If the execution of the statement returns `false`, then `preventDefault`is applied on the DOM event.
By default, angular only listens to the element on the event, and ignores events which bubble. To listen to bubbled
events (as in the case of clicking on any child) use the bubble option (`(event)` or `on-bubble-event`) as shown
below.
Angular listens to bubbled DOM events (as in the case of clicking on any child), as shown below:
<table>
<tr>
<th>Short form</th>
<td>`<some-element (^some-event)="statement">`</td>
<td>`<some-element (some-event)="statement">`</td>
</tr>
<tr>
<th>Canonical form</th>
<td>`<some-element on-bubble-some-event="statement">`</td>
<td>`<some-element on-some-event="statement">`</td>
</tr>
</table>

View File

@ -12,14 +12,13 @@ import {dashCaseToCamelCase} from '../util';
// Group 1 = "bind-"
// Group 2 = "var-" or "#"
// Group 3 = "on-"
// Group 4 = "onbubble-"
// Group 5 = "bindon-"
// Group 6 = the identifier after "bind-", "var-/#", or "on-"
// Group 7 = idenitifer inside [()]
// Group 8 = idenitifer inside []
// Group 9 = identifier inside ()
// Group 4 = "bindon-"
// Group 5 = the identifier after "bind-", "var-/#", or "on-"
// Group 6 = idenitifer inside [()]
// Group 7 = idenitifer inside []
// Group 8 = identifier inside ()
var BIND_NAME_REGEXP =
/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(onbubble-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g;
/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g;
/**
* Parses the property bindings on a single element.
*/
@ -39,33 +38,30 @@ export class PropertyBindingParser implements CompileStep {
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
if (isPresent(bindParts)) {
if (isPresent(bindParts[1])) { // match: bind-prop
this._bindProperty(bindParts[6], attrValue, current, newAttrs);
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
} else if (isPresent(
bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
var identifier = bindParts[6];
var identifier = bindParts[5];
var value = attrValue == '' ? '\$implicit' : attrValue;
this._bindVariable(identifier, value, current, newAttrs);
} else if (isPresent(bindParts[3])) { // match: on-event
this._bindEvent(bindParts[6], attrValue, current, newAttrs);
this._bindEvent(bindParts[5], attrValue, current, newAttrs);
} else if (isPresent(bindParts[4])) { // match: onbubble-event
this._bindEvent('^' + bindParts[6], attrValue, current, newAttrs);
} else if (isPresent(bindParts[4])) { // match: bindon-prop
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
this._bindAssignmentEvent(bindParts[5], attrValue, current, newAttrs);
} else if (isPresent(bindParts[5])) { // match: bindon-prop
} else if (isPresent(bindParts[6])) { // match: [(expr)]
this._bindProperty(bindParts[6], attrValue, current, newAttrs);
this._bindAssignmentEvent(bindParts[6], attrValue, current, newAttrs);
} else if (isPresent(bindParts[7])) { // match: [(expr)]
} else if (isPresent(bindParts[7])) { // match: [expr]
this._bindProperty(bindParts[7], attrValue, current, newAttrs);
this._bindAssignmentEvent(bindParts[7], attrValue, current, newAttrs);
} else if (isPresent(bindParts[8])) { // match: [expr]
this._bindProperty(bindParts[8], attrValue, current, newAttrs);
} else if (isPresent(bindParts[9])) { // match: (event)
this._bindEvent(bindParts[9], attrValue, current, newAttrs);
} else if (isPresent(bindParts[8])) { // match: (event)
this._bindEvent(bindParts[8], attrValue, current, newAttrs);
}
} else {
var expr = this._parser.parseInterpolation(attrValue, current.elementDescription);

View File

@ -2,8 +2,6 @@ import {isBlank, BaseException, isPresent, StringWrapper} from 'angular2/src/cor
import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
const BUBBLE_SYMBOL = '^';
export class EventManager {
constructor(public _plugins: EventManagerPlugin[], public _zone: NgZone) {
for (var i = 0; i < _plugins.length; i++) {
@ -12,17 +10,13 @@ export class EventManager {
}
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
var withoutBubbleSymbol = this._removeBubbleSymbol(eventName);
var plugin = this._findPluginFor(withoutBubbleSymbol);
plugin.addEventListener(element, withoutBubbleSymbol, handler,
withoutBubbleSymbol != eventName);
var plugin = this._findPluginFor(eventName);
plugin.addEventListener(element, eventName, handler);
}
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
var withoutBubbleSymbol = this._removeBubbleSymbol(eventName);
var plugin = this._findPluginFor(withoutBubbleSymbol);
return plugin.addGlobalEventListener(target, withoutBubbleSymbol, handler,
withoutBubbleSymbol != eventName);
var plugin = this._findPluginFor(eventName);
return plugin.addGlobalEventListener(target, eventName, handler);
}
getZone(): NgZone { return this._zone; }
@ -37,28 +31,19 @@ export class EventManager {
}
throw new BaseException(`No event manager plugin found for event ${eventName}`);
}
_removeBubbleSymbol(eventName: string): string {
return eventName[0] == BUBBLE_SYMBOL ? StringWrapper.substring(eventName, 1) : eventName;
}
}
export class EventManagerPlugin {
manager: EventManager;
// We are assuming here that all plugins support bubbled and non-bubbled events.
// That is equivalent to having supporting $event.target
// The bubbling flag (currently ^) is stripped before calling the supports and
// addEventListener methods.
supports(eventName: string): boolean { return false; }
addEventListener(element: HTMLElement, eventName: string, handler: Function,
shouldSupportBubble: boolean) {
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
throw "not implemented";
}
addGlobalEventListener(element: string, eventName: string, handler: Function,
shouldSupportBubble: boolean): Function {
addGlobalEventListener(element: string, eventName: string, handler: Function): Function {
throw "not implemented";
}
}
@ -70,39 +55,17 @@ export class DomEventsPlugin extends EventManagerPlugin {
// events.
supports(eventName: string): boolean { return true; }
addEventListener(element: HTMLElement, eventName: string, handler: Function,
shouldSupportBubble: boolean) {
var outsideHandler =
this._getOutsideHandler(shouldSupportBubble, element, handler, this.manager._zone);
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
var zone = this.manager._zone;
var outsideHandler = (event) => zone.run(() => handler(event));
this.manager._zone.runOutsideAngular(() => { DOM.on(element, eventName, outsideHandler); });
}
addGlobalEventListener(target: string, eventName: string, handler: Function,
shouldSupportBubble: boolean): Function {
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
var element = DOM.getGlobalEventTarget(target);
var outsideHandler =
this._getOutsideHandler(shouldSupportBubble, element, handler, this.manager._zone);
var zone = this.manager._zone;
var outsideHandler = (event) => zone.run(() => handler(event));
return this.manager._zone.runOutsideAngular(
() => { return DOM.onAndCancel(element, eventName, outsideHandler); });
}
_getOutsideHandler(shouldSupportBubble: boolean, element: HTMLElement, handler: Function,
zone: NgZone) {
return shouldSupportBubble ? DomEventsPlugin.bubbleCallback(element, handler, zone) :
DomEventsPlugin.sameElementCallback(element, handler, zone);
}
static sameElementCallback(element: HTMLElement, handler: Function, zone: NgZone):
(event: Event) => void {
return (event) => {
if (event.target === element) {
zone.run(() => handler(event));
}
};
}
static bubbleCallback(element: HTMLElement, handler: Function, zone: NgZone):
(event: Event) => void {
return (event) => zone.run(() => handler(event));
}
}

View File

@ -18,10 +18,7 @@ class HammerGesturesPlugin extends HammerGesturesPluginCommon {
return true;
}
addEventListener(Element element, String eventName, Function handler,
bool shouldSupportBubble) {
if (shouldSupportBubble) throw new BaseException(
'Hammer.js plugin does not support bubbling gestures.');
addEventListener(Element element, String eventName, Function handler) {
var zone = this.manager.getZone();
eventName = eventName.toLowerCase();

View File

@ -16,10 +16,7 @@ export class HammerGesturesPlugin extends HammerGesturesPluginCommon {
return true;
}
addEventListener(element: HTMLElement, eventName: string, handler: Function,
shouldSupportBubble: boolean) {
if (shouldSupportBubble)
throw new BaseException('Hammer.js plugin does not support bubbling gestures.');
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
var zone = this.manager.getZone();
eventName = eventName.toLowerCase();

View File

@ -26,13 +26,11 @@ export class KeyEventsPlugin extends EventManagerPlugin {
return isPresent(KeyEventsPlugin.parseEventName(eventName));
}
addEventListener(element: HTMLElement, eventName: string, handler: (Event: any) => any,
shouldSupportBubble: boolean) {
addEventListener(element: HTMLElement, eventName: string, handler: (Event: any) => any) {
var parsedEvent = KeyEventsPlugin.parseEventName(eventName);
var outsideHandler = KeyEventsPlugin.eventCallback(element, shouldSupportBubble,
StringMapWrapper.get(parsedEvent, 'fullKey'),
handler, this.manager.getZone());
var outsideHandler = KeyEventsPlugin.eventCallback(
element, StringMapWrapper.get(parsedEvent, 'fullKey'), handler, this.manager.getZone());
this.manager.getZone().runOutsideAngular(() => {
DOM.on(element, StringMapWrapper.get(parsedEvent, 'domEventName'), outsideHandler);
@ -91,11 +89,10 @@ export class KeyEventsPlugin extends EventManagerPlugin {
return fullKey;
}
static eventCallback(element: HTMLElement, shouldSupportBubble: boolean, fullKey: any,
handler: (Event) => any, zone: NgZone): (event: Event) => void {
static eventCallback(element: HTMLElement, fullKey: any, handler: (Event) => any, zone: NgZone):
(event: Event) => void {
return (event) => {
var correctElement = shouldSupportBubble || event.target === element;
if (correctElement && StringWrapper.equals(KeyEventsPlugin.getEventFullKey(event), fullKey)) {
if (StringWrapper.equals(KeyEventsPlugin.getEventFullKey(event), fullKey)) {
zone.run(() => handler(event));
}
};

View File

@ -38,7 +38,7 @@ import {Instruction, stringifyInstruction} from './instruction';
selector: '[router-link]',
properties: ['routeParams: routerLink'],
host: {
'(^click)': 'onClick()',
'(click)': 'onClick()',
'[attr.href]': 'visibleHref',
'[class.router-link-active]': 'isRouteActive'
}

View File

@ -856,7 +856,9 @@ export function main() {
dispatchEvent(tc.nativeElement, 'domEvent');
expect(listener.eventType).toEqual('domEvent');
expect(listener.eventTypes)
.toEqual(
['domEvent', 'body_domEvent', 'document_domEvent', 'window_domEvent']);
async.done();
});
@ -874,16 +876,16 @@ export function main() {
var tc = rootTC.componentViewChildren[0];
var listener = tc.inject(DirectiveListeningDomEvent);
dispatchEvent(DOM.getGlobalEventTarget("window"), 'domEvent');
expect(listener.eventType).toEqual('window_domEvent');
expect(listener.eventTypes).toEqual(['window_domEvent']);
listener = tc.inject(DirectiveListeningDomEvent);
listener.eventTypes = [];
dispatchEvent(DOM.getGlobalEventTarget("document"), 'domEvent');
expect(listener.eventType).toEqual('document_domEvent');
expect(listener.eventTypes).toEqual(['document_domEvent', 'window_domEvent']);
rootTC.destroy();
listener = tc.inject(DirectiveListeningDomEvent);
listener.eventTypes = [];
dispatchEvent(DOM.getGlobalEventTarget("body"), 'domEvent');
expect(listener.eventType).toEqual('');
expect(listener.eventTypes).toEqual([]);
async.done();
});
@ -983,7 +985,7 @@ export function main() {
var listener = tc.inject(DirectiveListeningDomEvent);
var listenerother = tc.inject(DirectiveListeningDomEventOther);
dispatchEvent(DOM.getGlobalEventTarget("window"), 'domEvent');
expect(listener.eventType).toEqual('window_domEvent');
expect(listener.eventTypes).toEqual(['window_domEvent']);
expect(listenerother.eventType).toEqual('other_domEvent');
expect(globalCounter).toEqual(1);
@ -1851,12 +1853,11 @@ class DirectiveListeningEvent {
})
@Injectable()
class DirectiveListeningDomEvent {
eventType: string;
constructor() { this.eventType = ''; }
onEvent(eventType: string) { this.eventType = eventType; }
onWindowEvent(eventType: string) { this.eventType = "window_" + eventType; }
onDocumentEvent(eventType: string) { this.eventType = "document_" + eventType; }
onBodyEvent(eventType: string) { this.eventType = "body_" + eventType; }
eventTypes: string[] = [];
onEvent(eventType: string) { this.eventTypes.push(eventType); }
onWindowEvent(eventType: string) { this.eventTypes.push("window_" + eventType); }
onDocumentEvent(eventType: string) { this.eventTypes.push("document_" + eventType); }
onBodyEvent(eventType: string) { this.eventTypes.push("body_" + eventType); }
}
var globalCounter = 0;

View File

@ -182,20 +182,6 @@ export function main() {
expect(eventBinding.fullName).toEqual('click');
});
it('should detect onbubble- syntax', () => {
var results = process(el('<div onbubble-click="b()"></div>'));
var eventBinding = results[0].eventBindings[0];
expect(eventBinding.source.source).toEqual('b()');
expect(eventBinding.fullName).toEqual('^click');
});
it('should detect onbubble- syntax with data- prefix', () => {
var results = process(el('<div data-onbubble-click="b()"></div>'));
var eventBinding = results[0].eventBindings[0];
expect(eventBinding.source.source).toEqual('b()');
expect(eventBinding.fullName).toEqual('^click');
});
it('should parse event handlers using on- syntax as actions', () => {
var results = process(el('<div on-click="foo=bar"></div>'));
var eventBinding = results[0].eventBindings[0];

View File

@ -31,16 +31,7 @@ export function main() {
var plugin = new FakeEventManagerPlugin(['click']);
var manager = new EventManager([plugin, domEventPlugin], new FakeNgZone());
manager.addEventListener(element, 'click', handler);
expect(plugin._nonBubbleEventHandlers.get('click')).toBe(handler);
});
it('should delegate bubbling events to plugins', () => {
var element = el('<div></div>');
var handler = (e) => e;
var plugin = new FakeEventManagerPlugin(['click']);
var manager = new EventManager([plugin, domEventPlugin], new FakeNgZone());
manager.addEventListener(element, '^click', handler);
expect(plugin._bubbleEventHandlers.get('click')).toBe(handler);
expect(plugin._eventHandler.get('click')).toBe(handler);
});
it('should delegate event bindings to the first plugin supporting the event', () => {
@ -52,10 +43,10 @@ export function main() {
var manager = new EventManager([plugin1, plugin2], new FakeNgZone());
manager.addEventListener(element, 'click', clickHandler);
manager.addEventListener(element, 'dblclick', dblClickHandler);
expect(plugin1._nonBubbleEventHandlers.has('click')).toBe(false);
expect(plugin2._nonBubbleEventHandlers.get('click')).toBe(clickHandler);
expect(plugin2._nonBubbleEventHandlers.has('dblclick')).toBe(false);
expect(plugin1._nonBubbleEventHandlers.get('dblclick')).toBe(dblClickHandler);
expect(plugin1._eventHandler.has('click')).toBe(false);
expect(plugin2._eventHandler.get('click')).toBe(clickHandler);
expect(plugin2._eventHandler.has('dblclick')).toBe(false);
expect(plugin1._eventHandler.get('dblclick')).toBe(dblClickHandler);
});
it('should throw when no plugin can handle the event', () => {
@ -66,20 +57,7 @@ export function main() {
.toThrowError('No event manager plugin found for event click');
});
it('by default events are only caught on same element', () => {
var element = el('<div><div></div></div>');
var child = DOM.firstChild(element);
var dispatchedEvent = DOM.createMouseEvent('click');
var receivedEvent = null;
var handler = (e) => { receivedEvent = e; };
var manager = new EventManager([domEventPlugin], new FakeNgZone());
manager.addEventListener(element, 'click', handler);
DOM.dispatchEvent(child, dispatchedEvent);
expect(receivedEvent).toBe(null);
});
it('bubbled events are caught when fired from a child', () => {
it('events are caught when fired from a child', () => {
var element = el('<div><div></div></div>');
// Workaround for https://bugs.webkit.org/show_bug.cgi?id=122755
DOM.appendChild(DOM.defaultDoc().body, element);
@ -89,13 +67,13 @@ export function main() {
var receivedEvent = null;
var handler = (e) => { receivedEvent = e; };
var manager = new EventManager([domEventPlugin], new FakeNgZone());
manager.addEventListener(element, '^click', handler);
manager.addEventListener(element, 'click', handler);
DOM.dispatchEvent(child, dispatchedEvent);
expect(receivedEvent).toBe(dispatchedEvent);
});
it('should add and remove global event listeners with correct bubbling', () => {
it('should add and remove global event listeners', () => {
var element = el('<div><div></div></div>');
DOM.appendChild(DOM.defaultDoc().body, element);
var dispatchedEvent = DOM.createMouseEvent('click');
@ -103,7 +81,7 @@ export function main() {
var handler = (e) => { receivedEvent = e; };
var manager = new EventManager([domEventPlugin], new FakeNgZone());
var remover = manager.addGlobalEventListener("document", '^click', handler);
var remover = manager.addGlobalEventListener("document", 'click', handler);
DOM.dispatchEvent(element, dispatchedEvent);
expect(receivedEvent).toBe(dispatchedEvent);
@ -111,37 +89,19 @@ export function main() {
remover();
DOM.dispatchEvent(element, dispatchedEvent);
expect(receivedEvent).toBe(null);
remover = manager.addGlobalEventListener("document", 'click', handler);
DOM.dispatchEvent(element, dispatchedEvent);
expect(receivedEvent).toBe(null);
});
});
}
class FakeEventManagerPlugin extends EventManagerPlugin {
_supports: string[];
_nonBubbleEventHandlers: Map<string, Function>;
_bubbleEventHandlers: Map<string, Function>;
constructor(supports: string[]) {
super();
this._supports = supports;
this._nonBubbleEventHandlers = new Map();
this._bubbleEventHandlers = new Map();
}
_eventHandler: Map<string, Function> = new Map();
constructor(public _supports: string[]) { super(); }
supports(eventName: string): boolean { return ListWrapper.contains(this._supports, eventName); }
addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) {
if (shouldSupportBubble) {
this._bubbleEventHandlers.set(eventName, handler);
} else {
this._nonBubbleEventHandlers.set(eventName, handler);
}
return () => {
MapWrapper.delete(
shouldSupportBubble ? this._bubbleEventHandlers : this._nonBubbleEventHandlers, eventName)
};
addEventListener(element, eventName: string, handler: Function) {
this._eventHandler.set(eventName, handler);
return () => { MapWrapper.delete(this._eventHandler, eventName) };
}
}

View File

@ -65,7 +65,7 @@ export function main() {
.then((testComponent) => {
testComponent.detectChanges();
// TODO: shouldn't this be just 'click' rather than '^click'?
testComponent.query(By.css('a')).triggerEventHandler('^click', null);
testComponent.query(By.css('a')).triggerEventHandler('click', null);
expect(router.spy('navigateInstruction')).toHaveBeenCalledWith(dummyInstruction);
async.done();
});

View File

@ -9,7 +9,7 @@ import {isPresent} from 'angular2/src/core/facade/lang';
@Component({
selector: '[md-button]:not(a), [md-fab]:not(a), [md-raised-button]:not(a)',
host: {
'(^mousedown)': 'onMousedown()',
'(mousedown)': 'onMousedown()',
'(focus)': 'onFocus()',
'(blur)': 'onBlur()',
'[class.md-button-focus]': 'isKeyboardFocused',
@ -50,8 +50,8 @@ export class MdButton {
properties: ['disabled'],
lifecycle: [LifecycleEvent.OnChanges],
host: {
'(^click)': 'onClick($event)',
'(^mousedown)': 'onMousedown()',
'(click)': 'onClick($event)',
'(mousedown)': 'onMousedown()',
'(focus)': 'onFocus()',
'(blur)': 'onBlur()',
'[tabIndex]': 'tabIndex',

View File

@ -1,6 +1,6 @@
<style>@import "package:angular2_material/src/components/checkbox/checkbox.css";</style>
<div (^click)="toggle($event)">
<div (click)="toggle($event)">
<div class="md-checkbox-container">
<div class="md-checkbox-icon"></div>
</div>

View File

@ -206,7 +206,7 @@ export class MdDialogConfig {
host: {
'class': 'md-dialog',
'tabindex': '0',
'(body:^keydown)': 'documentKeypress($event)',
'(body:keydown)': 'documentKeypress($event)',
},
})
@View({

View File

@ -4,7 +4,7 @@
<label role="radio" class="md-radio-root"
[class.md-radio-checked]="checked"
(^click)="select($event)">
(click)="select($event)">
<!-- The actual `radio` part of the control. -->
<div class="md-radio-container">
<div class="md-radio-off"></div>

View File

@ -41,7 +41,7 @@ var _uniqueIdCounter: number = 0;
'[attr.aria-disabled]': 'disabled',
'[attr.aria-activedescendant]': 'activedescendant',
// TODO(jelbourn): Remove ^ when event retargeting is fixed.
'(^keydown)': 'onKeydown($event)',
'(keydown)': 'onKeydown($event)',
'[tabindex]': 'tabindex',
}
})

View File

@ -1,6 +1,6 @@
<style>@import "package:angular2_material/src/components/switcher/switch.css";</style>
<div (^click)="toggle($event)">
<div (click)="toggle($event)">
<div class="md-switch-container">
<div class="md-switch-bar"></div>
<div class="md-switch-thumb-container">

View File

@ -9,10 +9,12 @@ describe('md-dialog', function() {
it('should open a dialog', function() {
var openButton = element(by.id('open'));
openButton.click();
browser.sleep(500);
expect(element(by.css('.md-dialog')).isPresent()).toEqual(true);
var dialog = element(by.css('.md-dialog'));
browser.sleep(500);
expect(dialog.isPresent()).toEqual(true);
dialog.sendKeys(protractor.Key.ESCAPE);
expect(element(by.css('.md-dialog')).isPresent()).toEqual(false);

View File

@ -34,7 +34,7 @@
</p>
<section>
<form (^submit)="submit('form submit')">
<form (submit)="submit('form submit')">
<button md-button>SUBMIT</button>
<button>Native button</button>
</form>
@ -45,32 +45,32 @@
<section>
<span class="label">Regular button</span>
<button md-button (^click)="click('button')">BUTTON</button>
<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>
<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>
<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>
<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>
@ -81,8 +81,8 @@
<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>
<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>

View File

@ -1,9 +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>
<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>

View File

@ -21,10 +21,10 @@
<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>
<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>

View File

@ -1,9 +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>
<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>