letter_opener_web 1.2.1 → 1.2.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/app/assets/javascripts/letter_opener_web/application.js +9 -0
- data/app/controllers/letter_opener_web/letters_controller.rb +23 -8
- data/app/models/letter_opener_web/letter.rb +4 -0
- data/app/views/layouts/letter_opener_web/application.html.erb +1 -0
- data/lib/letter_opener_web/engine.rb +7 -1
- data/lib/letter_opener_web/version.rb +1 -1
- data/spec/controllers/letter_opener_web/letters_controller_spec.rb +19 -6
- data/vendor/assets/images/letter_opener_web/blue-dot.ico +0 -0
- data/vendor/assets/javascripts/letter_opener_web/favcount.js +102 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c6a68770b043595bf19b9615ae05ed7ebd136c29
|
|
4
|
+
data.tar.gz: 35cc68611bee3af314dec5272832a425576f3af9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ecc4124d756e3ce10db48afe67600d3ea7cea179f15acbb4b60033da481d43142c8edd5a21fec7faef1ea722bea198e80ff15361669fe6276be9a57ae8b38db
|
|
7
|
+
data.tar.gz: 4d0f62dc1159ec23afcb9803f965d363d0a310087df622d1b29e3863f0be2024869a4ff2d6b3b746698bc2f8ee01a66c5af418ab4a59f7e643eaa97d94f71a9b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [1.2.2](https://github.com/fgrehm/letter_opener_web/compare/v1.2.1...v1.2.2) (Jul 17, 2014)
|
|
2
|
+
|
|
3
|
+
- Precompile glyphicons [#30](https://github.com/fgrehm/letter_opener_web/pull/30)
|
|
4
|
+
- Display letters count on the favicon [#29](https://github.com/fgrehm/letter_opener_web/pull/29)
|
|
5
|
+
- Validate params passed in to the LettersController and return a 404 in case an email can't be found [#28](https://github.com/fgrehm/letter_opener_web/pull/28)
|
|
6
|
+
|
|
1
7
|
## [1.2.1](https://github.com/fgrehm/letter_opener_web/compare/v1.2.0...v1.2.1) (Apr 07, 2014)
|
|
2
8
|
|
|
3
9
|
- Improve Rails 3 compatibility [#26](https://github.com/fgrehm/letter_opener_web/pull/26) / [#27](https://github.com/fgrehm/letter_opener_web/pull/27)
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
//= require letter_opener_web/jquery-1.8.3.min
|
|
2
2
|
//= require letter_opener_web/jquery_ujs
|
|
3
|
+
//= require letter_opener_web/favcount
|
|
4
|
+
|
|
5
|
+
function update_favicon(favicon) {
|
|
6
|
+
favicon.set($('.letter-opener tbody tr').length);
|
|
7
|
+
}
|
|
3
8
|
|
|
4
9
|
jQuery(function($) {
|
|
10
|
+
var favicon = new Favcount($('link[rel="icon"]').attr('href'));
|
|
11
|
+
update_favicon(favicon);
|
|
12
|
+
|
|
5
13
|
$('.letter-opener').on('click', 'tr', function() {
|
|
6
14
|
var $this = $(this);
|
|
7
15
|
$('iframe').attr('src', $this.find('a').attr('href'));
|
|
@@ -16,6 +24,7 @@ jQuery(function($) {
|
|
|
16
24
|
table.find('tbody').empty().append('<tr><td colspan="2">Loading...</td></tr>');
|
|
17
25
|
table.load(table.data('letters-path') + ' .letter-opener', function() {
|
|
18
26
|
$('iframe').attr('src', $('.letter-opener tbody a:first-child()').attr('href'));
|
|
27
|
+
update_favicon(favicon);
|
|
19
28
|
});
|
|
20
29
|
});
|
|
21
30
|
});
|
|
@@ -2,23 +2,25 @@ require_dependency "letter_opener_web/application_controller"
|
|
|
2
2
|
|
|
3
3
|
module LetterOpenerWeb
|
|
4
4
|
class LettersController < ApplicationController
|
|
5
|
+
before_filter :check_style, :only => [:show]
|
|
6
|
+
before_filter :load_letter, :only => [:show, :attachment, :destroy]
|
|
7
|
+
|
|
5
8
|
def index
|
|
6
9
|
@letters = Letter.search
|
|
7
10
|
end
|
|
8
11
|
|
|
9
12
|
def show
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
gsub(/"
|
|
13
|
-
gsub(/"rich\.html"/, "\"#{LetterOpenerWeb.railtie_routes_url_helpers.letter_path(:id => letter.id, :style => 'rich')}\"")
|
|
13
|
+
text = @letter.send("#{params[:style]}_text").
|
|
14
|
+
gsub(/"plain\.html"/, "\"#{LetterOpenerWeb.railtie_routes_url_helpers.letter_path(:id => @letter.id, :style => 'plain')}\"").
|
|
15
|
+
gsub(/"rich\.html"/, "\"#{LetterOpenerWeb.railtie_routes_url_helpers.letter_path(:id => @letter.id, :style => 'rich')}\"")
|
|
14
16
|
render :text => text
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def attachment
|
|
18
|
-
letter
|
|
20
|
+
@letter = Letter.find(params[:id])
|
|
19
21
|
filename = "#{params[:file]}.#{params[:format]}"
|
|
20
22
|
|
|
21
|
-
if file = letter.attachments[filename]
|
|
23
|
+
if file = @letter.attachments[filename]
|
|
22
24
|
send_file(file, :filename => filename, :disposition => 'inline')
|
|
23
25
|
else
|
|
24
26
|
render :text => 'Attachment not found!', :status => 404
|
|
@@ -31,9 +33,22 @@ module LetterOpenerWeb
|
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def destroy
|
|
34
|
-
letter = Letter.find(params[:id])
|
|
35
|
-
letter.delete
|
|
36
|
+
@letter = Letter.find(params[:id])
|
|
37
|
+
@letter.delete
|
|
36
38
|
redirect_to LetterOpenerWeb.railtie_routes_url_helpers.letters_path
|
|
37
39
|
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def check_style
|
|
44
|
+
params[:style] = 'rich' unless ['plain', 'rich'].include? params[:style]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load_letter
|
|
48
|
+
if params[:id]
|
|
49
|
+
@letter = Letter.find(params[:id])
|
|
50
|
+
render :nothing => true, :status => 404 unless @letter.exists?
|
|
51
|
+
end
|
|
52
|
+
end
|
|
38
53
|
end
|
|
39
54
|
end
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<title>LetterOpenerWeb</title>
|
|
5
5
|
<%= stylesheet_link_tag "letter_opener_web/application", :media => "all" %>
|
|
6
6
|
<%= javascript_include_tag "letter_opener_web/application" %>
|
|
7
|
+
<%= favicon_link_tag asset_path("letter_opener_web/blue-dot.ico"), :rel => "icon" %>
|
|
7
8
|
<%= csrf_meta_tags %>
|
|
8
9
|
</head>
|
|
9
10
|
<body>
|
|
@@ -13,7 +13,13 @@ module LetterOpenerWeb
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
initializer "assets" do |app|
|
|
16
|
-
Rails.application.config.assets.precompile += %w(
|
|
16
|
+
Rails.application.config.assets.precompile += %w(
|
|
17
|
+
letter_opener_web/application.js
|
|
18
|
+
letter_opener_web/application.css
|
|
19
|
+
letter_opener_web/glyphicons-halflings.png
|
|
20
|
+
letter_opener_web/glyphicons-halflings-white.png
|
|
21
|
+
letter_opener_web/blue-dot.ico
|
|
22
|
+
)
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
end
|
|
@@ -18,12 +18,12 @@ describe LetterOpenerWeb::LettersController do
|
|
|
18
18
|
let(:plain_text) { "plain text href=\"rich.html\"" }
|
|
19
19
|
let(:letter) { double(:letter, :rich_text => rich_text, :plain_text => plain_text, :id => id) }
|
|
20
20
|
|
|
21
|
-
before do
|
|
22
|
-
allow(LetterOpenerWeb::Letter).to receive_messages(:find => letter)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
21
|
context 'rich text version' do
|
|
26
|
-
before
|
|
22
|
+
before do
|
|
23
|
+
allow(LetterOpenerWeb::Letter).to receive_messages(:find => letter)
|
|
24
|
+
allow(letter).to receive_messages(:exists? => true)
|
|
25
|
+
get :show, :id => id, :style => 'rich'
|
|
26
|
+
end
|
|
27
27
|
|
|
28
28
|
it "returns letter's rich text contents" do
|
|
29
29
|
expect(response.body).to match(/^rich text/)
|
|
@@ -36,7 +36,11 @@ describe LetterOpenerWeb::LettersController do
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
context 'plain text version' do
|
|
39
|
-
before
|
|
39
|
+
before do
|
|
40
|
+
allow(LetterOpenerWeb::Letter).to receive_messages(:find => letter)
|
|
41
|
+
allow(letter).to receive_messages(:exists? => true)
|
|
42
|
+
get :show, :id => id, :style => 'plain'
|
|
43
|
+
end
|
|
40
44
|
|
|
41
45
|
it "returns letter's plain text contents" do
|
|
42
46
|
expect(response.body).to match(/^plain text/)
|
|
@@ -47,6 +51,13 @@ describe LetterOpenerWeb::LettersController do
|
|
|
47
51
|
expect(response.body).to match(/href="#{Regexp.escape letter_path(:id => letter.id, :style => 'rich')}"/)
|
|
48
52
|
end
|
|
49
53
|
end
|
|
54
|
+
|
|
55
|
+
context 'with wrong parameters' do
|
|
56
|
+
it 'should return 404 when invalid id given' do
|
|
57
|
+
get :show, :id => id, :style => 'rich'
|
|
58
|
+
expect(response.status).to eq(404)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
50
61
|
end
|
|
51
62
|
|
|
52
63
|
describe 'GET attachment' do
|
|
@@ -58,6 +69,7 @@ describe LetterOpenerWeb::LettersController do
|
|
|
58
69
|
before do
|
|
59
70
|
allow(LetterOpenerWeb::Letter).to receive_messages(:find => letter)
|
|
60
71
|
allow(controller).to receive(:send_file) { controller.render :nothing => true }
|
|
72
|
+
allow(letter).to receive_messages(:exists? => true)
|
|
61
73
|
end
|
|
62
74
|
|
|
63
75
|
it 'sends the file as an inline attachment' do
|
|
@@ -87,6 +99,7 @@ describe LetterOpenerWeb::LettersController do
|
|
|
87
99
|
describe 'DELETE destroy' do
|
|
88
100
|
let(:id) { 'an-id' }
|
|
89
101
|
it 'removes the selected letter' do
|
|
102
|
+
allow_any_instance_of(LetterOpenerWeb::Letter).to receive(:exists?).and_return(true)
|
|
90
103
|
expect_any_instance_of(LetterOpenerWeb::Letter).to receive(:delete)
|
|
91
104
|
delete :destroy, :id => id, :use_route => :letter_opener_web
|
|
92
105
|
end
|
|
Binary file
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* favcount.js v1.5.0
|
|
3
|
+
* http://chrishunt.co/favcount
|
|
4
|
+
* Dynamically updates the favicon with a number.
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2013, Chris Hunt
|
|
7
|
+
* Released under the MIT license
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
(function(){
|
|
11
|
+
function Favcount(icon) {
|
|
12
|
+
this.icon = icon;
|
|
13
|
+
this.opacity = 0.4;
|
|
14
|
+
this.canvas = document.createElement('canvas');
|
|
15
|
+
this.font = "Helvetica, Arial, sans-serif";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Favcount.prototype.set = function(count) {
|
|
19
|
+
var self = this,
|
|
20
|
+
img = document.createElement('img');
|
|
21
|
+
|
|
22
|
+
if (self.canvas.getContext) {
|
|
23
|
+
img.crossOrigin = "anonymous";
|
|
24
|
+
|
|
25
|
+
img.onload = function() {
|
|
26
|
+
drawCanvas(self.canvas, self.opacity, self.font, img, normalize(count));
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
img.src = this.icon;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function normalize(count) {
|
|
34
|
+
count = Math.round(count);
|
|
35
|
+
|
|
36
|
+
if (isNaN(count) || count < 1) {
|
|
37
|
+
return '';
|
|
38
|
+
} else if (count < 10) {
|
|
39
|
+
return ' ' + count;
|
|
40
|
+
} else if (count > 99) {
|
|
41
|
+
return '99';
|
|
42
|
+
} else {
|
|
43
|
+
return count;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function drawCanvas(canvas, opacity, font, img, count) {
|
|
48
|
+
var head = document.getElementsByTagName('head')[0],
|
|
49
|
+
favicon = document.createElement('link'),
|
|
50
|
+
multiplier, fontSize, context, xOffset, yOffset, border, shadow;
|
|
51
|
+
|
|
52
|
+
favicon.rel = 'icon';
|
|
53
|
+
|
|
54
|
+
// Scale canvas elements based on favicon size
|
|
55
|
+
multiplier = img.width / 16;
|
|
56
|
+
fontSize = multiplier * 11;
|
|
57
|
+
xOffset = multiplier;
|
|
58
|
+
yOffset = multiplier * 11;
|
|
59
|
+
border = multiplier;
|
|
60
|
+
shadow = multiplier * 2;
|
|
61
|
+
|
|
62
|
+
canvas.height = canvas.width = img.width;
|
|
63
|
+
context = canvas.getContext('2d');
|
|
64
|
+
context.font = 'bold ' + fontSize + 'px ' + font;
|
|
65
|
+
|
|
66
|
+
// Draw faded favicon background
|
|
67
|
+
if (count) { context.globalAlpha = opacity; }
|
|
68
|
+
context.drawImage(img, 0, 0);
|
|
69
|
+
context.globalAlpha = 1.0;
|
|
70
|
+
|
|
71
|
+
// Draw white drop shadow
|
|
72
|
+
context.shadowColor = '#FFF';
|
|
73
|
+
context.shadowBlur = shadow;
|
|
74
|
+
context.shadowOffsetX = 0;
|
|
75
|
+
context.shadowOffsetY = 0;
|
|
76
|
+
|
|
77
|
+
// Draw white border
|
|
78
|
+
context.fillStyle = '#FFF';
|
|
79
|
+
context.fillText(count, xOffset, yOffset);
|
|
80
|
+
context.fillText(count, xOffset + border, yOffset);
|
|
81
|
+
context.fillText(count, xOffset, yOffset + border);
|
|
82
|
+
context.fillText(count, xOffset + border, yOffset + border);
|
|
83
|
+
|
|
84
|
+
// Draw black count
|
|
85
|
+
context.fillStyle = '#000';
|
|
86
|
+
context.fillText(count,
|
|
87
|
+
xOffset + (border / 2.0),
|
|
88
|
+
yOffset + (border / 2.0)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Replace favicon with new favicon
|
|
92
|
+
favicon.href = canvas.toDataURL('image/png');
|
|
93
|
+
head.removeChild(document.querySelector('link[rel=icon]'));
|
|
94
|
+
head.appendChild(favicon);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.Favcount = Favcount;
|
|
98
|
+
}).call(this);
|
|
99
|
+
|
|
100
|
+
(function(){
|
|
101
|
+
Favcount.VERSION = '1.5.0';
|
|
102
|
+
}).call(this);
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: letter_opener_web
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fabio Rehm
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -120,9 +120,11 @@ files:
|
|
|
120
120
|
- spec/internal/public/favicon.ico
|
|
121
121
|
- spec/models/letter_opener_web/letter_spec.rb
|
|
122
122
|
- spec/spec_helper.rb
|
|
123
|
+
- vendor/assets/images/letter_opener_web/blue-dot.ico
|
|
123
124
|
- vendor/assets/images/letter_opener_web/glyphicons-halflings-white.png
|
|
124
125
|
- vendor/assets/images/letter_opener_web/glyphicons-halflings.png
|
|
125
126
|
- vendor/assets/javascripts/letter_opener_web/bootstrap.min.js
|
|
127
|
+
- vendor/assets/javascripts/letter_opener_web/favcount.js
|
|
126
128
|
- vendor/assets/javascripts/letter_opener_web/jquery-1.8.3.min.js
|
|
127
129
|
- vendor/assets/javascripts/letter_opener_web/jquery_ujs.js
|
|
128
130
|
- vendor/assets/stylesheets/letter_opener_web/bootstrap.min.css
|