mail_grabber 1.0.0.rc1 → 1.0.0
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 +16 -0
- data/lib/mail_grabber/version.rb +1 -1
- data/lib/mail_grabber/web/assets/javascripts/application.js +130 -521
- data/lib/mail_grabber/web/assets/javascripts/dom.js +86 -0
- data/lib/mail_grabber/web/assets/javascripts/message_attachment.js +36 -0
- data/lib/mail_grabber/web/assets/javascripts/message_content.js +114 -0
- data/lib/mail_grabber/web/assets/javascripts/message_html_part.js +26 -0
- data/lib/mail_grabber/web/assets/javascripts/message_inline_attachments.js +21 -0
- data/lib/mail_grabber/web/assets/javascripts/message_list.js +54 -0
- data/lib/mail_grabber/web/assets/javascripts/message_metadata.js +23 -0
- data/lib/mail_grabber/web/assets/javascripts/utilities.js +65 -0
- data/lib/mail_grabber/web/assets/javascripts/variables.js +24 -0
- data/lib/mail_grabber/web/assets/javascripts/web.js +6 -0
- data/lib/mail_grabber/web/views/index.html.erb +10 -0
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 700d9bdbeeed0c02117ec588e990fb4d69e5b239aa4fec3d13fbc70acbba1230
|
4
|
+
data.tar.gz: 71b84af90f8496cb0a07d9b96312ec37efa3b03e5fc871d57bd11468affabfb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aca1623fb80aa3f79ef16050d799c955352ac463cdd8dd03928b828ed5abb6a4821f19f7045ab592e79ad1524e3cd04ff59d4df2c7055064969e1ac00e9edb3
|
7
|
+
data.tar.gz: 981f1b1bb7f4310e3b6c703ea75e5c43a7e8626a377a80884a660c4d3f69b6d3546b21fa9acbcfea1c657379caea4aa6ed9ca4e508a7d374878efff255dadc5a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 1.0.0 (2021-04-02)
|
4
|
+
|
5
|
+
### Changes
|
6
|
+
|
7
|
+
* Update documentation.
|
8
|
+
* Change javascript to hide HTML tab if mail does not have HTML part.
|
9
|
+
* Refactoring the JavaScript code.
|
10
|
+
* Change the documentation uri in the gemspec file.
|
11
|
+
* Update .rubocop.yml.
|
12
|
+
* Update gems.
|
13
|
+
|
14
|
+
### Bug fixes
|
15
|
+
|
16
|
+
* Fix 3x load message list when reload tab and infinite scroll was used.
|
17
|
+
|
18
|
+
|
3
19
|
## 1.0.0.rc1 (2021-03-20)
|
4
20
|
|
5
21
|
* Implement MailGrabber methods and functionality. See [README.md](https://github.com/MailToolbox/mail_grabber/blob/main/README.md)
|
data/lib/mail_grabber/version.rb
CHANGED
@@ -1,539 +1,148 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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
|
-
|
325
|
-
|
326
|
-
|
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
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
.
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
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
|
-
|
494
|
-
|
495
|
-
|
95
|
+
document
|
96
|
+
.querySelector('li[data-content-type=message-clear-tab]')
|
97
|
+
.addEventListener('click', MailGrabberApplication.deleteMessageList);
|
496
98
|
|
497
|
-
|
498
|
-
|
499
|
-
|
99
|
+
MailGrabberApplication.loadMessageList();
|
100
|
+
MailGrabberDOM.defaultBackground();
|
101
|
+
},
|
500
102
|
|
501
|
-
|
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
|
-
|
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
|
-
|
515
|
-
|
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
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
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
|
-
*
|
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
|
-
|
539
|
-
|
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
|
+
};
|
@@ -0,0 +1,86 @@
|
|
1
|
+
var MailGrabberDOM = {
|
2
|
+
/**
|
3
|
+
* Change which content (message part) should show. When the page is loading
|
4
|
+
* the HTML content will be active and the others will be hidden. When we
|
5
|
+
* click on tab e.g. Plain Text then this content will active and other
|
6
|
+
* hidden.
|
7
|
+
*
|
8
|
+
* @param {Object} event - which part we clicked
|
9
|
+
*/
|
10
|
+
changeMessageContent: function(event) {
|
11
|
+
var messageTabs =
|
12
|
+
document
|
13
|
+
.querySelectorAll('[data-message-tab]');
|
14
|
+
|
15
|
+
var messageContents =
|
16
|
+
document
|
17
|
+
.querySelectorAll('[data-message-content]');
|
18
|
+
|
19
|
+
var clickedTabType = event.target.dataset.messageTab;
|
20
|
+
|
21
|
+
messageTabs.forEach(function(messageTab, index) {
|
22
|
+
messageTab.classList.remove('active');
|
23
|
+
messageContents[index].classList.remove('hide');
|
24
|
+
|
25
|
+
if(messageTab.dataset.messageTab === clickedTabType) {
|
26
|
+
messageTab.classList.add('active');
|
27
|
+
}
|
28
|
+
|
29
|
+
if(messageContents[index].dataset.messageContent !== clickedTabType) {
|
30
|
+
messageContents[index].classList.add('hide');
|
31
|
+
}
|
32
|
+
});
|
33
|
+
},
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Create a clone from an element e.g. template tag.
|
37
|
+
*
|
38
|
+
* @param {String} selector - which describe how find the element
|
39
|
+
*
|
40
|
+
* @return {Object} the clone of the found element
|
41
|
+
*/
|
42
|
+
cloneContent: function(selector) {
|
43
|
+
return document.querySelector(selector).content.cloneNode(true);
|
44
|
+
},
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Show default backgroud image instead of any content.
|
48
|
+
*/
|
49
|
+
defaultBackground: function() {
|
50
|
+
var messageContent =
|
51
|
+
document
|
52
|
+
.querySelector('div[data-content-type=message-content]');
|
53
|
+
|
54
|
+
messageContent.innerHTML = '';
|
55
|
+
|
56
|
+
messageContent.style.background =
|
57
|
+
"url('" + messageContent.dataset.backgroundImage +
|
58
|
+
"') center center no-repeat";
|
59
|
+
messageContent.style.backgroundSize = '50%';
|
60
|
+
messageContent.style.opacity = '10%';
|
61
|
+
},
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Delete all content (message list and message content as well),
|
65
|
+
* set default backgroud and the infinite scroll params when we click on
|
66
|
+
* the Reload or Delete tabs.
|
67
|
+
*/
|
68
|
+
deleteContent: function() {
|
69
|
+
MailGrabberVariables.lastMessageId = -1;
|
70
|
+
MailGrabberVariables.page = 1;
|
71
|
+
MailGrabberDOM.defaultBackground();
|
72
|
+
|
73
|
+
document
|
74
|
+
.querySelector('ul[data-content-type=message-list]')
|
75
|
+
.innerHTML = '';
|
76
|
+
},
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Root path which returns back with the server's root path. It can be empty
|
80
|
+
* string or a string. It depends on how the server is running (standalone
|
81
|
+
* or in Ruby on Rails).
|
82
|
+
*/
|
83
|
+
rootPath: function() {
|
84
|
+
return document.querySelector('body').dataset.rootPath;
|
85
|
+
}
|
86
|
+
};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
var MailGrabberMessageAttachment = {
|
2
|
+
/**
|
3
|
+
* Render message attachment. Show the list of attachments at the top of the
|
4
|
+
* message content.
|
5
|
+
*
|
6
|
+
* @param {Object} messageAttachments - the message attachments container
|
7
|
+
* @param {Object} messagePart - a message part which we loaded
|
8
|
+
*/
|
9
|
+
render: function(messageAttachments, messagePart) {
|
10
|
+
var messageAttachment = document.createElement('a');
|
11
|
+
var fileSize = document.createElement('span');
|
12
|
+
var messageAttachmentTemplate =
|
13
|
+
MailGrabberDOM
|
14
|
+
.cloneContent(
|
15
|
+
'template[data-content-type=message-attachment-template]'
|
16
|
+
);
|
17
|
+
|
18
|
+
messageAttachment.href =
|
19
|
+
'data:' + messagePart.mime_type + ';base64,' + messagePart.body;
|
20
|
+
messageAttachment.download = messagePart.filename;
|
21
|
+
messageAttachment.innerHTML = messagePart.filename;
|
22
|
+
messageAttachment.classList.add('color-black', 'no-text-decoration');
|
23
|
+
|
24
|
+
fileSize.innerHTML = MailGrabberUtilities.formatSize(messagePart.size);
|
25
|
+
fileSize.classList.add('color-gray', 'font-size-0_9', 'padding-left-10');
|
26
|
+
|
27
|
+
[messageAttachment, fileSize].forEach(function(node) {
|
28
|
+
messageAttachmentTemplate
|
29
|
+
.querySelector('li[data-content-type=message-attachment]')
|
30
|
+
.appendChild(node);
|
31
|
+
});
|
32
|
+
|
33
|
+
messageAttachments.classList.remove('hide');
|
34
|
+
messageAttachments.appendChild(messageAttachmentTemplate);
|
35
|
+
}
|
36
|
+
};
|
@@ -0,0 +1,114 @@
|
|
1
|
+
var MailGrabberMessageContent = {
|
2
|
+
/**
|
3
|
+
* Fill up the message content template with content.
|
4
|
+
*
|
5
|
+
* @param {Object} response - from the server with data
|
6
|
+
*
|
7
|
+
* @return {Object} the filled up template
|
8
|
+
*/
|
9
|
+
fillUpTemplateWith: function(response) {
|
10
|
+
var message = response.message;
|
11
|
+
var messageParts = response.message_parts;
|
12
|
+
var messageContentTemplate =
|
13
|
+
MailGrabberDOM
|
14
|
+
.cloneContent('template[data-content-type=message-content-template]');
|
15
|
+
|
16
|
+
messageContentTemplate
|
17
|
+
.querySelector('div[data-content-type=message-subject]')
|
18
|
+
.innerHTML = message.subject;
|
19
|
+
|
20
|
+
MailGrabberMessageMetadata.render(
|
21
|
+
messageContentTemplate
|
22
|
+
.querySelector('dl[data-content-type=metadata]'),
|
23
|
+
message
|
24
|
+
);
|
25
|
+
|
26
|
+
messageContentTemplate
|
27
|
+
.querySelector('time[data-content-type=message-sent-at]')
|
28
|
+
.innerHTML = MailGrabberUtilities.formatDateTime(message.created_at);
|
29
|
+
|
30
|
+
messageContentTemplate
|
31
|
+
.querySelectorAll('[data-message-tab]')
|
32
|
+
.forEach(function(tab) {
|
33
|
+
tab.addEventListener('click', MailGrabberDOM.changeMessageContent);
|
34
|
+
});
|
35
|
+
|
36
|
+
messageContentTemplate
|
37
|
+
.querySelector('li[data-content-type=message-delete-tab]')
|
38
|
+
.addEventListener('click', function() {
|
39
|
+
MailGrabberApplication.deleteMessage(message.id);
|
40
|
+
});
|
41
|
+
|
42
|
+
messageContentTemplate
|
43
|
+
.querySelector('li[data-content-type=message-close-tab]')
|
44
|
+
.addEventListener('click', MailGrabberDOM.defaultBackground);
|
45
|
+
|
46
|
+
messageParts.forEach(function(messagePart) {
|
47
|
+
if(messagePart.is_attachment === 0 && messagePart.is_inline === 0) {
|
48
|
+
switch(messagePart.mime_type) {
|
49
|
+
case 'text/html':
|
50
|
+
MailGrabberVariables.messageHasHtmlPart = true;
|
51
|
+
MailGrabberMessageHtmlPart.render(
|
52
|
+
messageContentTemplate
|
53
|
+
.querySelector('iframe[data-content-type=message-html-body]'),
|
54
|
+
messageParts,
|
55
|
+
messagePart.body
|
56
|
+
);
|
57
|
+
|
58
|
+
break;
|
59
|
+
case 'text/plain':
|
60
|
+
messageContentTemplate
|
61
|
+
.querySelector('pre[data-content-type=message-text-body]')
|
62
|
+
.innerText = messagePart.body;
|
63
|
+
|
64
|
+
break;
|
65
|
+
}
|
66
|
+
} else if(messagePart.is_attachment === 1 &&
|
67
|
+
messagePart.is_inline === 0) {
|
68
|
+
MailGrabberMessageAttachment.render(
|
69
|
+
messageContentTemplate
|
70
|
+
.querySelector('ul[data-content-type=message-attachments]'),
|
71
|
+
messagePart
|
72
|
+
);
|
73
|
+
}
|
74
|
+
});
|
75
|
+
|
76
|
+
messageContentTemplate
|
77
|
+
.querySelector('pre[data-content-type=message-raw-body]')
|
78
|
+
.innerText = message.raw;
|
79
|
+
|
80
|
+
return messageContentTemplate;
|
81
|
+
},
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Render the content of the message (all parts, inline attachments and
|
85
|
+
* attachments). Also it sets up event listeners of the HTML, PlainText,
|
86
|
+
* Raw, Delete and Close tabs.
|
87
|
+
*
|
88
|
+
* @param {Object} response - the response of the get message request
|
89
|
+
*/
|
90
|
+
render: function(response) {
|
91
|
+
var messageContent =
|
92
|
+
document
|
93
|
+
.querySelector('div[data-content-type=message-content]');
|
94
|
+
|
95
|
+
messageContent.removeAttribute('style');
|
96
|
+
messageContent.innerHTML = '';
|
97
|
+
|
98
|
+
MailGrabberVariables.messageHasHtmlPart = false;
|
99
|
+
|
100
|
+
messageContent.appendChild(
|
101
|
+
MailGrabberMessageContent.fillUpTemplateWith(response)
|
102
|
+
);
|
103
|
+
|
104
|
+
if(!MailGrabberVariables.messageHasHtmlPart) {
|
105
|
+
messageContent
|
106
|
+
.querySelector('li[data-message-tab=text]')
|
107
|
+
.click();
|
108
|
+
|
109
|
+
messageContent
|
110
|
+
.querySelector('li[data-message-tab=html]')
|
111
|
+
.classList.add('hide');
|
112
|
+
}
|
113
|
+
}
|
114
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
var MailGrabberMessageHtmlPart = {
|
2
|
+
/**
|
3
|
+
* Render the HTML part of the message. If the message has inline images
|
4
|
+
* then it will render those images as well. An iframe will contain this
|
5
|
+
* content.
|
6
|
+
*
|
7
|
+
* @param {Object} iFrame - the iframe HTML tag
|
8
|
+
* @param {Object} messageParts - the parts of the message
|
9
|
+
* @param {Object} messageHtmlPart - the HTML part of the message
|
10
|
+
*/
|
11
|
+
render: function(iFrame, messageParts, messageHtmlPart) {
|
12
|
+
var messageInlineAttachmentRegExp = new RegExp('cid:');
|
13
|
+
|
14
|
+
if(messageInlineAttachmentRegExp.test(messageHtmlPart)) {
|
15
|
+
messageHtmlPart =
|
16
|
+
MailGrabberMessageInlineAttachments.render(
|
17
|
+
messageParts, messageHtmlPart
|
18
|
+
);
|
19
|
+
}
|
20
|
+
|
21
|
+
iFrame.srcdoc = messageHtmlPart;
|
22
|
+
iFrame.onload = function() {
|
23
|
+
iFrame.height = iFrame.contentDocument.body.scrollHeight + 65;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
};
|
@@ -0,0 +1,21 @@
|
|
1
|
+
var MailGrabberMessageInlineAttachments = {
|
2
|
+
/**
|
3
|
+
* Render inline images of the message. Change the cid:something12345 with
|
4
|
+
* the encoded image content.
|
5
|
+
*
|
6
|
+
* @param {Object} messageParts - the parts of the message
|
7
|
+
* @param {Object} messageHtmlPart - the HTML part of the message
|
8
|
+
*
|
9
|
+
* @return {Object} messageHtmlPart - the modified HTML part of the message
|
10
|
+
*/
|
11
|
+
render: function(messageParts, messageHtmlPart) {
|
12
|
+
messageParts.forEach(function(messagePart) {
|
13
|
+
if(messagePart.is_attachment === 1 && messagePart.is_inline === 1) {
|
14
|
+
messageHtmlPart = messageHtmlPart.replace('cid:' + messagePart.cid,
|
15
|
+
'data:' + messagePart.mime_type + ';base64,' + messagePart.body);
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
return messageHtmlPart;
|
20
|
+
}
|
21
|
+
};
|
@@ -0,0 +1,54 @@
|
|
1
|
+
var MailGrabberMessageList = {
|
2
|
+
/**
|
3
|
+
* Fill up the message list template with content.
|
4
|
+
*
|
5
|
+
* @param {Object} message
|
6
|
+
*
|
7
|
+
* @return {Object} the filled up template
|
8
|
+
*/
|
9
|
+
fillUpTemplateWith: function(message) {
|
10
|
+
var messageListTemplate =
|
11
|
+
MailGrabberDOM
|
12
|
+
.cloneContent('template[data-content-type=message-list-template]');
|
13
|
+
|
14
|
+
messageListTemplate
|
15
|
+
.querySelector('li')
|
16
|
+
.addEventListener('click', function() {
|
17
|
+
MailGrabberApplication.getMessage(message.id);
|
18
|
+
});
|
19
|
+
|
20
|
+
messageListTemplate
|
21
|
+
.querySelector('div[data-content-type=message-senders]')
|
22
|
+
.innerHTML = message.senders;
|
23
|
+
|
24
|
+
messageListTemplate
|
25
|
+
.querySelector('time[data-content-type=message-sent-at]')
|
26
|
+
.innerHTML =
|
27
|
+
MailGrabberUtilities
|
28
|
+
.formatDateTime(message.created_at, 'messageListDateOrTime');
|
29
|
+
|
30
|
+
messageListTemplate
|
31
|
+
.querySelector('div[data-content-type=message-subject]')
|
32
|
+
.innerHTML = message.subject;
|
33
|
+
|
34
|
+
return messageListTemplate;
|
35
|
+
},
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Render the list of the messages. Also add event listener when click on a
|
39
|
+
* message then it will load that conent.
|
40
|
+
*
|
41
|
+
* @param {Object} messages - the list of the given message.
|
42
|
+
*/
|
43
|
+
render: function(messages) {
|
44
|
+
var messageList =
|
45
|
+
document
|
46
|
+
.querySelector('ul[data-content-type=message-list]');
|
47
|
+
|
48
|
+
messages.forEach(function(message) {
|
49
|
+
messageList.appendChild(
|
50
|
+
MailGrabberMessageList.fillUpTemplateWith(message)
|
51
|
+
);
|
52
|
+
});
|
53
|
+
}
|
54
|
+
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
var MailGrabberMessageMetadata = {
|
2
|
+
/**
|
3
|
+
* Render senders and recipients data of the message.
|
4
|
+
*
|
5
|
+
* @param {Object} messageMetadata - the metadata container
|
6
|
+
* @param {Object} message - the requested message
|
7
|
+
*/
|
8
|
+
render: function(messageMetadata, message) {
|
9
|
+
var metadata =
|
10
|
+
'<dt>From:</dt><dd>' + message.senders + '</dd>' +
|
11
|
+
'<dt>To:</dt><dd>' + message.recipients + '</dd>';
|
12
|
+
|
13
|
+
if(message.carbon_copy) {
|
14
|
+
metadata += '<dt>Cc:</dt><dd>' + message.carbon_copy + '</dd>';
|
15
|
+
}
|
16
|
+
|
17
|
+
if(message.blind_carbon_copy) {
|
18
|
+
metadata += '<dt>Bcc:</dt><dd>' + message.blind_carbon_copy + '</dd>';
|
19
|
+
}
|
20
|
+
|
21
|
+
messageMetadata.innerHTML = metadata;
|
22
|
+
}
|
23
|
+
};
|
@@ -0,0 +1,65 @@
|
|
1
|
+
var MailGrabberUtilities = {
|
2
|
+
/**
|
3
|
+
* Format the given date or time.
|
4
|
+
*
|
5
|
+
* @param {DateTime} dateTime - the message created at attribute
|
6
|
+
* @param {String} ouputType - what type we would like to see
|
7
|
+
*
|
8
|
+
* @return {String} the new format of the date or time
|
9
|
+
*/
|
10
|
+
formatDateTime: function(dateTime, outputType) {
|
11
|
+
dateTime = new Date(dateTime);
|
12
|
+
var dateTimeNow = new Date();
|
13
|
+
// Sun Feb 21 2021 21:00:00 GMT+0100 (Central European Standard Time)
|
14
|
+
// 0 1 2 3 4 5 6 7 8 9
|
15
|
+
var dateTimeComponents = dateTime.toString().split(' ');
|
16
|
+
var output;
|
17
|
+
|
18
|
+
switch(outputType) {
|
19
|
+
case 'messageListDateOrTime':
|
20
|
+
if(dateTime.getDate() === dateTimeNow.getDate()) {
|
21
|
+
output = MailGrabberUtilities.formatTime(dateTimeComponents[4]);
|
22
|
+
} else if(dateTime.getFullYear() === dateTimeNow.getFullYear()) {
|
23
|
+
output = dateTimeComponents[1] + ' ' + dateTimeComponents[2];
|
24
|
+
} else {
|
25
|
+
output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
|
26
|
+
dateTimeComponents[2];
|
27
|
+
}
|
28
|
+
|
29
|
+
break;
|
30
|
+
default:
|
31
|
+
output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
|
32
|
+
dateTimeComponents[2] + ' - ' +
|
33
|
+
MailGrabberUtilities.formatTime(dateTimeComponents[4]);
|
34
|
+
}
|
35
|
+
|
36
|
+
return output;
|
37
|
+
},
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Format the given number (attachment size).
|
41
|
+
*
|
42
|
+
* @param {Number} size - the size of the attachment in bytes
|
43
|
+
*
|
44
|
+
* @return {String} the formatted number with unit
|
45
|
+
*/
|
46
|
+
formatSize: function(size) {
|
47
|
+
var exponent = (Math.log(size) / Math.log(1024)) | 0;
|
48
|
+
var number = +(size / Math.pow(1024, exponent)).toFixed(1);
|
49
|
+
|
50
|
+
return number + ' ' + ('KMGTPEZY'[exponent - 1] || '') + 'B';
|
51
|
+
},
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Format the given time.
|
55
|
+
*
|
56
|
+
* @param {String} time
|
57
|
+
*
|
58
|
+
* @return {String} the new format of the time
|
59
|
+
*/
|
60
|
+
formatTime: function(time) {
|
61
|
+
var timeComponents = time.split(':');
|
62
|
+
|
63
|
+
return timeComponents[0] + ':' + timeComponents[1];
|
64
|
+
}
|
65
|
+
};
|
@@ -0,0 +1,24 @@
|
|
1
|
+
var MailGrabberVariables = {
|
2
|
+
/**
|
3
|
+
* The last message id what loaded. If it is -1 then we have no any
|
4
|
+
* messages.
|
5
|
+
*/
|
6
|
+
lastMessageId: -1,
|
7
|
+
|
8
|
+
/**
|
9
|
+
* The message has HTML part or not.
|
10
|
+
*/
|
11
|
+
messageHasHtmlPart: false,
|
12
|
+
|
13
|
+
/**
|
14
|
+
* The message is list reloading or not (click on the Reload tab).
|
15
|
+
*/
|
16
|
+
messageListReloading: false,
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Params that we can follow how many messages we have on the list. We are
|
20
|
+
* loading 15 messages in every requests.
|
21
|
+
*/
|
22
|
+
page: 1,
|
23
|
+
perPage: 15
|
24
|
+
};
|
@@ -11,6 +11,16 @@
|
|
11
11
|
<link rel="stylesheet" href="<%= root_path %>/stylesheets/application.css" type="text/css" charset="utf-8">
|
12
12
|
|
13
13
|
<script src="<%= root_path %>/javascripts/application.js"></script>
|
14
|
+
<script src="<%= root_path %>/javascripts/dom.js"></script>
|
15
|
+
<script src="<%= root_path %>/javascripts/message_attachment.js"></script>
|
16
|
+
<script src="<%= root_path %>/javascripts/message_content.js"></script>
|
17
|
+
<script src="<%= root_path %>/javascripts/message_html_part.js"></script>
|
18
|
+
<script src="<%= root_path %>/javascripts/message_inline_attachments.js"></script>
|
19
|
+
<script src="<%= root_path %>/javascripts/message_list.js"></script>
|
20
|
+
<script src="<%= root_path %>/javascripts/message_metadata.js"></script>
|
21
|
+
<script src="<%= root_path %>/javascripts/utilities.js"></script>
|
22
|
+
<script src="<%= root_path %>/javascripts/variables.js"></script>
|
23
|
+
<script src="<%= root_path %>/javascripts/web.js"></script>
|
14
24
|
</head>
|
15
25
|
|
16
26
|
<body data-root-path="<%= root_path %>">
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail_grabber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Norbert Szivós
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
@@ -78,6 +78,16 @@ files:
|
|
78
78
|
- lib/mail_grabber/web/application_router.rb
|
79
79
|
- lib/mail_grabber/web/assets/images/mail_grabber515x500.png
|
80
80
|
- lib/mail_grabber/web/assets/javascripts/application.js
|
81
|
+
- lib/mail_grabber/web/assets/javascripts/dom.js
|
82
|
+
- lib/mail_grabber/web/assets/javascripts/message_attachment.js
|
83
|
+
- lib/mail_grabber/web/assets/javascripts/message_content.js
|
84
|
+
- lib/mail_grabber/web/assets/javascripts/message_html_part.js
|
85
|
+
- lib/mail_grabber/web/assets/javascripts/message_inline_attachments.js
|
86
|
+
- lib/mail_grabber/web/assets/javascripts/message_list.js
|
87
|
+
- lib/mail_grabber/web/assets/javascripts/message_metadata.js
|
88
|
+
- lib/mail_grabber/web/assets/javascripts/utilities.js
|
89
|
+
- lib/mail_grabber/web/assets/javascripts/variables.js
|
90
|
+
- lib/mail_grabber/web/assets/javascripts/web.js
|
81
91
|
- lib/mail_grabber/web/assets/stylesheets/application.css
|
82
92
|
- lib/mail_grabber/web/views/_message_attachment_template.html.erb
|
83
93
|
- lib/mail_grabber/web/views/_message_content_template.html.erb
|
@@ -91,7 +101,7 @@ metadata:
|
|
91
101
|
source_code_uri: https://github.com/MailToolbox/mail_grabber
|
92
102
|
changelog_uri: https://github.com/MailToolbox/mail_grabber/blob/main/CHANGELOG.md
|
93
103
|
bug_tracker_uri: https://github.com/MailToolbox/mail_grabber/issues
|
94
|
-
documentation_uri: https://rubydoc.info/
|
104
|
+
documentation_uri: https://rubydoc.info/github/MailToolbox/mail_grabber/main
|
95
105
|
post_install_message:
|
96
106
|
rdoc_options: []
|
97
107
|
require_paths:
|
@@ -103,9 +113,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
113
|
version: 2.5.0
|
104
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
115
|
requirements:
|
106
|
-
- - "
|
116
|
+
- - ">="
|
107
117
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
118
|
+
version: '0'
|
109
119
|
requirements: []
|
110
120
|
rubygems_version: 3.1.4
|
111
121
|
signing_key:
|