class Barber::Precompiler
Public Class Methods
compile(template, options = nil)
click to toggle source
# File lib/barber/precompiler.rb, line 7 def compile(template, options = nil) instance.compile(template, options) end
compiler_version()
click to toggle source
# File lib/barber/precompiler.rb, line 11 def compiler_version instance.compiler_version end
handlebars_available?()
click to toggle source
# File lib/barber/precompiler.rb, line 15 def handlebars_available? require 'handlebars/source' # handlebars precompilation is optional feature. rescue LoadError => e raise e unless ['cannot load such file -- handlebars/source', 'no such file to load -- handlebars/source'].include?(e.message) ensure return !!defined?(Handlebars::Source) end
Private Class Methods
instance()
click to toggle source
# File lib/barber/precompiler.rb, line 25 def instance @instance ||= new end
Public Instance Methods
compile(template, options = nil)
click to toggle source
# File lib/barber/precompiler.rb, line 30 def compile(template, options = nil) context.call precompile_function, sanitize(template), options rescue ExecJS::ProgramError => ex raise Barber::PrecompilerError.new(template, ex) end
compiler_version()
click to toggle source
# File lib/barber/precompiler.rb, line 51 def compiler_version "handlebars:#{handlebars_version}" end
handlebars()
click to toggle source
# File lib/barber/precompiler.rb, line 47 def handlebars @handlebars ||= File.new(Handlebars::Source.bundled_path) end
precompile_function()
click to toggle source
# File lib/barber/precompiler.rb, line 36 def precompile_function "Barber.precompile" end
sources()
click to toggle source
# File lib/barber/precompiler.rb, line 40 def sources sources = [] sources << precompiler sources << handlebars if self.class.handlebars_available? sources end
Private Instance Methods
context()
click to toggle source
# File lib/barber/precompiler.rb, line 98 def context @context ||= ExecJS.compile source end
handlebars_version()
click to toggle source
# File lib/barber/precompiler.rb, line 137 def handlebars_version @handlebars_version ||= context.eval('Handlebars.VERSION') end
precompiler()
click to toggle source
# File lib/barber/precompiler.rb, line 94 def precompiler @precompiler ||= File.new(File.expand_path("../javascripts/handlebars_precompiler.js", __FILE__)) end
sanitize(template)
click to toggle source
This method handles different types of user input. The precompiler can be called from many different places which create interesting conditions. Case 1: Rake-Pipeline-Web-Filters: calls with a JSON encoded string. Case 2: Sanitize using a RegExp Case 3: “Normal” input. Reading from a file or something like that.
Each one of these cases is covered by a test case. If you find another breaking use case please address it here with a regression test.
# File lib/barber/precompiler.rb, line 65 def sanitize(template) begin if template =~ /\A".+"\Z/m # Case 1 sanitize_with_json(template) else # Case 2 sanitize_with_regexp(template) end rescue JSON::ParserError # Case 3 template end end
sanitize_with_json(template)
click to toggle source
# File lib/barber/precompiler.rb, line 80 def sanitize_with_json(template) JSON.load(%Q|{"template":#{template}}|)['template'] end
sanitize_with_regexp(template)
click to toggle source
# File lib/barber/precompiler.rb, line 84 def sanitize_with_regexp(template) if template.respond_to? :gsub sanitized = template.gsub(/\\n/,"\n") sanitized = sanitized.gsub(/\\["']/, '"') sanitized else template end end
source()
click to toggle source
# File lib/barber/precompiler.rb, line 102 def source source_fixes + sources.map(&:read).join("\n;\n") end
source_fixes()
click to toggle source
# File lib/barber/precompiler.rb, line 106 def source_fixes shims = [] # hbs 3 has no reference to `window` and `self`. shims << <<-JS if (typeof window === 'undefined') { window = this; } if (typeof self === 'undefined') { self = this; } JS # Workaround for `ExecJS::RubyRhinoRuntime`. It throws an error: `Invalid JavaScript value of type org.mozilla.javascript.MemberBox` on inherit `Error`. shims << <<-JS if (Object.defineProperty) { Object.defineProperty(Error, 'stackTraceLimit', {configurable: false}); Object.defineProperty(Error, 'prepareStackTrace', {configurable: false}); } JS # Workaround for `ExecJS::RubyRhinoRuntime`. It has no `setTimeout` but backburner references `setTimeout`. shims << <<-JS if (typeof setTimeout === 'undefined') { setTimeout = function(fn) { fn(); }; } JS shims.join("\n") end