tension 0.9.5 → 0.9.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 76c048b5004ade369c07e87cf54a73b3459f7151
4
- data.tar.gz: e2494f1c0198761e2464ec130b2107ba05aa1ae4
3
+ metadata.gz: 6c49b89ef37d4ed27d45267db1df9515e9b21676
4
+ data.tar.gz: a5dda13efcd5faad5b96b7f0277789c4426d5411
5
5
  SHA512:
6
- metadata.gz: 599a97dd6849f6a070d7d2cb1ac3a6c7da3e959a4046b9c6558995663fd6afe5a2d6d98138cd2aef8e89ce529ffec28c1ccf8bae42aa35e9da93d9bbd8ad4861
7
- data.tar.gz: 4902abbd406722db8bd6c680630ce1285bbc6f7613dd20aeba5e12e01f4349c0fab1083394ce8839a2c4b4c0d8e422550b7c37635a702383035ea86b9954effd
6
+ metadata.gz: 578e77cad85ee43ece8dd8405378370f35179704d2de8679e8b7cadeea1eb1db6b2b927826d66249d53d7f55b04191bb42c37065368ac2451b18588f6039b515
7
+ data.tar.gz: c7816a0237d55ac4ab45422a2e70ed0cbeff586d43372e4b5c2399f3f4db2351d3094624ff8430cd847376135097986aa2d776b22c80021086f6465c900ca27c
@@ -0,0 +1,67 @@
1
+ module Tension
2
+ class Context
3
+ attr_reader :controller, :action
4
+
5
+ def initialize(controller_path)
6
+ @controller = "#{ controller_path }_controller".classify.constantize
7
+ end
8
+
9
+ # Locates the best stylesheet for the given action name. Aliased as,
10
+ # for example, `#index( Tension::CSS )` or `#show(:css)`.
11
+ #
12
+ def css(action)
13
+ best_asset( action, Tension::CSS )
14
+ end
15
+
16
+ # Locates the best JavaScript for the given action name. Aliased as,
17
+ # for example, `#index( Tension::JS )` or `#show(:js)`.
18
+ #
19
+ def js(action)
20
+ best_asset( action, Tension::JS )
21
+ end
22
+
23
+ # Returns the action-level asset for the given action name and type,
24
+ # or nil.
25
+ #
26
+ def action_asset(action, type)
27
+ Tension::Utils.find_asset( controller: controller.controller_path, action: action, type: type )
28
+ end
29
+
30
+ # Returns the controller-level asset for the given type, or nil.
31
+ #
32
+ def controller_asset(type)
33
+ Tension::Utils.find_asset( controller: controller.controller_path, type: type )
34
+ end
35
+
36
+ # Returns the global asset for the given type (application.{css,js}).
37
+ #
38
+ def global_asset(type)
39
+ Tension::Utils.global_asset(type)
40
+ end
41
+
42
+ def has_action?(action_name)
43
+ controller.action_methods.include?(action_name)
44
+ end
45
+
46
+
47
+ private
48
+
49
+ # Locates the best asset for the given action name and type.
50
+ #
51
+ def best_asset(action, type)
52
+ action_asset(action, type) || controller_asset(type) || global_asset(type)
53
+ end
54
+
55
+ def method_missing(method_sym, *args)
56
+ action = method_sym.to_s
57
+ type = args.first
58
+
59
+ if has_action?(action)
60
+ best_asset(action, type)
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ end
67
+ end
@@ -4,15 +4,35 @@ module Tension
4
4
  module Controller
5
5
  extend ActiveSupport::Concern
6
6
 
7
- def action_assets
8
- controller = request.symbolized_path_parameters[:controller]
9
- action = request.symbolized_path_parameters[:action]
7
+ included do
8
+ # Make these methods available in helpers too.
9
+ helper_method :asset_context, :action_javascript, :action_stylesheet
10
+ end
11
+
12
+ # Returns the Context for the current controller.
13
+ #
14
+ def asset_context
15
+ find_asset( request.symbolized_path_parameters[:controller] )
16
+ end
17
+
18
+ # Returns the Sprockets Asset for the current action's JavaScript
19
+ # to be written into the template.
20
+ #
21
+ def action_javascript
22
+ asset_context.js( request.symbolized_path_parameters[:action] )
23
+ end
10
24
 
11
- Tension::Environment.find( controller, action )
25
+ # Returns the Sprockets Asset for the current action's stylesheet
26
+ # to be written into the template.
27
+ #
28
+ def action_stylesheet
29
+ asset_context.css( request.symbolized_path_parameters[:action] )
12
30
  end
13
31
 
14
- def assets
15
- Tension::Environment
32
+ # Proxy to Tension::Environment.find.
33
+ #
34
+ def find_asset_context(*args)
35
+ Tension::Environment.find(*args)
16
36
  end
17
37
  end
18
38
  end
@@ -1,39 +1,59 @@
1
1
  module Tension
2
2
 
3
- # Tension::Environment exposes `assets`, which describes the assets that
4
- # can be automatically included in templates.
5
- #
6
- # It's used automatically on application load (see Tension::Railtie) to populate
7
- # the asset pipeline's list of assets to precompile, and caches the result in-
8
- # process for use by Tension::Tagger when templates are rendered.
3
+ # This class describes routes and controller contexts, and through those contexts
4
+ # the assets to be included in templates.
9
5
  #
10
6
  class Environment
11
-
12
7
  class << self
13
8
 
14
- def [](key, action = nil)
15
- fetch( AssetGroup.path_for(key, action) )
9
+ # Loads a Context for the specified controller path.
10
+ #
11
+ def find(key)
12
+ fetch( Tension::Utils.controller_path(key) )
13
+ end
14
+ alias_method :[], :find
15
+
16
+ # A Hash mapping controller paths to Contexts.
17
+ #
18
+ def contexts
19
+ @contexts ||= Hash.new
16
20
  end
17
- alias_method :find, :[]
18
21
 
22
+ # Preloads all Contexts. Useful in environments where assets and controller
23
+ # actions don't change without an app reboot (production, staging).
24
+ #
19
25
  def eager_load!
20
26
  configured_get_defaults.each do |default|
21
- find( default[:controller], default[:action] )
27
+ find(default[:controller])
22
28
  end
29
+
30
+ true
23
31
  end
24
32
 
25
- def assets
26
- @assets ||= Hash.new
33
+ # Determines whether or not a given path refers to an asset that requires
34
+ # precompilation.
35
+ #
36
+ def precompilation_needed?(path)
37
+ if context = find(path)
38
+ context.has_action?( Tension::Utils.action_name(path) )
39
+ end
27
40
  end
28
41
 
42
+
29
43
  private
30
44
 
31
45
  def fetch(path)
32
- assets[path] || store(path)
46
+ contexts[path] || store(path)
33
47
  end
34
48
 
35
49
  def store(path)
36
- assets[path] = AssetGroup.new( path )
50
+ contexts[path] ||= Context.new(path) if valid_route?(path)
51
+ end
52
+
53
+ def valid_route?(controller)
54
+ configured_get_defaults.find do |default|
55
+ default[:controller] == controller
56
+ end
37
57
  end
38
58
 
39
59
  # Routing defaults (including controller path and action name) for all
@@ -52,7 +72,7 @@ module Tension
52
72
  @configured_get_defaults.compact!
53
73
  end
54
74
  end
55
- end
56
75
 
76
+ end
57
77
  end
58
78
  end
@@ -7,10 +7,16 @@ module Tension
7
7
  module Helper
8
8
  extend ActiveSupport::Concern
9
9
 
10
+ # Determines the best stylesheet to be included in a template based
11
+ # on the current controller and action.
12
+ #
10
13
  def best_stylesheet(*args)
11
14
  asset_for( Tension::CSS, *args )
12
15
  end
13
16
 
17
+ # Determines the best JavaScript to be included in a template based
18
+ # on the current controller and action.
19
+ #
14
20
  def best_javascript(*args)
15
21
  asset_for( Tension::JS, *args )
16
22
  end
@@ -18,10 +24,10 @@ module Tension
18
24
  private
19
25
 
20
26
  def asset_for(type, *args)
21
- controller = request.params[:controller]
22
- action = request.params[:action]
27
+ controller = request.symbolized_path_parameters[:controller]
28
+ action = request.symbolized_path_parameters[:action]
23
29
 
24
- asset = Tension::Environment.find( controller, action ).send( type )
30
+ asset = Tension::Environment.find( controller ).send( action, type )
25
31
 
26
32
  include_method = case type.to_s
27
33
  when "js"
@@ -5,21 +5,19 @@ module Tension
5
5
 
6
6
  class Railtie < Rails::Railtie
7
7
  initializer "tension.add_assets_to_precompile_list" do |app|
8
- ActiveSupport.on_load :after_initialize do
9
8
 
10
- if app.config.cache_classes
11
- app.reload_routes!
12
- Tension::Environment.eager_load!
13
- end
14
-
15
- ActionView::Base.send(:include, Tension::Helper)
16
- ActionController::Base.send(:include, Tension::Controller)
9
+ if app.config.cache_classes
10
+ app.reload_routes!
11
+ Tension::Environment.eager_load!
12
+ end
17
13
 
18
- app.config.assets.precompile << lambda do |path, filename|
19
- Tension::Environment.asset_paths.include?( filename )
20
- end
14
+ ActionView::Base.send(:include, Tension::Helper)
15
+ ActionController::Base.send(:include, Tension::Controller)
21
16
 
17
+ Rails.application.config.assets.precompile << lambda do |path, filename|
18
+ Tension::Environment.precompilation_needed?(path)
22
19
  end
20
+
23
21
  end
24
22
  end
25
23
  end
@@ -0,0 +1,102 @@
1
+ module Tension
2
+ module Utils
3
+ class << self
4
+
5
+ SHARED_SUFFIX = "_common".freeze
6
+ EXTENSION_REGEX = /(#{SHARED_SUFFIX})?\..*\z/.freeze
7
+
8
+ # Matches strings like "blog/comments".
9
+ CONTROLLER_REGEX = /([\w\/]+[^\.])/.freeze
10
+
11
+ # Attempts to build a valid controller path from the given path String.
12
+ # ARGS: path: a String path like "admin/blog_common.css"
13
+ #
14
+ def controller_path(path)
15
+ if asset_path?(path)
16
+ return controller_for_asset_path(path)
17
+
18
+ elsif matches = path.split("#").first.match(CONTROLLER_REGEX)
19
+ return matches[0]
20
+
21
+ else
22
+ return nil
23
+ end
24
+ end
25
+
26
+ # Attempts to find an action name for a given asset path.
27
+ #
28
+ def action_name(path)
29
+ strip_file_extension( path.split("/").last ) if asset_path?(path)
30
+ end
31
+
32
+ # Attempts to load an Asset from the Sprockets index. Uses the given
33
+ # Hash argument to build an asset path.
34
+ # ARGS: options: a Hash containing e.g.
35
+ # controller: "blog/comments"
36
+ # action: "index"
37
+ # type: Tension::CSS
38
+ #
39
+ def find_asset(options)
40
+ assets[ logical_asset_path(options) ]
41
+ end
42
+
43
+ # Returns the application-wide Sprockets Asset for the given type.
44
+ # ARGS: type: Tension::JS or Tension::CSS
45
+ #
46
+ def global_asset(type)
47
+ assets[ "application.#{type}" ]
48
+ end
49
+
50
+ private
51
+
52
+ # Builds a String path for an asset based on the given hash params.
53
+ # ARGS: options: a Hash containing e.g.
54
+ # controller: "blog/comments"
55
+ # action: "index"
56
+ # type: Tension::CSS
57
+ #
58
+ def logical_asset_path(options)
59
+ if options[:action].nil?
60
+ "#{options[:controller]}#{SHARED_SUFFIX}.#{options[:type]}"
61
+ else
62
+ "#{options[:controller]}/#{options[:action]}.#{options[:type]}"
63
+ end
64
+ end
65
+
66
+ # Alias for Sprockets' asset index.
67
+ #
68
+ def assets
69
+ Rails.application.assets
70
+ end
71
+
72
+ # Takes an asset path like "comments/base/index.js" and determines
73
+ # the controller ("comments/base") that should serve that asset.
74
+ # ARGS: path: a String path like "admin/blog_common.css"
75
+ #
76
+ def controller_for_asset_path(path)
77
+ parts = path.split("/")
78
+
79
+ if parts.last.match(SHARED_SUFFIX)
80
+ strip_file_extension( parts.last )
81
+ else
82
+ parts.pop
83
+ end
84
+
85
+ return parts.any? ? parts.join("/") : nil
86
+ end
87
+
88
+ def strip_file_extension(path)
89
+ path.gsub(EXTENSION_REGEX, "")
90
+ end
91
+
92
+ # Returns whether or not the given path represents an asset file
93
+ # for which Tension is useful: JavaScript or CSS.
94
+ # ARGS: path: a String path like "admin/blog_common.css"
95
+ #
96
+ def asset_path?(path)
97
+ path.match(/\.(#{ Tension::CSS }|#{ Tension::JS })\z/)
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -1,3 +1,3 @@
1
1
  module Tension
2
- VERSION = "0.9.5".freeze
2
+ VERSION = "0.9.6".freeze
3
3
  end
data/lib/tension.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'tension/asset_group'
1
+ require 'tension/utils'
2
+ require 'tension/context'
2
3
  require 'tension/controller'
3
4
  require 'tension/helper'
4
5
  require 'tension/environment'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tension
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piers Mainwaring
@@ -34,11 +34,12 @@ files:
34
34
  - LICENSE
35
35
  - README.md
36
36
  - lib/tension.rb
37
- - lib/tension/asset_group.rb
37
+ - lib/tension/context.rb
38
38
  - lib/tension/controller.rb
39
39
  - lib/tension/environment.rb
40
40
  - lib/tension/helper.rb
41
41
  - lib/tension/railtie.rb
42
+ - lib/tension/utils.rb
42
43
  - lib/tension/version.rb
43
44
  - tension.gemspec
44
45
  homepage: https://github.com/piersadrian/tension
@@ -1,82 +0,0 @@
1
- module Tension
2
- class AssetGroup
3
-
4
- class << self
5
- # Builds a valid routing Path.
6
- def path_for(key, action = nil)
7
- if key.match( path_regex )
8
- return key
9
-
10
- elsif key.include?("#")
11
- key, action = key.split("#")
12
- end
13
-
14
- unless key.try(:match, controller_regex) && action.try(:match, action_regex)
15
- raise ArgumentError, "[Tension] Couldn't build valid controller path!"
16
- end
17
-
18
- "#{ key }##{ action }"
19
- end
20
-
21
- # Matches strings like "blog/comments#show".
22
- def path_regex
23
- /([\w\/]+[^#])#(\w+)/
24
- end
25
-
26
- # Matches strings like "blog/comments".
27
- def controller_regex
28
- /([\w\/]+[^#])/
29
- end
30
-
31
- # Matches strings like "show".
32
- def action_regex
33
- /(\w+)/
34
- end
35
-
36
- def global_asset(type)
37
- assets[ "application.#{type}" ]
38
- end
39
-
40
- def assets
41
- Rails.application.assets
42
- end
43
- end
44
-
45
-
46
- attr_reader :controller, :action
47
-
48
- def initialize(key, action = nil)
49
- @controller, @action = self.class.path_for( key, action ).split("#")
50
- end
51
-
52
- def css
53
- best_asset( Tension::CSS )
54
- end
55
-
56
- def js
57
- best_asset( Tension::JS )
58
- end
59
-
60
- def action_asset(type)
61
- self.class.assets[ "#{controller}/#{action}.#{type}" ]
62
- end
63
-
64
- def controller_asset(type)
65
- self.class.assets[ "#{controller}_common.#{type}" ]
66
- end
67
-
68
- private
69
-
70
- def best_asset(type)
71
- action_asset(type) || controller_asset(type) || self.class.global_asset(type)
72
- end
73
-
74
- def method_missing(method_sym, *args)
75
- degree, type = method_sym.to_s.split("_")
76
- asset_method = "#{degree}_asset"
77
-
78
- respond_to?(asset_method) ? send(asset_method, type) : super
79
- end
80
-
81
- end
82
- end