mailcatcher-jruby 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee3b2fdd291a0f4ef4bf0a7d223577cab7f90f2d
4
- data.tar.gz: 22679dba081b3b6b08b7d03633634514067edc3e
3
+ metadata.gz: 3a72fd5a007a8e9c3276fd4ff1652fa93eb97143
4
+ data.tar.gz: 76a8694e4e0681844e3a9010bfd18acd8be85cd8
5
5
  SHA512:
6
- metadata.gz: a59ff3bc7c83df67c3c4b74545fb0724ecdcf4f1e2701ea48337b5e15582e2aa8e5989a0a7761b0b782e1e4639cb2ba5c21ffc66bd9c1ec7baf9b6581d0b895a
7
- data.tar.gz: 56340005b69b5893f443c550fe064873ad55c97625dc1bba6b1f9a93f5ac114053696cd4a2afbc35f9d336ec9376571315c238bf67673641ceeb1cd4cc3c46a6
6
+ metadata.gz: 57135e3a78f6d5fdac9879f33d78e531a50ea5a7a4cacbf8066ac236f7181d8e3a6161c4eac47575a7d4cda2cd323c33fa42274767c2250966d953adfc891328
7
+ data.tar.gz: 2d9be09f25b921138e64036a53a9b5b275a17b9b83371d989f17509eb37af1512929841444601a34ee926f920fb9159f80cd5d9586d78633a77ff301ddba1671
data/README.md CHANGED
@@ -2,26 +2,35 @@
2
2
 
3
3
  ## Usage for JRuby on Rails.
4
4
 
5
- 1. `gem install mailcatcher-jruby`
5
+ 1. Install
6
+ ```
7
+ gem install mailcatcher-jruby
8
+ ```
6
9
 
7
10
  2. Start the smpt server at port 9000
8
- `mailcatcher`
9
11
 
10
- use `--smtp-port 1080` to change the port to 1080
12
+ ```
13
+ mailcatcher
14
+ ```
15
+
16
+ use `--smtp-port 1080` to change the port to 1080
11
17
 
12
18
  3. Start Puma rack server to host web pages of emails at port 9090.
13
- `mailweb`
14
- add `-p 1080` to use port 1080
19
+ ```
20
+ mailweb
21
+ ```
22
+ add `-p 1080` to use port 1080
15
23
 
16
- Open [http://127.0.0.1:9090](http://127.0.0.1:9090) to see emails.
24
+ Open [http://127.0.0.1:9090](http://127.0.0.1:9090) to see emails.
17
25
 
18
26
 
19
27
  4. Configure rails.
20
- To set up your rails app, I recommend adding this to your `environment/development.rb`:
21
-
28
+ To set up your rails app, I recommend adding this to your `environment/development.rb`:
29
+ ```
22
30
  config.action_mailer.delivery_method = :smtp
23
31
  config.action_mailer.smtp_settings = { :address => "127.0.0.1", :port =>
24
32
  9000 }
33
+ ```
25
34
 
26
35
 
27
36
  # Original Documentation
File without changes
File without changes
File without changes
@@ -0,0 +1,7 @@
1
+ require 'sinatra/base'
2
+
3
+ $LOAD_PATH.unshift '.', 'lib'
4
+
5
+ require_relative 'lib/mail_catcher'
6
+
7
+ run MailCatcher::Web
@@ -1,3 +1,3 @@
1
1
  module MailCatcher
2
- VERSION = "1.1.1"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -2,6 +2,7 @@ require 'sinatra'
2
2
  require 'pathname'
3
3
  require 'net/http'
4
4
  require 'uri'
5
+ require 'haml'
5
6
  #require 'skinny'
6
7
 
7
8
 
@@ -1,452 +1,441 @@
1
- (function() {
2
- var MailCatcher,
3
- _this = this;
4
-
5
- jQuery.expr[':'].icontains = function(a, i, m) {
6
- var _ref, _ref1;
7
- return ((_ref = (_ref1 = a.textContent) != null ? _ref1 : a.innerText) != null ? _ref : "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
8
- };
9
-
10
- MailCatcher = (function() {
11
-
12
- function MailCatcher() {
13
- var _this = this;
14
- this.nextTab = function(tab) {
15
- return MailCatcher.prototype.nextTab.apply(_this, arguments);
16
- };
17
- this.previousTab = function(tab) {
18
- return MailCatcher.prototype.previousTab.apply(_this, arguments);
19
- };
20
- this.openTab = function(i) {
21
- return MailCatcher.prototype.openTab.apply(_this, arguments);
22
- };
23
- this.selectedTab = function() {
24
- return MailCatcher.prototype.selectedTab.apply(_this, arguments);
25
- };
26
- this.getTab = function(i) {
27
- return MailCatcher.prototype.getTab.apply(_this, arguments);
28
- };
29
- $('#messages tr').live('click', function(e) {
30
- e.preventDefault();
31
- return _this.loadMessage($(e.currentTarget).attr('data-message-id'));
32
- });
33
- $('input[name=search]').keyup(function(e) {
34
- var query;
35
- query = $.trim($(e.currentTarget).val());
36
- if (query) {
37
- return _this.searchMessages(query);
38
- } else {
39
- return _this.clearSearch();
40
- }
41
- });
42
- $('#message .views .format.tab a').live('click', function(e) {
43
- e.preventDefault();
44
- return _this.loadMessageBody(_this.selectedMessage(), $($(e.currentTarget).parent('li')).data('message-format'));
45
- });
46
- $('#message .views .analysis.tab a').live('click', function(e) {
47
- e.preventDefault();
48
- return _this.loadMessageAnalysis(_this.selectedMessage());
49
- });
50
- $('#message iframe').load(function() {
51
- return _this.decorateMessageBody();
52
- });
53
- $('#resizer').live({
54
- mousedown: function(e) {
55
- var events;
56
- e.preventDefault();
57
- return $(window).bind(events = {
58
- mouseup: function(e) {
59
- e.preventDefault();
60
- return $(window).unbind(events);
61
- },
62
- mousemove: function(e) {
63
- e.preventDefault();
64
- return _this.resizeTo(e.clientY);
65
- }
66
- });
67
- }
68
- });
69
- this.resizeToSaved();
70
- $('nav.app .clear a').live('click', function(e) {
71
- e.preventDefault();
72
- if (confirm("You will lose all your received messages.\n\nAre you sure you want to clear all messages?")) {
73
- return $.ajax({
74
- url: '/messages',
75
- type: 'DELETE',
76
- success: function() {
77
- return _this.unselectMessage();
78
- },
79
- error: function() {
80
- return alert('Error while clearing all messages.');
81
- }
82
- });
83
- }
84
- });
85
- $('nav.app .quit a').live('click', function(e) {
86
- e.preventDefault();
87
- if (confirm("You will lose all your received messages.\n\nAre you sure you want to quit?")) {
88
- return $.ajax({
89
- type: 'DELETE',
90
- success: function() {
91
- return location.replace($('body > header h1 a').attr('href'));
92
- },
93
- error: function() {
94
- return alert('Error while quitting.');
95
- }
96
- });
97
- }
98
- });
99
- key('up', function() {
100
- if (_this.selectedMessage()) {
101
- _this.loadMessage($('#messages tr.selected').prev().data('message-id'));
102
- } else {
103
- _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
104
- }
105
- return false;
106
- });
107
- key('down', function() {
108
- if (_this.selectedMessage()) {
109
- _this.loadMessage($('#messages tr.selected').next().data('message-id'));
110
- } else {
111
- _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
112
- }
113
- return false;
114
- });
115
- key('⌘+up, ctrl+up', function() {
116
- _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
117
- return false;
118
- });
119
- key('⌘+down, ctrl+down', function() {
120
- _this.loadMessage($('#messages tbody tr[data-message-id]:last').data('message-id'));
121
- return false;
122
- });
123
- key('left', function() {
124
- _this.openTab(_this.previousTab());
125
- return false;
126
- });
127
- key('right', function() {
128
- _this.openTab(_this.nextTab());
129
- return false;
130
- });
131
- key('backspace, delete', function() {
132
- var id;
133
- id = _this.selectedMessage();
134
- if (id != null) {
135
- $.ajax({
136
- url: '/messages/' + id,
137
- type: 'DELETE',
138
- success: function() {
139
- var messageRow, switchTo;
140
- messageRow = $("#messages tbody tr[data-message-id='" + id + "']");
141
- switchTo = messageRow.next().data('message-id') || messageRow.prev().data('message-id');
142
- messageRow.remove();
143
- if (switchTo) {
144
- return _this.loadMessage(switchTo);
145
- } else {
146
- return _this.unselectMessage();
147
- }
148
- },
149
- error: function() {
150
- return alert('Error while removing message.');
151
- }
152
- });
153
- }
154
- return false;
155
- });
156
- this.refresh();
157
- this.subscribe();
158
- }
159
-
160
- MailCatcher.prototype.parseDateRegexp = /^(\d{4})[-\/\\](\d{2})[-\/\\](\d{2})(?:\s+|T)(\d{2})[:-](\d{2})[:-](\d{2})(?:([ +-]\d{2}:\d{2}|\s*\S+|Z?))?$/;
161
-
162
- MailCatcher.prototype.parseDate = function(date) {
163
- var match;
164
- if (match = this.parseDateRegexp.exec(date)) {
165
- return new Date(match[1], match[2] - 1, match[3], match[4], match[5], match[6], 0);
166
- }
167
- };
168
-
169
- MailCatcher.prototype.offsetTimeZone = function(date) {
170
- var offset;
171
- offset = Date.now().getTimezoneOffset() * 60000;
172
- date.setTime(date.getTime() - offset);
173
- return date;
174
- };
175
-
176
- MailCatcher.prototype.formatDate = function(date) {
177
- if (typeof date === "string") {
178
- date && (date = this.parseDate(date));
179
- }
180
- date && (date = this.offsetTimeZone(date));
181
- return date && (date = date.toString("dddd, d MMM yyyy h:mm:ss tt"));
182
- };
183
-
184
- MailCatcher.prototype.messagesCount = function() {
185
- return $('#messages tr').length - 1;
186
- };
187
-
188
- MailCatcher.prototype.tabs = function() {
189
- return $('#message ul').children('.tab');
190
- };
191
-
192
- MailCatcher.prototype.getTab = function(i) {
193
- return $(this.tabs()[i]);
194
- };
195
-
196
- MailCatcher.prototype.selectedTab = function() {
197
- return this.tabs().index($('#message li.tab.selected'));
198
- };
199
-
200
- MailCatcher.prototype.openTab = function(i) {
201
- return this.getTab(i).children('a').click();
202
- };
203
-
204
- MailCatcher.prototype.previousTab = function(tab) {
205
- var i;
206
- i = tab || tab === 0 ? tab : this.selectedTab() - 1;
207
- if (i < 0) {
208
- i = this.tabs().length - 1;
209
- }
210
- if (this.getTab(i).is(":visible")) {
211
- return i;
212
- } else {
213
- return this.previousTab(i - 1);
214
- }
215
- };
216
-
217
- MailCatcher.prototype.nextTab = function(tab) {
218
- var i;
219
- i = tab ? tab : this.selectedTab() + 1;
220
- if (i > this.tabs().length - 1) {
221
- i = 0;
222
- }
223
- if (this.getTab(i).is(":visible")) {
224
- return i;
225
- } else {
226
- return this.nextTab(i + 1);
227
- }
228
- };
229
-
230
- MailCatcher.prototype.haveMessage = function(message) {
231
- if (message.id != null) {
232
- message = message.id;
233
- }
234
- return $("#messages tbody tr[data-message-id=\"" + message + "\"]").length > 0;
235
- };
236
-
237
- MailCatcher.prototype.selectedMessage = function() {
238
- return $('#messages tr.selected').data('message-id');
239
- };
240
-
241
- MailCatcher.prototype.searchMessages = function(query) {
242
- var $rows, selector, token;
243
- selector = ((function() {
244
- var _i, _len, _ref, _results;
245
- _ref = query.split(/\s+/);
246
- _results = [];
247
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
248
- token = _ref[_i];
249
- _results.push(":icontains('" + token + "')");
250
- }
251
- return _results;
252
- })()).join("");
253
- $rows = $("#messages tbody tr");
254
- $rows.not(selector).hide();
255
- return $rows.filter(selector).show();
256
- };
257
-
258
- MailCatcher.prototype.clearSearch = function() {
259
- return $('#messages tbody tr').show();
260
- };
261
-
262
- MailCatcher.prototype.addMessage = function(message) {
263
- return $('#messages tbody').prepend($('<tr />').attr('data-message-id', message.id.toString()).append($('<td/>').text(message.sender || "No sender").toggleClass("blank", !message.sender)).append($('<td/>').text((message.recipients || []).join(', ') || "No recipients").toggleClass("blank", !message.recipients.length)).append($('<td/>').text(message.subject || "No subject").toggleClass("blank", !message.subject)).append($('<td/>').text(this.formatDate(message.created_at))));
264
- };
265
-
266
- MailCatcher.prototype.scrollToRow = function(row) {
267
- var overflow, relativePosition;
268
- relativePosition = row.offset().top - $('#messages').offset().top;
269
- if (relativePosition < 0) {
270
- return $('#messages').scrollTop($('#messages').scrollTop() + relativePosition - 20);
271
- } else {
272
- overflow = relativePosition + row.height() - $('#messages').height();
273
- if (overflow > 0) {
274
- return $('#messages').scrollTop($('#messages').scrollTop() + overflow + 20);
275
- }
276
- }
277
- };
278
-
279
- MailCatcher.prototype.unselectMessage = function() {
280
- $('#messages tbody, #message .metadata dd').empty();
281
- $('#message .metadata .attachments').hide();
282
- $('#message iframe').attr('src', 'about:blank');
283
- return null;
284
- };
285
-
286
- MailCatcher.prototype.loadMessage = function(id) {
287
- var messageRow,
288
- _this = this;
289
- if ((id != null ? id.id : void 0) != null) {
290
- id = id.id;
291
- }
292
- id || (id = $('#messages tr.selected').attr('data-message-id'));
293
- if (id != null) {
294
- $("#messages tbody tr:not([data-message-id='" + id + "'])").removeClass('selected');
295
- messageRow = $("#messages tbody tr[data-message-id='" + id + "']");
296
- messageRow.addClass('selected');
297
- this.scrollToRow(messageRow);
298
- return $.getJSON("/messages/" + id + ".json", function(message) {
299
- var $ul;
300
- if (message.recipients != null) {
301
- message.recipients = JSON.parse(message.recipients);
302
- }
303
- $('#message .metadata dd.created_at').text(_this.formatDate(message.created_at));
304
- $('#message .metadata dd.from').text(message.sender);
305
- $('#message .metadata dd.to').text((message.recipients || []).join(', '));
306
- $('#message .metadata dd.subject').text(message.subject);
307
- $('#message .views .tab.format').each(function(i, el) {
308
- var $el, format;
309
- $el = $(el);
310
- format = $el.attr('data-message-format');
311
- if ($.inArray(format, message.formats) >= 0) {
312
- $el.find('a').attr('href', "/messages/" + id + "." + format);
313
- return $el.show();
314
- } else {
315
- return $el.hide();
316
- }
317
- });
318
- if ($("#message .views .tab.selected:not(:visible)").length) {
319
- $("#message .views .tab.selected").removeClass("selected");
320
- $("#message .views .tab:visible:first").addClass("selected");
321
- }
322
- if (message.attachments.length) {
323
- $ul = $('<ul/>').appendTo($('#message .metadata dd.attachments').empty());
324
- $.each(message.attachments, function(i, attachment) {
325
- return $ul.append($('<li>').append($('<a>').attr('href', attachment['href']).addClass(attachment['type'].split('/', 1)[0]).addClass(attachment['type'].replace('/', '-')).text(attachment['filename'])));
326
- });
327
- $('#message .metadata .attachments').show();
328
- } else {
329
- $('#message .metadata .attachments').hide();
330
- }
331
- $('#message .views .download a').attr('href', "/messages/" + id + ".eml");
332
- if ($('#message .views .tab.analysis.selected').length) {
333
- return _this.loadMessageAnalysis();
334
- } else {
335
- return _this.loadMessageBody();
336
- }
337
- });
338
- }
339
- };
340
-
341
- MailCatcher.prototype.loadMessageBody = function(id, format) {
342
- var app;
343
- id || (id = this.selectedMessage());
344
- format || (format = $('#message .views .tab.format.selected').attr('data-message-format'));
345
- format || (format = 'html');
346
- $("#message .views .tab[data-message-format=\"" + format + "\"]:not(.selected)").addClass('selected');
347
- $("#message .views .tab:not([data-message-format=\"" + format + "\"]).selected").removeClass('selected');
348
- if (id != null) {
349
- $('#message iframe').attr("src", "/messages/" + id + "." + format);
350
- return app = this;
351
- }
352
- };
353
-
354
- MailCatcher.prototype.decorateMessageBody = function() {
355
- var body, format, message_iframe, text;
356
- format = $('#message .views .tab.format.selected').attr('data-message-format');
357
- switch (format) {
358
- case 'html':
359
- body = $('#message iframe').contents().find('body');
360
- return $("a", body).attr("target", "_blank");
361
- case 'plain':
362
- message_iframe = $('#message iframe').contents();
363
- text = message_iframe.text();
364
- text = text.replace(/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?)/g, '<a href="$1" target="_blank">$1</a>');
365
- text = text.replace(/\n/g, '<br/>');
366
- return message_iframe.find('html').html('<html><body>' + text + '</html></body>');
367
- }
368
- };
369
-
370
- MailCatcher.prototype.loadMessageAnalysis = function(id) {
371
- var $form, $iframe;
372
- id || (id = this.selectedMessage());
373
- $("#message .views .analysis.tab:not(.selected)").addClass('selected');
374
- $("#message .views :not(.analysis).tab.selected").removeClass('selected');
375
- if (id != null) {
376
- $iframe = $('#message iframe').contents().children().html("<html>\n<head>\n<title>Analysis</title>\n" + ($('link[rel="stylesheet"]')[0].outerHTML) + "\n</head>\n<body class=\"iframe\">\n<h1>Analyse your email with Fractal</h1>\n<p><a href=\"http://getfractal.com/\" target=\"_blank\">Fractal</a> is a really neat service that applies common email design and development knowledge from <a href=\"http://www.email-standards.org/\" target=\"_blank\">Email Standards Project</a> to your HTML email and tells you what you've done wrong or what you should do instead.</p>\n<p>Please note that this <strong>sends your email to the Fractal service</strong> for analysis. Read their <a href=\"https://www.getfractal.com/page/terms\" target=\"_blank\">terms of service</a> if you're paranoid.</p>\n<form>\n<input type=\"submit\" value=\"Analyse\" /><span class=\"loading\" style=\"color: #999; display: none\">Analysing&hellip;</span>\n</form>\n</body>\n</html>");
377
- return $form = $iframe.find('form').submit(function(e) {
378
- e.preventDefault();
379
- $(this).find('input[type="submit"]').attr('disabled', 'disabled').end().find('.loading').show();
380
- return $('#message iframe').contents().find('body').xslt("/messages/" + id + "/analysis.xml", "/stylesheets/analysis.xsl");
381
- });
382
- }
383
- };
384
-
385
- MailCatcher.prototype.refresh = function() {
386
- var _this = this;
387
- return $.getJSON('/messages', function(messages) {
388
- return $.each(messages, function(i, message) {
389
- if (!_this.haveMessage(message)) {
390
- if (message.recipients != null) {
391
- message.recipients = JSON.parse(message.recipients);
392
- }
393
- return _this.addMessage(message);
394
- }
395
- });
396
- });
397
- };
398
-
399
- MailCatcher.prototype.subscribe = function() {
400
- if (typeof WebSocket !== "undefined" && WebSocket !== null) {
401
- return this.subscribeWebSocket();
402
- } else {
403
- return this.subscribePoll();
404
- }
405
- };
406
-
407
- MailCatcher.prototype.subscribeWebSocket = function() {
408
- var secure,
409
- _this = this;
410
- secure = window.location.scheme === 'https';
411
- this.websocket = new WebSocket("" + (secure ? 'wss' : 'ws') + "://" + window.location.host + "/messages");
412
- return this.websocket.onmessage = function(event) {
413
- return _this.addMessage($.parseJSON(event.data));
414
- };
415
- };
416
-
417
- MailCatcher.prototype.subscribePoll = function() {
418
- var _this = this;
419
- if (this.refreshInterval == null) {
420
- return this.refreshInterval = setInterval((function() {
421
- return _this.refresh();
422
- }), 1000);
423
- }
424
- };
425
-
426
- MailCatcher.prototype.resizeToSavedKey = 'mailcatcherSeparatorHeight';
427
-
428
- MailCatcher.prototype.resizeTo = function(height) {
429
- var _ref;
430
- $('#messages').css({
431
- height: height - $('#messages').offset().top
432
- });
433
- return (_ref = window.localStorage) != null ? _ref.setItem(this.resizeToSavedKey, height) : void 0;
434
- };
435
-
436
- MailCatcher.prototype.resizeToSaved = function() {
437
- var height, _ref;
438
- height = parseInt((_ref = window.localStorage) != null ? _ref.getItem(this.resizeToSavedKey) : void 0);
439
- if (!isNaN(height)) {
440
- return this.resizeTo(height);
441
- }
442
- };
443
-
444
- return MailCatcher;
445
-
446
- })();
447
-
448
- $(function() {
449
- return window.MailCatcher = new MailCatcher;
450
- });
451
-
452
- }).call(this);
1
+ (function() {
2
+ var MailCatcher,
3
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
4
+
5
+ jQuery.expr[':'].icontains = function(a, i, m) {
6
+ var _ref, _ref1;
7
+ return ((_ref = (_ref1 = a.textContent) != null ? _ref1 : a.innerText) != null ? _ref : "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
8
+ };
9
+
10
+ MailCatcher = (function() {
11
+ function MailCatcher() {
12
+ this.nextTab = __bind(this.nextTab, this);
13
+ this.previousTab = __bind(this.previousTab, this);
14
+ this.openTab = __bind(this.openTab, this);
15
+ this.selectedTab = __bind(this.selectedTab, this);
16
+ this.getTab = __bind(this.getTab, this);
17
+ var _this = this;
18
+ $('#messages tr').live('click', function(e) {
19
+ e.preventDefault();
20
+ return _this.loadMessage($(e.currentTarget).attr('data-message-id'));
21
+ });
22
+ $('input[name=search]').keyup(function(e) {
23
+ var query;
24
+ query = $.trim($(e.currentTarget).val());
25
+ if (query) {
26
+ return _this.searchMessages(query);
27
+ } else {
28
+ return _this.clearSearch();
29
+ }
30
+ });
31
+ $('#message .views .format.tab a').live('click', function(e) {
32
+ e.preventDefault();
33
+ return _this.loadMessageBody(_this.selectedMessage(), $($(e.currentTarget).parent('li')).data('message-format'));
34
+ });
35
+ $('#message .views .analysis.tab a').live('click', function(e) {
36
+ e.preventDefault();
37
+ return _this.loadMessageAnalysis(_this.selectedMessage());
38
+ });
39
+ $('#message iframe').load(function() {
40
+ return _this.decorateMessageBody();
41
+ });
42
+ $('#resizer').live({
43
+ mousedown: function(e) {
44
+ var events;
45
+ e.preventDefault();
46
+ return $(window).bind(events = {
47
+ mouseup: function(e) {
48
+ e.preventDefault();
49
+ return $(window).unbind(events);
50
+ },
51
+ mousemove: function(e) {
52
+ e.preventDefault();
53
+ return _this.resizeTo(e.clientY);
54
+ }
55
+ });
56
+ }
57
+ });
58
+ this.resizeToSaved();
59
+ $('nav.app .clear a').live('click', function(e) {
60
+ e.preventDefault();
61
+ if (confirm("You will lose all your received messages.\n\nAre you sure you want to clear all messages?")) {
62
+ return $.ajax({
63
+ url: '/messages',
64
+ type: 'DELETE',
65
+ success: function() {
66
+ return _this.unselectMessage();
67
+ },
68
+ error: function() {
69
+ return alert('Error while clearing all messages.');
70
+ }
71
+ });
72
+ }
73
+ });
74
+ $('nav.app .quit a').live('click', function(e) {
75
+ e.preventDefault();
76
+ if (confirm("You will lose all your received messages.\n\nAre you sure you want to quit?")) {
77
+ return $.ajax({
78
+ type: 'DELETE',
79
+ success: function() {
80
+ return location.replace($('body > header h1 a').attr('href'));
81
+ },
82
+ error: function() {
83
+ return alert('Error while quitting.');
84
+ }
85
+ });
86
+ }
87
+ });
88
+ key('up', function() {
89
+ if (_this.selectedMessage()) {
90
+ _this.loadMessage($('#messages tr.selected').prev().data('message-id'));
91
+ } else {
92
+ _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
93
+ }
94
+ return false;
95
+ });
96
+ key('down', function() {
97
+ if (_this.selectedMessage()) {
98
+ _this.loadMessage($('#messages tr.selected').next().data('message-id'));
99
+ } else {
100
+ _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
101
+ }
102
+ return false;
103
+ });
104
+ key('Γîÿ+up, ctrl+up', function() {
105
+ _this.loadMessage($('#messages tbody tr[data-message-id]:first').data('message-id'));
106
+ return false;
107
+ });
108
+ key('Γîÿ+down, ctrl+down', function() {
109
+ _this.loadMessage($('#messages tbody tr[data-message-id]:last').data('message-id'));
110
+ return false;
111
+ });
112
+ key('left', function() {
113
+ _this.openTab(_this.previousTab());
114
+ return false;
115
+ });
116
+ key('right', function() {
117
+ _this.openTab(_this.nextTab());
118
+ return false;
119
+ });
120
+ key('backspace, delete', function() {
121
+ var id;
122
+ id = _this.selectedMessage();
123
+ if (id != null) {
124
+ $.ajax({
125
+ url: '/messages/' + id,
126
+ type: 'DELETE',
127
+ success: function() {
128
+ var messageRow, switchTo;
129
+ messageRow = $("#messages tbody tr[data-message-id='" + id + "']");
130
+ switchTo = messageRow.next().data('message-id') || messageRow.prev().data('message-id');
131
+ messageRow.remove();
132
+ if (switchTo) {
133
+ return _this.loadMessage(switchTo);
134
+ } else {
135
+ return _this.unselectMessage();
136
+ }
137
+ },
138
+ error: function() {
139
+ return alert('Error while removing message.');
140
+ }
141
+ });
142
+ }
143
+ return false;
144
+ });
145
+ this.refresh();
146
+ this.subscribe();
147
+ }
148
+
149
+ MailCatcher.prototype.parseDateRegexp = /^(\d{4})[-\/\\](\d{2})[-\/\\](\d{2})(?:\s+|T)(\d{2})[:-](\d{2})[:-](\d{2})(?:([ +-]\d{2}:\d{2}|\s*\S+|Z?))?$/;
150
+
151
+ MailCatcher.prototype.parseDate = function(date) {
152
+ var match;
153
+ if (match = this.parseDateRegexp.exec(date)) {
154
+ return new Date(match[1], match[2] - 1, match[3], match[4], match[5], match[6], 0);
155
+ }
156
+ };
157
+
158
+ MailCatcher.prototype.offsetTimeZone = function(date) {
159
+ var offset;
160
+ offset = Date.now().getTimezoneOffset() * 60000;
161
+ date.setTime(date.getTime() - offset);
162
+ return date;
163
+ };
164
+
165
+ MailCatcher.prototype.formatDate = function(date) {
166
+ if (typeof date === "string") {
167
+ date && (date = this.parseDate(date));
168
+ }
169
+ date && (date = this.offsetTimeZone(date));
170
+ return date && (date = date.toString("dddd, d MMM yyyy h:mm:ss tt"));
171
+ };
172
+
173
+ MailCatcher.prototype.messagesCount = function() {
174
+ return $('#messages tr').length - 1;
175
+ };
176
+
177
+ MailCatcher.prototype.tabs = function() {
178
+ return $('#message ul').children('.tab');
179
+ };
180
+
181
+ MailCatcher.prototype.getTab = function(i) {
182
+ return $(this.tabs()[i]);
183
+ };
184
+
185
+ MailCatcher.prototype.selectedTab = function() {
186
+ return this.tabs().index($('#message li.tab.selected'));
187
+ };
188
+
189
+ MailCatcher.prototype.openTab = function(i) {
190
+ return this.getTab(i).children('a').click();
191
+ };
192
+
193
+ MailCatcher.prototype.previousTab = function(tab) {
194
+ var i;
195
+ i = tab || tab === 0 ? tab : this.selectedTab() - 1;
196
+ if (i < 0) {
197
+ i = this.tabs().length - 1;
198
+ }
199
+ if (this.getTab(i).is(":visible")) {
200
+ return i;
201
+ } else {
202
+ return this.previousTab(i - 1);
203
+ }
204
+ };
205
+
206
+ MailCatcher.prototype.nextTab = function(tab) {
207
+ var i;
208
+ i = tab ? tab : this.selectedTab() + 1;
209
+ if (i > this.tabs().length - 1) {
210
+ i = 0;
211
+ }
212
+ if (this.getTab(i).is(":visible")) {
213
+ return i;
214
+ } else {
215
+ return this.nextTab(i + 1);
216
+ }
217
+ };
218
+
219
+ MailCatcher.prototype.haveMessage = function(message) {
220
+ if (message.id != null) {
221
+ message = message.id;
222
+ }
223
+ return $("#messages tbody tr[data-message-id=\"" + message + "\"]").length > 0;
224
+ };
225
+
226
+ MailCatcher.prototype.selectedMessage = function() {
227
+ return $('#messages tr.selected').data('message-id');
228
+ };
229
+
230
+ MailCatcher.prototype.searchMessages = function(query) {
231
+ var $rows, selector, token;
232
+ selector = ((function() {
233
+ var _i, _len, _ref, _results;
234
+ _ref = query.split(/\s+/);
235
+ _results = [];
236
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
237
+ token = _ref[_i];
238
+ _results.push(":icontains('" + token + "')");
239
+ }
240
+ return _results;
241
+ })()).join("");
242
+ $rows = $("#messages tbody tr");
243
+ $rows.not(selector).hide();
244
+ return $rows.filter(selector).show();
245
+ };
246
+
247
+ MailCatcher.prototype.clearSearch = function() {
248
+ return $('#messages tbody tr').show();
249
+ };
250
+
251
+ MailCatcher.prototype.addMessage = function(message) {
252
+ return $('#messages tbody').prepend($('<tr />').attr('data-message-id', message.id.toString()).append($('<td/>').text(message.sender || "No sender").toggleClass("blank", !message.sender)).append($('<td/>').text((message.recipients || []).join(', ') || "No recipients").toggleClass("blank", !message.recipients.length)).append($('<td/>').text(message.subject || "No subject").toggleClass("blank", !message.subject)).append($('<td/>').text(this.formatDate(message.created_at))));
253
+ };
254
+
255
+ MailCatcher.prototype.scrollToRow = function(row) {
256
+ var overflow, relativePosition;
257
+ relativePosition = row.offset().top - $('#messages').offset().top;
258
+ if (relativePosition < 0) {
259
+ return $('#messages').scrollTop($('#messages').scrollTop() + relativePosition - 20);
260
+ } else {
261
+ overflow = relativePosition + row.height() - $('#messages').height();
262
+ if (overflow > 0) {
263
+ return $('#messages').scrollTop($('#messages').scrollTop() + overflow + 20);
264
+ }
265
+ }
266
+ };
267
+
268
+ MailCatcher.prototype.unselectMessage = function() {
269
+ $('#messages tbody, #message .metadata dd').empty();
270
+ $('#message .metadata .attachments').hide();
271
+ $('#message iframe').attr('src', 'about:blank');
272
+ return null;
273
+ };
274
+
275
+ MailCatcher.prototype.loadMessage = function(id) {
276
+ var messageRow,
277
+ _this = this;
278
+ if ((id != null ? id.id : void 0) != null) {
279
+ id = id.id;
280
+ }
281
+ id || (id = $('#messages tr.selected').attr('data-message-id'));
282
+ if (id != null) {
283
+ $("#messages tbody tr:not([data-message-id='" + id + "'])").removeClass('selected');
284
+ messageRow = $("#messages tbody tr[data-message-id='" + id + "']");
285
+ messageRow.addClass('selected');
286
+ this.scrollToRow(messageRow);
287
+ return $.getJSON("/messages/" + id + ".json", function(message) {
288
+ var $ul;
289
+ if (message.recipients != null) {
290
+ message.recipients = JSON.parse(message.recipients);
291
+ }
292
+ $('#message .metadata dd.created_at').text(_this.formatDate(message.created_at));
293
+ $('#message .metadata dd.from').text(message.sender);
294
+ $('#message .metadata dd.to').text((message.recipients || []).join(', '));
295
+ $('#message .metadata dd.subject').text(message.subject);
296
+ $('#message .views .tab.format').each(function(i, el) {
297
+ var $el, format;
298
+ $el = $(el);
299
+ format = $el.attr('data-message-format');
300
+ if ($.inArray(format, message.formats) >= 0) {
301
+ $el.find('a').attr('href', "/messages/" + id + "." + format);
302
+ return $el.show();
303
+ } else {
304
+ return $el.hide();
305
+ }
306
+ });
307
+ if ($("#message .views .tab.selected:not(:visible)").length) {
308
+ $("#message .views .tab.selected").removeClass("selected");
309
+ $("#message .views .tab:visible:first").addClass("selected");
310
+ }
311
+ if (message.attachments.length) {
312
+ $ul = $('<ul/>').appendTo($('#message .metadata dd.attachments').empty());
313
+ $.each(message.attachments, function(i, attachment) {
314
+ return $ul.append($('<li>').append($('<a>').attr('href', attachment['href']).addClass(attachment['type'].split('/', 1)[0]).addClass(attachment['type'].replace('/', '-')).text(attachment['filename'])));
315
+ });
316
+ $('#message .metadata .attachments').show();
317
+ } else {
318
+ $('#message .metadata .attachments').hide();
319
+ }
320
+ $('#message .views .download a').attr('href', "/messages/" + id + ".eml");
321
+ if ($('#message .views .tab.analysis.selected').length) {
322
+ return _this.loadMessageAnalysis();
323
+ } else {
324
+ return _this.loadMessageBody();
325
+ }
326
+ });
327
+ }
328
+ };
329
+
330
+ MailCatcher.prototype.loadMessageBody = function(id, format) {
331
+ var app;
332
+ id || (id = this.selectedMessage());
333
+ format || (format = $('#message .views .tab.format.selected').attr('data-message-format'));
334
+ format || (format = 'html');
335
+ $("#message .views .tab[data-message-format=\"" + format + "\"]:not(.selected)").addClass('selected');
336
+ $("#message .views .tab:not([data-message-format=\"" + format + "\"]).selected").removeClass('selected');
337
+ if (id != null) {
338
+ $('#message iframe').attr("src", "/messages/" + id + "." + format);
339
+ return app = this;
340
+ }
341
+ };
342
+
343
+ MailCatcher.prototype.decorateMessageBody = function() {
344
+ var body, format, message_iframe, text;
345
+ format = $('#message .views .tab.format.selected').attr('data-message-format');
346
+ switch (format) {
347
+ case 'html':
348
+ body = $('#message iframe').contents().find('body');
349
+ return $("a", body).attr("target", "_blank");
350
+ case 'plain':
351
+ message_iframe = $('#message iframe').contents();
352
+ text = message_iframe.text();
353
+ text = text.replace(/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?)/g, '<a href="$1" target="_blank">$1</a>');
354
+ text = text.replace(/\n/g, '<br/>');
355
+ return message_iframe.find('html').html('<html><body>' + text + '</html></body>');
356
+ }
357
+ };
358
+
359
+ MailCatcher.prototype.loadMessageAnalysis = function(id) {
360
+ var $form, $iframe;
361
+ id || (id = this.selectedMessage());
362
+ $("#message .views .analysis.tab:not(.selected)").addClass('selected');
363
+ $("#message .views :not(.analysis).tab.selected").removeClass('selected');
364
+ if (id != null) {
365
+ $iframe = $('#message iframe').contents().children().html("<html>\n<head>\n<title>Analysis</title>\n" + ($('link[rel="stylesheet"]')[0].outerHTML) + "\n</head>\n<body class=\"iframe\">\n<h1>Analyse your email with Fractal</h1>\n<p><a href=\"http://getfractal.com/\" target=\"_blank\">Fractal</a> is a really neat service that applies common email design and development knowledge from <a href=\"http://www.email-standards.org/\" target=\"_blank\">Email Standards Project</a> to your HTML email and tells you what you've done wrong or what you should do instead.</p>\n<p>Please note that this <strong>sends your email to the Fractal service</strong> for analysis. Read their <a href=\"https://www.getfractal.com/page/terms\" target=\"_blank\">terms of service</a> if you're paranoid.</p>\n<form>\n<input type=\"submit\" value=\"Analyse\" /><span class=\"loading\" style=\"color: #999; display: none\">Analysing&hellip;</span>\n</form>\n</body>\n</html>");
366
+ return $form = $iframe.find('form').submit(function(e) {
367
+ e.preventDefault();
368
+ $(this).find('input[type="submit"]').attr('disabled', 'disabled').end().find('.loading').show();
369
+ return $('#message iframe').contents().find('body').xslt("/messages/" + id + "/analysis.xml", "/stylesheets/analysis.xsl");
370
+ });
371
+ }
372
+ };
373
+
374
+ MailCatcher.prototype.refresh = function() {
375
+ var _this = this;
376
+ return $.getJSON('/messages', function(messages) {
377
+ return $.each(messages, function(i, message) {
378
+ if (!_this.haveMessage(message)) {
379
+ if (message.recipients != null) {
380
+ message.recipients = JSON.parse(message.recipients);
381
+ }
382
+ return _this.addMessage(message);
383
+ }
384
+ });
385
+ });
386
+ };
387
+
388
+ MailCatcher.prototype.subscribe = function() {
389
+ if (typeof WebSocket !== "undefined" && WebSocket !== null) {
390
+ return this.subscribeWebSocket();
391
+ } else {
392
+ return this.subscribePoll();
393
+ }
394
+ };
395
+
396
+ MailCatcher.prototype.subscribeWebSocket = function() {
397
+ var secure,
398
+ _this = this;
399
+ secure = window.location.scheme === 'https';
400
+ this.websocket = new WebSocket("" + (secure ? 'wss' : 'ws') + "://" + window.location.host + "/messages");
401
+ return this.websocket.onmessage = function(event) {
402
+ return _this.addMessage($.parseJSON(event.data));
403
+ };
404
+ };
405
+
406
+ MailCatcher.prototype.subscribePoll = function() {
407
+ var _this = this;
408
+ if (this.refreshInterval == null) {
409
+ return this.refreshInterval = setInterval((function() {
410
+ return _this.refresh();
411
+ }), 1000);
412
+ }
413
+ };
414
+
415
+ MailCatcher.prototype.resizeToSavedKey = 'mailcatcherSeparatorHeight';
416
+
417
+ MailCatcher.prototype.resizeTo = function(height) {
418
+ var _ref;
419
+ $('#messages').css({
420
+ height: height - $('#messages').offset().top
421
+ });
422
+ return (_ref = window.localStorage) != null ? _ref.setItem(this.resizeToSavedKey, height) : void 0;
423
+ };
424
+
425
+ MailCatcher.prototype.resizeToSaved = function() {
426
+ var height, _ref;
427
+ height = parseInt((_ref = window.localStorage) != null ? _ref.getItem(this.resizeToSavedKey) : void 0);
428
+ if (!isNaN(height)) {
429
+ return this.resizeTo(height);
430
+ }
431
+ };
432
+
433
+ return MailCatcher;
434
+
435
+ })();
436
+
437
+ $(function() {
438
+ return window.MailCatcher = new MailCatcher;
439
+ });
440
+
441
+ }).call(this);