require 'ajaxlibs/exceptions'
require 'ajaxlibs/versions_tools'
# Represents an ajaxlib library, regroups available version of a particular library
# and a few functions to generate either a filepath to local library or javascript loading code
# for Google CDN.
class Ajaxlibs::Library
# Available versions for this library.
Versions = []
Requirements = {}
attr_reader :version, :source, :secure
@@subclasses = {}
def self.inherited(child) #:nodoc:
@@subclasses[child.library_name.to_sym] = child
end
# Returns all available libraries (instance of Ajaxlibs::Library).
def self.all
@@subclasses.values
end
# Search a specific library by its name (could be either a string or a symbol) and initialized it with given version and source.
# See initialize method for available options.
def self.by_name(name, options = {})
@@subclasses[name.to_sym].new options
rescue NoMethodError
raise Ajaxlibs::Exception::LibraryNotFound
end
# Library name based on class name
def self.library_name
name.match(/::(\w+)$/)[1].downcase
end
# Initialize a new instance of a specific library.
# options can take the following arguments :
# * :version : specify a version (ex: "1.8.1").
# * :source : force the source to use, default to :local.
# * :secure : specify if the generated link should be secured (https) or not. Default is false.
# * :minified : true if you want a minified version of the javascript library, false otherwise. Default is true.
def initialize(options = {})
@version = check_version_or_latest_version(options[:version])
@source = options[:source] || :local
@minified = options[:minified].nil? ? true : options[:minified]
@secure = options[:secure] || false
end
# Returns requirements for a library (for example, prototype for scriptaculous)
def requires
self.class::Requirements[@version] || self.class::Requirements[:all] || {}
end
# Library name based on class name
def library_name
self.class.library_name
end
# Javascript library filename, can be different from library_name (jqueryui / jquery-ui for example)
def file_name
library_name
end
# Search for the latest version available using given Versions
def latest_version
self.class::Versions.max {|a, b| Ajaxlibs::VersionsTools.compare a, b}
end
# Local path for a particular version, or the latest if given version is nil.
# Search for the file in rails public path and copy it if needed.
def local_path
check_and_copy_local_file_to_rails_public
File.join('ajaxlibs', library_name, version, file_name)
end
# Include path using google CDN
def google_cdn_include_path
scheme = secure ? "https" : "http"
"#{scheme}://ajax.googleapis.com/ajax/libs/#{library_name}/#{version}/#{file_name}.js"
end
# Javascript include path regarding source (call either local_path or google_cdn_include_path)
def include_path
(source == :local or local_only?) ? local_path : google_cdn_include_path
end
def local_only?
false
end
def ==(other)
self.class == other.class and self.version == other.version and self.source == other.source
end
private
# Checks if given version is available for this library,
# raises Ajaxlibs::Exception::VersionNotFound if not and returns it.
# Passing a nil value will returns the latest available version
def check_version_or_latest_version(version = nil)
version ||= latest_version
raise Ajaxlibs::Exception::VersionNotFound unless self.class::Versions.include?(version)
version
end
def check_and_copy_local_file_to_rails_public
if Object.const_defined?(:Rails) and File.directory?(File.join(Rails.root, 'public'))
ajaxlibs_js_path = File.join(Rails.root, 'public', 'javascripts', 'ajaxlibs')
source_path = File.join(File.dirname(__FILE__), '../../public', library_name, version)
source = File.join(source_path, '*.*')
destination = File.join(ajaxlibs_js_path, library_name, version)
if not File.exists?(destination) or Dir.entries(source_path) != Dir.entries(destination)
FileUtils.mkdir_p(destination)
FileUtils.cp(Dir.glob(source), destination)
end
end
end
end