Class: Packr

Inherits:
Object
  • Object
show all
Defined in:
lib/packr.rb,
lib/packr/words.rb,
lib/packr/regexp_group.rb

Defined Under Namespace

Classes: RegexpGroup, Words

Constant Summary collapse

IGNORE =
RegexpGroup::IGNORE
REMOVE =
""
SPACE =
" "
WORDS =
/\w+/
CONTINUE =
/\\\r?\n/
ENCODE10 =
"String"
ENCODE36 =
"function(c){return c.toString(a)}"
ENCODE62 =
"function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}"
UNPACK =
lambda do |p,a,c,k,e,r|
  "eval(function(p,a,c,k,e,r){e=#{e};if(!''.replace(/^/,String)){while(c--)r[#{r}]=k[c]" +
      "||#{r};k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p." +
      "replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('#{p}',#{a},#{c},'#{k}'.split('|'),0,{}))"
end
CLEAN =
RegexpGroup.new(
  "\\(\\s*;\\s*;\\s*\\)" => "(;;)", # for (;;) loops
  "throw[^};]+[};]" => IGNORE, # a safari 1.3 bug
  ";+\\s*([};])" => "\\1"
)
DATA =
RegexpGroup.new(
  # strings
  "STRING1" => IGNORE,
  'STRING2' => IGNORE,
  "CONDITIONAL" => IGNORE, # conditional comments
  "(COMMENT1)\\n\\s*(REGEXP)?" => "\n\\3",
  "(COMMENT2)\\s*(REGEXP)?" => " \\3",
  "([\\[(\\^=,{}:;&|!*?])\\s*(REGEXP)" => "\\1\\2"
)
JAVASCRIPT =
RegexpGroup.new(
  :COMMENT1 =>    /(\/\/|;;;)[^\n]*/.source,
  :COMMENT2 =>    /\/\*[^*]*\*+([^\/][^*]*\*+)*\//.source,
  :CONDITIONAL => /\/\*@|@\*\/|\/\/@[^\n]*\n/.source,
  :REGEXP =>      /\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*/.source,
  :STRING1 =>     /'(\\.|[^'\\])*'/.source,
  :STRING2 =>     /"(\\.|[^"\\])*"/.source
)
WHITESPACE =
RegexpGroup.new(
  "(\\d)\\s+(\\.\\s*[a-z\\$_\\[(])" => "\\1 \\2", # http://dean.edwards.name/weblog/2007/04/packer3/#comment84066
  "([+-])\\s+([+-])" => "\\1 \\2", # c = a++ +b;
  "\\b\\s+\\$\\s+\\b" => " $ ", # var $ in
  "\\$\\s+\\b" => "$ ", # object$ in
  "\\b\\s+\\$" => " $", # return $object
  "\\b\\s+\\b" => SPACE,
  "\\s+" => REMOVE
)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePackr

Returns a new instance of Packr.



80
81
82
83
84
85
86
# File 'lib/packr.rb', line 80

def initialize
  @data = {}
  DATA.values.each { |item| @data[JAVASCRIPT.exec(item.expression)] = item.replacement }
  @data = RegexpGroup.new(@data)
  @whitespace = @data.union(WHITESPACE)
  @clean = @data.union(CLEAN)
end

Class Method Details

.minify(script) ⇒ Object



12
13
14
15
# File 'lib/packr.rb', line 12

def minify(script)
  @packr ||= self.new
  @packr.minify(script)
end

.pack(script, options = {}) ⇒ Object



17
18
19
20
# File 'lib/packr.rb', line 17

def pack(script, options = {})
  @packr ||= self.new
  @packr.pack(script, options)
end

.pack_file(path, options = {}) ⇒ Object



22
23
24
25
# File 'lib/packr.rb', line 22

def pack_file(path, options = {})
  @packr ||= self.new
  @packr.pack_file(path, options)
end

Instance Method Details

#minify(script) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/packr.rb', line 88

def minify(script)
  script = script.gsub(CONTINUE, "")
  script = @data.exec(script)
  script = @whitespace.exec(script)
  script = @clean.exec(script)
  script
end

#pack(script, options = {}) ⇒ Object



96
97
98
99
100
101
# File 'lib/packr.rb', line 96

def pack(script, options = {})
  script = minify(script + "\n")
  script = shrink_variables(script) if options[:shrink_vars]
  script = base62_encode(script) if options[:base62]
  script
end

#pack_file(path, options = {}) ⇒ Object



103
104
105
106
107
108
# File 'lib/packr.rb', line 103

def pack_file(path, options = {})
  path = path.gsub(Regexp.new("^((#{RAILS_ROOT.gsub(/\./, "\\.")})?/)?"), RAILS_ROOT + '/')
  script = File.read(path)
  script = pack(script, options)
  File.open(path, 'wb') { |f| f.write(script) }
end