This repository has been archived by the owner on Jul 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 39
Simplify Widget Registries #686
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
e87219c
first set of changes to only support base and local registry
agubler 7b9b304
update registries to registry
agubler bd8de6b
move logic into projector
agubler d8137f6
improve get logic in handler
agubler cf0c527
try and make registry handler a little cleaner
agubler 5dd4cfd
Add defineInjector to registry handler
agubler 6e54089
Unit tests for registry handler
agubler e672728
Unit tests for projector
agubler e407fa8
refactor to use tuple for registries and remove destory management logic
agubler 843ab96
emit the item and check before invalidating
agubler 7e6f5d7
tests for for the extra invalidates
agubler b7356ee
util _get for both get and getHandler
agubler c8b8f71
do not default projector properties
agubler 1ea5af1
use as for cast
agubler 8bd5fbb
Add generic for getInjector and correct define type
agubler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,74 @@ | ||
import { Map } from '@dojo/shim/Map'; | ||
import { Evented } from '@dojo/core/Evented'; | ||
import { Constructor, RegistryLabel, WidgetBaseInterface } from './interfaces'; | ||
import { Registry, RegistryEventObject } from './Registry'; | ||
import { Registry, RegistryEventObject, RegistryItem } from './Registry'; | ||
import { Injector } from './Injector'; | ||
|
||
export default class RegistryHandler extends Evented { | ||
private _registries: { handle?: any, registry: Registry }[] = []; | ||
export class RegistryHandler extends Evented { | ||
private _registry = new Registry(); | ||
private _baseRegistry: Registry; | ||
private _registryWidgetLabelMap: Map<Registry, RegistryLabel[]> = new Map(); | ||
private _registryInjectorLabelMap: Map<Registry, RegistryLabel[]> = new Map(); | ||
|
||
public add(registry: Registry, isDefault: boolean = false) { | ||
if (isDefault) { | ||
this._registries.push({ registry }); | ||
} | ||
else { | ||
this._registries.unshift({ registry }); | ||
} | ||
constructor() { | ||
super(); | ||
this.own(this._registry); | ||
} | ||
|
||
public remove(registry: Registry): boolean { | ||
return this._registries.some((registryWrapper, i) => { | ||
if (registryWrapper.registry === registry) { | ||
registry.destroy(); | ||
this._registries.splice(i, 1); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
public set base(baseRegistry: Registry) { | ||
this._registryWidgetLabelMap.delete(this._baseRegistry); | ||
this._registryInjectorLabelMap.delete(this._baseRegistry); | ||
this._baseRegistry = baseRegistry; | ||
} | ||
|
||
public replace(original: Registry, replacement: Registry): boolean { | ||
return this._registries.some((registryWrapper, i) => { | ||
if (registryWrapper.registry === original) { | ||
original.destroy(); | ||
registryWrapper.registry = replacement; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
public define(label: RegistryLabel, widget: RegistryItem): void { | ||
this._registry.define(label, widget); | ||
} | ||
|
||
public get defaultRegistry(): Registry | undefined { | ||
if (this._registries.length) { | ||
return this._registries[this._registries.length - 1].registry; | ||
} | ||
public defineInjector(label: RegistryLabel, injector: Injector): void { | ||
this._registry.defineInjector(label, injector); | ||
} | ||
|
||
public has(widgetLabel: RegistryLabel): boolean { | ||
return this._registries.some((registryWrapper) => { | ||
return registryWrapper.registry.has(widgetLabel); | ||
}); | ||
public has(label: RegistryLabel): boolean { | ||
return this._registry.has(label) || this._baseRegistry.has(label); | ||
} | ||
|
||
public getInjector<T extends Injector>(label: RegistryLabel): T | null { | ||
for (let i = 0; i < this._registries.length; i++) { | ||
const registryWrapper = this._registries[i]; | ||
return registryWrapper.registry.getInjector<T>(label); | ||
} | ||
return null; | ||
public hasInjector(label: RegistryLabel): boolean { | ||
return this._registry.hasInjector(label) || this._baseRegistry.hasInjector(label); | ||
} | ||
|
||
public get<T extends WidgetBaseInterface = WidgetBaseInterface>(widgetLabel: RegistryLabel): Constructor<T> | null { | ||
for (let i = 0; i < this._registries.length; i++) { | ||
const registryWrapper = this._registries[i]; | ||
const item = registryWrapper.registry.get<T>(widgetLabel); | ||
public get<T extends WidgetBaseInterface = WidgetBaseInterface>(label: RegistryLabel, globalPrecedence: boolean = false): Constructor<T> | null { | ||
return this._get(label, globalPrecedence, 'get', this._registryWidgetLabelMap); | ||
} | ||
|
||
public getInjector<T extends Injector>(label: RegistryLabel, globalPrecedence: boolean = false): T | null { | ||
return this._get(label, globalPrecedence, 'getInjector', this._registryInjectorLabelMap); | ||
} | ||
|
||
private _get(label: RegistryLabel, globalPrecedence: boolean, getFunctionName: 'getInjector' | 'get', labelMap: Map<Registry, RegistryLabel[]>): any { | ||
const registries = globalPrecedence ? [ this._baseRegistry, this._registry ] : [ this._registry, this._baseRegistry ]; | ||
for (let i = 0; i < registries.length; i++) { | ||
const registry: any = registries[i]; | ||
if (!registry) { | ||
continue; | ||
} | ||
const item = registry[getFunctionName](label); | ||
const registeredLabels = labelMap.get(registry) || []; | ||
if (item) { | ||
return item; | ||
} | ||
else if (!registryWrapper.handle) { | ||
registryWrapper.handle = registryWrapper.registry.on(widgetLabel, (event: RegistryEventObject) => { | ||
if (event.action === 'loaded') { | ||
else if (registeredLabels.indexOf(label) === -1) { | ||
const handle = registry.on(label, (event: RegistryEventObject) => { | ||
if (event.action === 'loaded' && (this as any)[getFunctionName](label) === event.item) { | ||
this.emit({ type: 'invalidate' }); | ||
registryWrapper.handle.destroy(); | ||
registryWrapper.handle = undefined; | ||
} | ||
}); | ||
this.own(handle); | ||
labelMap.set(registry, [ ...registeredLabels, label]); | ||
} | ||
} | ||
return null; | ||
} | ||
} | ||
|
||
export default RegistryHandler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No other decent type than
any
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's so we can use an index using the
string
function name that is passed.If the
getFunctionName
(which typing I realise is a bad name), is restricted to just'get'
or'getInjector'
then usingregistry[getFunctionName]('')
works but not if is it's typed as'get' | 'getInjector'
, any ideas?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... Recent versions of TypeScript allow you to access properties by method name just fine, if the variable is a string literal, unless I am missing something here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was fine is I typed the argument is just
'get'
or just'getInjector'
but not when I typed it as'getInjector' | 'get'
...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange, the playground example types it as
'getInjector' | 'get'
... wonder what is wrong.