ember-material-icons
Version:
Google Material icons for your ember-cli app
181 lines (138 loc) • 4.95 kB
text/typescript
import { PropertyReference } from './references/descriptors';
import RootReference from './references/root';
import { MetaOptions } from './types';
import { Dict, DictSet, HasGuid, Set, dict } from '@glimmer/util';
import {
RootReferenceFactory,
PathReferenceFactory,
Meta as IMeta,
RootReference as IRootReference
} from './types';
import { PathReference as IPathReference, VOLATILE_TAG } from '@glimmer/reference';
import { InnerReferenceFactory } from './references/descriptors';
const NOOP_DESTROY = { destroy() {} };
class ConstPath implements IPathReference<any> {
private parent: any;
private property: string;
public tag = VOLATILE_TAG;
constructor(parent: any, property: string) {
this.parent = parent;
}
chain() { return NOOP_DESTROY; }
notify() {}
value() {
return this.parent[this.property];
}
get(prop: string): IPathReference<any> {
return new ConstPath(this.parent[this.property], prop);
}
}
class ConstRoot implements IRootReference<any> {
private inner: any;
public tag = VOLATILE_TAG;
constructor(value) {
this.inner = value;
}
update(inner: any) {
this.inner = inner;
}
chain() { return NOOP_DESTROY; }
notify() {}
value(): any {
return this.inner;
}
referenceFromParts(parts: string[]): IPathReference<any> {
throw new Error("Not implemented");
}
chainFor(prop: string): IPathReference<any> {
throw new Error("Not implemented");
}
get(prop: string): IPathReference<any> {
return new ConstPath(this.inner, prop);
}
}
class ConstMeta /*implements IMeta*/ {
private object: any;
constructor(object: any) {
this.object = object;
}
root(): ConstRoot {
return new ConstRoot(this.object);
}
}
export const CLASS_META = "df8be4c8-4e89-44e2-a8f9-550c8dacdca7";
const hasOwnProperty = Object.hasOwnProperty;
class Meta implements IMeta, HasGuid {
static for(obj: any): IMeta {
if (obj === null || obj === undefined) return new Meta(obj, {});
if (hasOwnProperty.call(obj, '_meta') && obj._meta) return obj._meta;
if (!Object.isExtensible(obj)) return <any>new ConstMeta(obj);
let MetaToUse: typeof Meta = Meta;
if (obj.constructor && obj.constructor[CLASS_META]) {
let classMeta: ClassMeta = obj.constructor[CLASS_META];
MetaToUse = classMeta.InstanceMetaConstructor;
} else if (obj[CLASS_META]) {
MetaToUse = obj[CLASS_META].InstanceMetaConstructor;
}
return (obj._meta = new MetaToUse(obj, {}));
}
static exists(obj: any): boolean {
return typeof obj === 'object' && obj._meta;
}
static metadataForProperty(key: string): any {
return null;
}
private object: any;
private RootReferenceFactory: RootReferenceFactory<any>;
private DefaultPathReferenceFactory: InnerReferenceFactory<any>;
private rootCache: IRootReference<any>;
private references: Dict<DictSet<IPathReference<any> & HasGuid>> = null;
public _guid;
protected slots: Dict<any> = null;
protected referenceTypes: Dict<InnerReferenceFactory<any>> = null;
protected propertyMetadata: Dict<any> = null;
constructor(object: any, { RootReferenceFactory, DefaultPathReferenceFactory }: MetaOptions) {
this.object = object;
this.RootReferenceFactory = RootReferenceFactory || RootReference;
this.DefaultPathReferenceFactory = DefaultPathReferenceFactory || PropertyReference;
}
addReference(property: string, reference: IPathReference<any> & HasGuid) {
let refs = this.references = this.references || dict<DictSet<IPathReference<any> & HasGuid>>();
let set = refs[property] = refs[property] || new DictSet<IPathReference<any> & HasGuid>();
set.add(reference);
}
addReferenceTypeFor(property: string, type: PathReferenceFactory<any>) {
this.referenceTypes = this.referenceTypes || dict<PathReferenceFactory<any>>();
this.referenceTypes[property] = type;
}
referenceTypeFor(property: string): InnerReferenceFactory<any> {
if (!this.referenceTypes) return PropertyReference;
return this.referenceTypes[property] || PropertyReference;
}
removeReference(property: string, reference: IPathReference<any> & HasGuid) {
if (!this.references) return;
let set = this.references[property];
set.delete(reference);
}
getReferenceTypes(): Dict<InnerReferenceFactory<any>> {
this.referenceTypes = this.referenceTypes || dict<PathReferenceFactory<any>>();
return this.referenceTypes;
}
referencesFor(property: string): Set<IPathReference<any>> {
if (!this.references) return;
return this.references[property];
}
getSlots() {
return (this.slots = this.slots || dict());
}
root(): IRootReference<any> {
return (this.rootCache = this.rootCache || new this.RootReferenceFactory(this.object));
}
}
export default Meta;
interface ClassMeta {
InstanceMetaConstructor: typeof Meta;
}
export function metaFor(obj: any): IMeta {
return Meta.for(obj);
}