brancusi 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +13 -0
- data/lib/assets/javascripts/brancusi/application/application.js.coffee +114 -0
- data/lib/assets/javascripts/brancusi/application/application_controller.js.coffee +17 -0
- data/lib/assets/javascripts/brancusi/application/application_module.js.coffee +29 -0
- data/lib/assets/javascripts/brancusi/application/bootstrapper.js.coffee +18 -0
- data/lib/assets/javascripts/brancusi/application/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/application/sandbox.js.coffee +14 -0
- data/lib/assets/javascripts/brancusi/container/container.js.coffee +139 -0
- data/lib/assets/javascripts/brancusi/container/dependent_module.js.coffee +30 -0
- data/lib/assets/javascripts/brancusi/container/dependent_object.js.coffee +9 -0
- data/lib/assets/javascripts/brancusi/container/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/events/event_object.js.coffee +10 -0
- data/lib/assets/javascripts/brancusi/events/events_module.js.coffee +14 -0
- data/lib/assets/javascripts/brancusi/events/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/events/mediator.js.coffee +70 -0
- data/lib/assets/javascripts/brancusi/index.js.coffee +2 -0
- data/lib/assets/javascripts/brancusi/namespace.js.coffee +13 -0
- data/lib/assets/javascripts/brancusi/object_model/base_object.js.coffee +27 -0
- data/lib/assets/javascripts/brancusi/object_model/decorate.js.coffee +14 -0
- data/lib/assets/javascripts/brancusi/object_model/extend.js.coffee +10 -0
- data/lib/assets/javascripts/brancusi/object_model/include.js.coffee +13 -0
- data/lib/assets/javascripts/brancusi/object_model/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/renderer/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/renderer/region_manager.js.coffee +30 -0
- data/lib/assets/javascripts/brancusi/renderer/renderer.js.coffee +41 -0
- data/lib/assets/javascripts/brancusi/renderer/template_manager.js.coffee +0 -0
- data/lib/assets/javascripts/brancusi/routes/dispatcher.js.coffee +10 -0
- data/lib/assets/javascripts/brancusi/routes/index.js.coffee +1 -0
- data/lib/assets/javascripts/brancusi/routes/mapper.js.coffee +41 -0
- data/lib/assets/javascripts/brancusi/routes/router.js.coffee +15 -0
- data/lib/assets/javascripts/brancusi/support/davis_router.js.coffee +19 -0
- data/lib/assets/javascripts/brancusi/support/knockout_renderer.js.coffee +12 -0
- data/lib/assets/javascripts/davis.js +1838 -0
- data/lib/assets/javascripts/knockout.js +3583 -0
- data/lib/assets/javascripts/underscore.js +1221 -0
- data/lib/assets/javascripts/underscore.string.js +600 -0
- data/lib/brancusi.rb +4 -0
- data/lib/brancusi/engine.rb +4 -0
- data/lib/brancusi/version.rb +3 -0
- metadata +282 -0
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'guard/jasmine/task'
|
4
|
+
|
5
|
+
Guard::JasmineTask.new('jasmine:specs') do |task|
|
6
|
+
task.options = "-s thin -p 3001"
|
7
|
+
end
|
8
|
+
|
9
|
+
Guard::JasmineTask.new('jasmine:stories') do |task|
|
10
|
+
task.options = "-s thin -p 3001 -u http://localhost:3001/jasmine-stories"
|
11
|
+
end
|
12
|
+
|
13
|
+
task 'jasmine:all' => ['guard:jasmine:specs', 'guard:jasmine:stories']
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#= require brancusi/events
|
2
|
+
#= require brancusi/routes/mapper
|
3
|
+
|
4
|
+
namespace "brancusi"
|
5
|
+
|
6
|
+
class brancusi.Application extends brancusi.EventObject
|
7
|
+
|
8
|
+
@dependency mediator: "Mediator"
|
9
|
+
|
10
|
+
# Default configuration options, which may be overridden by instances
|
11
|
+
@config:
|
12
|
+
bootstrapper: brancusi.Bootstrapper
|
13
|
+
|
14
|
+
# Module classes for the application
|
15
|
+
@Modules: {}
|
16
|
+
|
17
|
+
# Module instances
|
18
|
+
modules: {}
|
19
|
+
|
20
|
+
# Controller classes for the application
|
21
|
+
@Controllers: {}
|
22
|
+
|
23
|
+
# Controller instances
|
24
|
+
controllers: {}
|
25
|
+
|
26
|
+
# Model classes for the application
|
27
|
+
@Models: {}
|
28
|
+
|
29
|
+
@routes: new brancusi.routes.Mapper
|
30
|
+
|
31
|
+
# Instantiates the application and bootstrapper, and resolves any dependencies, modules and controllers.
|
32
|
+
#
|
33
|
+
# @return [Application] an instance of the application.
|
34
|
+
#
|
35
|
+
@create: ->
|
36
|
+
@instance = new @
|
37
|
+
bootstrapper = new @Bootstrapper
|
38
|
+
@instance.resolve(bootstrapper)
|
39
|
+
|
40
|
+
# Resolves, initializes, and runs the application.
|
41
|
+
#
|
42
|
+
# @return [Application] an instance of the application.
|
43
|
+
#
|
44
|
+
@run: ->
|
45
|
+
@create().initialize().run()
|
46
|
+
|
47
|
+
# Creates and assigns the application container with the bootstrapper, then resolves dependencies, modules and controllers.
|
48
|
+
#
|
49
|
+
# @return [Application] the application instance.
|
50
|
+
#
|
51
|
+
resolve: (bootstrapper) ->
|
52
|
+
@container = bootstrapper.configure_container(@)
|
53
|
+
@container.resolve(@)
|
54
|
+
@_resolve_modules()
|
55
|
+
@_resolve_controllers()
|
56
|
+
@
|
57
|
+
|
58
|
+
# Binds event handlers on the modules and controllers, then publishes the application.initialize event.
|
59
|
+
#
|
60
|
+
# @return [Application] the application instance.
|
61
|
+
#
|
62
|
+
initialize: ->
|
63
|
+
@_bind_events()
|
64
|
+
@mediator.publish "application.initialize", @
|
65
|
+
@
|
66
|
+
|
67
|
+
# Publishes the application.ready event.
|
68
|
+
#
|
69
|
+
# @return [Application] the application instance.
|
70
|
+
#
|
71
|
+
run: (bootstrapper) ->
|
72
|
+
@mediator.publish "application.ready"
|
73
|
+
@
|
74
|
+
|
75
|
+
# @private
|
76
|
+
# Instantiates and resolves the application modules.
|
77
|
+
#
|
78
|
+
_resolve_modules: ->
|
79
|
+
# @modules.router = @router if @router?
|
80
|
+
# @modules.renderer = @renderer if @renderer?
|
81
|
+
module_regex = /(.*)Module/ # e.g. AuthModule
|
82
|
+
for klass_name, klass of @constructor.Modules when matches = module_regex.exec(klass_name)
|
83
|
+
module_name = _.string.underscored(matches[1]) # e.g. "auth"
|
84
|
+
module = @container.resolve(new klass(module_name))
|
85
|
+
# module.sandbox.bind_subscriptions(module)
|
86
|
+
@modules[module_name] = module
|
87
|
+
|
88
|
+
# @private
|
89
|
+
# Instantiates and resolves the application controllers.
|
90
|
+
#
|
91
|
+
_resolve_controllers: ->
|
92
|
+
controller_regex = /(.*)Controller/ # e.g. HomeController
|
93
|
+
for klass_name, klass of @constructor.Controllers when matches = controller_regex.exec(klass_name)
|
94
|
+
controller_name = _.string.underscored(matches[1]) # e.g. home
|
95
|
+
controller = @container.resolve(new klass(controller_name))
|
96
|
+
# controller.sandbox.bind_subscriptions(controller)
|
97
|
+
@controllers[controller_name] = controller
|
98
|
+
|
99
|
+
# @private
|
100
|
+
# Binds event handlers on the modules and controllers.
|
101
|
+
#
|
102
|
+
_bind_events: ->
|
103
|
+
@router.sandbox.bind_subscriptions(@router)
|
104
|
+
@renderer.sandbox.bind_subscriptions(@renderer)
|
105
|
+
|
106
|
+
for module_name, module of @modules
|
107
|
+
module.sandbox.bind_subscriptions(module)
|
108
|
+
|
109
|
+
for controller_name, controller of @controllers
|
110
|
+
controller.sandbox.bind_subscriptions(controller)
|
111
|
+
|
112
|
+
# route_mapper = new @container.resolve 'RouteMapper'
|
113
|
+
# route_mapper.draw(@constructor.routes.( config?.routes || -> )
|
114
|
+
# @router?.initialize?()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#= require ./application_module
|
2
|
+
|
3
|
+
namespace "brancusi"
|
4
|
+
|
5
|
+
class brancusi.ApplicationController extends brancusi.ApplicationModule
|
6
|
+
@dependency renderer: 'Renderer'
|
7
|
+
|
8
|
+
begin_request: (action_name) ->
|
9
|
+
@request =
|
10
|
+
action: action_name
|
11
|
+
|
12
|
+
render: (args...) ->
|
13
|
+
if args.length > 0
|
14
|
+
@renderer.render_page(args...)
|
15
|
+
else
|
16
|
+
@renderer.render_page("#{@name}/#{@request.action}")
|
17
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#= require brancusi/events
|
2
|
+
|
3
|
+
namespace "brancusi"
|
4
|
+
|
5
|
+
class brancusi.ApplicationModule extends brancusi.EventObject
|
6
|
+
constructor: (@name) ->
|
7
|
+
|
8
|
+
@dependency sandbox: (container) ->
|
9
|
+
container.resolve "Sandbox", [@name]
|
10
|
+
|
11
|
+
@dependency container: (container) ->
|
12
|
+
container.child().register_instance "Sandbox", @sandbox
|
13
|
+
|
14
|
+
publish: (args...) ->
|
15
|
+
@sandbox.publish(args...)
|
16
|
+
|
17
|
+
# TODO: maybe bind subscriptions automatically after resolving any EventObject (or anything with subscriptions)
|
18
|
+
# e.g.
|
19
|
+
# resolve: (ref, opts) ->
|
20
|
+
# resolution = @container.resolve(ref, opts)
|
21
|
+
# @sandbox.bind_scriptions(resolution)
|
22
|
+
# resolution.publish = @sandbox.publish
|
23
|
+
# resolution
|
24
|
+
# bind_subscriptions: (target) ->
|
25
|
+
# @sandbox.bind_subscriptions.apply( @sandbox, [target] )
|
26
|
+
# target.publish = @sandbox.publish
|
27
|
+
|
28
|
+
# create_model: ( class_name, opts ) ->
|
29
|
+
# @env.create( class_name, opts )
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#= require brancusi/container
|
2
|
+
|
3
|
+
namespace "brancusi"
|
4
|
+
|
5
|
+
class brancusi.Bootstrapper
|
6
|
+
|
7
|
+
configure_container: ( application ) ->
|
8
|
+
container = new brancusi.Container()
|
9
|
+
|
10
|
+
# TODO: do we need these?
|
11
|
+
container.register_instance "Application", application
|
12
|
+
container.register_instance "Container", container
|
13
|
+
|
14
|
+
container.register_class "Sandbox", brancusi.Sandbox
|
15
|
+
container.register_class "Mediator", brancusi.Mediator, singleton: true
|
16
|
+
container.register_class "RegionManager", brancusi.renderer.RegionManager, singleton: true
|
17
|
+
|
18
|
+
container
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require_tree .
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#= require brancusi/container
|
2
|
+
|
3
|
+
namespace "brancusi"
|
4
|
+
|
5
|
+
class brancusi.Sandbox extends brancusi.DependentObject
|
6
|
+
@dependency mediator: "Mediator"
|
7
|
+
|
8
|
+
constructor: (@scope) ->
|
9
|
+
|
10
|
+
publish: (event, args...) =>
|
11
|
+
@mediator.publish_scoped(event, @scope, args...)
|
12
|
+
|
13
|
+
bind_subscriptions: (target) =>
|
14
|
+
@mediator.bind_subscriptions(target, @scope)
|
@@ -0,0 +1,139 @@
|
|
1
|
+
namespace "brancusi"
|
2
|
+
|
3
|
+
# Implementation of a DI container.
|
4
|
+
#
|
5
|
+
class brancusi.Container
|
6
|
+
|
7
|
+
# Creates an instance of a container.
|
8
|
+
#
|
9
|
+
# @param parent [brancusi.Container] a parent container. When provided, if resolution of a dependency fails then resolution will be attempted with the parent container instead.
|
10
|
+
#
|
11
|
+
constructor: (@parent) ->
|
12
|
+
@_mappings = {}
|
13
|
+
|
14
|
+
# Registers a class mapping with the container.
|
15
|
+
#
|
16
|
+
# @param name [String] the name of the mapping to the class.
|
17
|
+
# @param klass [Class] the class the dependency should resolve with.
|
18
|
+
# @option opts [Boolean] singleton indicates whether the resolved dependency should be memoized.
|
19
|
+
# @return [Container] the container.
|
20
|
+
#
|
21
|
+
register_class: (name, klass, opts = {}) ->
|
22
|
+
@_register_mapping name, klass, "class", opts
|
23
|
+
@
|
24
|
+
|
25
|
+
|
26
|
+
# Registers an instance mapping with the container.
|
27
|
+
#
|
28
|
+
# @param name [String] the name of the mapping to the instance.
|
29
|
+
# @param obj [Object] the instance the dependency should resolve to.
|
30
|
+
# @return [Container] the container.
|
31
|
+
#
|
32
|
+
register_instance: (name, obj) ->
|
33
|
+
@_register_mapping name, obj, "instance"
|
34
|
+
@
|
35
|
+
|
36
|
+
|
37
|
+
# Registers a factory function for resolving dependencies
|
38
|
+
#
|
39
|
+
# @param name [String] the name of the mapping
|
40
|
+
# @param fn [Function] the factory function to resolve the mapping
|
41
|
+
# @return [Container] the container
|
42
|
+
#
|
43
|
+
register_factory: (name, fn) ->
|
44
|
+
@_register_mapping name, fn, "factory"
|
45
|
+
@
|
46
|
+
|
47
|
+
|
48
|
+
# Returns an instance of the given dependency, resolving any child dependencies.
|
49
|
+
#
|
50
|
+
# @overload resolve(name)
|
51
|
+
# Resolves the dependency according to the name of the mapping.
|
52
|
+
# @param name [String] the name of the dependency mapping.
|
53
|
+
# @return [Object] the fully resolved dependency.
|
54
|
+
#
|
55
|
+
# @overload resolve(target, opts)
|
56
|
+
# Resolves any unresolved dependencies on a given object.
|
57
|
+
# @param target [Object] the object to resolve dependencies for.
|
58
|
+
# @return [Object] target.
|
59
|
+
#
|
60
|
+
resolve: (ref, opts) ->
|
61
|
+
if typeof ref == "string"
|
62
|
+
resolution = @_resolve_string(ref, opts)
|
63
|
+
else if typeof ref == "function"
|
64
|
+
resolution = @_resolve_function(ref, opts)
|
65
|
+
else if typeof ref == "object"
|
66
|
+
resolution = @_resolve_object(ref)
|
67
|
+
|
68
|
+
if resolution?
|
69
|
+
resolution
|
70
|
+
else if @parent?
|
71
|
+
@parent.resolve ref, opts unless resolution?
|
72
|
+
else
|
73
|
+
throw new Error("Unable to resolve dependency: #{ref}") unless resolution?
|
74
|
+
|
75
|
+
|
76
|
+
# Creates a child container.
|
77
|
+
# @return [Container] a new child container.
|
78
|
+
#
|
79
|
+
child: ->
|
80
|
+
new Container(@)
|
81
|
+
|
82
|
+
|
83
|
+
# Helper method to set up a mapping. Merges in the given options to the definition.
|
84
|
+
#
|
85
|
+
# @private
|
86
|
+
# @param name [String] the name of the mapping
|
87
|
+
# @param [Class|Object|Function] the dependency to map too
|
88
|
+
# @param [String] the kind of mapping. Either 'class', 'object' or 'factory'
|
89
|
+
#
|
90
|
+
_register_mapping: (name, ref, kind, opts = {}) ->
|
91
|
+
@_mappings[name] = _.defaults({ kind: kind, ref: ref }, opts)
|
92
|
+
|
93
|
+
|
94
|
+
# Resolves a dependency by name, passing the given options (if provided) to the dependency when initialized.
|
95
|
+
#
|
96
|
+
# @private
|
97
|
+
# @param name [String] the name of the dependency.
|
98
|
+
# @param opts [Array] optional array of arguments to pass to the dependency
|
99
|
+
#
|
100
|
+
_resolve_string: (name, opts) ->
|
101
|
+
mapping = @_mappings[name]
|
102
|
+
return null unless mapping?
|
103
|
+
|
104
|
+
if mapping.kind == "instance"
|
105
|
+
mapping.ref
|
106
|
+
else if mapping.kind == "class" and mapping.singleton == true
|
107
|
+
mapping.instance = @resolve( mapping.ref, opts ) unless mapping.instance?
|
108
|
+
mapping.instance
|
109
|
+
else if mapping.kind == "factory"
|
110
|
+
mapping.ref.apply(null, opts)
|
111
|
+
else
|
112
|
+
@resolve(mapping.ref, opts)
|
113
|
+
|
114
|
+
|
115
|
+
# Resolves a dependency specified by a function.
|
116
|
+
#
|
117
|
+
# @private
|
118
|
+
# @param fn [Function] the function to invoke
|
119
|
+
# @param opts [Array] an optional array of arguments to pass to the function
|
120
|
+
#
|
121
|
+
_resolve_function: (fn, opts) ->
|
122
|
+
opts ?= []
|
123
|
+
obj = new fn(opts...)
|
124
|
+
@resolve obj
|
125
|
+
|
126
|
+
|
127
|
+
# Resolves dependencies on the given object.
|
128
|
+
#
|
129
|
+
# @private
|
130
|
+
# @param target [Object] the target object.
|
131
|
+
#
|
132
|
+
_resolve_object: (target) ->
|
133
|
+
for name, args of target.constructor.dependencies
|
134
|
+
[dependency, dependency_args] = args
|
135
|
+
if typeof dependency == "function"
|
136
|
+
target[name] = dependency.apply(target, [@])
|
137
|
+
else
|
138
|
+
target[name] = @resolve dependency, dependency_args
|
139
|
+
target
|
@@ -0,0 +1,30 @@
|
|
1
|
+
namespace "brancusi"
|
2
|
+
|
3
|
+
# A module to facilitate the specification of dependencies. Dependencies are defined on the
|
4
|
+
# 'dependencies' property of the target's prototype, in the format:
|
5
|
+
#
|
6
|
+
# {attr1: ['dep1', [<args1>]], attr2: ['dep2', [<args2>]]}
|
7
|
+
#
|
8
|
+
# @mixin
|
9
|
+
#
|
10
|
+
class brancusi.DependentModule
|
11
|
+
|
12
|
+
# Adds the named dependencies to the object's ::dependencies property
|
13
|
+
#
|
14
|
+
# @overload dependency(dependency, args...)
|
15
|
+
# Defines the given dependency on the subject class
|
16
|
+
# @param dependency [Object] an object with a single field in the format {<attribute>: '<dependency name>'}
|
17
|
+
# @param args [Array] optional an array of arguments to store with the dependency, to be passed as arguments on resolution
|
18
|
+
#
|
19
|
+
# @overload dependency(dependencies)
|
20
|
+
# Defines the given dependencies on the subject class
|
21
|
+
# @param dependencies [Object] an object naming a number of dependencies
|
22
|
+
#
|
23
|
+
@dependency: (dependencies, args...) ->
|
24
|
+
@dependencies ?= {}
|
25
|
+
|
26
|
+
if @__super__? and @__super__.constructor.dependencies == @dependencies
|
27
|
+
@dependencies = _.clone(@__super__.constructor.dependencies)
|
28
|
+
|
29
|
+
for dependency_name, dependency_type of dependencies
|
30
|
+
@dependencies[dependency_name] = [dependency_type, args]
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require_tree .
|
@@ -0,0 +1,14 @@
|
|
1
|
+
namespace "brancusi"
|
2
|
+
|
3
|
+
# Provides convenience methods @on and publish for subscribing and publishing to application events with AER.
|
4
|
+
#
|
5
|
+
class brancusi.EventsModule
|
6
|
+
|
7
|
+
# Generates a named event handler for AER.
|
8
|
+
#
|
9
|
+
# @param event [String] the name of the event.
|
10
|
+
# @param handler [Function] the event handler.
|
11
|
+
#
|
12
|
+
@on: (event, handler) ->
|
13
|
+
@::["@#{event}"] = handler
|
14
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require_tree .
|
@@ -0,0 +1,70 @@
|
|
1
|
+
namespace "brancusi"
|
2
|
+
|
3
|
+
# An implementation of the mediator pattern. This class should not be referred to directly, as the AER pattern is preferred.
|
4
|
+
#
|
5
|
+
class brancusi.Mediator
|
6
|
+
|
7
|
+
constructor: ->
|
8
|
+
@subscribers = {}
|
9
|
+
|
10
|
+
# Subscribes the given handler to the content for the specified event.
|
11
|
+
#
|
12
|
+
# @param event [String] the (fully qualified) name of the event.
|
13
|
+
# @param handler [Function] the event handler.
|
14
|
+
# @param context [Object] optional the context to invoke the handler against
|
15
|
+
#
|
16
|
+
subscribe: (event, handler, context) ->
|
17
|
+
@subscribers[event] ?= []
|
18
|
+
@subscribers[event].push(-> handler.apply(context, arguments))
|
19
|
+
|
20
|
+
# Invokes all handlers for the given event.
|
21
|
+
#
|
22
|
+
# @param event [String] the (fully qualified) name of the event.
|
23
|
+
# @param args... the arguments to forward to the handler.
|
24
|
+
#
|
25
|
+
publish: (event, args...) ->
|
26
|
+
@publish_scoped(event, null, args...)
|
27
|
+
|
28
|
+
# Invokes all handlers for the given event.
|
29
|
+
#
|
30
|
+
# @param event [String] the name of the event (either qualified or unqualified)
|
31
|
+
# @param scope [String] the name of the scope for unqualified event names.
|
32
|
+
# @param args... the arguments to forward to the handler.
|
33
|
+
#
|
34
|
+
publish_scoped: (event, scope, args...) ->
|
35
|
+
event = @_scoped_name(event, scope, true) if scope?
|
36
|
+
subscribers = (@subscribers?[event] || {})
|
37
|
+
for handler in subscribers
|
38
|
+
handler(args...)
|
39
|
+
|
40
|
+
# Binds all subscriptions on the target object (optionally using the given scope).
|
41
|
+
#
|
42
|
+
# @param target [Object] the target object.
|
43
|
+
# @param scope [String] optional the name of the scope of the object.
|
44
|
+
#
|
45
|
+
bind_subscriptions: (target, scope) ->
|
46
|
+
for name, handler of target when matches = /@(.*)/.exec(name)
|
47
|
+
event = matches[1]
|
48
|
+
event = @_scoped_name(event, scope) if scope?
|
49
|
+
@subscribe(event, handler, target)
|
50
|
+
|
51
|
+
# @private
|
52
|
+
# Returns the fully qualified name of the event, and optionally validates the inpute.
|
53
|
+
#
|
54
|
+
# @param input [String] the input to qualify (and maybe validate).
|
55
|
+
# @param scope [String] optional the name of the scope for unqualified event names.
|
56
|
+
# @param validate [Boolean] optional whether or not to error on invalid event names.
|
57
|
+
#
|
58
|
+
_scoped_name: (input, scope, validate) =>
|
59
|
+
regex = /^((\w+)\.)?(\w+)$/
|
60
|
+
|
61
|
+
if input.match(regex)
|
62
|
+
[_, _, event_scope, event] = regex.exec(input)
|
63
|
+
if scope?
|
64
|
+
event_scope ?= scope
|
65
|
+
"#{event_scope}.#{event}"
|
66
|
+
else
|
67
|
+
event
|
68
|
+
else if validate?
|
69
|
+
throw new Error("Invalid event name: #{input}")
|
70
|
+
|