Class: Rack::JQueryUI::Themes

Inherits:
Object
  • Object
show all
Includes:
JQuery::Helpers
Defined in:
lib/rack/jquery_ui/themes.rb,
lib/rack/jquery_ui/themes/version.rb

Overview

jQuery-UI themes’ CDN script tags and fallback in one neat package.

Defined Under Namespace

Modules: CDN

Constant Summary collapse

JQUERY_UI_THEME_FILE =

The standard CSS file.

"jquery-ui.min.css"
FALLBACK =

This javascript checks if the jQuery-UI object has loaded by issuing a head request to the CDN. If it doesn’t get a successful status, that most likely means the CDN is unreachable, so it uses the local jQuery-UI theme.

<<STR
<script type="text/javascript">
  $.ajax({
    type: "HEAD",
    url: ':CDNURL',
    success: function(css,status) {
      // do nothing
    },
    error: function(xhr,status,error) {
      console.log("error");
      var link = document.createElement("link");
      link.rel = "stylesheet";     
      link.href = ':FALLBACK_URL';
      document.getElementsByTagName("head")[0].appendChild(link); 
    }
  });
</script>
STR
STANDARD_THEMES =

List of the standard themes provided by jQuery UI.

%w{black-tie blitzer cupertino dark-hive dot-luv eggplant excite-bike flick hot-sneaks humanity le-frog mint-choc overcast pepper-grinder redmond smoothness south-street start sunny swanky-purse trontastic ui-darkness ui-lightness vader}
DEFAULT_APP_OPTIONS =

Default options hash for the middleware.

{
  :http_path => "/js/jquery-ui/#{JQueryUI::JQUERY_UI_VERSION}/themes/"
}
Path_to_vendor =

Used internally to find the vendored files.

::File.join(
  "../../../",
  "vendor/assets/javascripts/jquery-ui"
)
VERSION =

version of this library

"2.1.0"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Themes

Note:

***Don’t leave out the version number when using the :http_path option!***. The scripts provided by jQuery don’t contain the version in the filename like the jQuery scripts do, which means that organising them and sending the right headers back is bound to go wrong unless you put the version number somewhere in the route. You have been warned!

Returns a new instance of Themes.

Examples:

# The default:
use Rack::JQueryUI::Themes

# With a default theme other than smoothness:
use Rack::JQueryUI::Themes, :theme => "dot-luv"

# With a several themes, the main one being dot-luv:
use Rack::JQueryUI::Themes, :themes => %w{dot-luv blitzer eggplant trontastic}

# Another way to do the same thing
use Rack::JQueryUI::Themes, :theme => "dot-luv", :themes => %w{blitzer eggplant trontastic}

Parameters:

  • app (#call)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • theme (#to_s)

    The theme to use. The default is “smoothness”.

  • themes (Array<#to_s>)

    List of themes to allow. If the option for theme is set then this will be a backup set. If the option for theme is not set then the first theme listed will become the main theme.

  • :http_path (String)

    If you wish the jQuery CSS fallback route to be “/js/jquery-ui/1.10.1/smoothness/jquery-ui.min.css” (or whichever version this is at) then do nothing, that’s the default. If you want the path to be “/assets/javascripts/jquery-ui/1.10.1/smoothness…” then pass in ‘:http_path => “/assets/javascripts/#JQUERY_UI_VERSION”.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/rack/jquery_ui/themes.rb', line 197

def initialize( app, options={} )
  @app, @options  = app, DEFAULT_APP_OPTIONS.merge(options)
  theme, @themes = self.class.sort_out_options @options

  @http_base_path = @options[:http_path]

  # set the path to all the assets
  @paths = @themes.each_with_object({}) do |theme,paths|
    version_and_theme = ::File.join( 
      JQueryUI::JQUERY_UI_VERSION, "themes", theme
    )

    theme_url = ::File.join @http_base_path, theme
    theme_dir  = ::File.expand_path( ::File.join( Path_to_vendor, version_and_theme ), ::File.dirname(__FILE__) )

    # Store the HTTP path to the CSS as the key
    # with the file path to the CSS file as the value
    paths.store(
      ::File.join( theme_url, JQUERY_UI_THEME_FILE ),
      ::File.join( theme_dir, JQUERY_UI_THEME_FILE)
    )

    images_dir = ::File.join theme_dir, "images"

    Dir.new(images_dir)
        .entries
        .delete_if{|f| f =~ /^\./ }
        .select{|f| 
          Rack::Mime.mime_type(
            ::File.extname(f), "text/css" # fallback is a false
          ).start_with? "image"           # here
        }.each do |img|
          paths.store(
            ::File.join( theme_url, "images", img ), # url
            ::File.join( images_dir, img )           # file
          )
        end
  end
end

Class Method Details

.cdn(env, opts = {}) ⇒ String

Note:

The :theme option can override those given when setting up the middleware (see #initialize), but if the theme given here is not in the themes already set up, then there’ll be no URL paths for it, so use this option to pick which theme is favoured *from the already given set*.

Returns The HTML script tags to get the CDN, with a JQuery function that will be called if the CDN fails and sets the fallback path.

Examples:

# The easiest, use the defaults:
Rack::JQueryUI::Themes.cdn env

# Choose a CDN to favour:
Rack::JQueryUI::Themes.cdn env, :organisation => :media_temple

# Choose a theme to use:
Rack::JQueryUI::Themes.cdn env, :organisation => :media_temple, theme: "dot-luv"

Parameters:

  • env (Hash)

    The rack env hash.

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • organisation (#to_sym)

    Choose which CDN to use, either :media_temple, :microsoft, or :media_temple.

  • :theme (#to_s)

    Theme to use. Won’t set any routes or permanent settings, see note.

Returns:

  • (String)

    The HTML script tags to get the CDN, with a JQuery function that will be called if the CDN fails and sets the fallback path.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rack/jquery_ui/themes.rb', line 115

def self.cdn( env, opts={} )
  organisation = opts[:organisation] || :media_temple
  themes = env.fetch "rack.jquery_ui-themes", themes()
  theme, themes = sort_out_options opts.merge :themes => themes

  # Get the CDN URL for the given organisation.
  url = case organisation.to_sym
    when :google then CDN::GOOGLE
    when :microsoft then CDN::MICROSOFT
    when :media_temple then CDN::MEDIA_TEMPLE
    else CDN::MEDIA_TEMPLE
  end

  script_name = env.fetch("SCRIPT_NAME","/")

  fallback_url = ::File.join script_name, "/js/jquery-ui/#{JQueryUI::JQUERY_UI_VERSION}/themes/:THEME/#{JQUERY_UI_THEME_FILE}"

  fallback_script = FALLBACK.gsub(/\:CDNURL/, url)
                            .sub /\:FALLBACK_URL/, fallback_url

  script    = "<link rel='stylesheet' href='#{url}' type='text/css' />"
  [script,fallback_script].map{|x|
    x.gsub(/\:THEME/, theme)
  }.join("\n")
  #fallback_script.gsub(/\:THEME/, theme)
end

.sort_out_options(options = {}) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/rack/jquery_ui/themes.rb', line 157

def self.sort_out_options( options={} )
  theme = options[:theme]
  themes = options[:themes]

  if theme
    t = Array(theme).map(&:to_s).uniq # put in an array
    themes = themes ?
      (t + themes).uniq :
      t
  else
    themes = self.themes if themes.nil? || themes.empty?
    theme = themes.first
  end
  
  unless (ts = themes - STANDARD_THEMES).empty?
    fail ArgumentError, %Q!The themes given (#{ts.join(" ")}) are unknown for this version of the rack-jquery_ui-themes library. Choose from #{STANDARD_THEMES}!
  end

  [theme,themes]
end

.themeString

The chosen theme name.



62
63
64
# File 'lib/rack/jquery_ui/themes.rb', line 62

def self.theme
  @theme ||= "smoothness"
end

.theme=(name) ⇒ String

Set the theme.

Parameters:

  • name (String)

    Name of the theme.

Returns:

  • (String)


70
71
72
73
74
# File 'lib/rack/jquery_ui/themes.rb', line 70

def self.theme=( name )
  name = name.to_s
  fail ArgumentError, "That theme (#{name}) is unknown for this version of the rack-jquery_ui-themes library." unless STANDARD_THEMES.include? name
  @theme = name
end

.themesArray<String>

Get the selected themes

Returns:

  • (Array<String>)


89
90
91
# File 'lib/rack/jquery_ui/themes.rb', line 89

def self.themes
  @themes ||= Array(self.theme)
end

.themes=(themes) ⇒ Array<String>

Set the themes to use.

Examples:

self.class.themes = ["smoothness", "swanky-purse"]

Parameters:

  • themes (Array<String>)

Returns:

  • (Array<String>)


82
83
84
85
# File 'lib/rack/jquery_ui/themes.rb', line 82

def self.themes=( themes )
  themes = themes.pop if themes.first.respond_to? :each
  @themes = themes.map! &:to_s
end

Instance Method Details

#_call(env) ⇒ Object

For thread safety

Parameters:

  • env (Hash)

    Rack request environment hash.



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/rack/jquery_ui/themes.rb', line 246

def _call( env )
  env.merge! "rack.jquery_ui-themes" => @themes
  request = Rack::Request.new(env.dup)

  # path for CSS
  # TODO benchmark this condition
  # start_with? vs has_key vs regex
  if @paths.has_key? request.path_info
    response = Rack::Response.new
    if request.path_info.end_with? JQUERY_UI_THEME_FILE # CSS.
      # For caching:
      response.headers.merge! caching_headers("#{JQUERY_UI_THEME_FILE}-#{self.class.theme}-#{JQueryUI::JQUERY_UI_VERSION}", JQueryUI::JQUERY_UI_VERSION_DATE)
      # There's no need to test if the IF_MODIFIED_SINCE against the release date because the header will only be passed if the file was previously accessed by the requester, and the file is never updated. If it is updated then it is accessed by a different path.
      requested_file = open @paths[request.path_info], "r"
    elsif request.path_info =~ /images/
      # serve images
      requested_file = open @paths[request.path_info], "rb"
    else # bad route
      response.status = 404
      return response.finish # finish early, 404
    end

    # set status and read the requested file
    if request.env['HTTP_IF_MODIFIED_SINCE']
      response.status = 304
    else
      response.status = 200
      mime = Mime.mime_type(::File.extname(requested_file.path), 'text/css')
      response.headers.merge!( "Content-Type" => mime ) if mime
      response.write ::File.read( requested_file )
    end
    response.finish
  else
    @app.call(env)
  end
end

#call(env) ⇒ Object

Parameters:

  • env (Hash)

    Rack request environment hash.



239
240
241
# File 'lib/rack/jquery_ui/themes.rb', line 239

def call( env )
  dup._call env
end