mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-24 16:14:07 +01:00
Next step in upgrading Tracks to Rails 2.2. Some highlights:
* Ran rake rails:update * Added old actionwebservice framework * Updated RSpec and RSpec-Rails * Removed asset_packager plugin (not compatible, Scott no longer maintaining), and replaced with bundle_fu. See the bundle_fu README for more info. * Hacks to UJS and ARTS plugins, which are no longer supported. Probably should move off both UJS and RJS. * Hack to flashobject_helper plugin (upgrade to Rails 2.2-compatible version if/when it comes out.) * Hack to skinny-spec plugin, for Rails 2.2 compatibility. Should check for official release. * Hacks to resource_feeder plugin, for Rails 2.2 compatibility. Should check for official release (not likely) or move off it. * Addressed some deprecation warnings. More to come. * My mobile mime type hackery is no longer necessary with new Rails features. Yay! * Updated environment.rb.tmpl with changes TODO: * Restore view specs marked pending * Fix failing integration tests. * Try selenium tests. * Investigate OpenID support. * Address deprecation warnings. * Consider moving parts of environment.rb to initializers * Address annoying config.gem warning about highline gem
This commit is contained in:
parent
6d11ebd1b0
commit
35ae5fc431
394 changed files with 15184 additions and 9936 deletions
146
vendor/plugins/bundle-fu/lib/bundle_fu.rb
vendored
Normal file
146
vendor/plugins/bundle-fu/lib/bundle_fu.rb
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
class BundleFu
|
||||
|
||||
class << self
|
||||
attr_accessor :content_store
|
||||
def init
|
||||
@content_store = {}
|
||||
end
|
||||
|
||||
def bundle_files(filenames=[])
|
||||
output = ""
|
||||
filenames.each{ |filename|
|
||||
output << "/* --------- #{filename} --------- */ "
|
||||
output << "\n"
|
||||
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 =
|
||||
bundle_files(filenames) { |filename, content|
|
||||
if options[:compress]
|
||||
if Object.const_defined?("Packr")
|
||||
content
|
||||
else
|
||||
JSMinimizer.minimize_content(content)
|
||||
end
|
||||
else
|
||||
content
|
||||
end
|
||||
}
|
||||
|
||||
if Object.const_defined?("Packr")
|
||||
# use Packr plugin (http://blog.jcoglan.com/packr/)
|
||||
Packr.new.pack(output, options[:packr_options] || {:shrink_vars => false, :base62 => false})
|
||||
else
|
||||
output
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def bundle_css_files(filenames=[], options = {})
|
||||
bundle_files(filenames) { |filename, content|
|
||||
BundleFu::CSSUrlRewriter.rewrite_urls(filename, content)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
self.init
|
||||
|
||||
module InstanceMethods
|
||||
# valid options:
|
||||
# :name - The name of the css and js files you wish to output
|
||||
# returns true if a regen occured. False if not.
|
||||
def bundle(options={}, &block)
|
||||
# allow bypassing via the querystring
|
||||
session[:bundle_fu] = (params[:bundle_fu]=="true") if params.has_key?(:bundle_fu)
|
||||
|
||||
options = {
|
||||
:css_path => ($bundle_css_path || "/stylesheets/cache"),
|
||||
:js_path => ($bundle_js_path || "/javascripts/cache"),
|
||||
:name => ($bundle_default_name || "bundle"),
|
||||
:compress => true,
|
||||
:bundle_fu => ( session[:bundle_fu].nil? ? ($bundle_fu.nil? ? true : $bundle_fu) : session[:bundle_fu] )
|
||||
}.merge(options)
|
||||
|
||||
# allow them to bypass via parameter
|
||||
options[:bundle_fu] = false if options[:bypass]
|
||||
|
||||
paths = { :css => options[:css_path], :js => options[:js_path] }
|
||||
|
||||
content = capture(&block)
|
||||
content_changed = false
|
||||
|
||||
new_files = nil
|
||||
abs_filelist_paths = [:css, :js].inject({}) { | hash, filetype | hash[filetype] = File.join(RAILS_ROOT, "public", paths[filetype], "#{options[:name]}.#{filetype}.filelist"); hash }
|
||||
|
||||
# only rescan file list if content_changed, or if a filelist cache file is missing
|
||||
unless content == BundleFu.content_store[options[:name]] && File.exists?(abs_filelist_paths[:css]) && File.exists?(abs_filelist_paths[:js])
|
||||
BundleFu.content_store[options[:name]] = content
|
||||
new_files = {:js => [], :css => []}
|
||||
|
||||
content.scan(/(href|src) *= *["']([^"^'^\?]+)/i).each{ |property, value|
|
||||
case property
|
||||
when "src"
|
||||
new_files[:js] << value
|
||||
when "href"
|
||||
new_files[:css] << value
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
[:css, :js].each { |filetype|
|
||||
output_filename = File.join(paths[filetype], "#{options[:name]}.#{filetype}")
|
||||
abs_path = File.join(RAILS_ROOT, "public", output_filename)
|
||||
abs_filelist_path = abs_filelist_paths[filetype]
|
||||
|
||||
filelist = FileList.open( abs_filelist_path )
|
||||
|
||||
# check against newly parsed filelist. If we didn't parse the filelist from the output, then check against the updated mtimes.
|
||||
new_filelist = new_files ? BundleFu::FileList.new(new_files[filetype]) : filelist.clone.update_mtimes
|
||||
|
||||
unless new_filelist == filelist
|
||||
FileUtils.mkdir_p(File.join(RAILS_ROOT, "public", paths[filetype]))
|
||||
# regenerate everything
|
||||
if new_filelist.filenames.empty?
|
||||
# delete the javascript/css bundle file if it's empty, but keep the filelist cache
|
||||
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, options)
|
||||
File.open( abs_path, "w") {|f| f.puts output } if output
|
||||
end
|
||||
new_filelist.save_as(abs_filelist_path)
|
||||
end
|
||||
|
||||
if File.exists?(abs_path) && options[:bundle_fu]
|
||||
tag = filetype==:css ? stylesheet_link_tag(output_filename) : javascript_include_tag(output_filename)
|
||||
if Rails::version < "2.2.0"
|
||||
concat( tag , block.binding)
|
||||
else
|
||||
#concat doesn't need block.binding in Rails >= 2.2.0
|
||||
concat( tag )
|
||||
end
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
unless options[:bundle_fu]
|
||||
if Rails::version < "2.2.0"
|
||||
concat( content, block.binding )
|
||||
else
|
||||
#concat doesn't need block.binding in Rails >= 2.2.0
|
||||
concat( content )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
42
vendor/plugins/bundle-fu/lib/bundle_fu/css_url_rewriter.rb
vendored
Normal file
42
vendor/plugins/bundle-fu/lib/bundle_fu/css_url_rewriter.rb
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
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 == "/" || relative_url.include?("://")
|
||||
|
||||
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)})" }
|
||||
content
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
64
vendor/plugins/bundle-fu/lib/bundle_fu/file_list.rb
vendored
Normal file
64
vendor/plugins/bundle-fu/lib/bundle_fu/file_list.rb
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
require 'fileutils.rb'
|
||||
|
||||
class BundleFu::FileList
|
||||
attr_accessor :filelist
|
||||
|
||||
def initialize(filenames=[])
|
||||
self.filelist = []
|
||||
|
||||
self.add_files(filenames)
|
||||
end
|
||||
|
||||
def initialize_copy(from)
|
||||
self.filelist = from.filelist.collect{|entry| entry.clone}
|
||||
end
|
||||
|
||||
def filenames
|
||||
self.filelist.collect{ |entry| entry[0] }
|
||||
end
|
||||
|
||||
def update_mtimes
|
||||
old_filenames = self.filenames
|
||||
self.filelist = []
|
||||
# readding the files will effectively update the mtimes
|
||||
self.add_files(old_filenames)
|
||||
self
|
||||
end
|
||||
|
||||
def self.open(filename)
|
||||
return nil unless File.exists?(filename)
|
||||
b = new
|
||||
File.open(filename, "rb") {|f|
|
||||
b.filelist = Marshal.load(f) # rescue [])
|
||||
}
|
||||
b
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
# compares to see if one file list is exactly the same as another
|
||||
def ==(compare)
|
||||
return false if compare.nil?
|
||||
throw "cant compare with #{compare.class}" unless self.class===compare
|
||||
|
||||
self.filelist == compare.filelist
|
||||
end
|
||||
|
||||
def add_files(filenames=[])
|
||||
filenames.each{|filename|
|
||||
self.filelist << [ extract_filename_from_url(filename), (File.mtime(abs_location(filename)).to_i rescue 0) ]
|
||||
}
|
||||
end
|
||||
|
||||
def extract_filename_from_url(url)
|
||||
url.gsub(/^https?:\/\/[^\/]+/i, '')
|
||||
end
|
||||
|
||||
def save_as(filename)
|
||||
File.open(filename, "wb") {|f| f.puts Marshal.dump(self.filelist)}
|
||||
end
|
||||
protected
|
||||
def abs_location(filename)
|
||||
File.join(RAILS_ROOT, "public", filename)
|
||||
end
|
||||
end
|
||||
217
vendor/plugins/bundle-fu/lib/bundle_fu/js_minimizer.rb
vendored
Normal file
217
vendor/plugins/bundle-fu/lib/bundle_fu/js_minimizer.rb
vendored
Normal file
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue