handlebars_assets 0.8.1 → 0.23.9

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.
@@ -2,56 +2,144 @@ module HandlebarsAssets
2
2
  # Change config options in an initializer:
3
3
  #
4
4
  # HandlebarsAssets::Config.path_prefix = 'app/templates'
5
+
5
6
  module Config
6
7
  extend self
7
8
 
8
- attr_writer :compiler, :compiler_path, :ember, :haml_options, :known_helpers, :known_helpers_only, :options, :path_prefix, :template_namespace
9
+ attr_writer :compiler, :compiler_path, :ember, :multiple_frameworks,
10
+ :haml_options, :known_helpers, :known_helpers_only, :options,
11
+ :patch_files, :patch_path, :path_prefix, :slim_options, :template_namespace,
12
+ :precompile, :haml_enabled, :slim_enabled,
13
+ :handlebars_extensions, :hamlbars_extensions, :slimbars_extensions,
14
+ :amd, :handlebars_amd_path, :amd_with_template_namespace,
15
+ :chomp_underscore_for_partials
9
16
 
10
17
  def compiler
11
18
  @compiler || 'handlebars.js'
12
19
  end
13
20
 
21
+ def self.configure
22
+ yield self
23
+ end
24
+
14
25
  def compiler_path
15
26
  @compiler_path || HandlebarsAssets.path
16
27
  end
17
28
 
18
29
  def ember?
19
- @ember
30
+ @ember || false
31
+ end
32
+
33
+ def multiple_frameworks?
34
+ @multiple_frameworks
20
35
  end
21
36
 
22
37
  def haml_available?
23
38
  defined? ::Haml::Engine
24
39
  end
25
40
 
41
+ def haml_enabled?
42
+ @haml_enabled = true if @haml_enabled.nil?
43
+ @haml_enabled
44
+ end
45
+
26
46
  def haml_options
27
47
  @haml_options || {}
28
48
  end
29
49
 
50
+ def slim_available?
51
+ defined? ::Slim::Engine
52
+ end
53
+
54
+ def slim_enabled?
55
+ @slim_enabled = true if @slim_enabled.nil?
56
+ @slim_enabled
57
+ end
58
+
59
+ def slim_options
60
+ @slim_options || {}
61
+ end
62
+
30
63
  def known_helpers
31
64
  @known_helpers || []
32
65
  end
33
66
 
34
67
  def known_helpers_only
35
- @known_helpers_only || false
68
+ @known_helpers_only = false if @known_helpers_only.nil?
69
+ @known_helpers_only
36
70
  end
37
71
 
38
72
  def options
39
73
  @options ||= generate_options
40
74
  end
41
75
 
76
+ def patch_files
77
+ Array(@patch_files)
78
+ end
79
+
80
+ def patch_path
81
+ @patch_path ||= compiler_path
82
+ end
83
+
42
84
  def path_prefix
43
- @path_prefix || 'templates'
85
+ @path_prefix ||= 'templates'
86
+ end
87
+
88
+ def precompile
89
+ @precompile = true if @precompile.nil?
90
+ @precompile
44
91
  end
45
92
 
46
93
  def template_namespace
47
94
  @template_namespace || 'HandlebarsTemplates'
48
95
  end
49
96
 
97
+ def handlebars_extensions
98
+ @hbs_extensions ||= ['.hbs', '.handlebars']
99
+ end
100
+
101
+ def hamlbars_extensions
102
+ @hamlbars_extensions ||= ['.hamlbars']
103
+ end
104
+
105
+ def slimbars_extensions
106
+ @slimbars_extensions ||= ['.slimbars']
107
+ end
108
+
109
+ def ember_extensions
110
+ @ember_extensions ||= ['.ember']
111
+ end
112
+
113
+ def amd?
114
+ @amd || false
115
+ end
116
+
117
+ # indicate whether the template should
118
+ # be added to the global template namespace
119
+ def amd_with_template_namespace
120
+ @amd_with_template_namespace || false
121
+ end
122
+
123
+ # path specified by the require.js paths
124
+ # during configuration for the handlebars
125
+ def handlebars_amd_path
126
+ @handlebars_amd_path || 'handlebars'
127
+ end
128
+
129
+ # Indicate if leading underscore should be allowed
130
+ # when creating partial definition.
131
+ # Allows compatibility with handlebars-rails
132
+ # https://github.com/cowboyd/handlebars-rails/blob/f73a2d11df8aa2c21d335b8f04a8c5b59ae6a790/lib/handlebars-rails/tilt.rb#L18
133
+ def chomp_underscore_for_partials?
134
+ @chomp_underscore_for_partials || false
135
+ end
136
+
50
137
  private
51
138
 
52
139
  def generate_known_helpers_hash
53
140
  known_helpers.inject({}) do |hash, helper|
54
141
  hash[helper] = true
142
+ hash
55
143
  end
56
144
  end
57
145
 
@@ -1,10 +1,13 @@
1
1
  module HandlebarsAssets
2
+ # NOTE: must be an engine because we are including assets in the gem
2
3
  class Engine < ::Rails::Engine
3
- initializer "sprockets.handlebars", :after => "sprockets.environment", :group => :all do |app|
4
- next unless app.assets
5
- app.assets.register_engine('.hbs', TiltHandlebars)
6
- app.assets.register_engine('.handlebars', TiltHandlebars)
7
- app.assets.register_engine('.hamlbars', TiltHandlebars) if HandlebarsAssets::Config.haml_available?
4
+ initializer "handlebars_assets.assets.register", :group => :all do |app|
5
+ app.config.assets.configure do |sprockets_env|
6
+ ::HandlebarsAssets::register_extensions(sprockets_env)
7
+ if Gem::Version.new(Sprockets::VERSION) < Gem::Version.new('3')
8
+ ::HandlebarsAssets::add_to_asset_versioning(sprockets_env)
9
+ end
10
+ end
8
11
  end
9
12
  end
10
13
  end
@@ -5,18 +5,42 @@ require 'pathname'
5
5
  module HandlebarsAssets
6
6
  class Handlebars
7
7
  class << self
8
+
8
9
  def precompile(*args)
9
10
  context.call('Handlebars.precompile', *args)
10
11
  end
11
12
 
12
- private
13
+ protected
14
+
15
+ attr_writer :source
16
+
17
+ def append_patch(patch_file)
18
+ self.source += patch_source(patch_file)
19
+ end
20
+
21
+ def apply_patches_to_source
22
+ if HandlebarsAssets::Config.patch_files.any?
23
+ HandlebarsAssets::Config.patch_files.each do |patch_file|
24
+ append_patch(patch_file)
25
+ end
26
+ end
27
+ source
28
+ end
13
29
 
14
30
  def context
15
- @context ||= ExecJS.compile(source)
31
+ @context ||= ExecJS.compile(apply_patches_to_source)
16
32
  end
17
33
 
18
34
  def source
19
- @source ||= path.read
35
+ @source ||= "if (!window) { var window = {}; }\n#{path.read}"
36
+ end
37
+
38
+ def patch_path
39
+ @patch_path ||= Pathname(HandlebarsAssets::Config.patch_path)
40
+ end
41
+
42
+ def patch_source(patch_file)
43
+ patch_path.join(patch_file).read
20
44
  end
21
45
 
22
46
  def path
@@ -0,0 +1,267 @@
1
+ require 'tilt'
2
+ require 'json'
3
+
4
+ module HandlebarsAssets
5
+ module Unindent
6
+ # http://bit.ly/aze9FV
7
+ # Strip leading whitespace from each line that is the same as the
8
+ # amount of whitespace on the first line of the string.
9
+ # Leaves _additional_ indentation on later lines intact.
10
+ def unindent(heredoc)
11
+ heredoc.gsub(/^#{heredoc[/\A\s*/]}/, '')
12
+ end
13
+ end
14
+
15
+ # Sprockets <= 3
16
+ class HandlebarsTemplate < Tilt::Template
17
+ def self.default_mime_type
18
+ 'application/javascript'
19
+ end
20
+
21
+ def initialize_engine
22
+ HandlebarsRenderer.initialize_engine
23
+ end
24
+
25
+ def prepare
26
+ @engine = renderer.choose_engine(data)
27
+ end
28
+
29
+ def evaluate(scope, locals, &block)
30
+ source = @engine.render(scope, locals, &block)
31
+ renderer.compile(source)
32
+ end
33
+
34
+ private
35
+
36
+ def renderer
37
+ @renderer ||= HandlebarsRenderer.new(path: @file)
38
+ end
39
+ end
40
+
41
+ # Sprockets 4
42
+ class HandlebarsProcessor
43
+
44
+ def self.instance
45
+ @instance ||= new
46
+ end
47
+
48
+ def self.call(input)
49
+ instance.call(input)
50
+ end
51
+
52
+ def self.cache_key
53
+ instance.cache_key
54
+ end
55
+
56
+ attr_reader :cache_key
57
+
58
+ def initialize(options = {})
59
+ @cache_key = [self.class.name, ::HandlebarsAssets::VERSION, options].freeze
60
+ end
61
+
62
+ def call(input)
63
+ renderer = HandlebarsRenderer.new(path: input[:filename])
64
+ engine = renderer.choose_engine(input[:data])
65
+ renderer.compile(engine.render)
66
+ end
67
+ end
68
+
69
+ class NoOpEngine
70
+ def initialize(data)
71
+ @data = data
72
+ end
73
+
74
+ def render(*args)
75
+ @data
76
+ end
77
+ end
78
+
79
+ class HandlebarsRenderer
80
+ include Unindent
81
+
82
+ def self.initialize_engine
83
+ return if @initialized
84
+
85
+ begin
86
+ require 'haml'
87
+ rescue LoadError
88
+ # haml not available
89
+ end
90
+ begin
91
+ require 'slim'
92
+ rescue LoadError
93
+ # slim not available
94
+ end
95
+
96
+ @initialized = true
97
+ end
98
+
99
+ def initialize(options)
100
+ self.class.initialize_engine
101
+ @template_path = TemplatePath.new(options[:path])
102
+ end
103
+
104
+ def choose_engine(data)
105
+ if @template_path.is_haml?
106
+ Haml::Engine.new(data, HandlebarsAssets::Config.haml_options)
107
+ elsif @template_path.is_slim?
108
+ Slim::Template.new(HandlebarsAssets::Config.slim_options) { data }
109
+ else
110
+ NoOpEngine.new(data)
111
+ end
112
+ end
113
+
114
+ def compile(source)
115
+ # remove trailing \n on file, for some reason the directives pipeline adds this
116
+ source.chomp!($/)
117
+
118
+ # handle the case of multiple frameworks combined with ember
119
+ # DEFER: use extension setup for ember
120
+ if (HandlebarsAssets::Config.multiple_frameworks? && @template_path.is_ember?) ||
121
+ (HandlebarsAssets::Config.ember? && !HandlebarsAssets::Config.multiple_frameworks?)
122
+ compile_ember(source)
123
+ else
124
+ compile_default(source)
125
+ end
126
+ end
127
+
128
+ def compile_ember(source)
129
+ "window.Ember.TEMPLATES[#{@template_path.name}] = Ember.Handlebars.compile(#{JSON.dump(source)});"
130
+ end
131
+
132
+ def compile_default(source)
133
+ template =
134
+ if HandlebarsAssets::Config.precompile
135
+ compiled_hbs = Handlebars.precompile(source, HandlebarsAssets::Config.options)
136
+ "Handlebars.template(#{compiled_hbs})"
137
+ else
138
+ "Handlebars.compile(#{JSON.dump(source)})"
139
+ end
140
+
141
+ template_namespace = HandlebarsAssets::Config.template_namespace
142
+
143
+ if HandlebarsAssets::Config.amd?
144
+ handlebars_amd_path = HandlebarsAssets::Config.handlebars_amd_path
145
+ if HandlebarsAssets::Config.amd_with_template_namespace
146
+ if @template_path.is_partial?
147
+ unindent <<-PARTIAL
148
+ define(['#{handlebars_amd_path}'],function(Handlebars){
149
+ var t = #{template};
150
+ Handlebars.registerPartial(#{@template_path.name}, t);
151
+ return t;
152
+ ;})
153
+ PARTIAL
154
+ else
155
+ unindent <<-TEMPLATE
156
+ define(['#{handlebars_amd_path}'],function(Handlebars){
157
+ return #{template};
158
+ });
159
+ TEMPLATE
160
+ end
161
+ else
162
+ if @template_path.is_partial?
163
+ unindent <<-PARTIAL
164
+ define(['#{handlebars_amd_path}'],function(Handlebars){
165
+ var t = #{template};
166
+ Handlebars.registerPartial(#{@template_path.name}, t);
167
+ return t;
168
+ ;})
169
+ PARTIAL
170
+ else
171
+ unindent <<-TEMPLATE
172
+ define(['#{handlebars_amd_path}'],function(Handlebars){
173
+ this.#{template_namespace} || (this.#{template_namespace} = {});
174
+ this.#{template_namespace}[#{@template_path.name}] = #{template};
175
+ return this.#{template_namespace}[#{@template_path.name}];
176
+ });
177
+ TEMPLATE
178
+ end
179
+ end
180
+ else
181
+ if @template_path.is_partial?
182
+ unindent <<-PARTIAL
183
+ (function() {
184
+ Handlebars.registerPartial(#{@template_path.name}, #{template});
185
+ }).call(this);
186
+ PARTIAL
187
+ else
188
+ unindent <<-TEMPLATE
189
+ (function() {
190
+ this.#{template_namespace} || (this.#{template_namespace} = {});
191
+ this.#{template_namespace}[#{@template_path.name}] = #{template};
192
+ return this.#{template_namespace}[#{@template_path.name}];
193
+ }).call(this);
194
+ TEMPLATE
195
+ end
196
+ end
197
+ end
198
+
199
+ protected
200
+
201
+ class TemplatePath
202
+ def initialize(path)
203
+ @full_path = path
204
+ end
205
+
206
+ def check_extension(ext)
207
+ result = false
208
+ if ext.start_with? '.'
209
+ ext = "\\#{ext}"
210
+ result ||= !(@full_path =~ /#{ext}(\..*)*$/).nil?
211
+ else
212
+ result ||= !(@full_path =~ /\.#{ext}(\..*)*$/).nil?
213
+ end
214
+ result
215
+ end
216
+
217
+ def is_haml?
218
+ result = false
219
+ ::HandlebarsAssets::Config.hamlbars_extensions.each do |ext|
220
+ result ||= check_extension(ext)
221
+ end
222
+ result
223
+ end
224
+
225
+ def is_slim?
226
+ result = false
227
+ ::HandlebarsAssets::Config.slimbars_extensions.each do |ext|
228
+ result ||= check_extension(ext)
229
+ end
230
+ result
231
+ end
232
+
233
+ def is_ember?
234
+ result = false
235
+ ::HandlebarsAssets::Config.ember_extensions.each do |ext|
236
+ result ||= check_extension(ext)
237
+ end
238
+ result
239
+ end
240
+
241
+ def is_partial?
242
+ @full_path.gsub(%r{.*/}, '').start_with?('_')
243
+ end
244
+
245
+ def name
246
+ template_name
247
+ end
248
+
249
+ private
250
+
251
+ def relative_path
252
+ path = @full_path.match(/.*#{HandlebarsAssets::Config.path_prefix}\/((.*\/)*([^.]*)).*$/)[1]
253
+ if is_partial? && ::HandlebarsAssets::Config.chomp_underscore_for_partials?
254
+ #handle case if partial is in root level of template folder
255
+ path.gsub!(%r~^_~, '')
256
+ #handle case if partial is in a subfolder within the template folder
257
+ path.gsub!(%r~/_~, '/')
258
+ end
259
+ path
260
+ end
261
+
262
+ def template_name
263
+ relative_path.dump
264
+ end
265
+ end
266
+ end
267
+ end
@@ -1,3 +1,3 @@
1
1
  module HandlebarsAssets
2
- VERSION = "0.8.1"
2
+ VERSION = "0.23.9"
3
3
  end
@@ -1,21 +1,58 @@
1
- require "handlebars_assets/version"
1
+ require 'handlebars_assets/version'
2
2
 
3
3
  module HandlebarsAssets
4
- PATH = File.expand_path("../../vendor/assets/javascripts", __FILE__)
4
+ autoload(:Config, 'handlebars_assets/config')
5
+ autoload(:Handlebars, 'handlebars_assets/handlebars')
6
+ autoload(:HandlebarsTemplate, 'handlebars_assets/handlebars_template')
7
+ autoload(:HandlebarsProcessor, 'handlebars_assets/handlebars_template')
8
+
9
+ PATH = File.expand_path('../../vendor/assets/javascripts', __FILE__)
5
10
 
6
11
  def self.path
7
12
  PATH
8
13
  end
9
14
 
10
- autoload(:Config, 'handlebars_assets/config')
11
- autoload(:Handlebars, 'handlebars_assets/handlebars')
12
- autoload(:TiltHandlebars, 'handlebars_assets/tilt_handlebars')
15
+ def self.configure
16
+ yield Config
17
+ end
18
+
19
+ def self.register_extensions(sprockets_environment)
20
+ if Gem::Version.new(Sprockets::VERSION) < Gem::Version.new('3')
21
+ Config.handlebars_extensions.each do |ext|
22
+ sprockets_environment.register_engine(ext, HandlebarsTemplate)
23
+ end
24
+ if Config.haml_enabled? && Config.haml_available?
25
+ Config.hamlbars_extensions.each do |ext|
26
+ sprockets_environment.register_engine(ext, HandlebarsTemplate)
27
+ end
28
+ end
29
+ if Config.slim_enabled? && Config.slim_available?
30
+ Config.slimbars_extensions.each do |ext|
31
+ sprockets_environment.register_engine(ext, HandlebarsTemplate)
32
+ end
33
+ end
34
+ else
35
+ sprockets_environment.register_mime_type 'text/x-handlebars-template', extensions: Config.handlebars_extensions
36
+ if Config.slim_enabled? && Config.slim_available?
37
+ sprockets_environment.register_mime_type 'text/x-handlebars-template', extensions: Config.slimbars_extensions
38
+ end
39
+ if Config.haml_enabled? && Config.haml_available?
40
+ sprockets_environment.register_mime_type 'text/x-handlebars-template', extensions: Config.hamlbars_extensions
41
+ end
42
+ sprockets_environment.register_transformer 'text/x-handlebars-template', 'application/javascript', HandlebarsProcessor
43
+ end
44
+ end
13
45
 
14
- if defined?(Rails) && defined?(::Rails::Engine)
15
- require 'handlebars_assets/engine'
16
- else
17
- require 'sprockets'
18
- Sprockets.register_engine '.hbs', TiltHandlebars
19
- Sprockets.register_engine '.handlebars', TiltHandlebars
46
+ def self.add_to_asset_versioning(sprockets_environment)
47
+ sprockets_environment.version += "-#{HandlebarsAssets::VERSION}"
20
48
  end
21
49
  end
50
+
51
+ # Register the engine (which will register extension in the app)
52
+ # or ASSUME using sprockets
53
+ if defined?(Rails)
54
+ require 'handlebars_assets/engine'
55
+ else
56
+ require 'sprockets'
57
+ ::HandlebarsAssets.register_extensions(Sprockets)
58
+ end