shutterbug 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/concord-consortium/shutterbug.png?branch=master)](https://travis-ci.org/concord-consortium/shutterbug)
4
4
  [![Code Climate](https://codeclimate.com/github/concord-consortium/shutterbug.png)](https://codeclimate.com/github/concord-consortium/shutterbug)
5
5
 
6
- A rack utility that will create and save images (pngs) from parts of your html's documents current dom. These images become available as public png resources in the rack application. Currently shutterbug supports HTML, SVG and Canvas elements.
6
+ A rack utility that will create and save images (pngs) from parts of your html's documents current dom. These images become available as public png resources in the rack application. Currently shutterbug supports HTML, SVG and Canvas elements. Here is a sampel config.ru file:
7
7
 
8
8
 
9
9
  use Shutterbug::Rackapp do |config|
@@ -45,6 +45,42 @@ After adding `use Shutterbug::Rackapp` to your config.ru file, you can convert p
45
45
  1. include the following javascript in your pages: `<script src='http://<yourhost:port>/shutterbug/shutterbug.js' type='text/javascript'></script>`
46
46
  1. Elsewhere in your javascript call `getDomSnapshot($("#sourceDomID"),$("#imageOutputDomId"));` This will replace the contents of `$("#imageOutputDomId")` with an `<img src="http://<yourhost:port>/gete_png/sha1hash>` tag which will magically spring into existance.
47
47
 
48
+
49
+ ## Deploying on Heroku ##
50
+
51
+ To deploy on heroku, you are going to want to modify your stack following [these instructions](http://nerdery.crowdmob.com/post/33143120111/heroku-ruby-on-rails-and-phantomjs).
52
+
53
+ Your app should have a config.ru that looks something like this:
54
+
55
+
56
+ require 'shutterbug'
57
+ require 'rack/cors'
58
+
59
+ use Rack::Cors do
60
+ allow do
61
+ origins '*'
62
+ resource '/shutterbug/*', :headers => :any, :methods => :any
63
+ end
64
+ end
65
+
66
+ use Shutterbug::Rackapp do |config|
67
+ config.uri_prefix = "http://<your app name>.herokuapp.com/"
68
+ config.path_prefix = "/shutterbug"
69
+ config.phantom_bin_path = "/app/vendor/phantomjs/bin/phantomjs"
70
+ end
71
+
72
+ app = proc do |env|
73
+ [200, { 'Content-Type' => 'text/html' }, ['move along']]
74
+ end
75
+
76
+ run app
77
+
78
+ And a Procfile which looks like this:
79
+
80
+ web: bundle exec rackup config.ru -p $PORT
81
+
82
+
83
+
48
84
  ## TODO: ##
49
85
 
50
86
  * Configuration of the rack paths.
data/config.ru ADDED
@@ -0,0 +1,18 @@
1
+
2
+ require 'shutterbug'
3
+ require 'rack/cors'
4
+ use Rack::Cors do
5
+ allow do
6
+ origins '*'
7
+ resource '/shutterbug/*', :headers => :any, :methods => :any
8
+ end
9
+ end
10
+
11
+ use Shutterbug::Rackapp do |config|
12
+ config.uri_prefix = "http://localhost:9292"
13
+ config.path_prefix = "/shutterbug"
14
+ end
15
+
16
+ app = Rack::Directory.new "demo"
17
+
18
+ run app
data/demo/iframe.html ADDED
@@ -0,0 +1,30 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>demo</title>
5
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
6
+ <script type="text/javascript" src="/shutterbug/shutterbug.js"></script>
7
+ <link rel="stylesheet" type="text/css" href="main.css"></link>
8
+ <style type="text/css">
9
+ #src {
10
+ color: blue;
11
+ width: 100px;
12
+ height: 100px;
13
+ }
14
+ </style>
15
+ </head>
16
+
17
+ <body>
18
+ <div id="src">
19
+ (iframe)
20
+ </div>
21
+ </div>
22
+
23
+ </body>
24
+ <script type="text/javascript">
25
+ var dd = null;
26
+ $(document).ready(function(e) {
27
+ dd = new Shutterbug('#src');
28
+ });
29
+ </script>
30
+ </html>
data/demo/index.html ADDED
@@ -0,0 +1,35 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>demo</title>
5
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
6
+ <script type="text/javascript" src="/shutterbug/shutterbug.js"></script>
7
+ <link rel="stylesheet" type="text/css" href="main.css"></link>
8
+ <style type="text/css">
9
+ #src {
10
+ color: red;
11
+ }
12
+ </style>
13
+ </head>
14
+
15
+ <body>
16
+ <div id="src">
17
+ testing..
18
+ </div>
19
+ <button class="shutterbug" data-src="#src" data-dst="#dst">Snapshot</button>
20
+ <div id="dst">
21
+ </div>
22
+
23
+ </body>
24
+ <script type="text/javascript">
25
+ $(document).ready(function(e) {
26
+ $("button.shutterbug").click(function(e) {
27
+ var target = $(e.target);
28
+ var src = target.attr('data-src');
29
+ var dst = target.attr('data-dst');
30
+ var bug = new Shutterbug(src,dst);
31
+ bug.getDomSnapshot();
32
+ });
33
+ });
34
+ </script>
35
+ </html>
data/demo/main.css ADDED
@@ -0,0 +1,9 @@
1
+ div {
2
+ font-weight: bold;
3
+ font-family: sans-serif;
4
+ min-width: 100px;
5
+ min-height: 100px;
6
+ border: 1px solid black;
7
+ overflow: hidden;
8
+ padding: 10px;
9
+ }
@@ -0,0 +1,31 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>demo</title>
5
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
6
+ <script type="text/javascript" src="/shutterbug/shutterbug.js"></script>
7
+ <link rel="stylesheet" type="text/css" href="main.css">
8
+ <style type="text/css">
9
+ #src {
10
+ color: red;
11
+ }
12
+ </style>
13
+ </head>
14
+
15
+ <body>
16
+ <iframe src="iframe.html" width="300" height="300"></iframe>
17
+ <button class="shutterbug" data-dst="#dst">Snapshot</button>
18
+ <div id="dst">
19
+ </div>
20
+
21
+ </body>
22
+ <script type="text/javascript">
23
+ var bug = null;
24
+ $(document).ready(function(e) {
25
+ bug = new Shutterbug("iframe","#dst");
26
+ $("button.shutterbug").click(function(e) {
27
+ bug.getDomSnapshot();
28
+ });
29
+ });
30
+ </script>
31
+ </html>
@@ -1,9 +1,12 @@
1
1
  /*global $ */
2
2
  (function(){
3
+
3
4
  var getBaseUrl = function() {
4
- var base = window.location.protocol + "//" + window.location.host + "/";
5
- var root_path = window.location.pathname.split("/").slice(1,-1).join("/");
6
- return base + root_path;
5
+ // var base = window.location.protocol + "//" + window.location.host + "/";
6
+ // var root_path = window.location.pathname.split("/").slice(1,-1).join("/");
7
+ // return base + root_path;
8
+ var base = window.location.href;
9
+ return base;
7
10
  };
8
11
 
9
12
  var cloneDomItem =function(elem, elemTag) {
@@ -19,24 +22,26 @@
19
22
  return returnElm;
20
23
  };
21
24
 
22
- var getDomSnapshot = function(element, imgDst, callback) {
23
- var css = $('<div>').append($('link[rel="stylesheet"]').clone()).html();
24
- var width = element.width();
25
- var height = element.height();
25
+ var getHtmlFragment = function() {
26
+ var $element = $(this.element);
27
+
28
+ var css = $('<div>').append($('link[rel="stylesheet"]').clone()).append($('style').clone()).html();
29
+ var width = $element.width();
30
+ var height = $element.height();
31
+ var element = null;
26
32
  var html_content;
27
33
 
28
- var replacementImgs = element.find('canvas').map( function(count,elem) {
34
+ var replacementImgs = $element.find('canvas').map( function(count,elem) {
29
35
  var dataUrl = elem.toDataURL('image/png');
30
36
  var img = cloneDomItem($(elem),"<img>");
31
37
  img.attr('src', dataUrl);
32
38
  return img;
33
39
  });
34
40
 
35
- element = element.clone();
41
+ element = $element.clone();
36
42
  element.find('canvas').each(function(i,elm) {
37
43
  var backgroundDiv = cloneDomItem($(elm),"<div>");
38
- // we should also add a backing (background) dom element
39
- // $('canvas.overlay').css('background')
44
+ // Add a backing (background) dom element for BG canvas property
40
45
  $(elm).replaceWith(replacementImgs[i]);
41
46
  backgroundDiv.insertBefore($(elm));
42
47
  });
@@ -49,26 +54,88 @@
49
54
  'height':height
50
55
  });
51
56
 
52
- html_content = $('<div>').append(element).html();
57
+ html_content = {
58
+ content: $('<div>').append(element).html(),
59
+ css: css,
60
+ width: width,
61
+ height: height,
62
+ base_url: getBaseUrl()
63
+ };
64
+ return html_content;
65
+ };
53
66
 
67
+ var getPng = function(html) {
68
+ if(typeof html === 'undefined') {
69
+ if($(this.element)[0] && $(this.element)[0].contentWindow) {
70
+ this.requestHtmlFrag();
71
+ return;
72
+ }
73
+ else {
74
+ html = this.getHtmlFragment();
75
+ }
76
+ }
77
+ var self = this;
54
78
  $.ajax({
55
79
  url: "CONVERT_PATH",
56
80
  type: "POST",
57
- data: {
58
- 'content': html_content,
59
- 'css': css,
60
- 'width': width,
61
- 'height': height,
62
- 'base_url': getBaseUrl()
63
- }
81
+ data: html
64
82
  }).done(function(msg) {
65
- if(imgDst) {
66
- imgDst.html(msg);
83
+ if(self.imgDst) {
84
+ $(self.imgDst).html(msg);
67
85
  }
68
- if (callback) {
69
- callback(msg);
86
+ if (self.callback) {
87
+ self.callback(msg);
70
88
  }
71
89
  });
72
90
  };
73
- window.getDomSnapshot = getDomSnapshot;
91
+
92
+ var requestHtmlFrag = function() {
93
+ var destination = $(this.element)[0].contentWindow;
94
+ var message = {
95
+ type: 'htmlFragRequest'
96
+ };
97
+ destination.postMessage(JSON.stringify(message),"*");
98
+ };
99
+
100
+ window.Shutterbug = function(selector,imgDst,callback) {
101
+ var shutterbugInstance = {
102
+ element: selector,
103
+ imgDst: imgDst,
104
+ callback: callback,
105
+ getDomSnapshot: getPng,
106
+ getPng: getPng,
107
+ getHtmlFragment: getHtmlFragment,
108
+ requestHtmlFrag: requestHtmlFrag
109
+ };
110
+
111
+ var htmlFragRequestListen = function(message) {
112
+ var data = message.data;
113
+ if (typeof data === 'string') {
114
+ data = JSON.parse(data);
115
+ }
116
+ if(data.type === 'htmlFragRequest') {
117
+ var response = {
118
+ type: 'htmlFragResponse',
119
+ value: shutterbugInstance.getHtmlFragment()
120
+ };
121
+ message.source.postMessage(JSON.stringify(response),"*");
122
+ }
123
+ };
124
+
125
+ var htmlFragResponseListen = function(message) {
126
+ var data = message.data;
127
+ if (typeof data === 'string') {
128
+ data = JSON.parse(data);
129
+ }
130
+ var html = null;
131
+ if(data.type === 'htmlFragResponse') {
132
+ html = data.value;
133
+ shutterbugInstance.getPng(html);
134
+ }
135
+ };
136
+ window.addEventListener('message', htmlFragRequestListen, false);
137
+ window.addEventListener('message', htmlFragResponseListen, false);
138
+ return shutterbugInstance;
139
+ };
140
+
74
141
  })();
data/lib/shutterbug.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Shutterbug
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  autoload :Service, "shutterbug/service"
4
4
  autoload :Rackapp, "shutterbug/rackapp"
5
5
  autoload :Configuration, "shutterbug/configuration"
data/shutterbug.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "rake"
30
30
  spec.add_development_dependency "rspec"
31
31
  spec.add_development_dependency "guard-rspec"
32
+ spec.add_development_dependency "rack-cors"
32
33
 
33
34
  spec.add_dependency "rack"
34
35
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shutterbug
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-27 00:00:00.000000000 Z
12
+ date: 2013-07-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rack-cors
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  - !ruby/object:Gem::Dependency
79
95
  name: rack
80
96
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +127,11 @@ files:
111
127
  - LICENSE.md
112
128
  - README.md
113
129
  - Rakefile
130
+ - config.ru
131
+ - demo/iframe.html
132
+ - demo/index.html
133
+ - demo/main.css
134
+ - demo/withIframe.html
114
135
  - lib/shutterbug.rb
115
136
  - lib/shutterbug/bug_file.rb
116
137
  - lib/shutterbug/configuration.rb
@@ -140,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
161
  version: '0'
141
162
  segments:
142
163
  - 0
143
- hash: -1955539956353293088
164
+ hash: -375693095855382946
144
165
  required_rubygems_version: !ruby/object:Gem::Requirement
145
166
  none: false
146
167
  requirements:
@@ -149,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
170
  version: '0'
150
171
  segments:
151
172
  - 0
152
- hash: -1955539956353293088
173
+ hash: -375693095855382946
153
174
  requirements: []
154
175
  rubyforge_project:
155
176
  rubygems_version: 1.8.23