Americano.coffee | |
---|---|
Americano takes a shot at being one of those new-fangled Micro-JS-Frameworks. The goal of the project is to allow any Coffeescript developer to create an MVP style application without locking them into how they like to implement Widgets or Models. It's really just the "P" | |
Americano is a based on the GWT-Presenter project and it's implementation in the SheepdogInc.ca project gTrax. | |
The source for Americano is available on GitHub, along with examples of how to implement a sample application called Americanotes. | |
Still a WIP | |
You can help! Please submit feature requests and bug reports to GitHub Issues, or even better, Fork the project and submit a pull request! Good Luck! | |
The Codes | |
Presenter ClassYou should subclass this guy for your Presenter Implementation. The Presenter is the man in the middle between your Model and your Display. All events | class Presenter
constructor: (@display) ->
@bound = false
@handlers = {}
|
getDisplayGet the bound display for the presenter. | getDisplay: () -> @display |
bindThe method to call to put the processing gears into action and bind all the events | bind: () ->
@onBind()
@bound = true |
ensureBoundMakes sure the presenter is bound, if not it will call bind for you | ensureBound: () ->
if not @bound
@bind()
|
onBindShoddy interface. | onBind: () ->
alert "Unimplemented"
|
unbindDisables, and removes all event handlers from the presenter | unbind: () ->
@bound = false
for name, hndlrs of @handlers
for hndlr in hndlrs
hndlr.remove()
@handlers = {}
|
registerHandlerRegisters an event handler with the Presenter with the option of scoping it strictly to the presenter, globally, or an element @param {string} @param {boolean | window | Element} @param {Function} | registerHandler: (name, scope, handler) ->
hndlr = new Handler(name, scope, handler)
if scope and typeof scope is "object"
hndlr.bind()
else if scope |
if the scope is set to "true", we want to register the event globally | hndlr.scope = window
hndlr.bind()
@handlers[name] = [] if !@handlers[name]?
@handlers[name].push hndlr
|
unregisterHandlerRemoves all handlers from this presenter under an event name @param {string} | unregisterHandler: (name) ->
for nm, hndlrs of @handlers
if nm == name
for hndlr in hndlrs
hndlr.remove()
@handlers[nm] = [] |
fireHandlerFIRE HANDLE-PEDOS @param {string} @param {Object} | fireHandler: (name, data) ->
for nm, hndlrs of @handlers
if nm == name
for hndlr in hndlrs
hndlr.call({data:data}) |
Display ClassI'm the interface. I display the data from the model and provide hooks to the Presenter to reach DEEP inside of me to handle events that I might fire. I should not format data, or ever talk directly to a model. | class Display
|
asWidgetYou should implement me. | asWidget: -> "unimplemented" |
Handler ClassA Generic event handler wrapper around managing an event. Allows you to maintain it's stickyness to the scope and fire it. | class Handler |
constructor@param {string} @param {Object} @param {Function} | constructor: (@name, @scope, @handler) -> |
bindBind the handler function to the scope | bind: () ->
@scope.addEventListener(@name, @handler, false) |
removeTake the handler away from the scope | remove: () ->
if @scope
@scope.removeEventListener(@name, @handler, false) |
callFIRE CALL-PEDOS | call: (data) ->
@handler(data) |
EventBusKeeping track of events, and firing events in the global scope in hopes that someone is listening on 'window' for the event | class EventBus |
fireFire Event-predos, this shoots a new event across the EventBus. @param {string} @param {Object} | fire: (eventName, data) ->
e = document.createEvent "Event"
e.initEvent(eventName, true, true)
e.data = data
window.dispatchEvent e |
addHandlerAdd a generic event handler to the global scope. Keep track of it on your own, because a remove is not supported. | addHandler: (eventName, callback) ->
window.addEventListener(eventName, callback, false) |
Espresso MachineGWT-Style Injection Machine. Based on a gist by: bremac | class EspressoMachine |
constructorBuild a new EspressoMachine instance with a default dict of registered factories for the EspressoMachine to inject. | constructor: (dict) ->
@extend(dict) |
extendExtend the EspressoMachine instance with the provided list of factories | extend: (dict) ->
for k, v of dict
@[k] = v
@ |
registerRegister a new function getter with the esm. It will overwrite any existing registry entries at that key. | register: (name, factory) ->
@[name] = factory |
createCreate a new instance of a Type, it will read in dicts from both
decorators | create: (type) ->
if type.PRESS
pressArgs = []
for name, factory of type.PRESS
pressArgs.push @[factory](@)
typeInstance = new type(pressArgs...)
else
typeInstance = new type()
@inject(typeInstance, type.INJECT) |
injectPerform the injection of the dict into the new Type object. An | inject: (obj, dict) ->
if dict?
for name, factory of dict
obj[name] = @[factory](@)
obj.esm = @
obj |
LoggerHey Look, a handy-dandy logger TODO: make me awesomer | class Logger |
defaultLogThresholdA default log threshold (this doesn't really do anything yet.) | defaultLogThreshold = 2; |
logLog a message to the logger. @param {string} @param {int} | log: (message, logLevel) ->
if logLevel > defaultLogThreshold
message += "!"
console.log message
|