volt 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.md +47 -40
  3. data/VERSION +1 -1
  4. data/app/volt/controllers/notices_controller.rb +3 -3
  5. data/app/volt/tasks/live_query/data_store.rb +2 -2
  6. data/app/volt/tasks/live_query/live_query.rb +20 -20
  7. data/app/volt/tasks/live_query/live_query_pool.rb +6 -6
  8. data/app/volt/tasks/live_query/query_tracker.rb +15 -15
  9. data/app/volt/tasks/query_tasks.rb +13 -13
  10. data/app/volt/tasks/store_tasks.rb +7 -7
  11. data/app/volt/views/notices/index.html +17 -18
  12. data/lib/volt/assets/test.rb +2 -2
  13. data/lib/volt/benchmark/benchmark.rb +25 -23
  14. data/lib/volt/cli/asset_compile.rb +11 -0
  15. data/lib/volt/cli/new_gem.rb +16 -16
  16. data/lib/volt/cli.rb +14 -12
  17. data/lib/volt/console.rb +5 -6
  18. data/lib/volt/controllers/model_controller.rb +18 -18
  19. data/lib/volt/extra_core/array.rb +4 -4
  20. data/lib/volt/extra_core/hash.rb +3 -3
  21. data/lib/volt/extra_core/object.rb +6 -6
  22. data/lib/volt/extra_core/string.rb +6 -6
  23. data/lib/volt/extra_core/symbol.rb +5 -5
  24. data/lib/volt/extra_core/time.rb +4 -4
  25. data/lib/volt/extra_core/true_false.rb +6 -6
  26. data/lib/volt/extra_core/try.rb +9 -9
  27. data/lib/volt/models/array_model.rb +26 -26
  28. data/lib/volt/models/model.rb +35 -35
  29. data/lib/volt/models/model_hash_behaviour.rb +15 -15
  30. data/lib/volt/models/model_helpers.rb +8 -8
  31. data/lib/volt/models/model_wrapper.rb +6 -6
  32. data/lib/volt/models/persistors/array_store.rb +36 -36
  33. data/lib/volt/models/persistors/base.rb +6 -6
  34. data/lib/volt/models/persistors/flash.rb +5 -5
  35. data/lib/volt/models/persistors/model_identity_map.rb +2 -2
  36. data/lib/volt/models/persistors/model_store.rb +22 -22
  37. data/lib/volt/models/persistors/params.rb +3 -3
  38. data/lib/volt/models/persistors/query/query_listener.rb +14 -14
  39. data/lib/volt/models/persistors/query/query_listener_pool.rb +2 -2
  40. data/lib/volt/models/persistors/store.rb +8 -8
  41. data/lib/volt/models/persistors/store_factory.rb +2 -2
  42. data/lib/volt/models/url.rb +37 -37
  43. data/lib/volt/page/bindings/attribute_binding.rb +14 -14
  44. data/lib/volt/page/bindings/base_binding.rb +9 -9
  45. data/lib/volt/page/bindings/component_binding.rb +7 -7
  46. data/lib/volt/page/bindings/content_binding.rb +3 -3
  47. data/lib/volt/page/bindings/each_binding.rb +13 -13
  48. data/lib/volt/page/bindings/event_binding.rb +4 -4
  49. data/lib/volt/page/bindings/if_binding.rb +12 -12
  50. data/lib/volt/page/bindings/template_binding.rb +30 -30
  51. data/lib/volt/page/channel.rb +19 -19
  52. data/lib/volt/page/channel_stub.rb +6 -6
  53. data/lib/volt/page/document.rb +2 -2
  54. data/lib/volt/page/document_events.rb +4 -4
  55. data/lib/volt/page/draw_cycle.rb +3 -3
  56. data/lib/volt/page/memory_test.rb +6 -6
  57. data/lib/volt/page/page.rb +19 -19
  58. data/lib/volt/page/reactive_template.rb +9 -9
  59. data/lib/volt/page/sub_context.rb +5 -5
  60. data/lib/volt/page/targets/attribute_section.rb +9 -9
  61. data/lib/volt/page/targets/attribute_target.rb +3 -3
  62. data/lib/volt/page/targets/base_section.rb +2 -2
  63. data/lib/volt/page/targets/binding_document/component_node.rb +23 -23
  64. data/lib/volt/page/targets/binding_document/html_node.rb +2 -2
  65. data/lib/volt/page/targets/dom_section.rb +40 -38
  66. data/lib/volt/page/targets/dom_target.rb +2 -2
  67. data/lib/volt/page/tasks.rb +12 -12
  68. data/lib/volt/page/template_renderer.rb +4 -4
  69. data/lib/volt/page/url_tracker.rb +6 -6
  70. data/lib/volt/reactive/array_extensions.rb +2 -2
  71. data/lib/volt/reactive/destructive_methods.rb +5 -5
  72. data/lib/volt/reactive/event_chain.rb +25 -25
  73. data/lib/volt/reactive/events.rb +33 -33
  74. data/lib/volt/reactive/object_tracker.rb +21 -21
  75. data/lib/volt/reactive/object_tracking.rb +2 -2
  76. data/lib/volt/reactive/reactive_array.rb +57 -57
  77. data/lib/volt/reactive/reactive_tags.rb +16 -16
  78. data/lib/volt/reactive/reactive_value.rb +72 -72
  79. data/lib/volt/reactive/string_extensions.rb +3 -3
  80. data/lib/volt/router/routes.rb +22 -23
  81. data/lib/volt/server/component_handler.rb +5 -5
  82. data/lib/volt/server/component_templates.rb +14 -11
  83. data/lib/volt/server/html_parser/attribute_scope.rb +116 -0
  84. data/lib/volt/server/html_parser/each_scope.rb +18 -0
  85. data/lib/volt/server/html_parser/if_view_scope.rb +71 -0
  86. data/lib/volt/server/html_parser/sandlebars_parser.rb +219 -0
  87. data/lib/volt/server/html_parser/textarea_scope.rb +31 -0
  88. data/lib/volt/server/html_parser/view_handler.rb +82 -0
  89. data/lib/volt/server/html_parser/view_parser.rb +23 -0
  90. data/lib/volt/server/html_parser/view_scope.rb +145 -0
  91. data/lib/volt/server/rack/asset_files.rb +17 -17
  92. data/lib/volt/server/rack/component_paths.rb +18 -18
  93. data/lib/volt/server/rack/index_files.rb +8 -8
  94. data/lib/volt/server/rack/opal_files.rb +11 -11
  95. data/lib/volt/server/socket_connection_handler.rb +13 -13
  96. data/lib/volt/server/socket_connection_handler_stub.rb +2 -2
  97. data/lib/volt/server.rb +18 -18
  98. data/lib/volt/tasks/dispatcher.rb +5 -5
  99. data/lib/volt/utils/ejson.rb +2 -2
  100. data/lib/volt/utils/generic_counting_pool.rb +8 -8
  101. data/lib/volt/utils/generic_pool.rb +16 -16
  102. data/lib/volt/volt/environment.rb +4 -4
  103. data/lib/volt.rb +6 -6
  104. data/spec/integration/test_integration_spec.rb +2 -2
  105. data/spec/models/event_chain_spec.rb +38 -38
  106. data/spec/models/model_spec.rb +128 -128
  107. data/spec/models/old_model_spec.rb +17 -17
  108. data/spec/models/persistors/params_spec.rb +3 -3
  109. data/spec/models/persistors/store_spec.rb +7 -7
  110. data/spec/models/reactive_array_spec.rb +82 -82
  111. data/spec/models/reactive_generator_spec.rb +11 -11
  112. data/spec/models/reactive_tags_spec.rb +6 -6
  113. data/spec/models/reactive_value_spec.rb +70 -70
  114. data/spec/models/store_spec.rb +4 -4
  115. data/spec/models/string_extensions_spec.rb +13 -13
  116. data/spec/page/bindings/content_binding_spec.rb +6 -6
  117. data/spec/page/sub_context_spec.rb +1 -1
  118. data/spec/router/routes_spec.rb +3 -3
  119. data/spec/server/html_parser/sample_page.html +595 -0
  120. data/spec/server/html_parser/sandlebars_parser_spec.rb +192 -0
  121. data/spec/server/html_parser/view_parser_spec.rb +286 -0
  122. data/spec/server/rack/asset_files_spec.rb +6 -6
  123. data/spec/server/rack/component_paths_spec.rb +5 -5
  124. data/spec/spec_helper.rb +4 -5
  125. data/spec/store/mongo_spec.rb +3 -3
  126. data/spec/tasks/live_query_spec.rb +6 -6
  127. data/spec/tasks/query_tasks.rb +4 -4
  128. data/spec/tasks/query_tracker_spec.rb +20 -20
  129. data/spec/templates/targets/binding_document/component_node_spec.rb +4 -4
  130. data/spec/templates/template_binding_spec.rb +28 -28
  131. data/spec/utils/generic_counting_pool_spec.rb +5 -5
  132. data/spec/utils/generic_pool_spec.rb +14 -14
  133. data/templates/newgem/app/newgem/views/index/index.html +1 -2
  134. data/templates/project/app/home/config/dependencies.rb +1 -1
  135. data/templates/project/app/home/controllers/index_controller.rb +1 -1
  136. data/templates/project/app/home/views/index/about.html +4 -6
  137. data/templates/project/app/home/views/index/home.html +4 -5
  138. data/templates/project/app/home/views/index/index.html +8 -9
  139. data/templates/project/spec/spec_helper.rb +1 -1
  140. metadata +17 -8
  141. data/lib/volt/server/binding_setup.rb +0 -2
  142. data/lib/volt/server/if_binding_setup.rb +0 -31
  143. data/lib/volt/server/scope.rb +0 -43
  144. data/lib/volt/server/template_parser.rb +0 -453
  145. data/spec/server/template_parser_spec.rb +0 -50
@@ -3,22 +3,22 @@ module Persistors
3
3
  class Base
4
4
  def loaded
5
5
  end
6
-
6
+
7
7
  def changed(attribute_name)
8
8
  end
9
-
9
+
10
10
  def added(model, index)
11
11
  end
12
-
12
+
13
13
  # For removed, the default action is to call changed for it
14
14
  def removed(attribute_name)
15
15
  changed(attribute_name)
16
16
  end
17
-
17
+
18
18
  def event_added(event, scope_provider, first)
19
19
  end
20
-
20
+
21
21
  def event_removed(event, no_more_events)
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -5,9 +5,9 @@ module Persistors
5
5
  def initialize(model)
6
6
  @model = model
7
7
  end
8
-
8
+
9
9
  def added(model, index)
10
- if Volt.client?
10
+ if Volt.client?
11
11
  # Setup a new timer for clearing the flash.
12
12
  %x{
13
13
  setTimeout(function() {
@@ -16,10 +16,10 @@ module Persistors
16
16
  }
17
17
  end
18
18
  end
19
-
19
+
20
20
  def clear_model(model)
21
21
  @model.delete(model)
22
-
22
+
23
23
  # Clear out the parent collection (usually the main flash)
24
24
  # Makes it so flash.empty? reflects if there is any outstanding
25
25
  # flashes.
@@ -29,4 +29,4 @@ module Persistors
29
29
  end
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -2,11 +2,11 @@ require 'volt/utils/generic_counting_pool'
2
2
 
3
3
  # The identity map ensures that there is only one copy of a model
4
4
  # used on the front end at a time.
5
- class ModelIdentityMap < GenericCountingPool
5
+ class ModelIdentityMap < GenericCountingPool
6
6
  # add extends GenericCountingPool so it can add in a model without
7
7
  # a direct lookup. We use this when we create a model (without an id)
8
8
  # then save it and it gets assigned an id.
9
9
  def add(id, model)
10
10
  @pool[id] = [1, model]
11
11
  end
12
- end
12
+ end
@@ -4,26 +4,26 @@ require 'volt/models/persistors/store'
4
4
  module Persistors
5
5
  class ModelStore < Store
6
6
  ID_CHARS = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map {|v| v.to_a }.flatten
7
-
7
+
8
8
  attr_reader :model
9
9
  attr_accessor :in_identity_map
10
-
10
+
11
11
  def initialize(model, tasks)
12
12
  super
13
-
13
+
14
14
  @in_identity_map = false
15
15
  end
16
-
16
+
17
17
  def add_to_collection
18
18
  @in_collection = true
19
19
  ensure_setup
20
20
  changed
21
21
  end
22
-
22
+
23
23
  def remove_from_collection
24
24
  @in_collection = false
25
25
  end
26
-
26
+
27
27
  # Called the first time a value is assigned into this model
28
28
  def ensure_setup
29
29
  if @model.attributes
@@ -32,34 +32,34 @@ module Persistors
32
32
  add_to_identity_map
33
33
  end
34
34
  end
35
-
35
+
36
36
  def add_to_identity_map
37
37
  unless @in_identity_map
38
38
  @@identity_map.add(@model._id, @model)
39
-
39
+
40
40
  @in_identity_map = true
41
- end
41
+ end
42
42
  end
43
43
 
44
44
  # Create a random unique id that can be used as the mongo id as well
45
45
  def generate_id
46
46
  id = []
47
47
  12.times { id << ID_CHARS.sample }
48
-
48
+
49
49
  return id.join
50
50
  end
51
-
51
+
52
52
  # Called when the model changes
53
53
  def changed(attribute_name=nil)
54
54
  # puts "CHANGED: #{attribute_name.inspect} - #{@model.inspect}"
55
55
  ensure_setup
56
-
56
+
57
57
  path_size = @model.path.size
58
- if !(defined?($loading_models) && $loading_models) && @tasks && path_size > 0 && !@model.nil?
58
+ if !(defined?($loading_models) && $loading_models) && @tasks && path_size > 0 && !@model.nil?
59
59
  if path_size > 3 && (parent = @model.parent) && source = parent.parent
60
60
  @model.attributes[:"#{@model.path[-4].singularize}_id"] = source._id
61
61
  end
62
-
62
+
63
63
  puts "Save: #{collection} - #{self_attributes.inspect} - #{@model.path.inspect}"
64
64
  @tasks.call('StoreTasks', 'save', collection, self_attributes)
65
65
  end
@@ -70,12 +70,12 @@ module Persistors
70
70
  ensure_setup
71
71
  end
72
72
  end
73
-
73
+
74
74
  # Update the models based on the id/identity map. Usually these requests
75
75
  # will come from the backend.
76
76
  def self.changed(model_id, data)
77
77
  model = @@identity_map.lookup(model_id)
78
-
78
+
79
79
  if model
80
80
  data.each_pair do |key, value|
81
81
  if key != '_id'
@@ -84,21 +84,21 @@ module Persistors
84
84
  end
85
85
  end
86
86
  end
87
-
87
+
88
88
  def [](val)
89
89
  raise "Models do not support hash style lookup. Hashes inserted into other models are converted to models, see https://github.com/voltrb/volt#automatic-model-conversion"
90
90
  end
91
-
91
+
92
92
  private
93
93
  # Return the attributes that are only for this store, not any sub-associations.
94
94
  def self_attributes
95
95
  # Don't store any sub-stores, those will do their own saving.
96
- @model.attributes.reject {|k,v| v.is_a?(Model) || v.is_a?(ArrayModel) }
96
+ @model.attributes.reject {|k,v| v.is_a?(Model) || v.is_a?(ArrayModel) }
97
97
  end
98
-
98
+
99
99
  def collection
100
100
  @model.path[-2]
101
101
  end
102
-
102
+
103
103
  end
104
- end
104
+ end
@@ -5,7 +5,7 @@ module Persistors
5
5
  def initialize(model)
6
6
  @model = model
7
7
  end
8
-
8
+
9
9
  def changed(attribute_name)
10
10
  if RUBY_PLATFORM == 'opal'
11
11
  %x{
@@ -18,9 +18,9 @@ module Persistors
18
18
  }
19
19
  end
20
20
  end
21
-
21
+
22
22
  def run_update
23
23
  $page.params.trigger!('child_changed') if Volt.client?
24
24
  end
25
25
  end
26
- end
26
+ end
@@ -6,13 +6,13 @@ class QueryListener
6
6
  @query_listener_pool = query_listener_pool
7
7
  @tasks = tasks
8
8
  @stores = []
9
-
9
+
10
10
  @collection = collection
11
11
  @query = query
12
-
12
+
13
13
  @listening = false
14
14
  end
15
-
15
+
16
16
  def add_listener
17
17
  @listening = true
18
18
  @tasks.call('QueryTasks', 'add_listener', @collection, @query) do |results|
@@ -22,15 +22,15 @@ class QueryListener
22
22
  results.each do |index, data|
23
23
  store.add(index, data)
24
24
  end
25
-
25
+
26
26
  store.change_state_to(:loaded)
27
27
  end
28
28
  end
29
29
  end
30
-
30
+
31
31
  def add_store(store, &block)
32
32
  @stores << store
33
-
33
+
34
34
  if @listening
35
35
  # We are already listening and have this model somewhere else,
36
36
  # copy the data from the existing model.
@@ -44,40 +44,40 @@ class QueryListener
44
44
  add_listener
45
45
  end
46
46
  end
47
-
47
+
48
48
  def remove_store(store)
49
49
  @stores.delete(store)
50
-
50
+
51
51
  # When there are no stores left, remove the query listener from
52
52
  # the pool, it can get created again later.
53
53
  if @stores.size == 0
54
54
  @query_listener_pool.remove(@collection, @query)
55
-
55
+
56
56
  # Stop listening
57
57
  if @listening
58
58
  @listening = false
59
- @tasks.call('QueryTasks', 'remove_listener', @collection, @query)
59
+ @tasks.call('QueryTasks', 'remove_listener', @collection, @query)
60
60
  end
61
61
  end
62
62
  end
63
-
63
+
64
64
  def added(index, data)
65
65
  @stores.each do |store|
66
66
  store.add(index, data)
67
67
  end
68
68
  puts "Added: #{index} - #{data.inspect}"
69
69
  end
70
-
70
+
71
71
  def removed(ids)
72
72
  @stores.each do |store|
73
73
  store.remove(ids)
74
74
  end
75
75
  end
76
-
76
+
77
77
  def changed(model_id, data)
78
78
  $loading_models = true
79
79
  puts "From Backend: UPDATE: #{model_id} with #{data.inspect}"
80
80
  Persistors::ModelStore.changed(model_id, data)
81
81
  $loading_models = false
82
82
  end
83
- end
83
+ end
@@ -5,5 +5,5 @@ require 'volt/models/persistors/query/query_listener'
5
5
  # places. Dynamically generated queries may end up producing the same
6
6
  # query in different places. This makes it so we only need to track a
7
7
  # single query at once. Data updates will only be sent once as well.
8
- class QueryListenerPool < GenericPool
9
- end
8
+ class QueryListenerPool < GenericPool
9
+ end
@@ -3,16 +3,16 @@ require 'volt/models/persistors/model_identity_map'
3
3
 
4
4
  module Persistors
5
5
  class Store < Base
6
-
6
+
7
7
  @@identity_map = ModelIdentityMap.new
8
-
9
- def initialize(model, tasks=nil)
8
+
9
+ def initialize(model, tasks=nil)
10
10
  @tasks = tasks
11
11
  @model = model
12
-
12
+
13
13
  @saved = false
14
14
  end
15
-
15
+
16
16
  def saved?
17
17
  @saved
18
18
  end
@@ -28,15 +28,15 @@ module Persistors
28
28
  else
29
29
  model = @model.new_model(nil, options)
30
30
  end
31
-
31
+
32
32
  @model.attributes ||= {}
33
33
  @model.attributes[method_name] = model
34
34
 
35
35
  # if model.is_a?(StoreArray)# && model.state == :not_loaded
36
36
  # model.load!
37
37
  # end
38
-
38
+
39
39
  return model
40
40
  end
41
41
  end
42
- end
42
+ end
@@ -3,7 +3,7 @@ module Persistors
3
3
  def initialize(tasks)
4
4
  @tasks = tasks
5
5
  end
6
-
6
+
7
7
  def new(model)
8
8
  if model.is_a?(ArrayModel)
9
9
  ArrayStore.new(model, @tasks)
@@ -12,4 +12,4 @@ module Persistors
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -1,16 +1,16 @@
1
1
  # The url class handles parsing and updating the url
2
2
  class URL
3
3
  include ReactiveTags
4
-
4
+
5
5
  # TODO: we need to make it so change events only trigger on changes
6
6
  attr_reader :scheme, :host, :port, :path, :query, :params
7
7
  attr_accessor :router
8
-
8
+
9
9
  def initialize(router=nil)
10
10
  @router = router
11
11
  @params = Model.new({}, persistor: Persistors::Params)
12
12
  end
13
-
13
+
14
14
  # Parse takes in a url and extracts each sections.
15
15
  # It also assigns and changes to the params.
16
16
  tag_method(:parse) do
@@ -34,21 +34,21 @@ class URL
34
34
  return false
35
35
  end
36
36
  end
37
-
37
+
38
38
  matcher = url.match(/^(https?)[:]\/\/([^\/]+)(.*)$/)
39
39
  @scheme = matcher[1]
40
40
  @host, @port = matcher[2].split(':')
41
41
  @port ||= 80
42
-
42
+
43
43
  @path = matcher[3]
44
44
  @path, @fragment = @path.split('#', 2)
45
45
  @path, @query = @path.split('?', 2)
46
46
 
47
47
  assign_query_hash_to_params
48
48
  end
49
-
49
+
50
50
  scroll
51
-
51
+
52
52
  return true
53
53
  end
54
54
 
@@ -59,11 +59,11 @@ class URL
59
59
  else
60
60
  host_with_port = @host
61
61
  end
62
-
62
+
63
63
  path, params = @router.url_for_params(@params)
64
64
 
65
65
  new_url = "#{@scheme}://#{host_with_port}#{(path || @path).chomp('/')}"
66
-
66
+
67
67
  unless params.empty?
68
68
  new_url += '?'
69
69
  query_parts = []
@@ -73,28 +73,28 @@ class URL
73
73
  value = `encodeURI(value)`
74
74
  query_parts << "#{key}=#{value}"
75
75
  end
76
-
76
+
77
77
  new_url += query_parts.join('&')
78
78
  end
79
-
79
+
80
80
  new_url += '#' + @fragment if @fragment
81
-
81
+
82
82
  return new_url
83
83
  end
84
-
84
+
85
85
  # Called when the state has changed and the url in the
86
86
  # browser should be updated
87
87
  # Called when an attribute changes to update the url
88
88
  def update!
89
89
  if Volt.client?
90
90
  new_url = full_url()
91
-
91
+
92
92
  if `(document.location.href != new_url)`
93
93
  `history.pushState(null, null, new_url)`
94
94
  end
95
95
  end
96
96
  end
97
-
97
+
98
98
  def scroll
99
99
  if Volt.client?
100
100
  if @fragment
@@ -115,35 +115,35 @@ class URL
115
115
  end
116
116
  end
117
117
  end
118
-
118
+
119
119
  private
120
120
  # Assigning the params is tricky since we don't want to trigger changed on
121
121
  # any values that have not changed. So we first loop through all current
122
122
  # url params, removing any not present in the params, while also removing
123
- # them from the list of new params as added. Then we loop through the
123
+ # them from the list of new params as added. Then we loop through the
124
124
  # remaining new parameters and assign them.
125
125
  def assign_query_hash_to_params
126
126
  # Get a nested hash representing the current url params.
127
127
  query_hash = self.query_hash
128
-
128
+
129
129
  # Get the params that are in the route
130
130
  query_hash.merge!(@router.params_for_path(@path))
131
-
131
+
132
132
  # Loop through the .params we already have assigned.
133
133
  assign_from_old(@params, query_hash)
134
134
  assign_new(@params, query_hash)
135
135
  end
136
-
136
+
137
137
  # Loop through the old params, and overwrite any existing values,
138
138
  # and delete the values that don't exist in the new params. Also
139
139
  # remove any assigned to the new params (query_hash)
140
140
  def assign_from_old(params, new_params)
141
141
  queued_deletes = []
142
-
142
+
143
143
  params.cur.attributes.each_pair do |name,old_val|
144
144
  # If there is a new value, see if it has [name]
145
145
  new_val = new_params ? new_params[name] : nil
146
-
146
+
147
147
  if !new_val
148
148
  # Queues the delete until after we finish the each_pair loop
149
149
  queued_deletes << name
@@ -157,10 +157,10 @@ class URL
157
157
  new_params.delete(name)
158
158
  end
159
159
  end
160
-
160
+
161
161
  queued_deletes.each {|name| params.delete(name) }
162
162
  end
163
-
163
+
164
164
  # Assign any new params, which weren't in the old params.
165
165
  def assign_new(params, new_params)
166
166
  new_params.each_pair do |name, value|
@@ -172,19 +172,19 @@ class URL
172
172
  end
173
173
  end
174
174
  end
175
-
175
+
176
176
  def query_hash
177
177
  query_hash = {}
178
178
  if @query
179
179
  @query.split('&').reject {|v| v == '' }.each do |part|
180
180
  parts = part.split('=').reject {|v| v == '' }
181
-
181
+
182
182
  # Decode string
183
183
  # parts[0] = `decodeURI(parts[0])`
184
184
  parts[1] = `decodeURI(parts[1])`
185
-
185
+
186
186
  sections = query_key_sections(parts[0])
187
-
187
+
188
188
  hash_part = query_hash
189
189
  sections.each_with_index do |section,index|
190
190
  if index == sections.size-1
@@ -196,18 +196,18 @@ class URL
196
196
  end
197
197
  end
198
198
  end
199
-
199
+
200
200
  return query_hash
201
201
  end
202
-
203
- # Splits a key from a ?key=value&... parameter into its nested
202
+
203
+ # Splits a key from a ?key=value&... parameter into its nested
204
204
  # parts. It also adds back the _'s used to access them in params.
205
205
  # Example:
206
206
  # user[name]=Ryan would parse as [:_user, :_name]
207
207
  def query_key_sections(key)
208
208
  key.split(/\[([^\]]+)\]/).reject(&:empty?).map {|v| :"_#{v}"}
209
209
  end
210
-
210
+
211
211
  # Generate the key for a nested param attribute
212
212
  def query_key(path)
213
213
  i = 0
@@ -221,10 +221,10 @@ class URL
221
221
  end
222
222
  end.join('')
223
223
  end
224
-
224
+
225
225
  def nested_params_hash(params, path=[])
226
226
  results = {}
227
-
227
+
228
228
  params.each_pair do |key,value|
229
229
  if value.respond_to?(:persistor) && value.persistor && value.persistor.is_a?(Persistors::Params)
230
230
  # TODO: Should be a param
@@ -233,8 +233,8 @@ class URL
233
233
  results[query_key(path + [key])] = value
234
234
  end
235
235
  end
236
-
236
+
237
237
  return results
238
238
  end
239
-
240
- end
239
+
240
+ end
@@ -8,12 +8,12 @@ class AttributeBinding < BaseBinding
8
8
 
9
9
  @attribute_name = attribute_name
10
10
  @getter = getter
11
-
11
+
12
12
  setup
13
13
  end
14
-
14
+
15
15
  def setup
16
-
16
+
17
17
  # Find the source for the content binding
18
18
  @value = value_from_getter(@getter)
19
19
 
@@ -47,7 +47,7 @@ class AttributeBinding < BaseBinding
47
47
  Element.find('#' + binding_name)
48
48
  end
49
49
 
50
- def update
50
+ def update
51
51
  if @attribute_target
52
52
  value = @attribute_target.to_html
53
53
  else
@@ -58,14 +58,14 @@ class AttributeBinding < BaseBinding
58
58
  update_checked
59
59
  return
60
60
  end
61
-
61
+
62
62
  if value.is_a?(NilMethodCall) || value.nil?
63
63
  value = ''
64
64
  end
65
65
 
66
66
  self.value = value
67
67
  end
68
-
68
+
69
69
  def value=(val)
70
70
  case @attribute_name
71
71
  when 'value'
@@ -78,18 +78,18 @@ class AttributeBinding < BaseBinding
78
78
  element[@attribute_name] = val
79
79
  end
80
80
  end
81
-
81
+
82
82
  def update_checked
83
83
  value = @value.cur
84
-
84
+
85
85
  if value.is_a?(NilMethodCall) || value.nil?
86
86
  value = false
87
87
  end
88
-
88
+
89
89
  element.prop('checked', value)
90
-
90
+
91
91
  end
92
-
92
+
93
93
  def remove
94
94
  # Unbind events, leave the element there since attribute bindings
95
95
  # aren't responsible for it being there.
@@ -99,12 +99,12 @@ class AttributeBinding < BaseBinding
99
99
  when 'checked'
100
100
  element.off('change.attrbind', nil)
101
101
  end
102
-
102
+
103
103
  if @update_listener
104
104
  @update_listener.remove
105
105
  @update_listener = nil
106
106
  end
107
-
107
+
108
108
  # Clear any references
109
109
  @target = nil
110
110
  @context = nil
@@ -112,4 +112,4 @@ class AttributeBinding < BaseBinding
112
112
  end
113
113
 
114
114
 
115
- end
115
+ end