diff --git a/lib/barista.rb b/lib/barista.rb index 53af466..db2807a 100644 --- a/lib/barista.rb +++ b/lib/barista.rb @@ -57,7 +57,7 @@ def invoke_hook(name, *args) # Configuration - Tweak how you use Barista. - has_boolean_options :verbose, :bare, :add_filter, :add_preamble, :exception_on_error, :embedded_interpreter, :auto_compile + has_boolean_options :verbose, :bare, :add_filter, :add_preamble, :exception_on_error, :embedded_interpreter, :auto_compile, :add_namespaces has_delegate_methods Compiler, :bin_path, :bin_path=, :js_path, :js_path= has_delegate_methods Framework, :register has_deprecated_methods :compiler, :compiler=, :compiler_klass, :compiler_klass= @@ -174,6 +174,10 @@ def default_for_embedded_interpreter def default_for_auto_compile true end + + def default_for_add_namespaces + false + end # Actual tasks on the barista module. diff --git a/lib/barista/compiler.rb b/lib/barista/compiler.rb index 2619ad7..7a5b89d 100644 --- a/lib/barista/compiler.rb +++ b/lib/barista/compiler.rb @@ -117,6 +117,7 @@ def initialize(context, options = {}) def compile! location = @options.fetch(:origin, 'inline') @compiled_content = compile(@context, location) + add_namespace(location) if location != 'inline' && Barista.add_namespaces? @compiled_content = preamble(location) + @compiled_content if location != 'inline' && Barista.add_preamble? @compiled = true end @@ -167,6 +168,33 @@ def preamble(location) inner_message = copyable?(location) ? "copied" : "compiled" "/* DO NOT MODIFY. This file was #{inner_message} #{Time.now.httpdate} from\n * #{location.strip}\n */\n\n" end + + def add_namespace(input_path) + path_info = parse_path(input_path) + if path_info[:directories].count > 0 + controller = path_info[:directories].join('_') + @compiled_content.gsub("\n", "\n ") # Corrent indentation + if path_info[:filename_without_extension] == path_info[:directories].last + function_name = 'init' + else + function_name = path_info[:filename_without_extension] + end + @compiled_content = "if(typeof #{controller} === 'undefined') var #{controller} = {}\n#{controller}.#{function_name} = function() {\n #{@compiled_content}\n }" + end + end + + def parse_path(input_path) + relative_path = input_path.gsub(Barista.root.to_s, '') + filename = relative_path.slice!(/(\w+\.\w+)+\z/) + filename_without_extension = filename.slice(/^\w+/) + directories = relative_path.split('/').delete_if(&:empty?) + { + :relative_path => relative_path, + :filename => filename, + :filename_without_extension => filename_without_extension, + :directories => directories + } + end def compilation_error_for(location, message) details = "Compilation of '#{location}' failed:\n#{message}" @@ -189,6 +217,6 @@ def setup_compiler_context(context) @options[:origin] ||= 'inline' end end - + end end diff --git a/lib/barista/helpers.rb b/lib/barista/helpers.rb index 17412fd..243159b 100644 --- a/lib/barista/helpers.rb +++ b/lib/barista/helpers.rb @@ -41,6 +41,13 @@ def coffeescript_tag(code, html_options = {}) end end + def coffeescript_namespace_init_tag(controller = params[:controller], action = params[:action]) + output = defined?(ActiveSupport::SafeBuffer) ? ActiveSupport::SafeBuffer.new : "" + output << "#{controller.gsub('/', '_')}.init();\n" + output << "#{controller.gsub('/', '_')}.#{action}();" + javascript_tag output + end + protected def normalise_coffeescript_path(path) diff --git a/lib/generators/barista/install/templates/initializer.rb b/lib/generators/barista/install/templates/initializer.rb index 4c4dbfe..f82ee9f 100644 --- a/lib/generators/barista/install/templates/initializer.rb +++ b/lib/generators/barista/install/templates/initializer.rb @@ -58,5 +58,9 @@ # Make helpers and the HAML filter output coffee-script instead of the compiled JS. # Used in combination with the coffeescript_interpreter_js helper in Rails. # c.embedded_interpreter = true + + # Wrap compiled JS in namespacing functions. Call these with the coffeescript_namespace_init_tag helper + # When used in combination with a JS packager allows you to have 1 JS file per site; calling only functions for current controller & action. + # c.add_namespacing = true end