mail_grabber 1.0.0.rc1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,539 +1,148 @@
1
- (function() {
2
- var MailGrabber = {
3
- /**
4
- * Change which content (message part) should show. When the page is loading
5
- * the HTML content will be active and the others will be hidden. When we
6
- * click on tab e.g. Plain Text then this content will active and other
7
- * hidden.
8
- *
9
- * @param {Object} event - which part we clicked
10
- */
11
- changeMessageContent: function(event) {
12
- var messageTabs =
13
- document
14
- .querySelectorAll('[data-message-tab]');
15
-
16
- var messageContents =
17
- document
18
- .querySelectorAll('[data-message-content]');
19
-
20
- var clickedTabType = event.target.dataset.messageTab;
21
-
22
- messageTabs.forEach(function(messageTab, index) {
23
- messageTab.classList.remove('active');
24
- messageContents[index].classList.remove('hide');
25
-
26
- if(messageTab.dataset.messageTab === clickedTabType) {
27
- messageTab.classList.add('active');
28
- }
29
-
30
- if(messageContents[index].dataset.messageContent !== clickedTabType) {
31
- messageContents[index].classList.add('hide');
32
- }
33
- });
34
- },
35
-
36
- /**
37
- * Show default backgroud image instead of any content.
38
- */
39
- defaultBackground: function() {
40
- var messageContent =
41
- document
42
- .querySelector('div[data-content-type=message-content]');
43
-
44
- messageContent.innerHTML = '';
45
-
46
- messageContent.style.background =
47
- "url('" + messageContent.dataset.backgroundImage +
48
- "') center center no-repeat";
49
- messageContent.style.backgroundSize = '50%';
50
- messageContent.style.opacity = '10%';
51
- },
52
-
53
- /**
54
- * Delete all content (message list and message content as well),
55
- * set default backgroud and the infinite scroll params when we click on
56
- * the Reload or Delete tabs.
57
- */
58
- deleteContent: function() {
59
- MailGrabber.lastMessageId = -1;
60
- MailGrabber.page = 1;
61
- MailGrabber.defaultBackground();
62
-
63
- document
64
- .querySelector('ul[data-content-type=message-list]')
65
- .innerHTML = '';
66
- },
67
-
68
- /**
69
- * Delete a message when we click on the Delete tab. It will remove all
70
- * content and reload the message list.
71
- *
72
- * @param {Number} messageId - which message we would like to delete
73
- */
74
- deleteMessage: function(messageId) {
75
- MailGrabber.request('DELETE', '/message/' + messageId + '.json',
76
- function() {
77
- MailGrabber.deleteContent();
78
- MailGrabber.getMessageList();
79
- }
80
- );
81
- },
82
-
83
- /**
84
- * Delete message list when we click on the Clear tab. It will remove
85
- * everything.
86
- */
87
- deleteMessageList: function() {
88
- MailGrabber.request('DELETE', '/messages.json', function() {
89
- MailGrabber.deleteContent();
90
- });
91
- },
92
-
93
- /**
94
- * Get a message and render the message content, when we click on an item
95
- * from the message list.
96
- *
97
- * @param {Number} messageId - which message we would like to see
98
- */
99
- getMessage: function(messageId) {
100
- MailGrabber.request('GET', '/message/' + messageId + '.json',
101
- function(response) {
102
- MailGrabber.renderMessageContent(JSON.parse(response));
103
- }
104
- );
105
- },
106
-
107
- /**
108
- * Get a list of the messages. Also change the params of the infinite scroll
109
- * that we can know which page we are on. It checks the message ids to not
110
- * load those messages which are already on the list.
111
- */
112
- getMessageList: function() {
113
- var messageIds;
114
-
115
- MailGrabber.request('GET', '/messages.json?page=' + MailGrabber.page +
116
- '&per_page=' + MailGrabber.perPage,
117
- function(response) {
118
- response = JSON.parse(response);
119
- messageIds = response.map(function(hash) { return hash['id'] });
120
-
121
- if(response.length > 0) {
122
- if(messageIds.indexOf(MailGrabber.lastMessageId) === -1) {
123
- MailGrabber.lastMessageId = messageIds.pop();
124
- MailGrabber.page++;
125
- MailGrabber.renderMessageList(response);
126
- } else {
127
- MailGrabber.reloadMessageList();
128
- }
129
- }
130
- }
131
- );
132
- },
133
-
134
- /**
135
- * Scrolling infinitely. Count the height of the list and if we reached the
136
- * bottom of the list then tries to load more message.
137
- *
138
- * @param {Object} messageList - the message list container
139
- */
140
- infiniteScroll: function(messageList) {
141
- var scrollHeight = messageList.scrollHeight;
142
- var scrollTop = messageList.scrollTop;
143
- var clientHeight = messageList.clientHeight;
144
-
145
- if(scrollHeight - scrollTop === clientHeight) {
146
- MailGrabber.getMessageList();
147
- }
148
- },
149
-
150
- /**
151
- * Initialize MailGrabber. Add some event listeners to the Reload and the
152
- * Clear tabs then load messages and the default background.
153
- */
154
- init: function() {
155
- document
156
- .querySelector('li[data-content-type=message-reload-tab]')
157
- .addEventListener('click', MailGrabber.reloadMessageList);
158
-
159
- document
160
- .querySelector('li[data-content-type=message-clear-tab]')
161
- .addEventListener('click', MailGrabber.deleteMessageList);
162
-
163
- MailGrabber.loadMessageList();
164
- MailGrabber.defaultBackground();
165
- },
166
-
167
- /**
168
- * Format the given date or time.
169
- *
170
- * @param {DateTime} dateTime - the message created at attribute
171
- * @param {String} ouputType - what type we would like to see
172
- *
173
- * @return {String} the new format of the date or time
174
- */
175
- formatDateTime: function(dateTime, outputType) {
176
- dateTime = new Date(dateTime);
177
- var dateTimeNow = new Date();
178
- // Sun Feb 21 2021 21:00:00 GMT+0100 (Central European Standard Time)
179
- // 0 1 2 3 4 5 6 7 8 9
180
- var dateTimeComponents = dateTime.toString().split(' ');
181
- var output;
182
-
183
- switch(outputType) {
184
- case 'messageListDateOrTime':
185
- if(dateTime.getDate() === dateTimeNow.getDate()) {
186
- output = MailGrabber.formatTime(dateTimeComponents[4]);
187
- } else if(dateTime.getFullYear() === dateTimeNow.getFullYear()) {
188
- output = dateTimeComponents[1] + ' ' + dateTimeComponents[2];
189
- } else {
190
- output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
191
- dateTimeComponents[2];
192
- }
193
-
194
- break;
195
- default:
196
- output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
197
- dateTimeComponents[2] + ' - ' +
198
- MailGrabber.formatTime(dateTimeComponents[4]);
1
+ var MailGrabberApplication = {
2
+ /**
3
+ * Delete a message when we click on the Delete tab. It will remove all
4
+ * content and reload the message list.
5
+ *
6
+ * @param {Number} messageId - which message we would like to delete
7
+ */
8
+ deleteMessage: function(messageId) {
9
+ MailGrabberApplication.request('DELETE', '/message/' + messageId + '.json',
10
+ function() {
11
+ MailGrabberDOM.deleteContent();
12
+ MailGrabberApplication.getMessageList();
199
13
  }
14
+ );
15
+ },
200
16
 
201
- return output;
202
- },
203
-
204
- /**
205
- * Format the given number (attachment size).
206
- *
207
- * @param {Number} size - the size of the attachment in bytes
208
- *
209
- * @return {String} the formatted number with unit
210
- */
211
- formatSize: function(size) {
212
- var exponent = (Math.log(size) / Math.log(1024)) | 0;
213
- var number = +(size / Math.pow(1024, exponent)).toFixed(1);
214
-
215
- return number + ' ' + ('KMGTPEZY'[exponent - 1] || '') + 'B';
216
- },
217
-
218
- /**
219
- * Format the given time.
220
- *
221
- * @param {String} time
222
- *
223
- * @return {String} the new format of the time
224
- */
225
- formatTime: function(time) {
226
- var timeComponents = time.split(':');
227
-
228
- return timeComponents[0] + ':' + timeComponents[1];
229
- },
230
-
231
- /**
232
- * The last message id what loaded. If it is -1 then we have no any
233
- * messages.
234
- */
235
- lastMessageId: -1,
236
-
237
- /**
238
- * Load the message list. Also add event listener for infinite scroll.
239
- */
240
- loadMessageList: function() {
241
- var messageList =
242
- document
243
- .querySelector('ul[data-content-type=message-list]');
244
-
245
- messageList.addEventListener('scroll', function() {
246
- MailGrabber.infiniteScroll(messageList);
247
- });
248
-
249
- MailGrabber.getMessageList();
250
- },
251
-
252
- /**
253
- * Params that we can follow how many messages we have on the list. We are
254
- * loading 15 messages in every requests.
255
- */
256
- page: 1,
257
- perPage: 15,
258
-
259
- /**
260
- * Reload the message list. When we have new messages in the database, but
261
- * we scrolled down or clicked on the Reload tab.
262
- */
263
- reloadMessageList: function() {
264
- MailGrabber.deleteContent();
265
- MailGrabber.getMessageList();
266
- },
267
-
268
- /**
269
- * Render message attachment. Show the list of attachments at the top of the
270
- * message content.
271
- *
272
- * @param {Object} messageAttachments - the message attachments container
273
- * @param {Object} messagePart - a message part which we loaded
274
- */
275
- renderMessageAttachment: function(messageAttachments, messagePart) {
276
- var messageAttachment = document.createElement('a');
277
- var fileSize = document.createElement('span');
278
- var messageAttachmentTemplate =
279
- document
280
- .querySelector(
281
- 'template[data-content-type=message-attachment-template]'
282
- )
283
- .content
284
- .cloneNode(true);
285
-
286
- messageAttachment.href =
287
- 'data:' + messagePart.mime_type + ';base64,' + messagePart.body;
288
- messageAttachment.download = messagePart.filename;
289
- messageAttachment.innerHTML = messagePart.filename;
290
- messageAttachment.classList.add('color-black', 'no-text-decoration');
291
-
292
- fileSize.innerHTML = MailGrabber.formatSize(messagePart.size);
293
- fileSize.classList.add('color-gray', 'font-size-0_9', 'padding-left-10');
294
-
295
- [messageAttachment, fileSize].forEach(function(node) {
296
- messageAttachmentTemplate
297
- .querySelector('li[data-content-type=message-attachment]')
298
- .appendChild(node);
299
- });
300
-
301
- messageAttachments.classList.remove('hide');
302
- messageAttachments.appendChild(messageAttachmentTemplate);
303
- },
304
-
305
- /**
306
- * Render the HTML part of the message. If the message has inline images
307
- * then it will render those images as well. An iframe will contain this
308
- * content.
309
- *
310
- * @param {Object} iFrame - the iframe HTML tag
311
- * @param {Object} messageParts - the parts of the message
312
- * @param {Object} messageHtmlPart - the HTML part of the message
313
- */
314
- renderMessageHtmlPart: function(iFrame, messageParts, messageHtmlPart) {
315
- var messageInlineAttachmentRegExp = new RegExp("cid:");
316
-
317
- if(messageInlineAttachmentRegExp.test(messageHtmlPart)) {
318
- messageHtmlPart =
319
- MailGrabber.renderMessageInlineAttachments(
320
- messageParts, messageHtmlPart
321
- );
322
- }
17
+ /**
18
+ * Delete message list when we click on the Clear tab. It will remove
19
+ * everything.
20
+ */
21
+ deleteMessageList: function() {
22
+ MailGrabberApplication.request('DELETE', '/messages.json', function() {
23
+ MailGrabberDOM.deleteContent();
24
+ });
25
+ },
323
26
 
324
- iFrame.srcdoc = messageHtmlPart;
325
- iFrame.onload = function() {
326
- iFrame.height = iFrame.contentDocument.body.scrollHeight + 65;
27
+ /**
28
+ * Get a message and render the message content, when we click on an item
29
+ * from the message list.
30
+ *
31
+ * @param {Number} messageId - which message we would like to see
32
+ */
33
+ getMessage: function(messageId) {
34
+ MailGrabberApplication.request('GET', '/message/' + messageId + '.json',
35
+ function(response) {
36
+ MailGrabberMessageContent.render(JSON.parse(response));
327
37
  }
328
- },
329
-
330
- /**
331
- * Render inline images of the message. Change the cid:something12345 with
332
- * the encoded image content.
333
- *
334
- * @param {Object} messageParts - the parts of the message
335
- * @param {Object} messageHtmlPart - the HTML part of the message
336
- *
337
- * @return {Object} messageHtmlPart - the modified HTML part of the message
338
- */
339
- renderMessageInlineAttachments: function(messageParts, messageHtmlPart) {
340
- messageParts.forEach(function(messagePart) {
341
- if(messagePart.is_attachment === 1 && messagePart.is_inline === 1) {
342
- messageHtmlPart = messageHtmlPart.replace('cid:' + messagePart.cid,
343
- 'data:' + messagePart.mime_type + ';base64,' + messagePart.body);
344
- }
345
- });
346
-
347
- return messageHtmlPart;
348
- },
349
-
350
- /**
351
- * Render the content of the message (all parts, inline attachments and
352
- * attachments). Also it sets up event listeners of the HTML, PlainText,
353
- * Raw, Delete and Close tabs.
354
- *
355
- * @param {Object} response - the response the get message request
356
- */
357
- renderMessageContent: function(response) {
358
- var message = response.message;
359
- var messageParts = response.message_parts;
360
- var messageContentTemplate =
361
- document
362
- .querySelector('template[data-content-type=message-content-template]')
363
- .content
364
- .cloneNode(true);
38
+ );
39
+ },
365
40
 
366
- var messageContent =
367
- document
368
- .querySelector('div[data-content-type=message-content]');
369
-
370
- messageContent.removeAttribute('style');
371
- messageContent.innerHTML = '';
372
-
373
- messageContentTemplate
374
- .querySelector('div[data-content-type=message-subject]')
375
- .innerHTML = message.subject;
376
-
377
- messageContentTemplate
378
- .querySelector('dl[data-content-type=metadata]')
379
- .innerHTML = MailGrabber.renderMetadata(message);
380
-
381
- messageContentTemplate
382
- .querySelector('time[data-content-type=message-sent-at]')
383
- .innerHTML = MailGrabber.formatDateTime(message.created_at);
384
-
385
- messageContentTemplate
386
- .querySelectorAll('[data-message-tab]')
387
- .forEach(function(tab) {
388
- tab.addEventListener('click', MailGrabber.changeMessageContent);
389
- });
390
-
391
- messageContentTemplate
392
- .querySelector('li[data-content-type=message-delete-tab]')
393
- .addEventListener('click', function() {
394
- MailGrabber.deleteMessage(message.id);
395
- });
396
-
397
- messageContentTemplate
398
- .querySelector('li[data-content-type=message-close-tab]')
399
- .addEventListener('click', MailGrabber.defaultBackground);
400
-
401
- messageParts.forEach(function(messagePart) {
402
- if(messagePart.is_attachment === 0 && messagePart.is_inline === 0) {
403
- switch(messagePart.mime_type) {
404
- case 'text/html':
405
- MailGrabber.renderMessageHtmlPart(
406
- messageContentTemplate
407
- .querySelector('iframe[data-content-type=message-html-body]'),
408
- messageParts,
409
- messagePart.body
410
- );
411
-
412
- break;
413
- case 'text/plain':
414
- messageContentTemplate
415
- .querySelector('pre[data-content-type=message-text-body]')
416
- .innerText = messagePart.body;
417
-
418
- break;
41
+ /**
42
+ * Get a list of the messages. Also change the params of the infinite scroll
43
+ * that we can know which page we are on. It checks the message ids to not
44
+ * load those messages which are already on the list.
45
+ */
46
+ getMessageList: function() {
47
+ var messageIds;
48
+
49
+ MailGrabberApplication.request('GET', '/messages.json?page=' +
50
+ MailGrabberVariables.page + '&per_page=' + MailGrabberVariables.perPage,
51
+ function(response) {
52
+ response = JSON.parse(response);
53
+ messageIds = response.map(function(hash) { return hash['id'] });
54
+
55
+ if(response.length > 0) {
56
+ if(messageIds.indexOf(MailGrabberVariables.lastMessageId) === -1) {
57
+ MailGrabberVariables.lastMessageId = messageIds.pop();
58
+ MailGrabberVariables.messageListReloading = false;
59
+ MailGrabberVariables.page++;
60
+ MailGrabberMessageList.render(response);
61
+ } else {
62
+ MailGrabberApplication.reloadMessageList();
419
63
  }
420
- } else if(messagePart.is_attachment === 1 &&
421
- messagePart.is_inline === 0) {
422
- MailGrabber.renderMessageAttachment(
423
- messageContentTemplate
424
- .querySelector('ul[data-content-type=message-attachments]'),
425
- messagePart
426
- );
427
64
  }
428
- });
429
-
430
- messageContentTemplate
431
- .querySelector('pre[data-content-type=message-raw-body]')
432
- .innerText = message.raw;
433
-
434
- messageContent.appendChild(messageContentTemplate);
435
- },
436
-
437
- /**
438
- * Render the list of the messages. Also add event listener when click on a
439
- * message then it will load that conent.
440
- *
441
- * @param {Object} messages - the list of the given message.
442
- */
443
- renderMessageList: function(messages) {
444
- var messageListTemplate;
445
-
446
- var messageList =
447
- document
448
- .querySelector('ul[data-content-type=message-list]');
449
-
450
- messages.forEach(function(message) {
451
- messageListTemplate =
452
- document
453
- .querySelector('template[data-content-type=message-list-template]')
454
- .content
455
- .cloneNode(true);
456
-
457
- messageListTemplate
458
- .querySelector('li')
459
- .addEventListener('click', function() {
460
- MailGrabber.getMessage(message.id);
461
- });
462
-
463
- messageListTemplate
464
- .querySelector('div[data-content-type=message-senders]')
465
- .innerHTML = message.senders;
466
-
467
- messageListTemplate
468
- .querySelector('time[data-content-type=message-sent-at]')
469
- .innerHTML =
470
- MailGrabber
471
- .formatDateTime(message.created_at, 'messageListDateOrTime');
472
-
473
- messageListTemplate
474
- .querySelector('div[data-content-type=message-subject]')
475
- .innerHTML = message.subject;
65
+ }
66
+ );
67
+ },
476
68
 
477
- messageList.appendChild(messageListTemplate);
478
- });
479
- },
69
+ /**
70
+ * Scrolling infinitely. Count the height of the list and if we reached the
71
+ * bottom of the list then tries to load more message.
72
+ *
73
+ * @param {Object} messageList - the message list container
74
+ */
75
+ infiniteScroll: function(messageList) {
76
+ var scrollHeight = messageList.scrollHeight;
77
+ var scrollTop = messageList.scrollTop;
78
+ var clientHeight = messageList.clientHeight;
79
+
80
+ if(scrollHeight - scrollTop === clientHeight &&
81
+ !MailGrabberVariables.messageListReloading) {
82
+ MailGrabberApplication.getMessageList();
83
+ }
84
+ },
480
85
 
481
- /**
482
- * Render senders and recipients data of the message.
483
- *
484
- * @param {Object} message - the requested message
485
- *
486
- * @return {Object} the rendered metadata
487
- */
488
- renderMetadata: function(message) {
489
- var metadata =
490
- '<dt>From:</dt><dd>' + message.senders + '</dd>' +
491
- '<dt>To:</dt><dd>' + message.recipients + '</dd>';
86
+ /**
87
+ * Initialize MailGrabber. Add some event listeners to the Reload and the
88
+ * Clear tabs, then load messages and the default background.
89
+ */
90
+ init: function() {
91
+ document
92
+ .querySelector('li[data-content-type=message-reload-tab]')
93
+ .addEventListener('click', MailGrabberApplication.reloadMessageList);
492
94
 
493
- if(message.carbon_copy) {
494
- metadata += '<dt>Cc:</dt><dd>' + message.carbon_copy + '</dd>';
495
- }
95
+ document
96
+ .querySelector('li[data-content-type=message-clear-tab]')
97
+ .addEventListener('click', MailGrabberApplication.deleteMessageList);
496
98
 
497
- if(message.blind_carbon_copy) {
498
- metadata += '<dt>Bcc:</dt><dd>' + message.blind_carbon_copy + '</dd>';
499
- }
99
+ MailGrabberApplication.loadMessageList();
100
+ MailGrabberDOM.defaultBackground();
101
+ },
500
102
 
501
- return metadata;
502
- },
103
+ /**
104
+ * Load the message list. Also add event listener for infinite scroll.
105
+ */
106
+ loadMessageList: function() {
107
+ var messageList =
108
+ document
109
+ .querySelector('ul[data-content-type=message-list]');
503
110
 
504
- /**
505
- * Request function to get data from the server.
506
- *
507
- * @param {String} method - the request method e.g. GET, POST, DELETE
508
- * @param {String} path - the path which we can get/send data
509
- * @param {Function} fn - the function which handle the response
510
- */
511
- request: function(method, path, fn) {
512
- var xhr = new XMLHttpRequest();
111
+ messageList.addEventListener('scroll', function() {
112
+ MailGrabberApplication.infiniteScroll(messageList);
113
+ });
513
114
 
514
- xhr.onload = function() {
515
- if(xhr.status === 200) {
516
- fn(xhr.responseText);
517
- } else {
518
- console.log('MailGrabberRequestError:', xhr.status, xhr.statusText);
519
- }
520
- };
521
- xhr.open(method, MailGrabber.rootPath() + path, true);
522
- xhr.send();
523
- },
115
+ MailGrabberApplication.getMessageList();
116
+ },
524
117
 
525
- /**
526
- * Root path which returns back with the server's root path. It can be empty
527
- * string or a string. It depends on how the server is running (standalone
528
- * or in Ruby on Rails).
529
- */
530
- rootPath: function() {
531
- return document.querySelector('body').dataset.rootPath;
532
- }
533
- };
118
+ /**
119
+ * Reload the message list. When we have new messages in the database, but
120
+ * we scrolled down or clicked on the Reload tab.
121
+ */
122
+ reloadMessageList: function() {
123
+ MailGrabberVariables.messageListReloading = true;
124
+ MailGrabberDOM.deleteContent();
125
+ MailGrabberApplication.getMessageList();
126
+ },
534
127
 
535
128
  /**
536
- * When DOM loaded then call MailGrabber's init function.
129
+ * Request function to get data from the server.
130
+ *
131
+ * @param {String} method - the request method e.g. GET, POST, DELETE
132
+ * @param {String} path - the path which we can get/send data
133
+ * @param {Function} fn - the function which handle the response
537
134
  */
538
- document.addEventListener('DOMContentLoaded', MailGrabber.init);
539
- }).call(this);
135
+ request: function(method, path, fn) {
136
+ var xhr = new XMLHttpRequest();
137
+
138
+ xhr.onload = function() {
139
+ if(xhr.status === 200) {
140
+ fn(xhr.responseText);
141
+ } else {
142
+ console.log('MailGrabberRequestError:', xhr.status, xhr.statusText);
143
+ }
144
+ };
145
+ xhr.open(method, MailGrabberDOM.rootPath() + path, true);
146
+ xhr.send();
147
+ }
148
+ };