diff --git a/public/javascripts/application.coffee b/public/javascripts/application.coffee new file mode 100644 index 0000000..4696906 --- /dev/null +++ b/public/javascripts/application.coffee @@ -0,0 +1,95 @@ +class MailCatcher + constructor: -> + $('#mail tr').live 'click', (e) => + @loadMessage $(e.currentTarget).attr 'data-message-id' + + $('#message .actions ul li.tab').live 'click', (e) => + @loadMessageBody $('#mail tr.selected').attr('data-message-id'), $(e.currentTarget).attr 'data-message-format' + + @refresh() + @subscribe() + + haveMessage: (message) -> + message = message.id if message.id? + $("#mail tbody tr[data-message-id=\"#{message}\"]").length > 0 + + addMessage: (message) -> + $('#mail tbody').append \ + $('').attr('data-message-id', message.id.toString()) + .append($('').text(message.sender)) + .append($('').text((message.recipients || []).join(', '))) + .append($('').text(message.subject)) + .append($('').text((new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt"))) + + loadMessage: (id) -> + id = id.id if id?.id? + id ||= $('#mail tr.selected').attr 'data-message-id' + + if id? + $('#mail tbody tr:not([data-message-id="'+id+'"])').removeClass 'selected' + $('#mail tbody tr[data-message-id="'+id+'"]').addClass 'selected' + + $.getJSON '/messages/' + id + '.json', (message) => + $('#message .received span').text (new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt") + $('#message .from span').text message.sender + $('#message .to span').text (message.recipients || []).join(', ') + $('#message .subject span').text message.subject + $('#message .actions ul li.format').each (i, el) -> + $el = $(el) + format = $el.attr 'data-message-format' + if $.inArray(format, message.formats) >= 0 + $el.show() + else + $el.hide() + + if $("#message .actions ul li.tab.selected:not(:visible)").count + $("#message .actions ul li.tab.selected").removeClass "selected" + $("#message .actions ul li.tab:visible:first").addClass "selected" + + if message.attachments.length + $('#message .metadata .attachments ul').empty() + $.each message.attachments, (i, attachment) -> + $('#message .metadata .attachments ul').append($('
  • ').append($('').attr('href', attachment['href']).addClass(attachment['type'].split('/', 1)[0]).addClass(attachment['type'].replace('/', '-')).text(attachment['filename']))); + $('#message .metadata .attachments').show() + else + $('#message .metadata .attachments').hide() + + $('#message .actions ul li.download a').attr 'href', "/messages/#{id}.eml" + + @loadMessageBody() + + loadMessageBody: (id, format) -> + id ||= $('#mail tr.selected').attr 'data-message-id' + format ||= $('#message .actions ul li.selected').first().attr 'data-message-format' + format ||= 'html' + + $("#message .actions ul li.tab[data-message-format=\"#{format}\"]").addClass 'selected' + $("#message .actions ul li.tab:not([data-message-format=\"#{format}\"])").removeClass 'selected' + + if id? + $('#message iframe').attr "src", "/messages/#{id}.#{format}" + + refresh: -> + $.getJSON '/messages', (messages) => + $.each messages, (i, message) => + unless @haveMessage message + @addMessage message + + subscribe: -> + if WebSocket? + @subscribeWebSocket() + else + @subscribePoll() + + subscribeWebSocket: -> + secure = window.location.scheme == 'https' + @websocket = new WebSocket("#{if secure then 'wss' else 'ws'}://#{window.location.host}/messages"); + @websocket.onmessage = (event) => + @addMessage $.parseJSON event.data + + subscribePoll: -> + unless @refreshInterval? + @refreshInterval = setInterval (=> @refresh()), 1000 + + +$ -> window.MailCatcher = new MailCatcher \ No newline at end of file diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 1498221..8b92785 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1,98 +1,111 @@ -var MailCatcher = { - init: function() { - $('#mail tr').live('click', function() { - MailCatcher.load($(this).attr('data-message-id')); - }); - - $('#message .actions ul li.tab').live('click', function() { - MailCatcher.loadBody($('#mail tr.selected').attr('data-message-id'), $(this).attr('data-message-format')); - }); - - MailCatcher.refresh(); - - MailCatcher.subscribe(); - }, - - addMessage: function(message) { - $('#mail tbody').append( - $('').attr('data-message-id', message.id.toString()) - .append($('').text(message.sender)) - .append($('').text((message.recipients || []).join(', '))) - .append($('').text(message.subject)) - .append($('').text((new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt"))) - ); - }, - - refresh: function() { - $.getJSON('/messages', function(mail) { - $.each(mail, function(i, message) { - MailCatcher.addMessage(message); - }); - }); - }, - - subscribe: function () { - if (WebSocket !== undefined) { - MailCatcher.websocket = new WebSocket("ws" + (window.location.scheme == 'https' ? 's' : '') + "://" + window.location.host + "/messages"); - MailCatcher.websocket.onmessage = function (event) { - MailCatcher.addMessage($.parseJSON(event.data)); - }; - } else { - if (!MailCatcher.refreshInterval) { - MailCatcher.refreshInterval = setInterval(MailCatcher.refresh, 30000); +(function() { + var MailCatcher; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + MailCatcher = (function() { + function MailCatcher() { + $('#mail tr').live('click', __bind(function(e) { + return this.loadMessage($(e.currentTarget).attr('data-message-id')); + }, this)); + $('#message .actions ul li.tab').live('click', __bind(function(e) { + return this.loadMessageBody($('#mail tr.selected').attr('data-message-id'), $(e.currentTarget).attr('data-message-format')); + }, this)); + this.refresh(); + this.subscribe(); + } + MailCatcher.prototype.haveMessage = function(message) { + if (message.id != null) { + message = message.id; } - } - }, - - load: function(id) { - id = id || $('#mail tr.selected').attr('data-message-id'); - - if (id !== null) { - $('#mail tbody tr:not([data-message-id="'+id+'"])').removeClass('selected'); - $('#mail tbody tr[data-message-id="'+id+'"]').addClass('selected'); - - $.getJSON('/messages/' + id + '.json', function(message) { - $('#message .received span').text((new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt")); - $('#message .from span').text(message.sender); - $('#message .to span').text((message.recipients || []).join(', ')); - $('#message .subject span').text(message.subject); - $('#message .actions ul li.format').each(function(i, el) { - var $el = $(el), + return $("#mail tbody tr[data-message-id=\"" + message + "\"]").length > 0; + }; + MailCatcher.prototype.addMessage = function(message) { + return $('#mail tbody').append($('').attr('data-message-id', message.id.toString()).append($('').text(message.sender)).append($('').text((message.recipients || []).join(', '))).append($('').text(message.subject)).append($('').text((new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt")))); + }; + MailCatcher.prototype.loadMessage = function(id) { + if ((id != null ? id.id : void 0) != null) { + id = id.id; + } + id || (id = $('#mail tr.selected').attr('data-message-id')); + if (id != null) { + $('#mail tbody tr:not([data-message-id="' + id + '"])').removeClass('selected'); + $('#mail tbody tr[data-message-id="' + id + '"]').addClass('selected'); + return $.getJSON('/messages/' + id + '.json', __bind(function(message) { + $('#message .received span').text((new Date(message.created_at)).toString("dddd, d MMM yyyy h:mm:ss tt")); + $('#message .from span').text(message.sender); + $('#message .to span').text((message.recipients || []).join(', ')); + $('#message .subject span').text(message.subject); + $('#message .actions ul li.format').each(function(i, el) { + var $el, format; + $el = $(el); format = $el.attr('data-message-format'); - if ($.inArray(format, message.formats) >= 0) { - $el.show(); - } else { - $el.hide(); - } - }); - if ($("#message .actions ul li.tab.selected:not(:visible)")) { - $("#message .actions ul li.tab.selected").removeClass("selected"); - $("#message .actions ul li.tab:visible:first").addClass("selected"); - } - if (message.attachments.length > 0) { - $('#message .metadata .attachments ul').empty(); - $.each(message.attachments, function (i, attachment) { - $('#message .metadata .attachments ul').append($('
  • ').append($('').attr('href', attachment['href']).addClass(attachment['type'].split('/', 1)[0]).addClass(attachment['type'].replace('/', '-')).text(attachment['filename']))); + if ($.inArray(format, message.formats) >= 0) { + return $el.show(); + } else { + return $el.hide(); + } }); - $('#message .metadata .attachments').show(); - } else { - $('#message .metadata .attachments').hide(); - } - $('#message .actions ul li.download a').attr('href', '/messages/' + id + '.eml'); - MailCatcher.loadBody(); - }); - } - }, - - loadBody: function(id, format) { - id = id || $('#mail tr.selected').attr('data-message-id'); - format = format || $('#message .actions ul li.selected').first().attr('data-message-format') || 'html'; - - $('#message .actions ul li.tab[data-message-format="'+format+'"]').addClass('selected'); - $('#message .actions ul li.tab:not([data-message-format="'+format+'"])').removeClass('selected'); - - if (id !== undefined && id !== null) { - $('#message iframe').attr('src', '/messages/' + id + '.' + format); - } - } -}; \ No newline at end of file + if ($("#message .actions ul li.tab.selected:not(:visible)").count) { + $("#message .actions ul li.tab.selected").removeClass("selected"); + $("#message .actions ul li.tab:visible:first").addClass("selected"); + } + if (message.attachments.length) { + $('#message .metadata .attachments ul').empty(); + $.each(message.attachments, function(i, attachment) { + return $('#message .metadata .attachments ul').append($('
  • ').append($('').attr('href', attachment['href']).addClass(attachment['type'].split('/', 1)[0]).addClass(attachment['type'].replace('/', '-')).text(attachment['filename']))); + }); + $('#message .metadata .attachments').show(); + } else { + $('#message .metadata .attachments').hide(); + } + $('#message .actions ul li.download a').attr('href', "/messages/" + id + ".eml"); + return this.loadMessageBody(); + }, this)); + } + }; + MailCatcher.prototype.loadMessageBody = function(id, format) { + id || (id = $('#mail tr.selected').attr('data-message-id')); + format || (format = $('#message .actions ul li.selected').first().attr('data-message-format')); + format || (format = 'html'); + $("#message .actions ul li.tab[data-message-format=\"" + format + "\"]").addClass('selected'); + $("#message .actions ul li.tab:not([data-message-format=\"" + format + "\"])").removeClass('selected'); + if (id != null) { + return $('#message iframe').attr("src", "/messages/" + id + "." + format); + } + }; + MailCatcher.prototype.refresh = function() { + return $.getJSON('/messages', __bind(function(messages) { + return $.each(messages, __bind(function(i, message) { + if (!this.haveMessage(message)) { + return this.addMessage(message); + } + }, this)); + }, this)); + }; + MailCatcher.prototype.subscribe = function() { + if (typeof WebSocket !== "undefined" && WebSocket !== null) { + return this.subscribeWebSocket(); + } else { + return this.subscribePoll(); + } + }; + MailCatcher.prototype.subscribeWebSocket = function() { + var secure; + secure = window.location.scheme === 'https'; + this.websocket = new WebSocket("" + (secure ? 'wss' : 'ws') + "://" + window.location.host + "/messages"); + return this.websocket.onmessage = __bind(function(event) { + return this.addMessage($.parseJSON(event.data)); + }, this); + }; + MailCatcher.prototype.subscribePoll = function() { + if (this.refreshInterval == null) { + return this.refreshInterval = setInterval((__bind(function() { + return this.refresh(); + }, this)), 1000); + } + }; + return MailCatcher; + })(); + $(function() { + return window.MailCatcher = new MailCatcher; + }); +}).call(this); diff --git a/views/index.haml b/views/index.haml index f0c012a..5a05b44 100644 --- a/views/index.haml +++ b/views/index.haml @@ -6,8 +6,6 @@ %script{:src => "/javascripts/jquery.js"} %script{:src => "/javascripts/date.js"} %script{:src => "/javascripts/application.js"} - :javascript - $(MailCatcher.init); %body #mail %table