alpha-simprini-engine 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.
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)