fastimage_inline 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +0 -0
- data/README.textile +100 -0
- data/Rakefile +19 -0
- data/VERSION.yml +4 -0
- data/lib/fastimage_inline.rb +114 -0
- data/test/app/controllers/main_controller.rb +4 -0
- data/test/app/views/main/index.erb +7 -0
- data/test/config/boot.rb +110 -0
- data/test/config/environment.rb +39 -0
- data/test/config/environments/test.rb +0 -0
- data/test/config/routes.rb +3 -0
- data/test/public/images/bg.png +0 -0
- data/test/public/images/bullet.gif +0 -0
- data/test/public/images/flag.jpg +0 -0
- data/test/test.rb +75 -0
- metadata +84 -0
data/README
ADDED
File without changes
|
data/README.textile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
h1. FastImage Inline
|
2
|
+
|
3
|
+
h4. FastImage Inline speeds up your webpages with inline images in HTML using a data url
|
4
|
+
|
5
|
+
FastImage Inline uses the data uri scheme to place images inline in your image tags, thus saving the http connections that would otherwise have to be made from the browser for each image.
|
6
|
+
|
7
|
+
Some major sites already use this optimisation technique - for instance google news. It's effective when you are using small images (less than 3k bytes), and you do not use those images more than once in a page. Also do not use this for images that you might wish to be cached by the browser - page elements that appear in multiple pages on your site are not good candidates.
|
8
|
+
|
9
|
+
This plugin (or gem) adds a helper to rails that adds a method to ask for an image to be served inline inside the html if possible.
|
10
|
+
|
11
|
+
h2. Browser support
|
12
|
+
|
13
|
+
All modern browsers support this technique except for IE versions 7 and below. This is still a major segment of the market of course, but as IE users migrate to IE 8 this will become less of a problem.
|
14
|
+
|
15
|
+
FastImage Inline uses a simple browser detection mechanism by looking at the user agent string. If the browser is known to not have support, or if we do not recognise it at all, we serve a normal image tag which includes the path to the image file in the src attribute. But if we know the browser can handle it, we send the image inline, and the browser won't need to fetch it separately.
|
16
|
+
|
17
|
+
h2. Examples
|
18
|
+
|
19
|
+
<pre>
|
20
|
+
inline_image_tag("bullet.gif")
|
21
|
+
</pre>
|
22
|
+
|
23
|
+
Result for request from a data-uri capable browser:
|
24
|
+
|
25
|
+
<pre>
|
26
|
+
<img alt="Bullet" src="data:image/gif;base64,R0lGODlhCAANAJECAAAAAP///////wAAACH5BAEAAAIALAAAAAAIAA0AAAITlI+p
|
27
|
+
yxgPI5gAUvruzJpfi0ViAQA7" />
|
28
|
+
</pre>
|
29
|
+
|
30
|
+
Result for a non-capable browser:
|
31
|
+
|
32
|
+
<pre>
|
33
|
+
<img alt="Bullet" src="/images/bullet.gif?1206090639" />
|
34
|
+
</pre>
|
35
|
+
|
36
|
+
h2. Limits
|
37
|
+
|
38
|
+
Reportedly IE8 will not handle data strings longer than 32k bytes. But it is probably unwise to inline images this big anyway. Google news serves images that are up to about 3.5k in length, and this seems a reasonable approach. However, FastImage Inline does not enforce any particular constraints, it is for you to decide.
|
39
|
+
|
40
|
+
FastImage Inline does not cache the images it has read - so every time an image is sent it will be read from disk. This feature may be added in a later release.
|
41
|
+
|
42
|
+
h2. Installation
|
43
|
+
|
44
|
+
Note that the FastImage gem must be installed first, check the requirements section below.
|
45
|
+
|
46
|
+
h4. As a Rails plugin
|
47
|
+
|
48
|
+
<pre>
|
49
|
+
./script/plugin install git://github.com/sdsykes/fastimage_inline.git
|
50
|
+
</pre>
|
51
|
+
|
52
|
+
h4. As a Gem
|
53
|
+
|
54
|
+
<pre>
|
55
|
+
sudo gem install sdsykes-fastimage_inline -s http://gems.github.com
|
56
|
+
</pre>
|
57
|
+
|
58
|
+
Install the gem as above, and configure it in your environment.rb file as below:
|
59
|
+
|
60
|
+
<pre>
|
61
|
+
...
|
62
|
+
Rails::Initializer.run do |config|
|
63
|
+
...
|
64
|
+
config.gem "sdsykes-fastimage_inline", :lib=>"fastimage_inline"
|
65
|
+
...
|
66
|
+
end
|
67
|
+
...
|
68
|
+
</pre>
|
69
|
+
|
70
|
+
h2. Requirements
|
71
|
+
|
72
|
+
* "FastImage":http://github.com/sdsykes/fastimage
|
73
|
+
|
74
|
+
<pre>
|
75
|
+
sudo gem install sdsykes-fastimage -s http://gems.github.com
|
76
|
+
</pre>
|
77
|
+
|
78
|
+
h2. Documentation
|
79
|
+
|
80
|
+
"http://rdoc.info/projects/sdsykes/fastimage_inline":http://rdoc.info/projects/sdsykes/fastimage_inline
|
81
|
+
|
82
|
+
|
83
|
+
h2. Tests
|
84
|
+
|
85
|
+
The tests are run like this
|
86
|
+
|
87
|
+
<pre>
|
88
|
+
$ ruby test/test.rb
|
89
|
+
Loaded suite test/test
|
90
|
+
Started
|
91
|
+
.....
|
92
|
+
Finished in 0.46836 seconds.
|
93
|
+
|
94
|
+
5 tests, 17 assertions, 0 failures, 0 errors
|
95
|
+
</pre>
|
96
|
+
|
97
|
+
h2. References
|
98
|
+
|
99
|
+
* "http://tools.ietf.org/html/rfc2397":http://tools.ietf.org/html/rfc2397
|
100
|
+
* "http://en.wikipedia.org/wiki/Data_URI_scheme":http://en.wikipedia.org/wiki/Data_URI_scheme
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |s|
|
6
|
+
s.name = "fastimage_inline"
|
7
|
+
s.summary = "FastImage Inline - Speeds up your webpages with inline images in HTML using a data url"
|
8
|
+
s.email = "sdsykes@gmail.com"
|
9
|
+
s.homepage = "http://github.com/sdsykes/fastimage_inline"
|
10
|
+
s.description = "FastImage Inline places small images inline in you HTML IMG tags code using a 'data' url."
|
11
|
+
s.authors = ["Stephen Sykes"]
|
12
|
+
s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
|
13
|
+
s.add_dependency('sdsykes-fastimage', '>= 1.1.2')
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://
|
18
|
+
gems.github.com"
|
19
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# FastImage Inline speeds up your webpages with inline images in HTML using a data uri
|
2
|
+
#
|
3
|
+
# FastImage Inline uses the data uri scheme to place images inline in your image tags,
|
4
|
+
# thus saving the http connections that would otherwise have to be made from the browser
|
5
|
+
# for each image.
|
6
|
+
#
|
7
|
+
# === Example
|
8
|
+
#
|
9
|
+
# inline_image_tag("bullet.gif")
|
10
|
+
#
|
11
|
+
# Result for request from data-uri capable browser:
|
12
|
+
#
|
13
|
+
# "<img alt=\"Bullet\" src=\"data:image/gif;base64,R0lGODlhCAANAJECAAAAAP///////wAAACH5BAEAAAIALAAAAAAIAA0AAAITlI+p
|
14
|
+
# yxgPI5gAUvruzJpfi0ViAQA7\" />"
|
15
|
+
#
|
16
|
+
# Result for non-capable browser:
|
17
|
+
#
|
18
|
+
# "<img alt=\"Bullet\" src=\"/images/bullet.gif?1206090639\" />"
|
19
|
+
#
|
20
|
+
# === Requirements
|
21
|
+
#
|
22
|
+
# FastImage
|
23
|
+
#
|
24
|
+
# sudo gem install sdsykes-fastimage -s http://gems.github.com
|
25
|
+
#
|
26
|
+
# === References
|
27
|
+
#
|
28
|
+
# * "http://tools.ietf.org/html/rfc2397":http://tools.ietf.org/html/rfc2397
|
29
|
+
# * "http://en.wikipedia.org/wiki/Data_URI_scheme":http://en.wikipedia.org/wiki/Data_URI_scheme
|
30
|
+
|
31
|
+
require 'open-uri'
|
32
|
+
require 'fastimage'
|
33
|
+
|
34
|
+
module FastImageInline
|
35
|
+
# Returns a tag for the image
|
36
|
+
# Works just like image_tag, except that if the browser making the request being processed
|
37
|
+
# can handle data uris then the image itself is sent placed in the src attribute rather
|
38
|
+
# than just the path to it.
|
39
|
+
#
|
40
|
+
def inline_image_tag(source, options = {})
|
41
|
+
options.symbolize_keys!
|
42
|
+
options[:alt] ||= File.basename(source, '.*').split('.').first.to_s.capitalize
|
43
|
+
options[:src] = inline_image_path(source)
|
44
|
+
|
45
|
+
if size = options.delete(:size)
|
46
|
+
options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
|
47
|
+
end
|
48
|
+
|
49
|
+
if mouseover = options.delete(:mouseover)
|
50
|
+
options[:onmouseover] = "this.src='#{inline_image_path(mouseover)}'"
|
51
|
+
options[:onmouseout] = "this.src='#{inline_image_path(options[:src])}'"
|
52
|
+
end
|
53
|
+
|
54
|
+
tag("img", options)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the image path for use in a src parameter in an image tag
|
58
|
+
# Usage is the same as image_path, or path_to_image, except that if the browser
|
59
|
+
# making the request is capable of handling it then the image itself is included
|
60
|
+
# in a data uri rather than just the path to the image
|
61
|
+
#
|
62
|
+
def inline_image_path(source)
|
63
|
+
has_request = respond_to?(:request)
|
64
|
+
if has_request && inline_capable_browser?
|
65
|
+
inline_image_data(compute_public_path(source, 'images'))
|
66
|
+
else
|
67
|
+
compute_public_path(source, 'images')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def inline_image_data(uri)
|
73
|
+
if is_uri?(uri)
|
74
|
+
u = URI.parse(uri)
|
75
|
+
contents = open(u).read
|
76
|
+
else
|
77
|
+
uri = "#{Rails.root}/public#{uri.gsub(/\?.*$/, "")}"
|
78
|
+
contents = File.read(uri)
|
79
|
+
end
|
80
|
+
data = [contents].pack("m").gsub(/\n/,"")
|
81
|
+
type = FastImage.type(uri, :raise_on_failure=>true)
|
82
|
+
"data:image/#{type};base64,#{data}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def is_uri?(path)
|
86
|
+
path =~ %r{^[-a-z]+://}
|
87
|
+
end
|
88
|
+
|
89
|
+
def inline_capable_browser?
|
90
|
+
if @inline_capable_browser.nil?
|
91
|
+
ua = request.env['HTTP_USER_AGENT'].downcase
|
92
|
+
@inline_capable_browser = if ua.index('msie') && !ua.index('opera') && !ua.index('webtv')
|
93
|
+
ua[(ua.index('msie') + 5)..-1].to_i > 7
|
94
|
+
elsif ua.index('gecko/')
|
95
|
+
true
|
96
|
+
elsif ua.index('opera')
|
97
|
+
true
|
98
|
+
elsif ua.index('konqueror')
|
99
|
+
true
|
100
|
+
elsif ua.index('applewebkit/')
|
101
|
+
true
|
102
|
+
elsif ua.index('mozilla/')
|
103
|
+
true
|
104
|
+
else
|
105
|
+
false
|
106
|
+
end
|
107
|
+
else
|
108
|
+
@inline_capable_browser
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
ActionView::Base.send(:include, FastImageInline)
|
data/test/config/boot.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# Don't change this file!
|
2
|
+
# Configure your app in config/environment.rb and config/environments/*.rb
|
3
|
+
|
4
|
+
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
class << self
|
8
|
+
def boot!
|
9
|
+
unless booted?
|
10
|
+
preinitialize
|
11
|
+
pick_boot.run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def booted?
|
16
|
+
defined? Rails::Initializer
|
17
|
+
end
|
18
|
+
|
19
|
+
def pick_boot
|
20
|
+
(vendor_rails? ? VendorBoot : GemBoot).new
|
21
|
+
end
|
22
|
+
|
23
|
+
def vendor_rails?
|
24
|
+
File.exist?("#{RAILS_ROOT}/vendor/rails")
|
25
|
+
end
|
26
|
+
|
27
|
+
def preinitialize
|
28
|
+
load(preinitializer_path) if File.exist?(preinitializer_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def preinitializer_path
|
32
|
+
"#{RAILS_ROOT}/config/preinitializer.rb"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Boot
|
37
|
+
def run
|
38
|
+
load_initializer
|
39
|
+
Rails::Initializer.run(:set_load_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class VendorBoot < Boot
|
44
|
+
def load_initializer
|
45
|
+
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
|
46
|
+
Rails::Initializer.run(:install_gem_spec_stubs)
|
47
|
+
Rails::GemDependency.add_frozen_gem_path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class GemBoot < Boot
|
52
|
+
def load_initializer
|
53
|
+
self.class.load_rubygems
|
54
|
+
load_rails_gem
|
55
|
+
require 'initializer'
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_rails_gem
|
59
|
+
if version = self.class.gem_version
|
60
|
+
gem 'rails', version
|
61
|
+
else
|
62
|
+
gem 'rails'
|
63
|
+
end
|
64
|
+
rescue Gem::LoadError => load_error
|
65
|
+
$stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
class << self
|
70
|
+
def rubygems_version
|
71
|
+
Gem::RubyGemsVersion rescue nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def gem_version
|
75
|
+
if defined? RAILS_GEM_VERSION
|
76
|
+
RAILS_GEM_VERSION
|
77
|
+
elsif ENV.include?('RAILS_GEM_VERSION')
|
78
|
+
ENV['RAILS_GEM_VERSION']
|
79
|
+
else
|
80
|
+
parse_gem_version(read_environment_rb)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_rubygems
|
85
|
+
min_version = '1.3.2'
|
86
|
+
require 'rubygems'
|
87
|
+
unless rubygems_version >= min_version
|
88
|
+
$stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
|
92
|
+
rescue LoadError
|
93
|
+
$stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
|
94
|
+
exit 1
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_gem_version(text)
|
98
|
+
$1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def read_environment_rb
|
103
|
+
File.read("#{RAILS_ROOT}/config/environment.rb")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# All that for this:
|
110
|
+
Rails.boot!
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file
|
2
|
+
|
3
|
+
# Bootstrap the Rails environment, frameworks, and default configuration
|
4
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
5
|
+
|
6
|
+
Rails::Initializer.run do |config|
|
7
|
+
# Settings in config/environments/* take precedence over those specified here.
|
8
|
+
# Application configuration should go into files in config/initializers
|
9
|
+
# -- all .rb files in that directory are automatically loaded.
|
10
|
+
|
11
|
+
# Add additional load paths for your own custom dirs
|
12
|
+
# config.load_paths += %W( #{RAILS_ROOT}/extras )
|
13
|
+
|
14
|
+
# Specify gems that this application depends on and have them installed with rake gems:install
|
15
|
+
# config.gem "bj"
|
16
|
+
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
|
17
|
+
# config.gem "sqlite3-ruby", :lib => "sqlite3"
|
18
|
+
# config.gem "aws-s3", :lib => "aws/s3"
|
19
|
+
|
20
|
+
# Only load the plugins named here, in the order given (default is alphabetical).
|
21
|
+
# :all can be used as a placeholder for all plugins not explicitly named
|
22
|
+
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
23
|
+
|
24
|
+
# Skip frameworks you're not going to use. To use Rails without a database,
|
25
|
+
# you must remove the Active Record framework.
|
26
|
+
config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
|
27
|
+
|
28
|
+
# Activate observers that should always be running
|
29
|
+
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
30
|
+
|
31
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
32
|
+
# Run "rake -D time" for a list of tasks for finding time zone names.
|
33
|
+
config.time_zone = 'UTC'
|
34
|
+
|
35
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
36
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
|
37
|
+
# config.i18n.default_locale = :de
|
38
|
+
config.action_controller.session = { :key => "_myapp_session", :secret => "some secret phrase blah blah blah blah" }
|
39
|
+
end
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
data/test/test.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
PathHere = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
require 'fakeweb'
|
8
|
+
|
9
|
+
FixturePath = File.join(PathHere, "fixtures")
|
10
|
+
|
11
|
+
gem 'rails'
|
12
|
+
|
13
|
+
RAILS_ROOT = PathHere
|
14
|
+
RAILS_ENV = "test"
|
15
|
+
|
16
|
+
require File.join(PathHere, 'config', 'environment')
|
17
|
+
|
18
|
+
require File.join(PathHere, "..", "lib", 'fastimage_inline')
|
19
|
+
|
20
|
+
require 'test_help'
|
21
|
+
|
22
|
+
class InlineTests < ActionController::TestCase
|
23
|
+
def setup
|
24
|
+
@controller = MainController.new
|
25
|
+
@request = ActionController::TestRequest.new
|
26
|
+
@response = ActionController::TestResponse.new
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
BG_PNG_ENC = "data:image/png;base64,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"
|
31
|
+
BULLET_GIF_ENC = "data:image/gif;base64,R0lGODlhCAANAJECAAAAAP///////wAAACH5BAEAAAIALAAAAAAIAA0AAAITlI+pyxgPI5gAUvruzJpfi0ViAQA7"
|
32
|
+
FLAG_JPG_ENC = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAPAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoKDBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgADwAZAwERAAIRAQMRAf/EAIgAAAMBAQAAAAAAAAAAAAAAAAIEBQMGAQEBAQEAAAAAAAAAAAAAAAADBAAFEAABBAAEAwUJAQAAAAAAAAADAQIEBQARIQZBEhRRUhNTlDFhIkLT1BUWVgcRAAECAwUECAcAAAAAAAAAAAIBAwARBCFxElIFMVFhE4GRodHhkiMU8EHBInKiFf/aAAwDAQACEQMRAD8AxiyaW2pR029rClsoUVqpDfHNKYcOeirFKsbmDp8juYbuxuF960yU2CWWUtnXHfXR6qoST7SoeccP7DOS3pJb4RSt2bVmr6Gv3IGZVrHtxutXhIxA9eFWCaViJmrkXi3Rfdgn9QE6kHcu2LKPRqgKB5lR+81SXZDNFS/53tupU1fY1lreFao3Cmkkijo1eJ3sArytXyRoxvec7DOaiNQvqlhbyj9ViMNGqadPQaVXM5Smn4jOy+1boP8Add//ANHtD0a/aYbn6fuWJv5Wrbi8yd8GO52vt6tKW9ZSbgt1RG9LWQgrEA5ddHj5SSX5disGneXErg0zhYWkEUzEXjF7X9IBxvE8u4RRVJb7JD028Ikxdx0Exay6JTVsd8ePaKarexrBmeAauidQNqs+IjtG5ZZ8M8C7TsC+AISEHzWyXdFzFRXFRvEouC5NMCSLFKzZO1eMVo+49n7krCGqIdVt60G3xDVtlDj8qKiZL08gvhiMxV15HqwicFd7MM4wwyU1wOBwJJp2xAy9XujhXntOb8JKK32TS9OqOY/KXXm7V9Cz6WG5um5S+OmN7TW86+bwj//Z"
|
33
|
+
|
34
|
+
test "normal image tags are unaffected by browser version" do
|
35
|
+
@request.env['HTTP_USER_AGENT'] = "msie 7"
|
36
|
+
get "index"
|
37
|
+
assert_response :success
|
38
|
+
assert_select "img#i1[src=?]", %r{/images/bg.png\?\d+}
|
39
|
+
@request.env['HTTP_USER_AGENT'] = "msie 8"
|
40
|
+
get "index"
|
41
|
+
assert_response :success
|
42
|
+
assert_select "img#i1[src=?]", %r{/images/bg.png\?\d+}
|
43
|
+
end
|
44
|
+
|
45
|
+
test "inline image tags are rendered as normal tags if browser is not recognised" do
|
46
|
+
@request.env['HTTP_USER_AGENT'] = "rails test"
|
47
|
+
get "index"
|
48
|
+
assert_response :success
|
49
|
+
assert_select "img#i2[src=?]", %r{/images/bg.png\?\d+}
|
50
|
+
assert_select "img#i3[src=?]", %r{/images/bullet.gif\?\d+}
|
51
|
+
assert_select "img#i4[src=?]", %r{/images/flag.jpg\?\d+}
|
52
|
+
end
|
53
|
+
|
54
|
+
test "inline images are rendered inline for ie 8" do
|
55
|
+
@request.env['HTTP_USER_AGENT'] = "msie 8"
|
56
|
+
get "index"
|
57
|
+
assert_select "img#i3[src=?]", BULLET_GIF_ENC
|
58
|
+
end
|
59
|
+
|
60
|
+
test "inline images are rendered correctly" do
|
61
|
+
@request.env['HTTP_USER_AGENT'] = "opera"
|
62
|
+
get "index"
|
63
|
+
assert_select "img#i2[src=?]", BG_PNG_ENC
|
64
|
+
assert_select "img#i3[src=?]", BULLET_GIF_ENC
|
65
|
+
assert_select "img#i4[src=?]", FLAG_JPG_ENC
|
66
|
+
end
|
67
|
+
|
68
|
+
test "specified user agents must receive encoded images" do
|
69
|
+
%w{opera gecko/ konqueror applewebkit/ mozilla/}.each do |ua|
|
70
|
+
@request.env['HTTP_USER_AGENT'] = ua
|
71
|
+
get "index"
|
72
|
+
assert_select "img#i2[src=?]", BG_PNG_ENC
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastimage_inline
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Sykes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-10 00:00:00 +03:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sdsykes-fastimage
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.1.2
|
24
|
+
version:
|
25
|
+
description: FastImage Inline places small images inline in you HTML IMG tags code using a 'data' url.
|
26
|
+
email: sdsykes@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
- README.textile
|
34
|
+
files:
|
35
|
+
- README
|
36
|
+
- README.textile
|
37
|
+
- Rakefile
|
38
|
+
- VERSION.yml
|
39
|
+
- lib/fastimage_inline.rb
|
40
|
+
- test/app/controllers/main_controller.rb
|
41
|
+
- test/app/views/main/index.erb
|
42
|
+
- test/config/boot.rb
|
43
|
+
- test/config/environment.rb
|
44
|
+
- test/config/environments/test.rb
|
45
|
+
- test/config/routes.rb
|
46
|
+
- test/public/images/bg.png
|
47
|
+
- test/public/images/bullet.gif
|
48
|
+
- test/public/images/flag.jpg
|
49
|
+
- test/test.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/sdsykes/fastimage_inline
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.5
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: FastImage Inline - Speeds up your webpages with inline images in HTML using a data url
|
78
|
+
test_files:
|
79
|
+
- test/app/controllers/main_controller.rb
|
80
|
+
- test/config/boot.rb
|
81
|
+
- test/config/environment.rb
|
82
|
+
- test/config/environments/test.rb
|
83
|
+
- test/config/routes.rb
|
84
|
+
- test/test.rb
|