volt 0.9.4 → 0.9.5.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -1
  3. data/Gemfile +3 -1
  4. data/lib/volt/cli/asset_compile.rb +8 -9
  5. data/lib/volt/extra_core/object.rb +3 -1
  6. data/lib/volt/models/associations.rb +9 -6
  7. data/lib/volt/models/buffer.rb +3 -0
  8. data/lib/volt/models/field_helpers.rb +38 -21
  9. data/lib/volt/models/model.rb +1 -1
  10. data/lib/volt/models/permissions.rb +2 -2
  11. data/lib/volt/models/validations/validations.rb +5 -1
  12. data/lib/volt/models/validators/numericality_validator.rb +6 -2
  13. data/lib/volt/page/bindings/each_binding.rb +7 -0
  14. data/lib/volt/page/bindings/view_binding.rb +22 -20
  15. data/lib/volt/server/component_templates.rb +21 -7
  16. data/lib/volt/server/message_bus/message_encoder.rb +4 -0
  17. data/lib/volt/server/message_bus/peer_to_peer/peer_connection.rb +1 -1
  18. data/lib/volt/server/middleware/default_middleware_stack.rb +1 -5
  19. data/lib/volt/server/rack/asset_files.rb +59 -13
  20. data/lib/volt/server/rack/component_code.rb +1 -7
  21. data/lib/volt/server/rack/index_files.rb +12 -4
  22. data/lib/volt/server/rack/opal_files.rb +29 -7
  23. data/lib/volt/server/template_handlers/sprockets_component_handler.rb +163 -0
  24. data/lib/volt/server.rb +2 -3
  25. data/lib/volt/utils/generic_pool.rb +1 -1
  26. data/lib/volt/version.rb +1 -1
  27. data/lib/volt/volt/app.rb +1 -1
  28. data/lib/volt.rb +6 -1
  29. data/spec/apps/kitchen_sink/config/base/index.html +3 -7
  30. data/spec/integration/bindings_spec.rb +1 -0
  31. data/spec/models/associations_spec.rb +18 -0
  32. data/spec/models/buffer_spec.rb +12 -0
  33. data/spec/server/rack/asset_files_spec.rb +35 -25
  34. data/templates/project/config/base/index.html +2 -7
  35. data/volt.gemspec +5 -5
  36. metadata +13 -28
  37. data/lib/volt/server/component_handler.rb +0 -42
  38. data/lib/volt/server/template_handlers/handlers.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b818f9b2d02006b327aab20af6df7bb258b94ce6
4
- data.tar.gz: 186ea61b4516a781fb3bac6b800e7e10a3bf1bef
3
+ metadata.gz: 6a75b8e5c26d8b7a65f1db6e74aa3a439409b9dd
4
+ data.tar.gz: d672f1462c31eb1dfc1cc757019445290648ba96
5
5
  SHA512:
6
- metadata.gz: 0a3898e2d3cab1dfe549cd34538f74df0ba5e9dc0587f94a426480badc4d606a67a51349d9c2f07a2a36881213699ed58d8fe5c04eab9d51a8e95cfecf901e45
7
- data.tar.gz: 235f5228b227b80a07179c6f8ac309474e7dbeb209b48318c324c970a5d93810c67c76aa827871138eca29767f96d4bea30413e75081a62f0bb82bd06d53b2e5
6
+ metadata.gz: e9462ea295ea9bf43b4e5acdebec5fd6962451a68c2cb656316b0cca67f259f85442df3c1d9ecb7175f8ecbbf9a5402032c552479b5e0164f2e15414c75abf07
7
+ data.tar.gz: 78804d64f6f96755c02cf27b980e4a831a5cd86fb43679d5dacea621381f0c848a3960510fea4e6da39f0392aec60a85b81652feb5781b285fe81fc59e636624
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Change Log
2
2
 
3
- ## 0.9.4.pre1
3
+ ## 0.9.5
4
+ ### Added
5
+ - You can now disable auto-import of JS/CSS with ```disable_auto_import``` in a dependencies.rb file
6
+
7
+ ## 0.9.4
4
8
  ### Lingo Change
5
9
  the base collections will now be called "Repositories" or "Repo's" for short. This will only matter directly for internal volt code, but for the data provider api, this will help.
6
10
 
data/Gemfile CHANGED
@@ -10,8 +10,10 @@ gem 'volt-mongo'
10
10
  gem 'rbnacl', require: false
11
11
  gem 'rbnacl-libsodium', require: false
12
12
 
13
+ # temp until 0.8.0 of opal
14
+ # gem 'opal-rspec', github: 'opal/opal-rspec'
13
15
 
14
- group :development do
16
+ group :development, :test do
15
17
  # For testing the kitchen sink app
16
18
  # Twitter bootstrap
17
19
  gem 'volt-bootstrap'
@@ -18,6 +18,7 @@ module Volt
18
18
  require 'volt'
19
19
  require 'volt/volt/core'
20
20
  require 'volt/boot'
21
+ require 'volt/server'
21
22
 
22
23
  @root_path ||= Dir.pwd
23
24
  Volt.root = @root_path
@@ -26,7 +27,6 @@ module Volt
26
27
 
27
28
  require 'volt/server/rack/component_paths'
28
29
  require 'volt/server/rack/component_code'
29
- require 'volt/server/component_handler'
30
30
 
31
31
  @app_path = File.expand_path(File.join(@root_path, 'app'))
32
32
 
@@ -34,7 +34,6 @@ module Volt
34
34
  @app = Rack::Builder.new
35
35
  @opal_files = OpalFiles.new(@app, @app_path, @component_paths)
36
36
  @index_files = IndexFiles.new(@app, volt_app, @component_paths, @opal_files)
37
- @component_handler = ComponentHandler.new(@component_paths)
38
37
 
39
38
  puts 'Compile Opal for components'
40
39
  write_component_js
@@ -49,10 +48,13 @@ module Volt
49
48
  end
50
49
 
51
50
  def logical_paths_and_full_paths
52
- @opal_files.environment.each_file do |full_path|
53
- logical_path = @opal_files.environment.send(:logical_path_for_filename, full_path, []).to_s
51
+ env = @opal_files.environment
52
+ env.each_file do |full_path|
53
+ # logical_path = env[full_path].logical_path
54
+ # logical_path = @opal_files.environment.send(:logical_path_for_filename, full_path, []).to_s
55
+ # puts "FULL PATH: #{full_path.inspect} -- #{logical_path}"
54
56
 
55
- yield(logical_path, full_path.to_s)
57
+ # yield(logical_path, full_path.to_s)
56
58
  end
57
59
 
58
60
  end
@@ -94,10 +96,7 @@ module Volt
94
96
  end
95
97
 
96
98
  def write_component_js
97
- javascript_code = @component_handler.compile_for_component('main', true)
98
-
99
- path = File.join(Volt.root, '/public/components/main.js')
100
- write_file(path, javascript_code)
99
+ write_sprocket_file('components/main.js')
101
100
  end
102
101
 
103
102
  def write_index
@@ -1,3 +1,5 @@
1
+ require 'volt/utils/ejson'
2
+
1
3
  class Object
2
4
  # Setup a default pretty_inspect
3
5
  # alias_method :pretty_inspect, :inspect
@@ -13,7 +15,7 @@ class Object
13
15
  # TODO: Need a real implementation of this
14
16
  def deep_clone
15
17
  if RUBY_PLATFORM == 'opal'
16
- JSON.parse(to_json)
18
+ Volt::EJSON.parse(Volt::EJSON.stringify(self))
17
19
  else
18
20
  Marshal.load(Marshal.dump(self))
19
21
  end
@@ -1,19 +1,22 @@
1
1
  module Volt
2
2
  module Associations
3
3
  module ClassMethods
4
- def belongs_to(method_name, key_name = nil)
5
- key_name ||= "#{method_name}_id"
4
+ def belongs_to(method_name, options = {})
5
+ collection ||= options.fetch(:collection, method_name)
6
+ foreign_key ||= options.fetch(:foreign_key, :id)
7
+ local_key ||= options.fetch(:local_key, "#{method_name}_id")
8
+
6
9
  # Add a field for the association_id
7
- field(key_name)
10
+ field(local_key)
8
11
 
9
12
  # getter
10
13
  define_method(method_name) do
11
14
  association_with_root_model('belongs_to') do |root|
12
15
  # Lookup the associated model id
13
- lookup_key = get(key_name)
16
+ lookup_key = get(local_key)
14
17
 
15
18
  # Return a promise for the belongs_to
16
- root.get(method_name.pluralize).where(id: lookup_key).first
19
+ root.get(collection.pluralize).where(foreign_key => lookup_key).first
17
20
  end
18
21
  end
19
22
 
@@ -21,7 +24,7 @@ module Volt
21
24
  id = obj.is_a?(Fixnum) ? obj : obj.id
22
25
 
23
26
  # Assign the current model's something_id to the object's id
24
- set("#{method_name}_id", id)
27
+ set(local_key, id)
25
28
  end
26
29
  end
27
30
 
@@ -42,6 +42,9 @@ module Volt
42
42
  # Copy attributes back from save_to model
43
43
  @attributes = new_model.attributes
44
44
 
45
+ # Remove tracked changes
46
+ clear_tracked_changes!
47
+
45
48
  new_model
46
49
  end.fail do |errors|
47
50
  if errors.is_a?(Hash)
@@ -2,16 +2,48 @@
2
2
  module FieldHelpers
3
3
  class InvalidFieldClass < RuntimeError; end
4
4
 
5
+ NUMERIC_CAST = lambda do |convert_method, val|
6
+ begin
7
+ orig = val
8
+ val = send(convert_method, val)
9
+
10
+ if RUBY_PLATFORM == 'opal'
11
+ # Opal has a bug in 0.7.2 that gives us back NaN without an
12
+ # error sometimes.
13
+ val = orig if val.nan?
14
+ end
15
+ rescue TypeError, ArgumentError => e
16
+ # ignore, unmatched types will be caught below.
17
+ val = orig
18
+ end
19
+
20
+ return val
21
+ end
22
+
23
+ FIELD_CASTS = {
24
+ String => :to_s.to_proc,
25
+ Fixnum => lambda {|val| NUMERIC_CAST[:Integer, val] },
26
+ Numeric => lambda {|val| NUMERIC_CAST[:Float, val] },
27
+ Float => lambda {|val| NUMERIC_CAST[:Float, val] },
28
+ Time => nil,
29
+ TrueClass => nil,
30
+ FalseClass => nil
31
+ }
32
+ VALID_FIELD_CLASSES = FIELD_CASTS.keys
33
+
34
+
5
35
  module ClassMethods
6
36
  # field lets you declare your fields instead of using the underscore syntax.
7
37
  # An optional class restriction can be passed in.
8
- def field(name, klass = nil)
9
- if klass && ![String, Numeric].include?(klass)
10
- fail FieldHelpers::InvalidFieldClass, 'valid field types is currently limited to String or Numeric'
38
+ def field(name, klass = nil, auto_cast = true)
39
+ if klass && !VALID_FIELD_CLASSES.include?(klass)
40
+ klass_names = VALID_FIELD_CLASSES.map(&:to_s).join(', ')
41
+ msg = "valid field types is currently limited to #{klass_names}"
42
+ fail FieldHelpers::InvalidFieldClass, msg
11
43
  end
12
44
 
13
45
  if klass
14
- # Add type validation, execpt for String, since anything can be a string.
46
+ # Add type validation, execpt for String, since anything can be a string.
15
47
  unless klass == String
16
48
  validate name, type: klass
17
49
  end
@@ -25,23 +57,8 @@ module FieldHelpers
25
57
  # Check if the value assigned matches the class restriction
26
58
  if klass
27
59
  # Cast to the right type
28
- if klass == String
29
- val = val.to_s
30
- elsif klass == Numeric
31
- begin
32
- orig = val
33
- unless val.is_a?(Numeric)
34
- val = Float(val)
35
- end
36
-
37
- if RUBY_PLATFORM == 'opal'
38
- # Opal has a bug in 0.7.2 that gives us back NaN without an
39
- # error sometimes.
40
- val = orig if val.nan?
41
- end
42
- rescue TypeError, ArgumentError => e
43
- # ignore, unmatched types will be caught below.
44
- end
60
+ if (func = FIELD_CASTS[klass])
61
+ val = func[val]
45
62
  end
46
63
  end
47
64
 
@@ -119,7 +119,7 @@ module Volt
119
119
  end
120
120
 
121
121
  def _id
122
- raise "Accessing _id has been deprecated in favor of id"
122
+ get(:id)
123
123
  end
124
124
 
125
125
  # Return true if the model hasn't been saved yet
@@ -18,8 +18,8 @@ module Volt
18
18
  end # When the model is created, assign it the user_id (if the user is logged in)
19
19
  on(:new) do
20
20
  # Only assign the user_id if there isn't already one and the user is logged in.
21
- if _user_id.nil? && !(user_id = Volt.current_user_id).nil?
22
- send(:"_#{key}=", user_id)
21
+ if get(:user_id).nil? && !(user_id = Volt.current_user_id).nil?
22
+ set(key, user_id)
23
23
  end
24
24
  end
25
25
 
@@ -127,7 +127,11 @@ module Volt
127
127
  def validate!
128
128
  errors.clear
129
129
 
130
- run_validations.then do
130
+ # Run the before_validate callbacks
131
+ run_callbacks(:before_validate).then do
132
+ # Run the actual validations
133
+ run_validations
134
+ end.then do
131
135
  # See if any server errors are in place and merge them in if they are
132
136
  errors.merge!(server_errors.to_h) if Volt.client?
133
137
  end.then do
@@ -17,8 +17,12 @@ module Volt
17
17
  # Convert to float if it is a string for a float
18
18
  # The nil check and the nan? check are only require for opal 0.6
19
19
  unless @value.nil?
20
- @value = Kernel.Float(@value) rescue nil
21
- @value = nil if RUBY_PLATFORM == 'opal' && @value.nan?
20
+ begin
21
+ @value = Kernel.Float(@value)
22
+ rescue ArgumentError => e
23
+ @value = nil
24
+ end
25
+ # @value = nil if RUBY_PLATFORM == 'opal' && @value.nan?
22
26
  end
23
27
 
24
28
  check_errors
@@ -1,6 +1,8 @@
1
1
  require 'volt/page/bindings/base_binding'
2
2
 
3
3
  module Volt
4
+ class InvalidObjectForEachBinding < Exception ; end
5
+
4
6
  class EachBinding < BaseBinding
5
7
  def initialize(volt_app, target, context, binding_name, getter, variable_name, index_name, template_name)
6
8
  super(volt_app, target, context, binding_name)
@@ -57,6 +59,11 @@ module Volt
57
59
 
58
60
  Volt.run_in_mode(:no_model_promises) do
59
61
  templates_size = @templates.size
62
+
63
+ unless values.respond_to?(:size)
64
+ fail InvalidObjectForEachBinding, "Each binding's require an object that responds to size and [] methods. The binding received: #{values.inspect}"
65
+ end
66
+
60
67
  values_size = values.size
61
68
  end
62
69
 
@@ -69,26 +69,25 @@ module Volt
69
69
 
70
70
  full_path, controller_path = @view_lookup.path_for_template(path, section)
71
71
 
72
- unless full_path
72
+ if full_path
73
+ @starting_controller_handler, generated_new, chain_stopped = create_controller_handler(full_path, controller_path)
74
+
75
+ # Check if chain was stopped when the action ran
76
+ if chain_stopped
77
+ # An action stopped the chain. When this happens, we stop running here.
78
+ remove_starting_controller
79
+ else
80
+ # None of the actions stopped the chain
81
+ # Wait until the controller is loaded before we actually render.
82
+ @waiting_for_load = -> { @starting_controller_handler.controller.loaded? }.watch_until!(true) do
83
+ render_next_template(full_path, path)
84
+ end
85
+
86
+ queue_clear_grouped_controller
87
+ end
88
+ else
73
89
  # if we don't have a full path, then we have a missing template
74
90
  render_next_template(full_path, path)
75
- return
76
- end
77
-
78
- @starting_controller_handler, generated_new, chain_stopped = create_controller_handler(full_path, controller_path)
79
-
80
- # Check if chain was stopped when the action ran
81
- if chain_stopped
82
- # An action stopped the chain. When this happens, we stop running here.
83
- remove_starting_controller
84
- else
85
- # None of the actions stopped the chain
86
- # Wait until the controller is loaded before we actually render.
87
- @waiting_for_load = -> { @starting_controller_handler.controller.loaded? }.watch_until!(true) do
88
- render_next_template(full_path, path)
89
- end
90
-
91
- queue_clear_grouped_controller
92
91
  end
93
92
  end
94
93
  end
@@ -155,8 +154,11 @@ module Volt
155
154
  end
156
155
 
157
156
  if @grouped_controller && @current_controller_handler
158
- # Remove a reference for the controller in the group.
159
- @grouped_controller.remove(@current_controller_handler.controller.class)
157
+ # We remove the controller after all of the current rendering is done.
158
+ Timers.next_tick do
159
+ # Remove a reference for the controller in the group.
160
+ @grouped_controller.remove(@current_controller_handler.controller.class)
161
+ end
160
162
  end
161
163
 
162
164
  @controller = nil
@@ -138,9 +138,10 @@ module Volt
138
138
  explicit_controllers = Dir["#{controllers_path}*_controller.rb"].sort
139
139
 
140
140
  controllers = (implicit_controllers + explicit_controllers).uniq
141
+
141
142
  controllers.each do |path|
142
143
  if File.exists?(path)
143
- code << File.read(path) + "\n\n"
144
+ code << "require '#{localize_path(path)}'\n"
144
145
  else
145
146
  # parts = path.scan(/([^\/]+)\/controllers\/([^\/]+)_controller[.]rb$/)
146
147
  # component, controller = parts[0]
@@ -159,9 +160,12 @@ module Volt
159
160
  models_path = "#{@component_path}/models/"
160
161
 
161
162
  Dir["#{models_path}*.rb"].sort.each do |model_path|
162
- code << File.read(model_path) + "\n\n"
163
+ # code << File.read(model_path) + "\n\n"
163
164
 
164
- model_name = model_path.match(/([^\/]+)[.]rb$/)[1]
165
+ # model_name = model_path.match(/([^\/]+)[.]rb$/)[1]
166
+ if File.exists?(model_path)
167
+ code << "require '#{localize_path(model_path)}'\n"
168
+ end
165
169
  end
166
170
 
167
171
  code
@@ -200,16 +204,26 @@ module Volt
200
204
  end
201
205
 
202
206
  def generate_initializers_code
207
+ # Include the root initializers
208
+ paths = Dir["#{Volt.root}/config/initializers/*.rb"]
209
+ paths += Dir["#{Volt.root}/config/initializers/client/*.rb"]
210
+
203
211
  paths = Dir["#{@component_path}/config/initializers/*.rb"]
204
212
  paths += Dir["#{@component_path}/config/initializers/client/*.rb"]
205
213
 
206
- cpath_size = @component_path.size
207
- paths.map! {|path| @component_name + path[cpath_size..-1]}
208
-
209
- code = "\n" + paths.map { |path| "require '#{path}'" }.join("\n")
214
+ code = "\n" + paths.map { |path| "require '#{localize_path(path)}'" }.join("\n")
210
215
 
211
216
  code
212
217
  end
213
218
 
219
+ private
220
+
221
+ # Takes a full path and returns the localized version so opal supprots it
222
+ def localize_path(path)
223
+ cpath_size = @component_path.size
224
+ return @component_name + path[cpath_size..-1]
225
+ end
226
+
227
+
214
228
  end
215
229
  end
@@ -32,6 +32,10 @@ module Volt
32
32
  raise e
33
33
  end
34
34
 
35
+ if Volt.config.app_secret.blank?
36
+ raise "No app_secret has been specified in Volt.config"
37
+ end
38
+
35
39
  # use the first 32 chars of the app secret for the encryption key.
36
40
  key = Base64.decode64(Volt.config.app_secret)[0..31]
37
41
 
@@ -96,7 +96,7 @@ module Volt
96
96
  # @worker_thread.kill
97
97
 
98
98
  # Wait for the worker to publish all messages
99
- @worker_thread.join if Thread.current != @worker_thread
99
+ @worker_thread.join if Thread.current != @worker_thread && @worker_thread
100
100
 
101
101
  @message_bus.remove_peer_connection(self)
102
102
  end
@@ -39,13 +39,9 @@ module Volt
39
39
  # Setup the middleware that we need to wait for components to boot before we
40
40
  # can set them up.
41
41
  def self.postboot_setup(volt_app, rack_app)
42
- component_paths = volt_app.component_paths
43
- rack_app.map '/components' do
44
- run ComponentHandler.new(component_paths)
45
- end
46
-
47
42
  # Serve the opal files
48
43
  opal_files = OpalFiles.new(rack_app, volt_app.app_path, volt_app.component_paths)
44
+ volt_app.opal_files = opal_files
49
45
  volt_app.sprockets = opal_files.environment
50
46
 
51
47
  # Serve the main html files from public, also figure out
@@ -10,7 +10,7 @@ module Volt
10
10
  @included_components = {}
11
11
  @components = []
12
12
  @disable_auto_import = []
13
-
13
+
14
14
  # Include each of the default included components
15
15
  Volt.config.default_components.each do |def_comp_name|
16
16
  component(def_comp_name)
@@ -22,7 +22,7 @@ module Volt
22
22
  def disable_auto_import
23
23
  @disable_auto_import.push(*@current_component).uniq
24
24
  end
25
-
25
+
26
26
  def load_dependencies(path, component_name)
27
27
  if path
28
28
  dependencies_file = File.join(path, 'config/dependencies.rb')
@@ -80,11 +80,11 @@ module Volt
80
80
  end
81
81
  locator
82
82
  end
83
-
83
+
84
84
  def url_or_path?(url)
85
85
  (url =~ URI::regexp || url =~ /^\/(\/)?.*/) ? true : false
86
86
  end
87
-
87
+
88
88
  def component_paths
89
89
  @components
90
90
  end
@@ -94,31 +94,58 @@ module Volt
94
94
  @assets << [:folder, asset_folder] if File.directory?(asset_folder)
95
95
  end
96
96
 
97
- def javascript_files(opal_files)
97
+ def javascript_files(*args)
98
+ fail "Deprecation: #javascript_files is deprecated in config/base/index.html, opal 0.8 required a new format. For an updated config/base/index.html file, see https://gist.github.com/ryanstout/0858cf7dfc32c514f790"
99
+ end
100
+
101
+ def css_files(*args)
102
+ fail "Deprecation: #css_files is deprecated in config/base/index.html, opal 0.8 required a new format. For an updated config/base/index.html file, see https://gist.github.com/ryanstout/0858cf7dfc32c514f790"
103
+ end
104
+
105
+ # Returns script tags that should be included
106
+ def javascript_tags(volt_app)
107
+ @opal_tag_generator ||= Opal::Server::Index.new(nil, volt_app.opal_files.server)
108
+
98
109
  javascript_files = []
99
110
  @assets.each do |type, path|
100
111
  case type
101
112
  when :folder
113
+ # for a folder, we search for all .js files and return a tag for them
102
114
  javascript_files += Dir["#{path}/**/*.js"].sort.map { |folder| '/assets' + folder[path.size..-1] }
103
115
  when :javascript_file
116
+ # javascript_file is a cdn path to a JS file
104
117
  javascript_files << path
105
118
  end
106
119
  end
107
120
 
108
- opal_js_files = []
109
- if Volt.source_maps?
110
- opal_js_files += opal_files.environment['volt/volt/app'].to_a.map { |v| '/assets/' + v.logical_path + '?body=1' }
121
+ javascript_files = javascript_files.uniq
122
+
123
+ scripts = javascript_files.map {|url| "<script src=\"#{url}\"></script>" }
124
+
125
+ # Include volt itself. Unless we are running with MAPS=all, just include
126
+ # the main file without sourcemaps.
127
+ volt_path = 'volt/volt/app'
128
+ if ENV['MAPS'] == 'all'
129
+ scripts << @opal_tag_generator.javascript_include_tag(volt_path)
111
130
  else
112
- opal_js_files << '/assets/volt/volt/app.js'
131
+ scripts << "<script src=\"/assets/#{volt_path}.js\"></script>"
132
+ scripts << "<script>#{Opal::Processor.load_asset_code(volt_app.sprockets, volt_path)}</script>"
113
133
  end
114
- opal_js_files << '/components/main.js'
115
134
 
116
- javascript_files += opal_js_files
135
+ scripts << @opal_tag_generator.javascript_include_tag('components/main')
136
+
137
+ scripts.join("\n")
138
+ end
117
139
 
118
- javascript_files.uniq
140
+ # Returns the link tags for the css
141
+ def css_tags
142
+ css.map do |url|
143
+ "<link href=\"#{url}\" media=\"all\" rel=\"stylesheet\" type=\"text/css\" />"
144
+ end.join("\n")
119
145
  end
120
146
 
121
- def css_files
147
+ # Returns an array of all css files that should be included.
148
+ def css
122
149
  css_files = []
123
150
  @assets.each do |type, path|
124
151
  case type
@@ -136,5 +163,24 @@ module Volt
136
163
 
137
164
  css_files.uniq
138
165
  end
166
+
167
+ # #javascript is only used on the server
168
+ unless RUBY_PLATFORM == 'opal'
169
+ # Parses the javascript tags to reutrn the following:
170
+ # [[:url, '/somefile.js'], [:body, 'var inlinejs = true;']]
171
+ def javascript(volt_app)
172
+ javascript_tags(volt_app)
173
+ .scan(/[<]script([^>]*)[>](.*?)[<]\/script[^>]*[>]/)
174
+ .map do |attrs, body|
175
+ src = attrs.match(/[\s|$]src\s*[=]\s*["']([^"']+?)["']/)
176
+
177
+ if src
178
+ [:src, src[1]]
179
+ else
180
+ [:body, body]
181
+ end
182
+ end
183
+ end
184
+ end
139
185
  end
140
186
  end
@@ -28,13 +28,7 @@ module Volt
28
28
 
29
29
  def generate_config_code
30
30
  # Setup Volt.config on the client
31
- code = "\nVolt.setup_client_config(#{Volt.config.public.to_h.inspect})\n"
32
-
33
- # Include the root initializers
34
- code << "require_tree '#{Volt.root}/config/initializers'\n"
35
- code << "require_tree '#{Volt.root}/config/initializers/client'\n"
36
-
37
- code
31
+ "\nVolt.setup_client_config(#{Volt.config.public.to_h.inspect})\n"
38
32
  end
39
33
  end
40
34
  end
@@ -48,13 +48,21 @@ module Volt
48
48
  ERB.new(html, nil, '-').result(binding)
49
49
  end
50
50
 
51
- def javascript_files
51
+ def javascript_files(*args)
52
+ fail "Deprecation: #javascript_files is deprecated in config/base/index.html, opal 0.8 required a new format."
53
+ end
54
+
55
+ def css_files(*args)
56
+ fail "Deprecation: #css_files is deprecated in config/base/index.html, opal 0.8 required a new format."
57
+ end
58
+
59
+ def javascript_tags
52
60
  # TODO: Cache somehow, this is being loaded every time
53
- AssetFiles.new('main', @component_paths).javascript_files(@opal_files)
61
+ AssetFiles.new('main', @component_paths).javascript_tags(@volt_app)
54
62
  end
55
63
 
56
- def css_files
57
- AssetFiles.new('main', @component_paths).css_files
64
+ def css_tags
65
+ AssetFiles.new('main', @component_paths).css_tags
58
66
  end
59
67
  end
60
68
  end