gatchaman 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 83669db5ec638c57ccfd8f56068d4db631a061d4
4
+ data.tar.gz: 4f143d83b8e109c79b6d463dac40806433e991ad
5
+ SHA512:
6
+ metadata.gz: e3c44f552269b19291486c5aec3d00e4035f4f66bcee93e42f516fe8b55a96219fe395ec709d707175c8de9c76aed7dd8b92961b1d91bfb525870a32421058e0
7
+ data.tar.gz: f4471f7a121ae95344d9f155e6fdb9c1752ce8a8853b575442657bdfd7119333aaf93043219c4aeb12a1d2b91b5394d4b252ff5460891b748b87ee9619a05fcb
data/ChangeLog CHANGED
@@ -10,3 +10,14 @@
10
10
 
11
11
  * RADME.md add usage of Gatchaman class
12
12
  * relaese version 0.1.1
13
+
14
+ 2013-02-20 maruyama shinepi <shinpeim@gmail.com>
15
+
16
+ * release version 0.2.0
17
+ * now gatchan expand js and css(thanks to wneko)
18
+
19
+ 2013-03-18 maruyama shinpei <shinpeim@gmail.com>
20
+
21
+ * release version 0.2.1
22
+ * some bug fixes
23
+ * refactor (thanks to wneko)
data/README.md CHANGED
@@ -25,6 +25,6 @@ or
25
25
  4. Push to the branch (`git push origin my-new-feature`)
26
26
  5. Create new Pull Request
27
27
 
28
- ## Contributers
28
+ ## Contributors
29
29
 
30
30
  wneko [js and css expand options]
data/Rakefile CHANGED
@@ -1 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = 'spec/**/*_spec.rb'
7
+ spec.rspec_opts = ['-cfs']
8
+ end
9
+ rescue LoadError => e
10
+ end
@@ -24,8 +24,8 @@ options = parse_options
24
24
  input_file = ARGV.shift or help
25
25
 
26
26
  begin
27
- print Gatchaman.new(options[:document_root], options[:current_directory] || File.dirname(input_file)).
28
- data_uri_schemize(IO.read(input_file))
27
+ options[:current_directory] ||= File.dirname(input_file)
28
+ print Gatchaman.new(options).data_uri_schemize(IO.read(input_file))
29
29
  rescue => e
30
30
  warn e.message
31
31
  exit 2
@@ -20,4 +20,5 @@ Gem::Specification.new do |gem|
20
20
  gem.add_runtime_dependency "nokogiri", "~> 1.5.6"
21
21
  gem.add_runtime_dependency "mime-types", "~> 1.19"
22
22
  gem.add_development_dependency "rspec", "~> 2.12.0"
23
+ gem.add_development_dependency "rake", "~> 10.0.3"
23
24
  end
@@ -1,91 +1,41 @@
1
1
  require "gatchaman/version"
2
- require "nokogiri"
3
- require "mime/types"
4
- require "open-uri"
5
- require "base64"
2
+ require "gatchaman/embedder"
3
+
6
4
  class Gatchaman
7
- SCHEMIZE_TARGET_ELEMENTS = [
8
- :img,
9
- :audio,
10
- :video
5
+ EMBED_OPTION_KEYS = [
6
+ :document_root,
7
+ :current_dir,
11
8
  ].freeze
12
-
9
+
13
10
  def initialize(options = {})
14
- @document_root = chomp_last_slash(options[:document_root])
15
- @current_dir = chomp_last_slash(options[:current_dir])
11
+ @options = options
12
+ @embed_options = {}
13
+ EMBED_OPTION_KEYS.each do |key|
14
+ @embed_options[key] = @options[key] if @options[key]
15
+ end
16
+ end
16
17
 
17
- @expand_js = options[:expand_js] || false
18
- @expand_css = options[:expand_css] || false
18
+ def embedders
19
+ if @embedders.nil?
20
+ @embedders = []
21
+ @embedders << Gatchaman::Embedder::Media.new(@embed_options)
22
+ @embedders << Gatchaman::Embedder::JS.new(@embed_options) if @options[:expand_js]
23
+ @embedders << Gatchaman::Embedder::CSS.new(@embed_options) if @options[:expand_css]
24
+ end
25
+ @embedders
19
26
  end
20
27
 
21
28
  def data_uri_schemize(html_string)
22
- doc = Nokogiri::HTML::DocumentFragment.parse(html_string)
29
+ doc = if Nokogiri.XML(html_string).root.name == "html"
30
+ Nokogiri::HTML::Document.parse(html_string)
31
+ else
32
+ Nokogiri::HTML::DocumentFragment.parse(html_string)
33
+ end
23
34
 
24
- doc.css(SCHEMIZE_TARGET_ELEMENTS.join(',')).each do |element|
25
- element[:src] = to_data_scheme(extract_path(element[:src]))
35
+ embedders.each do |embedder|
36
+ embedder.embed(doc)
26
37
  end
27
38
 
28
- expand_js(doc) if @expand_js
29
- expand_css(doc) if @expand_css
30
-
31
39
  doc.to_s
32
40
  end
33
-
34
- private
35
- def chomp_last_slash(str)
36
- str.gsub(/\/$/,"")
37
- end
38
- def extract_path(path)
39
- if path =~ /^http/
40
- return path
41
- elsif path =~ /^\//
42
- return @document_root + path
43
- else
44
- return @current_dir + "/" + path
45
- end
46
- end
47
- def to_data_scheme(path)
48
- mime = MIME::Types.type_for(path).first
49
- image_binary = open(path, "r:ASCII-8BIT"){|f|
50
- f.read(nil)
51
- }
52
- base64 = Base64.encode64(image_binary).gsub(/\s/,'')
53
- "data:#{mime.to_s};base64,#{base64}"
54
- end
55
- def inner_html_from_file(filename)
56
- ["", open(extract_path(filename)).read.chomp, ""].join("\n")
57
- end
58
- def expand_js(doc)
59
- doc.css('script').each do |element|
60
- expand_js_element(element)
61
- end
62
- doc
63
- end
64
- def expand_css(doc)
65
- doc.css('link[rel=stylesheet]').each do |element|
66
- expand_css_element(element)
67
- end
68
- doc
69
- end
70
- def expand_js_element(element)
71
- return if element[:src].nil? or element[:src].size == 0
72
- element.inner_html += inner_html_from_file(element[:src])
73
- [:src, :charset].each {|attr| element.delete(attr.to_s)}
74
- end
75
- def expand_css_element(element)
76
- element.name = "style"
77
- content = inner_html_from_file(element[:href])
78
- content = expand_css_url(content)
79
- element.inner_html = content
80
- element.attributes.keys.each do |attr_name|
81
- next if [:media, :type].include? attr_name.to_sym
82
- element.delete(attr_name)
83
- end
84
- end
85
- def expand_css_url(css_content)
86
- css_content.gsub(/\burl\b\(([^)]+)\)/) do
87
- data_scheme = to_data_scheme(extract_path($1))
88
- "url(#{data_scheme})"
89
- end
90
- end
91
41
  end
@@ -0,0 +1,28 @@
1
+ require "mime/types"
2
+ require "open-uri"
3
+ require "base64"
4
+
5
+ class Gatchaman
6
+ class DataScheme < String
7
+ def initialize(path)
8
+ @path = path
9
+ super(to_s)
10
+ end
11
+
12
+ def mime_type
13
+ @mime_type ||= MIME::Types.type_for(@path).first.to_s
14
+ end
15
+
16
+ def binary
17
+ @binary ||= open(@path, "r:ASCII-8BIT") {|f| f.read(nil) }
18
+ end
19
+
20
+ def base64
21
+ @base64 ||= Base64.encode64(binary).gsub(/\s/, '')
22
+ end
23
+
24
+ def to_s
25
+ "data:#{mime_type};base64,#{base64}"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ require 'open-uri'
2
+ require "nokogiri"
3
+ require "gatchaman/data_scheme"
4
+ require "gatchaman/path"
5
+ require "gatchaman/embedder/media"
6
+ require "gatchaman/embedder/css"
7
+ require "gatchaman/embedder/js"
8
+
9
+ class Gatchaman
10
+ module Embedder
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ require 'gatchaman/embedder/generic'
2
+
3
+ class Gatchaman::Embedder::CSS < Gatchaman::Embedder::Generic
4
+ def embed(doc)
5
+ doc.css('link[rel=stylesheet]').each do |element|
6
+ embed_element(element)
7
+ end
8
+ doc.css('style').each do |element|
9
+ element.content = embed_all_url_in_css(element.content)
10
+ end
11
+ doc
12
+ end
13
+
14
+ private
15
+ def embed_element(element)
16
+ element.name = "style"
17
+ content = inner_html_from_file(element[:href])
18
+ element.inner_html = content
19
+ element.attributes.keys.each do |attr_name|
20
+ next if [:media, :type].include? attr_name.to_sym
21
+ element.delete(attr_name)
22
+ end
23
+ end
24
+
25
+ def embed_all_url_in_css(css_content)
26
+ css_content.gsub(/\burl\b\(([^)]+)\)/) do
27
+ data_scheme = Gatchaman::DataScheme.new(path($1))
28
+ "url(#{data_scheme})"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ class Gatchaman
2
+ module Embedder
3
+ class Generic
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def expand(doc)
9
+ doc
10
+ end
11
+
12
+ private
13
+ def path(path)
14
+ Path.new(path, @options)
15
+ end
16
+
17
+ def inner_html_from_file(filename)
18
+ ["", open(path(filename)).read.chomp, ""].join("\n")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'gatchaman/embedder/generic'
2
+
3
+ class Gatchaman::Embedder::JS < Gatchaman::Embedder::Generic
4
+ def embed(doc)
5
+ doc.css('script').each do |element|
6
+ embed_element(element)
7
+ end
8
+ doc
9
+ end
10
+
11
+ private
12
+ def embed_element(element)
13
+ return if element[:src].nil? or element[:src].size == 0
14
+ element.inner_html += html_comment_out(inner_html_from_file(element[:src]))
15
+ [:src, :charset].each {|attr| element.delete(attr.to_s)}
16
+ end
17
+
18
+ def html_comment_out(content)
19
+ ["<!--", content, "-->"].join("\n")
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'gatchaman/embedder/generic'
2
+
3
+ class Gatchaman::Embedder::Media < Gatchaman::Embedder::Generic
4
+ TARGET_ELEMENTS = [
5
+ :img,
6
+ :audio,
7
+ :video
8
+ ].freeze
9
+
10
+ def embed(doc)
11
+ doc.css(TARGET_ELEMENTS.join(',')).each do |element|
12
+ element[:src] = Gatchaman::DataScheme.new(path(element[:src]))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ require 'uri'
2
+ require 'pathname'
3
+
4
+ class Gatchaman
5
+ class Path < String
6
+ HTTP_REGEX = /^(?:shttp|http|https):/
7
+
8
+ def initialize(path, options = {})
9
+ @path = path
10
+ @document_root = options[:document_root]
11
+ @current_dir = options[:current_dir]
12
+ super(normalized)
13
+ end
14
+
15
+ def normalized
16
+ if @path =~ HTTP_REGEX
17
+ @path
18
+ else
19
+ path = Pathname.new(@path)
20
+ if path.relative?
21
+ Pathname.new(@current_dir).join(@path).to_s
22
+ else
23
+ Pathname.new(@document_root).join(path.relative_path_from(root)).to_s
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+ def root
30
+ Pathname.new("/")
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  class Gatchaman
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -7,7 +7,7 @@ describe Gatchaman do
7
7
  let(:document_root) {File.dirname(File.dirname(__FILE__))}
8
8
  let(:current_dir) {File.dirname(__FILE__)}
9
9
  let(:gatchaman){Gatchaman.new(document_root: document_root, current_dir: current_dir, expand_js: true, expand_css: true)}
10
- let(:base64_encoded_resouce){
10
+ let(:base64_encoded_resource){
11
11
  "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAGCAIAAABrW6giAAAACXBIWXMAA
12
12
  BYlAAAWJQFJUiTwAAABy2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPH
13
13
  g6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0
@@ -23,39 +23,54 @@ describe Gatchaman do
23
23
  bXBtZXRhPgrjpclbAAAAFUlEQVQIHWOUlJRkgAEmGANEk8MBABhmAFcTc
24
24
  YlpAAAAAElFTkSuQmCC".gsub(/[\s\n]/,'')
25
25
  }
26
- let(:test_css_content) { open("#{current_dir}/resouces/test.css").read.chomp }
27
- let(:test_js_content) { open("#{current_dir}/resouces/test.js").read.chomp }
26
+ let(:test_css_content) { open("#{current_dir}/resources/test.css").read.chomp }
27
+ let(:test_js_content) { open("#{current_dir}/resources/test.js").read.chomp }
28
28
 
29
29
  it "絶対urlのsrcをdata schemeで置き換えてくれること" do
30
- gatchaman.should_receive(:open).with("http://example.com/img/test.png", "r:ASCII-8BIT").
31
- and_return(Base64.decode64(base64_encoded_resouce))
30
+ Gatchaman::DataScheme.any_instance.should_receive(:open).with("http://example.com/img/test.png", "r:ASCII-8BIT").
31
+ and_return(Base64.decode64(base64_encoded_resource))
32
32
  gatchaman.data_uri_schemize("<img src='http://example.com/img/test.png'>").
33
- should == "<img src=\"data:image/png;base64,#{base64_encoded_resouce}\">"
33
+ should == "<img src=\"data:image/png;base64,#{base64_encoded_resource}\">"
34
34
  end
35
35
 
36
36
  it "相対urlの相対パスsrcをdata schemeで置き換えてくれること" do
37
- gatchaman.data_uri_schemize('<img src="resouces/test.png">').
38
- should == "<img src=\"data:image/png;base64,#{base64_encoded_resouce}\">"
37
+ gatchaman.data_uri_schemize('<img src="resources/test.png">').
38
+ should == "<img src=\"data:image/png;base64,#{base64_encoded_resource}\">"
39
39
  end
40
40
 
41
41
  it "相対urlの絶対パスsrcをdata schemeで置き換えてくれること" do
42
- gatchaman.data_uri_schemize('<img src="/spec/resouces/test.png">').
43
- should == "<img src=\"data:image/png;base64,#{base64_encoded_resouce}\">"
42
+ gatchaman.data_uri_schemize('<img src="/spec/resources/test.png">').
43
+ should == "<img src=\"data:image/png;base64,#{base64_encoded_resource}\">"
44
+ end
45
+
46
+ it "ルートにhtmlタグを含む場合、htmlページとして出力すること" do
47
+ gatchaman.data_uri_schemize('<html><body><h1>nyan!</h1></body></html>').
48
+ should match /^<html>/
49
+ end
50
+
51
+ it "ルートにhtmlタグを含まない場合、htmlの断片として出力すること" do
52
+ gatchaman.data_uri_schemize('<body><h1>nyan!</h1></body>').
53
+ should_not match /^<html>/
44
54
  end
45
55
 
46
56
  it "cssを展開してくれること" do
47
- gatchaman.data_uri_schemize('<link rel="stylesheet" type="text/css" media="screen" href="resouces/test.css">').
57
+ gatchaman.data_uri_schemize('<link rel="stylesheet" type="text/css" media="screen" href="resources/test.css">').
48
58
  should == %[<style type="text/css" media="screen">\n#{test_css_content}\n</style>]
49
59
  end
50
60
 
51
61
  it "css内部のurl参照を展開してくれること" do
52
- gatchaman.data_uri_schemize('<link rel="stylesheet" type="text/css" media="screen" href="resouces/test_2.css">').
53
- include?(base64_encoded_resouce).should be_true
62
+ gatchaman.data_uri_schemize('<link rel="stylesheet" type="text/css" media="screen" href="resources/test_2.css">').
63
+ include?(base64_encoded_resource).should be_true
64
+ end
65
+
66
+ it "styleタグ内部のURLを展開してくれること" do
67
+ gatchaman.data_uri_schemize('<style> * { background: url(/spec/resources/test.png); } </style>').
68
+ include?(base64_encoded_resource).should be_true
54
69
  end
55
70
 
56
71
  it "jsを展開してくれること" do
57
- gatchaman.data_uri_schemize('<script src="resouces/test.js" type="text/javascript" charset="utf-8"></script>').
58
- should == %[<script type="text/javascript">\n#{test_js_content}\n</script>]
72
+ gatchaman.data_uri_schemize('<script src="resources/test.js" type="text/javascript" charset="utf-8"></script>').
73
+ should == %[<script type="text/javascript"><!--\n\n#{test_js_content}\n\n--></script>]
59
74
  end
60
75
  end
61
76
  end
@@ -3,3 +3,15 @@
3
3
  body {
4
4
  background: url(resouces/test.png);
5
5
  }
6
+
7
+ .a {
8
+ background: url(resouces/test.png);
9
+ }
10
+
11
+ .b {
12
+ background: url(resouces/test.png);
13
+ }
14
+
15
+ .c {
16
+ background: url(resouces/test.png);
17
+ }
File without changes
File without changes
File without changes
@@ -0,0 +1,5 @@
1
+ /* Here is Comment */
2
+
3
+ body {
4
+ background: url(resources/test.png);
5
+ }
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gatchaman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Shinpei Maruyama
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-20 00:00:00.000000000 Z
11
+ date: 2013-03-18 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: nokogiri
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: mime-types
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,11 +48,24 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
61
54
  version: 2.12.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 10.0.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 10.0.3
62
69
  description: Gatchaman is a gem to replace src values in HTML documents with data
63
70
  URI scheme
64
71
  email:
@@ -77,42 +84,50 @@ files:
77
84
  - bin/gatchan
78
85
  - gatchaman.gemspec
79
86
  - lib/gatchaman.rb
87
+ - lib/gatchaman/data_scheme.rb
88
+ - lib/gatchaman/embedder.rb
89
+ - lib/gatchaman/embedder/css.rb
90
+ - lib/gatchaman/embedder/generic.rb
91
+ - lib/gatchaman/embedder/js.rb
92
+ - lib/gatchaman/embedder/media.rb
93
+ - lib/gatchaman/path.rb
80
94
  - lib/gatchaman/version.rb
81
95
  - spec/gatchaman_spec.rb
82
- - spec/resouces/test.css
83
- - spec/resouces/test.js
84
- - spec/resouces/test.png
85
96
  - spec/resouces/test_2.css
97
+ - spec/resources/test.css
98
+ - spec/resources/test.js
99
+ - spec/resources/test.png
100
+ - spec/resources/test_2.css
86
101
  - spec/spec_helper.rb
87
102
  homepage: https://github.com/Shinpeim/Gatchaman
88
103
  licenses: []
104
+ metadata: {}
89
105
  post_install_message:
90
106
  rdoc_options: []
91
107
  require_paths:
92
108
  - lib
93
109
  required_ruby_version: !ruby/object:Gem::Requirement
94
- none: false
95
110
  requirements:
96
- - - ! '>='
111
+ - - '>='
97
112
  - !ruby/object:Gem::Version
98
113
  version: '0'
99
114
  required_rubygems_version: !ruby/object:Gem::Requirement
100
- none: false
101
115
  requirements:
102
- - - ! '>='
116
+ - - '>='
103
117
  - !ruby/object:Gem::Version
104
118
  version: '0'
105
119
  requirements: []
106
120
  rubyforge_project:
107
- rubygems_version: 1.8.24
121
+ rubygems_version: 2.0.0
108
122
  signing_key:
109
- specification_version: 3
123
+ specification_version: 4
110
124
  summary: Gatchaman is a gem to replace src values in HTML documents with data URI
111
125
  scheme
112
126
  test_files:
113
127
  - spec/gatchaman_spec.rb
114
- - spec/resouces/test.css
115
- - spec/resouces/test.js
116
- - spec/resouces/test.png
117
128
  - spec/resouces/test_2.css
129
+ - spec/resources/test.css
130
+ - spec/resources/test.js
131
+ - spec/resources/test.png
132
+ - spec/resources/test_2.css
118
133
  - spec/spec_helper.rb