shutterbug 0.2.1 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +28 -1
- data/bower.json +1 -1
- data/config.ru +1 -1
- data/lib/shutterbug.rb +1 -1
- data/lib/shutterbug/handlers/shutterbug.js +64 -11
- data/lib/shutterbug/phantom_job.rb +2 -2
- data/shutterbug.gemspec +1 -1
- metadata +9 -35
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjVmZDdiYjY0NmUzYzc1YzNlN2QwMGI5MmEwOTk1MzNjNWZkNjM2NA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2I1N2ZlYzM5ZjAzOGNkMTA2ZGY4ZTE0N2VlYTQ3NmUyNjUzMzk5MQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MmNjZWJlMmI1ZTI1OWJkMzc5MWVhZjhiZWQxYTk0MjNlMTIzNWMzYjk5YzI2
|
10
|
+
ZDdkOTExNmQ0NzBkYzFkN2UxOWY4MTAxNTJmMjY3YTc0OWZkNGUzOWYwMDY5
|
11
|
+
NTY5Zjc4YmUzNTEzZjllZmE2NDE1YTFmZjllNTllMTc0YmYzY2I=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
M2E0OTFkZTlkN2ZmNmU1NjdiZjlmYzY5ZjE4YmI0NjRmYzQ2ZDU4MjgyMWQ4
|
14
|
+
ZDhjY2QzNmMxNjM0YjVjMzc1M2MzMWYzNDA1NjUwODdhZGQyNGE2NzM4YTg5
|
15
|
+
YmZkZmI3MWQwYTQyODgxOTYyNmRiMGU5Yzc0YTVjNTQwYTMzMTQ=
|
data/README.md
CHANGED
@@ -6,6 +6,22 @@
|
|
6
6
|
|
7
7
|
## Overview ##
|
8
8
|
|
9
|
+
Shutterbug has two parts: a browser javascript library for taking html snapshots, and a server side utility for turning those html snapshots into images.
|
10
|
+
|
11
|
+
### Browser Javascript library
|
12
|
+
|
13
|
+
By itself `shutterbug.js` is useful for authors of iframe'able content. With `shutterbug.js` on the iframe'd page, the parent window can request an html snapshot even if the iframe'd page is on a different domain. To enable this functionality you need to add the following lines to your iframe'able page:
|
14
|
+
|
15
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
|
16
|
+
<script src="shutterbug.js"></script>
|
17
|
+
<script>new Shutterbug('body');</script>
|
18
|
+
|
19
|
+
The `shutterbug.js` file is located in this repository: `lib/shutterbug/handlers/shutterbug.js`
|
20
|
+
|
21
|
+
`shutterbug.js` also includes the API to talk to the server side utility to generate a image of the html snapshot. See the [Usage section](#usage) below for information.
|
22
|
+
|
23
|
+
### Server Side Utility
|
24
|
+
|
9
25
|
A rack utility using phantomjs 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 sample config.ru file:
|
10
26
|
|
11
27
|
|
@@ -69,6 +85,12 @@ This will replace the contents of `$("#outselector")` with an `<img src="http://
|
|
69
85
|
|
70
86
|
## Advanced usage
|
71
87
|
|
88
|
+
You can specify a failure callback on your shutterbug object. This callback will be invoked when the server response was not 200:
|
89
|
+
|
90
|
+
var shutterbug = new Shutterbug('#sourceselector', '#outselector',optCallbackFn, optIdentifier);
|
91
|
+
shutterbug.setFailureCallback(function(jqXHR, textStatus, errorThrown) {
|
92
|
+
alert("Something went wrong: " + textStatus);
|
93
|
+
});
|
72
94
|
|
73
95
|
### IFrame support
|
74
96
|
|
@@ -129,7 +151,7 @@ Your app should have a config.ru that looks something like this:
|
|
129
151
|
use Rack::Cors do
|
130
152
|
allow do
|
131
153
|
origins '*'
|
132
|
-
resource '/shutterbug/*', :headers => :any, :methods => :
|
154
|
+
resource '/shutterbug/*'', :headers => :any, :methods => [:get, :post, :options]
|
133
155
|
end
|
134
156
|
end
|
135
157
|
|
@@ -155,6 +177,11 @@ And a Procfile which looks like this:
|
|
155
177
|
|
156
178
|
web: bundle exec rackup config.ru -p $PORT
|
157
179
|
|
180
|
+
## Changes ##
|
181
|
+
|
182
|
+
* November 12, 2014 – v 0.2.5
|
183
|
+
* Added setFailureCallback to shutterbug.js for gracefully handling ajax failures in some custom way.
|
184
|
+
* Updated CORS configuration in config.ru to allow [:options] requests.
|
158
185
|
|
159
186
|
|
160
187
|
## TODO: ##
|
data/bower.json
CHANGED
data/config.ru
CHANGED
data/lib/shutterbug.rb
CHANGED
@@ -9,6 +9,11 @@
|
|
9
9
|
return base;
|
10
10
|
};
|
11
11
|
|
12
|
+
var _useIframeSizeHack = false;
|
13
|
+
var useIframeSizeHack = function(b) {
|
14
|
+
_useIframeSizeHack = b;
|
15
|
+
};
|
16
|
+
|
12
17
|
var cloneDomItem = function(elem, elemTag) {
|
13
18
|
var width = elem.width();
|
14
19
|
var height = elem.height();
|
@@ -22,18 +27,17 @@
|
|
22
27
|
return returnElm;
|
23
28
|
};
|
24
29
|
|
25
|
-
var
|
26
|
-
return "
|
27
|
-
"<!DOCTYPE html>" +
|
30
|
+
var generateFullHtmlFromFragment = function (fragment) {
|
31
|
+
return "<!DOCTYPE html>" +
|
28
32
|
"<html>" +
|
29
33
|
"<head>" +
|
30
|
-
"<base href='" +
|
34
|
+
"<base href='" + fragment.base_url + "'>" +
|
31
35
|
"<meta content='text/html;charset=utf-8' http-equiv='Content-Type'>" +
|
32
|
-
"<title>content from " +
|
33
|
-
|
36
|
+
"<title>content from " + fragment.base_url + "</title>" +
|
37
|
+
fragment.css +
|
34
38
|
"</head>" +
|
35
39
|
"<body>" +
|
36
|
-
|
40
|
+
fragment.content +
|
37
41
|
"</body>" +
|
38
42
|
"</html>";
|
39
43
|
};
|
@@ -80,6 +84,10 @@
|
|
80
84
|
var height = $element.height();
|
81
85
|
var element = $element.clone();
|
82
86
|
|
87
|
+
// remove all script elements from the clone we don't want the html fragement
|
88
|
+
// changing itself
|
89
|
+
element.find("script").remove();
|
90
|
+
|
83
91
|
if (arguments.length > 0) {
|
84
92
|
var nestedIFrames = arguments;
|
85
93
|
// This supports two cases:
|
@@ -89,7 +97,7 @@
|
|
89
97
|
// When iframe doesn't support Shutterbug, request will timeout and null will be received.
|
90
98
|
// In such case just ignore this iframe, we won't be able to render it.
|
91
99
|
if (nestedIFrames[i] == null) return;
|
92
|
-
$(iframeElem).attr("src",
|
100
|
+
$(iframeElem).attr("src", "data:text/html," + generateFullHtmlFromFragment(nestedIFrames[i]));
|
93
101
|
});
|
94
102
|
}
|
95
103
|
|
@@ -106,7 +114,7 @@
|
|
106
114
|
$(elm).replaceWith(replacementImgs[i]);
|
107
115
|
backgroundDiv.insertBefore($(elm));
|
108
116
|
});
|
109
|
-
|
117
|
+
|
110
118
|
element.css({
|
111
119
|
'top':0,
|
112
120
|
'left':0,
|
@@ -115,6 +123,12 @@
|
|
115
123
|
'height':height
|
116
124
|
});
|
117
125
|
|
126
|
+
// Due to a weird layout bug in PhantomJS, inner iframes sometimes don't render
|
127
|
+
// unless we set the width small. This doesn't affect the actual output at all.
|
128
|
+
if (_useIframeSizeHack) {
|
129
|
+
width = 10;
|
130
|
+
}
|
131
|
+
|
118
132
|
var html_content = {
|
119
133
|
content: $('<div>').append(element).html(),
|
120
134
|
css: css,
|
@@ -154,8 +168,11 @@
|
|
154
168
|
self.callback(msg);
|
155
169
|
}
|
156
170
|
clearInterval(timer);
|
157
|
-
}).fail(function(
|
171
|
+
}).fail(function(jqXHR, textStatus, errorThrown) {
|
158
172
|
$(self.imgDst).html("snapshot failed");
|
173
|
+
if (self.failCallback) {
|
174
|
+
self.failCallback(jqXHR, textStatus, errorThrown);
|
175
|
+
}
|
159
176
|
clearInterval(timer);
|
160
177
|
});
|
161
178
|
});
|
@@ -170,6 +187,38 @@
|
|
170
187
|
destination.postMessage(JSON.stringify(message), "*");
|
171
188
|
};
|
172
189
|
|
190
|
+
var htmlSnap = function() {
|
191
|
+
this.getHtmlFragment(function callback(fragment){
|
192
|
+
// FIXME btoa is not intended to encode text it is for for 8bit per char strings
|
193
|
+
// so if you send it a UTF8 string with a special char in it, it will fail
|
194
|
+
// this SO has a note about handling this:
|
195
|
+
// http://stackoverflow.com/questions/246801/how-can-you-encode-a-string-to-base64-in-javascript
|
196
|
+
// also note that btoa is only available in IE10+
|
197
|
+
var encodedContent = btoa(generateFullHtmlFromFragment(fragment));
|
198
|
+
window.open("data:text/html;base64," + encodedContent);
|
199
|
+
});
|
200
|
+
};
|
201
|
+
|
202
|
+
var imageSnap = function() {
|
203
|
+
var oldImgDst = this.imgDst,
|
204
|
+
oldCallback = this.callback,
|
205
|
+
self = this;
|
206
|
+
this.imgDst = null;
|
207
|
+
this.callback = function (msg){
|
208
|
+
// extract the url out of the returned html fragment
|
209
|
+
var imgUrl = msg.match(/src='([^']*)'/)[1]
|
210
|
+
window.open(imgUrl);
|
211
|
+
self.imgDst = oldImgDst;
|
212
|
+
self.callback = oldCallback;
|
213
|
+
}
|
214
|
+
this.getDomSnapshot();
|
215
|
+
};
|
216
|
+
|
217
|
+
var setFailureCallback = function(failCallback) {
|
218
|
+
this.failCallback = failCallback;
|
219
|
+
};
|
220
|
+
|
221
|
+
// TODO: Construct using opts instead of positional arguments.
|
173
222
|
window.Shutterbug = function(selector, imgDst, callback, id, jQuery) {
|
174
223
|
if (typeof(jQuery) != "undefined" && jQuery != null) {
|
175
224
|
$ = jQuery;
|
@@ -188,7 +237,11 @@
|
|
188
237
|
getDomSnapshot: getDomSnapshot,
|
189
238
|
getHtmlFragment: getHtmlFragment,
|
190
239
|
requestHtmlFrag: requestHtmlFrag,
|
191
|
-
|
240
|
+
htmlSnap: htmlSnap,
|
241
|
+
imageSnap: imageSnap,
|
242
|
+
useIframeSizeHack: useIframeSizeHack,
|
243
|
+
iframeReqTimeout: MAX_TIMEOUT,
|
244
|
+
setFailureCallback: setFailureCallback
|
192
245
|
};
|
193
246
|
|
194
247
|
var handleMessage = function(message, signature, func) {
|
@@ -60,7 +60,7 @@ module Shutterbug
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def rasterize_cl
|
63
|
-
%x[#{self.program} #{self.rasterize_js} #{self.input_path} #{self.output_path} #{@width}*#{@height}]
|
63
|
+
%x[#{self.program} --ignore-ssl-errors=true --ssl-protocol=any #{self.rasterize_js} #{self.input_path} #{self.output_path} #{@width}*#{@height}]
|
64
64
|
end
|
65
65
|
|
66
66
|
def rasterize
|
@@ -72,4 +72,4 @@ module Shutterbug
|
|
72
72
|
self.html_file = @config.storage.new(html_file_name, Shutterbug::Handlers::FileHandlers::HtmlFile.new)
|
73
73
|
end
|
74
74
|
end
|
75
|
-
end
|
75
|
+
end
|
data/shutterbug.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_development_dependency "bundler", "~> 1.3"
|
29
29
|
spec.add_development_dependency "rake"
|
30
|
-
spec.add_development_dependency "rspec"
|
30
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
31
31
|
spec.add_development_dependency "guard-rspec"
|
32
32
|
spec.add_development_dependency "rack-cors"
|
33
33
|
spec.add_development_dependency "guard-rack"
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shutterbug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.5
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Noah Paessel
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-11-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
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: :development
|
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: rake
|
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: :development
|
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,23 +41,20 @@ 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
|
53
|
-
version: '
|
47
|
+
version: '2.14'
|
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
|
-
version: '
|
54
|
+
version: '2.14'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: guard-rspec
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ! '>='
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ! '>='
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rack-cors
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ! '>='
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ! '>='
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,7 +83,6 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: guard-rack
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ! '>='
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ! '>='
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,7 +97,6 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rack-test
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ! '>='
|
116
102
|
- !ruby/object:Gem::Version
|
@@ -118,7 +104,6 @@ dependencies:
|
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ! '>='
|
124
109
|
- !ruby/object:Gem::Version
|
@@ -126,7 +111,6 @@ dependencies:
|
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: rack
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ! '>='
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :runtime
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ! '>='
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,7 +125,6 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: fog
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ! '>='
|
148
130
|
- !ruby/object:Gem::Version
|
@@ -150,7 +132,6 @@ dependencies:
|
|
150
132
|
type: :runtime
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ! '>='
|
156
137
|
- !ruby/object:Gem::Version
|
@@ -227,33 +208,26 @@ files:
|
|
227
208
|
homepage: http://github.com/concord-consortium/shutterbug
|
228
209
|
licenses:
|
229
210
|
- MIT, Simplified BSD, Apache 2.0
|
211
|
+
metadata: {}
|
230
212
|
post_install_message:
|
231
213
|
rdoc_options: []
|
232
214
|
require_paths:
|
233
215
|
- lib
|
234
216
|
required_ruby_version: !ruby/object:Gem::Requirement
|
235
|
-
none: false
|
236
217
|
requirements:
|
237
218
|
- - ! '>='
|
238
219
|
- !ruby/object:Gem::Version
|
239
220
|
version: '0'
|
240
|
-
segments:
|
241
|
-
- 0
|
242
|
-
hash: 4021893285741860284
|
243
221
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
244
|
-
none: false
|
245
222
|
requirements:
|
246
223
|
- - ! '>='
|
247
224
|
- !ruby/object:Gem::Version
|
248
225
|
version: '0'
|
249
|
-
segments:
|
250
|
-
- 0
|
251
|
-
hash: 4021893285741860284
|
252
226
|
requirements: []
|
253
227
|
rubyforge_project:
|
254
|
-
rubygems_version:
|
228
|
+
rubygems_version: 2.2.2
|
255
229
|
signing_key:
|
256
|
-
specification_version:
|
230
|
+
specification_version: 4
|
257
231
|
summary: use Shutterbug::Rackapp
|
258
232
|
test_files:
|
259
233
|
- spec/shared_examples_for_file_handlers.rb
|