Permalink
Browse files

pushed new branch: 1_2

git-svn-id: http://bundle-fu.googlecode.com/svn/tags/bundle_fu@52 1db77ec0-6337-0410-9320-454da9aca44f
  • Loading branch information...
timcharper
timcharper committed Oct 31, 2007
2 parents 4e23d07 + e93ef1c commit e6accfd9eb6295d7095288ba5450eb2a01994e59
View
@@ -0,0 +1,4 @@
+# load all files
+for file in ["/lib/bundle_fu.rb", "/lib/bundle_fu/js_minimizer.rb", "/lib/bundle_fu/css_url_rewriter.rb", "/lib/bundle_fu/file_list.rb"]
+ require File.expand_path(File.join(File.dirname(__FILE__), file))
+end
View
@@ -1,6 +1,6 @@
# EZ Bundle
-for file in ["/lib/bundle_fu.rb", "/lib/bundle_fu/file_list.rb"]
- require File.expand_path(File.join(File.dirname(__FILE__), file))
+for file in ["/lib/bundle_fu.rb", "/lib/js_minimizer.rb", "/lib/bundle_fu/file_list.rb"]
end
+require File.expand_path(File.join(File.dirname(__FILE__), "environment.rb"))
ActionView::Base.send(:include, BundleFu::InstanceMethods)
View
@@ -6,63 +6,38 @@ def init
@content_store = {}
end
- def each_read_file(filenames=[])
+ def bundle_files(filenames=[])
+ output = ""
filenames.each{ |filename|
- output = "/* -------------- #{filename} ------------- */ "
- output << "\n"
- output << (File.read(File.join(RAILS_ROOT, "public", filename)) rescue ( "/* FILE READ ERROR! */"))
+ output << "/* --------- #{filename} --------- */ "
output << "\n"
- yield filename, output
+ begin
+ content = (File.read(File.join(RAILS_ROOT, "public", filename)))
+ rescue
+ output << "/* FILE READ ERROR! */"
+ next
+ end
+
+ output << (yield(filename, content)||"")
}
+ output
end
def bundle_js_files(filenames=[], options={})
output = ""
- each_read_file(filenames) { |filename, content|
- output << content
- }
- output
- end
-
- # rewrites a relative path to an absolute path, removing excess "../" and "./"
- # rewrite_relative_path("stylesheets/default/global.css", "../image.gif") => "/stylesheets/image.gif"
- def rewrite_relative_path(source_filename, relative_url)
- relative_url = relative_url.strip
- return relative_url if relative_url.first == "/"
-
- elements = File.join("/", File.dirname(source_filename)).gsub(/\/+/, '/').split("/")
- elements += relative_url.gsub(/\/+/, '/').split("/")
-
- index = 0
- while(elements[index])
- if (elements[index]==".")
- elements.delete_at(index)
- elsif (elements[index]=="..")
- next if index==0
- index-=1
- 2.times { elements.delete_at(index)}
-
+ bundle_files(filenames) { |filename, content|
+ if options[:compress]
+ JSMinimizer.minimize_content(content)
else
- index+=1
+ content
end
- end
-
- elements * "/"
+ }
end
-
+
def bundle_css_files(filenames=[], options = {})
- output = ""
- each_read_file(filenames) { |filename, content|
- # rewrite the URL reference paths
- # url(../../../images/active_scaffold/default/add.gif);
- # url(/stylesheets/active_scaffold/default/../../../images/active_scaffold/default/add.gif);
- # url(/stylesheets/active_scaffold/../../images/active_scaffold/default/add.gif);
- # url(/stylesheets/../images/active_scaffold/default/add.gif);
- # url(/images/active_scaffold/default/add.gif);
- content.gsub!(/url *\(([^\)]+)\)/) { "url(#{rewrite_relative_path(filename, $1)})" }
- output << content
+ bundle_files(filenames) { |filename, content|
+ BundleFu::CSSUrlRewriter.rewrite_urls(filename, content)
}
- output
end
end
@@ -80,6 +55,7 @@ def bundle(options={}, &block)
:css_path => ($bundle_css_path || "/stylesheets/cache"),
:js_path => ($bundle_js_path || "/javascripts/cache"),
:name => ($bundle_default_name || "bundle"),
+ :compress => false,
:bundle_fu => ( session[:bundle_fu].nil? ? ($bundle_fu.nil? ? true : $bundle_fu) : session[:bundle_fu] )
}.merge(options)
@@ -127,7 +103,7 @@ def bundle(options={}, &block)
FileUtils.rm_f(abs_path)
else
# call bundle_css_files or bundle_js_files to bundle all files listed. output it's contents to a file
- output = BundleFu.send("bundle_#{filetype}_files", new_filelist.filenames)
+ output = BundleFu.send("bundle_#{filetype}_files", new_filelist.filenames, options)
File.open( abs_path, "w") {|f| f.puts output } if output
end
new_filelist.save_as(abs_filelist_path)
@@ -0,0 +1,41 @@
+class BundleFu::CSSUrlRewriter
+ class << self
+ # rewrites a relative path to an absolute path, removing excess "../" and "./"
+ # rewrite_relative_path("stylesheets/default/global.css", "../image.gif") => "/stylesheets/image.gif"
+ def rewrite_relative_path(source_filename, relative_url)
+ relative_url = relative_url.to_s.strip.gsub(/["']/, "")
+
+ return relative_url if relative_url.first == "/"
+
+ elements = File.join("/", File.dirname(source_filename)).gsub(/\/+/, '/').split("/")
+ elements += relative_url.gsub(/\/+/, '/').split("/")
+
+ index = 0
+ while(elements[index])
+ if (elements[index]==".")
+ elements.delete_at(index)
+ elsif (elements[index]=="..")
+ next if index==0
+ index-=1
+ 2.times { elements.delete_at(index)}
+
+ else
+ index+=1
+ end
+ end
+
+ elements * "/"
+ end
+
+ # rewrite the URL reference paths
+ # url(../../../images/active_scaffold/default/add.gif);
+ # url(/stylesheets/active_scaffold/default/../../../images/active_scaffold/default/add.gif);
+ # url(/stylesheets/active_scaffold/../../images/active_scaffold/default/add.gif);
+ # url(/stylesheets/../images/active_scaffold/default/add.gif);
+ # url('/images/active_scaffold/default/add.gif');
+ def rewrite_urls(filename, content)
+ content.gsub!(/url *\(([^\)]+)\)/) { "url(#{rewrite_relative_path(filename, $1)})" }
+ end
+
+ end
+end
@@ -0,0 +1,217 @@
+#!/usr/bin/ruby
+# jsmin.rb 2007-07-20
+# Author: Uladzislau Latynski
+# This work is a translation from C to Ruby of jsmin.c published by
+# Douglas Crockford. Permission is hereby granted to use the Ruby
+# version under the same conditions as the jsmin.c on which it is
+# based.
+#
+# /* jsmin.c
+# 2003-04-21
+#
+# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# The Software shall be used for Good, not Evil.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+require 'stringio'
+
+class BundleFu::JSMinimizer
+ attr_accessor :input
+ attr_accessor :output
+
+ EOF = -1
+ @theA = ""
+ @theB = ""
+
+ # isAlphanum -- return true if the character is a letter, digit, underscore,
+ # dollar sign, or non-ASCII character
+ def isAlphanum(c)
+ return false if !c || c == EOF
+ return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') || c == '_' || c == '$' ||
+ c == '\\' || c[0] > 126)
+ end
+
+ # get -- return the next character from input. Watch out for lookahead. If
+ # the character is a control character, translate it to a space or linefeed.
+ def get()
+ c = @input.getc
+ return EOF if(!c)
+ c = c.chr
+ return c if (c >= " " || c == "\n" || c.unpack("c") == EOF)
+ return "\n" if (c == "\r")
+ return " "
+ end
+
+ # Get the next character without getting it.
+ def peek()
+ lookaheadChar = @input.getc
+ @input.ungetc(lookaheadChar)
+ return lookaheadChar.chr
+ end
+
+ # mynext -- get the next character, excluding comments.
+ # peek() is used to see if a '/' is followed by a '/' or '*'.
+ def mynext()
+ c = get
+ if (c == "/")
+ if(peek == "/")
+ while(true)
+ c = get
+ if (c <= "\n")
+ return c
+ end
+ end
+ end
+ if(peek == "*")
+ get
+ while(true)
+ case get
+ when "*"
+ if (peek == "/")
+ get
+ return " "
+ end
+ when EOF
+ raise "Unterminated comment"
+ end
+ end
+ end
+ end
+ return c
+ end
+
+
+ # action -- do something! What you do is determined by the argument: 1
+ # Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B.
+ # (Delete A). 3 Get the next B. (Delete B). action treats a string as a
+ # single character. Wow! action recognizes a regular expression if it is
+ # preceded by ( or , or =.
+ def action(a)
+ if(a==1)
+ @output.write @theA
+ end
+ if(a==1 || a==2)
+ @theA = @theB
+ if (@theA == "\'" || @theA == "\"")
+ while (true)
+ @output.write @theA
+ @theA = get
+ break if (@theA == @theB)
+ raise "Unterminated string literal" if (@theA <= "\n")
+ if (@theA == "\\")
+ @output.write @theA
+ @theA = get
+ end
+ end
+ end
+ end
+ if(a==1 || a==2 || a==3)
+ @theB = mynext
+ if (@theB == "/" && (@theA == "(" || @theA == "," || @theA == "=" ||
+ @theA == ":" || @theA == "[" || @theA == "!" ||
+ @theA == "&" || @theA == "|" || @theA == "?" ||
+ @theA == "{" || @theA == "}" || @theA == ";" ||
+ @theA == "\n"))
+ @output.write @theA
+ @output.write @theB
+ while (true)
+ @theA = get
+ if (@theA == "/")
+ break
+ elsif (@theA == "\\")
+ @output.write @theA
+ @theA = get
+ elsif (@theA <= "\n")
+ raise "Unterminated RegExp Literal"
+ end
+ @output.write @theA
+ end
+ @theB = mynext
+ end
+ end
+ end
+
+ # jsmin -- Copy the input to the output, deleting the characters which are
+ # insignificant to JavaScript. Comments will be removed. Tabs will be
+ # replaced with spaces. Carriage returns will be replaced with linefeeds.
+ # Most spaces and linefeeds will be removed.
+ def jsmin
+ @theA = "\n"
+ action(3)
+ while (@theA != EOF)
+ case @theA
+ when " "
+ if (isAlphanum(@theB))
+ action(1)
+ else
+ action(2)
+ end
+ when "\n"
+ case (@theB)
+ when "{","[","(","+","-"
+ action(1)
+ when " "
+ action(3)
+ else
+ if (isAlphanum(@theB))
+ action(1)
+ else
+ action(2)
+ end
+ end
+ else
+ case (@theB)
+ when " "
+ if (isAlphanum(@theA))
+ action(1)
+ else
+ action(3)
+ end
+ when "\n"
+ case (@theA)
+ when "}","]",")","+","-","\"","\\", "'", '"'
+ action(1)
+ else
+ if (isAlphanum(@theA))
+ action(1)
+ else
+ action(3)
+ end
+ end
+ else
+ action(1)
+ end
+ end
+ end
+ end
+
+ def self.minimize_content(content)
+ js_minimizer = new
+ js_minimizer.input = StringIO.new(content)
+ js_minimizer.output = StringIO.new
+
+ js_minimizer.jsmin
+
+ js_minimizer.output.string
+ end
+
+end
@@ -1 +1,12 @@
-function js_1() { alert('hi')};
+function js_1() { alert('hi')};
+
+// this is a function
+function func() {
+ alert('hi')
+ return true
+}
+
+function func() {
+ alert('hi')
+ return true
+}
Oops, something went wrong.

0 comments on commit e6accfd

Please sign in to comment.