alpha-simprini-engine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/javascripts/alpha_simprini.coffee +15 -0
  5. data/app/assets/javascripts/alpha_simprini/application.coffee +22 -0
  6. data/app/assets/javascripts/alpha_simprini/coffee_kup/binding.coffee +119 -0
  7. data/app/assets/javascripts/alpha_simprini/coffee_kup/helpers.coffee +17 -0
  8. data/app/assets/javascripts/alpha_simprini/coffee_kup/tags.coffee +7 -0
  9. data/app/assets/javascripts/alpha_simprini/collection.coffee +62 -0
  10. data/app/assets/javascripts/alpha_simprini/delegate.coffee +21 -0
  11. data/app/assets/javascripts/alpha_simprini/event.coffee +75 -0
  12. data/app/assets/javascripts/alpha_simprini/html.coffee +56 -0
  13. data/app/assets/javascripts/alpha_simprini/mixin.coffee +10 -0
  14. data/app/assets/javascripts/alpha_simprini/model.coffee +137 -0
  15. data/app/assets/javascripts/alpha_simprini/models/radio_selection_model.coffee +9 -0
  16. data/app/assets/javascripts/alpha_simprini/packer.coffee +93 -0
  17. data/app/assets/javascripts/alpha_simprini/template_helpers.coffee +8 -0
  18. data/app/assets/javascripts/alpha_simprini/view.coffee +182 -0
  19. data/app/assets/javascripts/alpha_simprini/views/canvas.coffee +2 -0
  20. data/app/assets/javascripts/alpha_simprini/views/horizontal_split.coffee +9 -0
  21. data/app/assets/javascripts/alpha_simprini/views/panel.coffee +2 -0
  22. data/app/assets/javascripts/alpha_simprini/views/splitter.coffee +2 -0
  23. data/app/assets/javascripts/alpha_simprini/views/stage.coffee +7 -0
  24. data/app/assets/javascripts/alpha_simprini/views/vertical_split.coffee +8 -0
  25. data/app/assets/javascripts/alpha_simprini/views/viewport.coffee +0 -0
  26. data/app/assets/javascripts/bundle.js +16416 -0
  27. data/app/assets/javascripts/lib/backbone.coffee +11 -0
  28. data/app/assets/javascripts/lib/koffeecup_backbone_databind.coffee +25 -0
  29. data/app/assets/javascripts/lib/module.coffee +15 -0
  30. data/app/assets/javascripts/lib/state_machine.coffee +33 -0
  31. data/app/assets/javascripts/lib/string.coffee +13 -0
  32. data/app/assets/javascripts/qunit.js +1513 -0
  33. data/app/assets/javascripts/test.coffee +4 -0
  34. data/app/assets/javascripts/test/alpha_simprini/coffee_kup/binding.coffee +118 -0
  35. data/app/assets/javascripts/test/alpha_simprini/coffee_kup/helpers.coffee +10 -0
  36. data/app/assets/javascripts/test/alpha_simprini/coffee_kup/tags.coffee +18 -0
  37. data/app/assets/javascripts/test/alpha_simprini/collection.coffee +7 -0
  38. data/app/assets/javascripts/test/alpha_simprini/event.coffee +43 -0
  39. data/app/assets/javascripts/test/alpha_simprini/model.coffee +63 -0
  40. data/app/assets/javascripts/test/alpha_simprini/view.coffee +72 -0
  41. data/app/assets/javascripts/test/alpha_simprini/views/canvas.coffee +8 -0
  42. data/app/assets/javascripts/test/alpha_simprini/views/horizontal_split.coffee +13 -0
  43. data/app/assets/javascripts/test/alpha_simprini/views/vertical_split.coffee +13 -0
  44. data/app/assets/javascripts/test/backbone/collection.js +345 -0
  45. data/app/assets/javascripts/test/backbone/events.js +86 -0
  46. data/app/assets/javascripts/test/backbone/model.js +426 -0
  47. data/app/assets/javascripts/test/backbone/view.js +137 -0
  48. data/app/assets/stylesheets/bootstrap.sass +6 -0
  49. data/app/assets/stylesheets/paneling.sass +2 -0
  50. data/app/assets/stylesheets/qunit.scss +228 -0
  51. data/app/assets/stylesheets/table.sass +10 -0
  52. data/app/assets/stylesheets/typography.sass +19 -0
  53. data/app/controllers/alpha_simprini/test_controller.rb +3 -0
  54. data/app/controllers/resources_controller.rb +7 -0
  55. data/app/views/alpha_simprini/test/root.rb +13 -0
  56. data/app/views/resources/base.rb +2 -0
  57. data/app/views/resources/edit.rb +9 -0
  58. data/app/views/resources/form.rb +26 -0
  59. data/app/views/resources/index.rb +41 -0
  60. data/app/views/resources/new.rb +9 -0
  61. data/app/views/resources/show.rb +42 -0
  62. data/app/views/resources/show_has_many.rb +28 -0
  63. data/config/locales/en.yml +4 -0
  64. data/config/routes.rb +3 -0
  65. data/lib/alpha-simprini-engine.rb +33 -0
  66. data/lib/alpha-simprini-engine/version.rb +3 -0
  67. data/lib/alpha_simprini/directive_processor.rb +77 -0
  68. data/lib/alpha_simprini/packer.rb +161 -0
  69. data/lib/alpha_simprini/page.rb +37 -0
  70. data/lib/tasks/alpha-simprini-engine_tasks.rake +4 -0
  71. data/test/alpha-simprini-engine_test.rb +7 -0
  72. data/test/dummy/Rakefile +7 -0
  73. data/test/dummy/app/assets/javascripts/application.js +9 -0
  74. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  75. data/test/dummy/app/controllers/application_controller.rb +3 -0
  76. data/test/dummy/app/helpers/application_helper.rb +2 -0
  77. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  78. data/test/dummy/config.ru +4 -0
  79. data/test/dummy/config/application.rb +42 -0
  80. data/test/dummy/config/boot.rb +10 -0
  81. data/test/dummy/config/database.yml +25 -0
  82. data/test/dummy/config/environment.rb +5 -0
  83. data/test/dummy/config/environments/development.rb +27 -0
  84. data/test/dummy/config/environments/production.rb +51 -0
  85. data/test/dummy/config/environments/test.rb +39 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/inflections.rb +10 -0
  88. data/test/dummy/config/initializers/mime_types.rb +5 -0
  89. data/test/dummy/config/initializers/secret_token.rb +7 -0
  90. data/test/dummy/config/initializers/session_store.rb +8 -0
  91. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  92. data/test/dummy/config/locales/en.yml +4 -0
  93. data/test/dummy/config/routes.rb +58 -0
  94. data/test/dummy/db/development.sqlite3 +0 -0
  95. data/test/dummy/log/development.log +800 -0
  96. data/test/dummy/public/404.html +26 -0
  97. data/test/dummy/public/422.html +26 -0
  98. data/test/dummy/public/500.html +26 -0
  99. data/test/dummy/public/favicon.ico +0 -0
  100. data/test/dummy/script/rails +6 -0
  101. data/test/dummy/tmp/cache/assets/C24/D70/sprockets%2F388a550030239f3784f207fa32954f64 +0 -0
  102. data/test/dummy/tmp/cache/assets/C34/620/sprockets%2F097ee8532856d48d70420c006f475889 +0 -0
  103. data/test/dummy/tmp/cache/assets/C6F/710/sprockets%2F908d18b0f21c18dad508851126164a41 +0 -0
  104. data/test/dummy/tmp/cache/assets/CA7/120/sprockets%2F35278a6c0150c40394fe02629c8b0eb9 +0 -0
  105. data/test/dummy/tmp/cache/assets/CDB/A80/sprockets%2F443b1c6e71b482fdd83b1833b7e27712 +0 -0
  106. data/test/dummy/tmp/cache/assets/CE3/FB0/sprockets%2F6d3f87a4232e0368bb86760780c5f1bd +0 -0
  107. data/test/dummy/tmp/cache/assets/D1C/160/sprockets%2F87876f7e55ebc78ae11c6c08a27f0605 +0 -0
  108. data/test/dummy/tmp/cache/assets/D26/6C0/sprockets%2F65bce2254bb3140a50326ea1654ea5df +0 -0
  109. data/test/dummy/tmp/cache/assets/D26/FA0/sprockets%2F1f50f59148df5f3e2ab889df381d9744 +0 -0
  110. data/test/dummy/tmp/cache/assets/D36/220/sprockets%2F841654b01d89eada195d7d1fe10b57b0 +0 -0
  111. data/test/dummy/tmp/cache/assets/D47/410/sprockets%2Ff1fe319eb4064bd5b861ac28f7d76555 +18122 -0
  112. data/test/dummy/tmp/cache/assets/D57/1E0/sprockets%2Fe267e3e1059799c429e4f5cfb95ec53c +0 -0
  113. data/test/dummy/tmp/cache/assets/D64/3E0/sprockets%2Fb49b7f8034b81ec601bc32fb127fbe08 +0 -0
  114. data/test/dummy/tmp/cache/assets/D65/850/sprockets%2F7a9b6a0e2d51adb43a1d3f859213e6b8 +15469 -0
  115. data/test/dummy/tmp/cache/assets/D6C/E30/sprockets%2Fcc7322b05ac2bef75e9f4f145d38117f +0 -0
  116. data/test/dummy/tmp/cache/assets/D7D/E00/sprockets%2Fce33b82451c73df1cfec69928b4f77b6 +0 -0
  117. data/test/dummy/tmp/cache/assets/D85/5D0/sprockets%2Fcf743946c378c148b19ce78eeaa9cc75 +0 -0
  118. data/test/dummy/tmp/cache/assets/DBB/560/sprockets%2F5a1d70cf7dd81a5ab5ce7a40a3a38d06 +0 -0
  119. data/test/dummy/tmp/cache/assets/DC1/670/sprockets%2Fefdfad0542298a1db90d24dc27ecc250 +0 -0
  120. data/test/dummy/tmp/cache/assets/DC5/1E0/sprockets%2F7517f22ad0f9dc13b8f0f6e0cc0e5de2 +0 -0
  121. data/test/dummy/tmp/cache/assets/DCC/220/sprockets%2F28d953c6ab9cc9a7db15600aabc6d77d +208 -0
  122. data/test/dummy/tmp/cache/assets/DCF/DF0/sprockets%2Ff0d3068f05825e1dfd9f5aaba946d3dc +0 -0
  123. data/test/dummy/tmp/cache/assets/DD3/0E0/sprockets%2F3e9e08a334bae7deadb5335f5e4f195f +0 -0
  124. data/test/dummy/tmp/cache/assets/DDB/980/sprockets%2Fbd2abc80a17c901e2f497f88f9be58cf +0 -0
  125. data/test/dummy/tmp/cache/assets/E00/ED0/sprockets%2Ffecf3bffeb200a47e96bd04cbc878076 +1535 -0
  126. data/test/dummy/tmp/cache/assets/EFB/560/sprockets%2Fbca0daf751c020cdeddabbefa51cb6ea +0 -0
  127. data/test/dummy/tmp/restart.txt +0 -0
  128. data/test/test_helper.rb +10 -0
  129. metadata +326 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = AlphaSimpriniEngine
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'AlphaSimpriniEngine'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'test'
33
+ t.pattern = 'test/**/*_test.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :test
@@ -0,0 +1,15 @@
1
+ #= require bundle
2
+ #= require ./lib/string
3
+ #= require ./lib/module
4
+ #= require ./alpha_simprini/mixin
5
+ #= require ./alpha_simprini/delegate
6
+ #= require ./alpha_simprini/event
7
+ #= require ./alpha_simprini/event
8
+ #= require ./alpha_simprini/html
9
+ #= require ./alpha_simprini/view
10
+ #= require_tree ./alpha_simprini/coffee_kup
11
+ #= require ./alpha_simprini/views/panel
12
+ #= require_tree ./alpha_simprini/views
13
+ #= require_tree ./alpha_simprini
14
+
15
+
@@ -0,0 +1,22 @@
1
+ module "AS", ->
2
+ class @Application
3
+ AS.Event.extends(this)
4
+
5
+ constructor: (args) ->
6
+ @template_source = @template_source()
7
+ for name, template of @template_source
8
+ @template_source[name] = CoffeeKup.compile(template, locals:yes, hardcode:AS.TemplateHelpers)
9
+
10
+ $ => @initialize?()
11
+
12
+ template_source: -> @Templates
13
+
14
+ view: (constructor, options={}) ->
15
+ options.application = this
16
+ new constructor options
17
+
18
+ render: (template_name, locals={}) ->
19
+ data = {context: this, locals:locals}
20
+ @template_source[template_name](data)
21
+
22
+
@@ -0,0 +1,119 @@
1
+ module "AS.CK", ->
2
+ @Binding =
3
+ binding: (model, property, getter) ->
4
+ id = AS.CK.Helpers.autoId()
5
+ model.bind "destroy", -> id.query().remove()
6
+ if getter
7
+ model.bind "change:#{property}", -> id.query().text getter.call(this, model.get(property)) || ""
8
+ span id: id.string, -> getter.call(this, model.get(property))
9
+ else
10
+ model.bind "change:#{property}", -> id.query().text model.get(property) || ""
11
+ span id: id.string, -> model.get(property)
12
+
13
+ bound_input: (model, property, options={}) ->
14
+ id = AS.CK.Helpers.autoId()
15
+ model.bind "change:#{property}", -> id.query().val model.get(property)
16
+ id.query().live 'change', ->
17
+ data = {}
18
+ data[property] = id.query().val()
19
+ model.set data
20
+ id.query().live 'keyup', ->
21
+ data = {}
22
+ data[property] = id.query().val()
23
+ model.set data
24
+ input _.extend(options, id: id.string, value: model.get property)
25
+
26
+ bind_collection: (container_tag, collection, templateName) ->
27
+ # DONT FORGET TO COMBINE LOCALS AS NEEDED
28
+
29
+ id = AS.CK.Helpers.autoId()
30
+
31
+ # Unbind before you rebind, or you'll be very :(
32
+ # As you will have a lot of templates being added EVERYWHERE
33
+
34
+ collection.unbind "add.#{templateName}-bind_collection"
35
+ collection.bind "add.#{templateName}-bind_collection", (item) =>
36
+ not_wanted = id.query().find("[data-cid=#{item.cid}]")
37
+ if not_wanted[0]
38
+ debugger
39
+ console.error "Why u add", item, "to", collection, "again?"
40
+ return
41
+ if _.isFunction(templateName)
42
+ console.error "ADDING w/o named template unimplemented sucka"
43
+ else
44
+ content = @context.render(templateName, _.extend(data.locals, item:item))
45
+ index = collection.indexOf(item)
46
+ container = id.query()
47
+ siblings = container.children()
48
+ if siblings.get(0) is undefined or siblings.get(index) is undefined
49
+ container.append(content)
50
+ else
51
+ $(siblings.get(index)).before(content)
52
+
53
+ collection.unbind "remove.#{templateName}-bind_collection"
54
+ collection.bind "remove.#{templateName}-bind_collection", (item) ->
55
+ console.log "remove", item, "from", collection
56
+ not_wanted = id.query().find("[data-cid=#{item.cid}]")
57
+ if not_wanted[0] is undefined
58
+ console.error "Could not find element to remove."
59
+ not_wanted.remove()
60
+
61
+ if container_tag.constructor is String
62
+ container_tag = [container_tag, id:id.string]
63
+ else
64
+ container_tag[1] ?= {}
65
+ container_tag[1].id = id.string
66
+
67
+ if _.isFunction(templateName)
68
+ container_tag.push ->
69
+ for item in collection.models
70
+ templateName(item)
71
+ else
72
+ container_tag.push ->
73
+ for item in collection.models
74
+ # Combine locals
75
+ text @context.render(templateName, _.extend(data.locals, item:item))
76
+
77
+ tag.apply this, container_tag
78
+
79
+ bound_select: (model, property, options, option_value_key, config={}) ->
80
+ id = AS.CK.Helpers.autoId()
81
+ model.bind "change:#{property}", ->
82
+ id.query().val model.get(property).cid
83
+
84
+ id.query().live "change", ->
85
+ data = {}
86
+ data[property] = options.getByCid(id.query().val())
87
+ model.set data
88
+
89
+ options.bind "change:#{option_value_key}", (_option) ->
90
+ id.query().find("[value=#{_option.cid}]").text _option.get(option_value_key)
91
+
92
+ options.bind "add", (_option) =>
93
+ console.error "FIXME: add option at correct position"
94
+
95
+ # THIS HERE IS A LITTLE :(
96
+ template = ->
97
+ bound_select_option(_option, option_value_key)
98
+
99
+ compiled = CoffeeKup.compile template, locals: yes, hardcode: AS.TemplateHelpers
100
+ @locals ?={}
101
+ @locals.option_value_key = option_value_key
102
+ @locals._option = _option
103
+ # YES IT IS, BUT IT ALSO WORKS :)
104
+
105
+ id.query().append compiled this
106
+
107
+ options.bind "remove", (_option) ->
108
+ id.query().find("[value=#{_option.cid}]").remove()
109
+ id.query().change()
110
+
111
+ selection = model.get(property)
112
+ select id: id.string, ->
113
+ (option -> config.blank) if config.blank
114
+ bound_select_option(_option, option_value_key, _option == selection) for _option in options.models
115
+
116
+ bound_select_option: (model, property, selected) ->
117
+ id = AS.CK.Helpers.autoId()
118
+ model.bind "change:#{property}", -> id.query().text model.get(property)
119
+ option id: id.string, value: model.cid, selected: selected, -> model.get(property)
@@ -0,0 +1,17 @@
1
+ module "AS.CK", ->
2
+ @Helpers =
3
+ shy: (string="") ->
4
+ string.replace(/([a-z])([A-Z])/g, (a, b, c) -> b + "&shy;" + c)
5
+
6
+ incr: 0
7
+
8
+ autoId: ->
9
+ id = "CoffeeKup-#{@incr++}"
10
+ query_function = -> @node = jQuery "##{id}"
11
+ return string: id, query: _.bind(query_function, {})
12
+
13
+ _cycles: {}
14
+
15
+
16
+
17
+
@@ -0,0 +1,7 @@
1
+ module "AS.CK", ->
2
+ @Tags =
3
+ model_tag: (model, options={}, fn) ->
4
+ [options, fn] = [{}, options] if options.constructor is Function
5
+ tagname = options.tagname or "div"
6
+ delete options.tagname
7
+ tag tagname, _.extend(options, id: model.cid), fn
@@ -0,0 +1,62 @@
1
+ class module("AS").Collection
2
+ AS.Delegate.extends(this)
3
+ AS.Event.extends(this)
4
+
5
+ @delegate "first", "rest", "last", "compact", "flatten", "without", "union",
6
+ "intersection", "difference", "uniq", "zip", "indexOf", "find", "detect", "at",
7
+ "lastIndexOf", "range", "include", "each", "map", "reject","all", "toArray", to: "models"
8
+
9
+ @model: -> AS.Model
10
+
11
+ constructor: (@models=[]) ->
12
+ @initialize()
13
+
14
+ initialize: () ->
15
+ given_models = @models
16
+ @length = 0
17
+ @byId = {}
18
+ @byCid = {}
19
+ @models = _([]).chain()
20
+ @add(model) for model in given_models
21
+
22
+ add: (model={}, options={}) ->
23
+ throw new Error("Cannot add model to collection twice.") if @models.include(model).value()
24
+
25
+ unless model instanceof AS.Model
26
+ model = @build(model)
27
+
28
+ @_add(model, options)
29
+
30
+ model
31
+
32
+ _add: (model, options={}) ->
33
+ options.at ?= this.length
34
+ index = options.at
35
+ @byCid[model.cid] = @byId[model.id] = model
36
+ @models.splice index, 0, model
37
+ @length++
38
+ model.bind("all", @_on_model_event, this)
39
+ model.trigger "add", this, options
40
+
41
+ remove: (model, options) -> @_remove(model, options)
42
+
43
+ _remove: (model, options) ->
44
+ @length--
45
+ delete @byId[model.id]
46
+ delete @byCid[model.cid]
47
+ @models = @models.chain().without(model)
48
+ model.trigger("remove", this, options)
49
+ model.unbind("all", @_on_model_event)
50
+
51
+ build: (model) ->
52
+ if model._type
53
+ ctor = module(model._type)
54
+ else
55
+ ctor = @constructor.model()
56
+ new ctor(model)
57
+
58
+ # When an event is triggered from a model, it is bubbled up through the collection.
59
+ _on_model_event: (event, model, collection, options) ->
60
+ return if (event is "add" or event is "remove") and (this isnt collection)
61
+ @_remove(model, options) if event is "destroy"
62
+ @trigger.apply(this, arguments)
@@ -0,0 +1,21 @@
1
+ module("AS").Delegate = new AS.Mixin
2
+ class_methods:
3
+ delegate: (delegated_methods..., options) ->
4
+ delegatee = options.to
5
+ callOrReturn = (object, fn_or_object, args) ->
6
+ if _.isFunction(fn_or_object)
7
+ fn_or_object.apply(object, args)
8
+ else
9
+ object
10
+
11
+ _(delegated_methods).chain().flatten().each (method) =>
12
+ if _.isString(delegatee)
13
+ @::[method] = ->
14
+ _delegatee = @[delegatee]
15
+ callOrReturn _delegatee, _delegatee[method], arguments
16
+ else if _.isFunction(delegatee)
17
+ @::[method] = ->
18
+ _delegatee = delegatee()
19
+ callOrReturn _delegatee, _delegatee[method], arguments
20
+ else
21
+ @::[method] = -> callOrReturn delegatee, delegatee[method], arguments
@@ -0,0 +1,75 @@
1
+ @module "AS", ->
2
+ @Event = new AS.Mixin
3
+ instance_methods:
4
+ _eventNamespacer: /\.([\w-_]+)$/
5
+ bind: (ev, callback, context) ->
6
+ if match = ev.match @_eventNamespacer
7
+ [ev, namespace] = ev.split(".")
8
+ namespace ?= 'none'
9
+
10
+ calls = @_callbacks ?= {}
11
+ list = calls[ev] ?= { none: [] }
12
+
13
+ list[namespace] ?= []
14
+ list[namespace].push [callback, context]
15
+ this
16
+
17
+ unbind: (ev, callback) ->
18
+ if !ev
19
+ delete @_callbacks
20
+ else if calls = @_callbacks
21
+ if !callback
22
+ if ev[0] is "."
23
+ namespace = ev.slice(1)
24
+ for event, namespaces of calls
25
+ namespaces[namespace] = []
26
+ else
27
+ return this unless calls[ev.split(".")[0]]
28
+ if match = ev.match @_eventNamespacer
29
+ [ev, namespace] = ev.split(".")
30
+ calls[ev][namespace] = []
31
+ else
32
+ calls[ev] = { none: [] }
33
+ else
34
+ for key, handlers of calls[ev]
35
+ calls[ev][key] = _(handlers).reject (handler) -> handler[0] is callback
36
+ # for handler, index in handlers
37
+ # delete handlers[index] if handler[0] is callback
38
+ # break
39
+ # # Delete leaves around [undefined] nonsense
40
+ # cals[ev][key] = _.compact(handlers)
41
+
42
+ this
43
+
44
+ trigger: (eventName) ->
45
+ return this unless calls = @_callbacks
46
+ if eventName.match @_eventNamespacer
47
+ [eventName, namespace] = eventName.split(".")
48
+ both = 2
49
+ while both--
50
+ ev = if both
51
+ eventName
52
+ else
53
+ 'all'
54
+ if list = calls[ev]
55
+ if namespace and ev isnt 'all'
56
+ if list[namespace]
57
+ for handler in list[namespace]
58
+ args = if both
59
+ Array::slice.call(arguments, 1)
60
+ else
61
+ arguments
62
+ handler[0].apply(handler[1] || this, args)
63
+ else
64
+ for key, handlers of list
65
+ for handler in handlers
66
+ args = if both
67
+ Array::slice.call(arguments, 1)
68
+ else
69
+ arguments
70
+ handler[0].apply(handler[1] || this, args)
71
+ this
72
+
73
+ # _.extend(Backbone.Model::, EventExtensions)
74
+ # _.extend(Backbone.Collection::, EventExtensions)
75
+ # _.extend(Backbone.View::, EventExtensions)
@@ -0,0 +1,56 @@
1
+ class module("AS").HTML
2
+ @elements: _('a abbr address article aside audio b bdi bdo blockquote body button
3
+ canvas caption cite code colgroup datalist dd del details dfn div dl dt em
4
+ fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup
5
+ html i iframe ins kbd label legend li map mark menu meter nav noscript object
6
+ ol optgroup option output p pre progress q rp rt ruby s samp script section
7
+ select small span strong style sub summary sup table tbody td textarea tfoot
8
+ th thead time title tr u ul video area base br col command embed hr img input keygen link meta param
9
+ source track wbr'.split(" ")).chain().compact()
10
+
11
+ constructor: (args) ->
12
+ # body...
13
+
14
+ text: (text_content) ->
15
+ @span text_content
16
+
17
+ raw: (html) ->
18
+ $(@span()).html(html)
19
+
20
+ tag: (name, attrs, content) ->
21
+ @current_node ?= document.createDocumentFragment()
22
+
23
+ if _.isFunction(attrs)
24
+ content = attrs
25
+ attrs = undefined
26
+ if _.isString(attrs)
27
+ text_content = attrs
28
+ attrs = undefined
29
+
30
+ # TODO: use jQuery for better compatibility / less performance
31
+ node = document.createElement(name)
32
+ node.setAttribute(key, value) for key, value of attrs unless attrs is undefined
33
+ @current_node.appendChild node
34
+
35
+ if text_content
36
+ $(node).text text_content
37
+ else if content
38
+ @within_node node, ->
39
+ last = content.call(this)
40
+ if _.isString(last)
41
+ @text(last)
42
+
43
+ node
44
+
45
+ within_node: (node, fn) ->
46
+ node = node[0] if node?.jquery
47
+ prior_node = @current_node
48
+ @current_node = node
49
+ content = fn.call(this)
50
+ @current_node = prior_node
51
+ content
52
+
53
+ dangling_content: (fn) -> @within_node(null, fn)
54
+
55
+ AS.HTML.elements.each (element) ->
56
+ AS.HTML::[element] = -> @tag.apply this, _(arguments).unshift(element)