chore: fix up ngClass for types/export missing public API

Closes #7202
This commit is contained in:
Misko Hevery 2016-02-20 08:52:51 -08:00 committed by Miško Hevery
parent 5a59e44765
commit 6402d61f69
7 changed files with 118 additions and 79 deletions

View File

@ -1,14 +1,16 @@
import {isPresent, isString, StringWrapper, isBlank, isArray} from 'angular2/src/facade/lang';
import {isPresent, isString, isArray} from 'angular2/src/facade/lang';
import {
DoCheck,
OnDestroy,
Directive,
ElementRef,
IterableDiffer,
IterableDiffers,
KeyValueDiffer,
KeyValueDiffers,
Renderer
Renderer,
IterableDiffer,
KeyValueDiffer,
CollectionChangeRecord,
KeyValueChangeRecord
} from 'angular2/core';
import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
@ -73,66 +75,68 @@ import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collecti
*/
@Directive({selector: '[ngClass]', inputs: ['rawClass: ngClass', 'initialClasses: class']})
export class NgClass implements DoCheck, OnDestroy {
private _differ: any;
private _mode: string;
private _initialClasses = [];
private _rawClass;
private _iterableDiffer: IterableDiffer;
private _keyValueDiffer: KeyValueDiffer;
private _initialClasses: string[] = [];
private _rawClass: string[] | Set<string>;
constructor(private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
private _ngEl: ElementRef, private _renderer: Renderer) {}
set initialClasses(v) {
set initialClasses(v: string) {
this._applyInitialClasses(true);
this._initialClasses = isPresent(v) && isString(v) ? v.split(' ') : [];
this._applyInitialClasses(false);
this._applyClasses(this._rawClass, false);
}
set rawClass(v) {
set rawClass(v: string | string[] | Set<string>| {[key: string]: any}) {
this._cleanupClasses(this._rawClass);
if (isString(v)) {
v = v.split(' ');
v = (<string>v).split(' ');
}
this._rawClass = v;
this._rawClass = <string[] | Set<string>>v;
this._iterableDiffer = null;
this._keyValueDiffer = null;
if (isPresent(v)) {
if (isListLikeIterable(v)) {
this._differ = this._iterableDiffers.find(v).create(null);
this._mode = 'iterable';
this._iterableDiffer = this._iterableDiffers.find(v).create(null);
} else {
this._differ = this._keyValueDiffers.find(v).create(null);
this._mode = 'keyValue';
this._keyValueDiffer = this._keyValueDiffers.find(v).create(null);
}
} else {
this._differ = null;
}
}
ngDoCheck(): void {
if (isPresent(this._differ)) {
var changes = this._differ.diff(this._rawClass);
if (isPresent(this._iterableDiffer)) {
var changes = this._iterableDiffer.diff(this._rawClass);
if (isPresent(changes)) {
if (this._mode == 'iterable') {
this._applyIterableChanges(changes);
} else {
this._applyKeyValueChanges(changes);
}
this._applyIterableChanges(changes);
}
}
if (isPresent(this._keyValueDiffer)) {
var changes = this._keyValueDiffer.diff(this._rawClass);
if (isPresent(changes)) {
this._applyKeyValueChanges(changes);
}
}
}
ngOnDestroy(): void { this._cleanupClasses(this._rawClass); }
private _cleanupClasses(rawClassVal): void {
private _cleanupClasses(rawClassVal: string[] | Set<string>| {[key: string]: any}): void {
this._applyClasses(rawClassVal, true);
this._applyInitialClasses(false);
}
private _applyKeyValueChanges(changes: any): void {
changes.forEachAddedItem((record) => { this._toggleClass(record.key, record.currentValue); });
changes.forEachChangedItem((record) => { this._toggleClass(record.key, record.currentValue); });
changes.forEachRemovedItem((record) => {
changes.forEachAddedItem(
(record: KeyValueChangeRecord) => { this._toggleClass(record.key, record.currentValue); });
changes.forEachChangedItem(
(record: KeyValueChangeRecord) => { this._toggleClass(record.key, record.currentValue); });
changes.forEachRemovedItem((record: KeyValueChangeRecord) => {
if (record.previousValue) {
this._toggleClass(record.key, false);
}
@ -140,15 +144,17 @@ export class NgClass implements DoCheck, OnDestroy {
}
private _applyIterableChanges(changes: any): void {
changes.forEachAddedItem((record) => { this._toggleClass(record.item, true); });
changes.forEachRemovedItem((record) => { this._toggleClass(record.item, false); });
changes.forEachAddedItem(
(record: CollectionChangeRecord) => { this._toggleClass(record.item, true); });
changes.forEachRemovedItem(
(record: CollectionChangeRecord) => { this._toggleClass(record.item, false); });
}
private _applyInitialClasses(isCleanup: boolean) {
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
}
private _applyClasses(rawClassVal: string[] | Set<string>| {[key: string]: string},
private _applyClasses(rawClassVal: string[] | Set<string>| {[key: string]: any},
isCleanup: boolean) {
if (isPresent(rawClassVal)) {
if (isArray(rawClassVal)) {
@ -156,14 +162,15 @@ export class NgClass implements DoCheck, OnDestroy {
} else if (rawClassVal instanceof Set) {
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
} else {
StringMapWrapper.forEach(<{[k: string]: string}>rawClassVal, (expVal, className) => {
if (expVal) this._toggleClass(className, !isCleanup);
});
StringMapWrapper.forEach(<{[k: string]: any}>rawClassVal,
(expVal: any, className: string) => {
if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
});
}
}
}
private _toggleClass(className: string, enabled): void {
private _toggleClass(className: string, enabled: boolean): void {
className = className.trim();
if (className.length > 0) {
if (className.indexOf(' ') > -1) {

View File

@ -7,7 +7,7 @@ import {
Renderer
} from 'angular2/core';
import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
import {KVChangeRecord} from "../../core/change_detection/differs/default_keyvalue_differ";
import {KeyValueChangeRecord} from "../../core/change_detection/differs/default_keyvalue_differ";
/**
* The `NgStyle` directive changes styles based on a result of expression evaluation.
@ -88,10 +88,11 @@ export class NgStyle implements DoCheck {
private _applyChanges(changes: any): void {
changes.forEachAddedItem(
(record: KVChangeRecord) => { this._setStyle(record.key, record.currentValue); });
(record: KeyValueChangeRecord) => { this._setStyle(record.key, record.currentValue); });
changes.forEachChangedItem(
(record: KVChangeRecord) => { this._setStyle(record.key, record.currentValue); });
changes.forEachRemovedItem((record: KVChangeRecord) => { this._setStyle(record.key, null); });
(record: KeyValueChangeRecord) => { this._setStyle(record.key, record.currentValue); });
changes.forEachRemovedItem(
(record: KeyValueChangeRecord) => { this._setStyle(record.key, null); });
}
private _setStyle(name: string, val: string): void {

View File

@ -21,5 +21,7 @@ export {
KeyValueDiffers,
KeyValueDiffer,
KeyValueDifferFactory,
CollectionChangeRecord,
KeyValueChangeRecord,
TrackByFn
} from './change_detection/change_detection';

View File

@ -1,9 +1,20 @@
import {IterableDiffers, IterableDifferFactory, TrackByFn} from './differs/iterable_differs';
import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs';
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
import {DefaultKeyValueDifferFactory} from './differs/default_keyvalue_differ';
import {CONST, CONST_EXPR, isPresent} from 'angular2/src/facade/lang';
import {
DefaultKeyValueDifferFactory,
KeyValueChangeRecord
} from './differs/default_keyvalue_differ';
import {CONST_EXPR} from 'angular2/src/facade/lang';
export {
DefaultKeyValueDifferFactory,
KeyValueChangeRecord
} from './differs/default_keyvalue_differ';
export {
DefaultIterableDifferFactory,
CollectionChangeRecord
} from './differs/default_iterable_differ';
export {
ASTWithSource,
AST,

View File

@ -13,14 +13,14 @@ export class DefaultKeyValueDifferFactory implements KeyValueDifferFactory {
export class DefaultKeyValueDiffer implements KeyValueDiffer {
private _records: Map<any, any> = new Map();
private _mapHead: KVChangeRecord = null;
private _previousMapHead: KVChangeRecord = null;
private _changesHead: KVChangeRecord = null;
private _changesTail: KVChangeRecord = null;
private _additionsHead: KVChangeRecord = null;
private _additionsTail: KVChangeRecord = null;
private _removalsHead: KVChangeRecord = null;
private _removalsTail: KVChangeRecord = null;
private _mapHead: KeyValueChangeRecord = null;
private _previousMapHead: KeyValueChangeRecord = null;
private _changesHead: KeyValueChangeRecord = null;
private _changesTail: KeyValueChangeRecord = null;
private _additionsHead: KeyValueChangeRecord = null;
private _additionsTail: KeyValueChangeRecord = null;
private _removalsHead: KeyValueChangeRecord = null;
private _removalsTail: KeyValueChangeRecord = null;
get isDirty(): boolean {
return this._additionsHead !== null || this._changesHead !== null ||
@ -28,35 +28,35 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
forEachItem(fn: Function) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._mapHead; record !== null; record = record._next) {
fn(record);
}
}
forEachPreviousItem(fn: Function) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
fn(record);
}
}
forEachChangedItem(fn: Function) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._changesHead; record !== null; record = record._nextChanged) {
fn(record);
}
}
forEachAddedItem(fn: Function) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._additionsHead; record !== null; record = record._nextAdded) {
fn(record);
}
}
forEachRemovedItem(fn: Function) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
fn(record);
}
@ -80,9 +80,9 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
check(map: Map<any, any>): boolean {
this._reset();
var records = this._records;
var oldSeqRecord: KVChangeRecord = this._mapHead;
var lastOldSeqRecord: KVChangeRecord = null;
var lastNewSeqRecord: KVChangeRecord = null;
var oldSeqRecord: KeyValueChangeRecord = this._mapHead;
var lastOldSeqRecord: KeyValueChangeRecord = null;
var lastNewSeqRecord: KeyValueChangeRecord = null;
var seqChanged: boolean = false;
this._forEach(map, (value, key) => {
@ -104,7 +104,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
if (records.has(key)) {
newSeqRecord = records.get(key);
} else {
newSeqRecord = new KVChangeRecord(key);
newSeqRecord = new KeyValueChangeRecord(key);
records.set(key, newSeqRecord);
newSeqRecord.currentValue = value;
this._addToAdditions(newSeqRecord);
@ -132,7 +132,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
/** @internal */
_reset() {
if (this.isDirty) {
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
// Record the state of the mapping
for (record = this._previousMapHead = this._mapHead; record !== null; record = record._next) {
record._nextPrevious = record._next;
@ -178,7 +178,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_truncate(lastRecord: KVChangeRecord, record: KVChangeRecord) {
_truncate(lastRecord: KeyValueChangeRecord, record: KeyValueChangeRecord) {
while (record !== null) {
if (lastRecord === null) {
this._mapHead = null;
@ -196,7 +196,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
record = nextRecord;
}
for (var rec: KVChangeRecord = this._removalsHead; rec !== null; rec = rec._nextRemoved) {
for (var rec: KeyValueChangeRecord = this._removalsHead; rec !== null; rec = rec._nextRemoved) {
rec.previousValue = rec.currentValue;
rec.currentValue = null;
this._records.delete(rec.key);
@ -204,13 +204,13 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_isInRemovals(record: KVChangeRecord) {
_isInRemovals(record: KeyValueChangeRecord) {
return record === this._removalsHead || record._nextRemoved !== null ||
record._prevRemoved !== null;
}
/** @internal */
_addToRemovals(record: KVChangeRecord) {
_addToRemovals(record: KeyValueChangeRecord) {
// todo(vicb) assert
// assert(record._next == null);
// assert(record._nextAdded == null);
@ -227,7 +227,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_removeFromSeq(prev: KVChangeRecord, record: KVChangeRecord) {
_removeFromSeq(prev: KeyValueChangeRecord, record: KeyValueChangeRecord) {
var next = record._next;
if (prev === null) {
this._mapHead = next;
@ -242,7 +242,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_removeFromRemovals(record: KVChangeRecord) {
_removeFromRemovals(record: KeyValueChangeRecord) {
// todo(vicb) assert
// assert(record._next == null);
// assert(record._nextAdded == null);
@ -264,7 +264,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_addToAdditions(record: KVChangeRecord) {
_addToAdditions(record: KeyValueChangeRecord) {
// todo(vicb): assert
// assert(record._next == null);
// assert(record._nextAdded == null);
@ -280,7 +280,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
/** @internal */
_addToChanges(record: KVChangeRecord) {
_addToChanges(record: KeyValueChangeRecord) {
// todo(vicb) assert
// assert(record._nextAdded == null);
// assert(record._nextChanged == null);
@ -300,7 +300,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
var changes = [];
var additions = [];
var removals = [];
var record: KVChangeRecord;
var record: KeyValueChangeRecord;
for (record = this._mapHead; record !== null; record = record._next) {
items.push(stringify(record));
@ -334,22 +334,22 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
}
export class KVChangeRecord {
export class KeyValueChangeRecord {
previousValue: any = null;
currentValue: any = null;
/** @internal */
_nextPrevious: KVChangeRecord = null;
_nextPrevious: KeyValueChangeRecord = null;
/** @internal */
_next: KVChangeRecord = null;
_next: KeyValueChangeRecord = null;
/** @internal */
_nextAdded: KVChangeRecord = null;
_nextAdded: KeyValueChangeRecord = null;
/** @internal */
_nextRemoved: KVChangeRecord = null;
_nextRemoved: KeyValueChangeRecord = null;
/** @internal */
_prevRemoved: KVChangeRecord = null;
_prevRemoved: KeyValueChangeRecord = null;
/** @internal */
_nextChanged: KVChangeRecord = null;
_nextChanged: KeyValueChangeRecord = null;
constructor(public key: any) {}

View File

@ -789,6 +789,7 @@ var NG_CORE = [
'ProviderBuilder.token',
'ProviderBuilder.token=',
'PLATFORM_DIRECTIVES:js',
"CollectionChangeRecord",
'ChangeDetectionError',
'ChangeDetectionError.context',
'ChangeDetectionError.location',
@ -1152,6 +1153,13 @@ var NG_CORE = [
'Key.id=',
'Key.token',
'Key.token=',
'KeyValueChangeRecord',
'KeyValueChangeRecord.currentValue',
'KeyValueChangeRecord.currentValue=',
'KeyValueChangeRecord.key',
'KeyValueChangeRecord.key=',
'KeyValueChangeRecord.previousValue',
'KeyValueChangeRecord.previousValue=',
'KeyValueDiffers#create()',
'KeyValueDiffers#extend()',
'KeyValueDiffers',

View File

@ -80,6 +80,11 @@ const CORE = [
'ClassDefinition',
'ClassDefinition.constructor:Function|any[]',
'ClassDefinition.extends:Type',
'CollectionChangeRecord',
'CollectionChangeRecord.constructor(item:any, trackById:any)',
'CollectionChangeRecord.currentIndex:number',
'CollectionChangeRecord.previousIndex:number',
'CollectionChangeRecord.toString():string',
'Compiler',
'Compiler.clearCache():any',
'Compiler.compileInHost(componentType:Type):Promise<HostViewFactoryRef>',
@ -260,6 +265,11 @@ const CORE = [
'Key.displayName:string',
'Key.get(token:Object):Key',
'Key.numberOfKeys:number',
'KeyValueChangeRecord',
'KeyValueChangeRecord.constructor(key:any)',
'KeyValueChangeRecord.currentValue:any',
'KeyValueChangeRecord.previousValue:any',
'KeyValueChangeRecord.toString():string',
'KeyValueDiffer',
'KeyValueDiffer.diff(object:any):any',
'KeyValueDiffer.onDestroy():any',
@ -656,10 +666,10 @@ const COMMON = [
'MinLengthValidator.validate(c:Control):{[key:string]:any}',
'NgClass',
'NgClass.constructor(_iterableDiffers:IterableDiffers, _keyValueDiffers:KeyValueDiffers, _ngEl:ElementRef, _renderer:Renderer)',
'NgClass.initialClasses=(v:any)',
'NgClass.initialClasses=(v:string)',
'NgClass.ngDoCheck():void',
'NgClass.ngOnDestroy():void',
'NgClass.rawClass=(v:any)',
'NgClass.rawClass=(v:string|string[]|Set<string>|{[key:string]:any})',
'NgControl',
'NgControl.asyncValidator:Function',
'NgControl.name:string',