View difference between Paste ID: pK4EG9vh and x57U0A6w
SHOW: | | - or go back to the newest paste.
1
// Generated by CoffeeScript 1.6.1
2
3
/*
4
Gmailr v0.0.1
5
Licensed under The MIT License
6
7
Copyright 2012, James Yu, Joscha Feth
8
*/
9
10
(function() {
11
  
12
	 		
13
		
14
  var __slice = [].slice;
15
  (function($, window) {
16
    var Gmailr, XHRWatcher, dbg, isDescendant,
17
      _this = this;
18
    XHRWatcher = (function() {
19
20
      XHRWatcher.prototype.initialized = false;
21
22
      XHRWatcher.prototype.iframeData = {};
23
24
      XHRWatcher.prototype.iframeCachedData = [];
25
26
      XHRWatcher.prototype._Gmail_open = null;
27
28
      XHRWatcher.prototype._Gmail_send = null;
29
30
      function XHRWatcher(cb) {
31
        var self, win, _ref, _ref1, _ref2;
32
        if (!this.initialized) {
33
          this.initialized = true;
34
          self = this;
35
          win = top.document.getElementById("js_frame").contentDocument.defaultView;
36
          if ((_ref = this._Gmail_open) == null) {
37
            this._Gmail_open = win.XMLHttpRequest.prototype.open;
38
          }
39
          win.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
40
            this.xhrParams = {
41
              method: method.toString(),
42
              url: url.toString()
43
            };
44
            return self._Gmail_open.apply(this, arguments);
45
          };
46
          if ((_ref1 = this._Gmail_send) == null) {
47
            this._Gmail_send = win.XMLHttpRequest.prototype.send;
48
          }
49
          win.XMLHttpRequest.prototype.send = function(body) {
50
            if (this.xhrParams) {
51
              this.xhrParams.body = body;
52
              cb(this.xhrParams);
53
            }
54
            return self._Gmail_send.apply(this, arguments);
55
          };
56
          if ((_ref2 = top._Gmail_iframeFn) == null) {
57
            top._Gmail_iframeFn = top.GG_iframeFn;
58
          }
59
          this.iframeCachedData.push({
60
            responseDataId: 1,
61
            url: top.location.href,
62
            responseData: top.VIEW_DATA
63
          });
64
          top.GG_iframeFn = function(win, data) {
65
            var body, d, parent, tmp, url, _ref3, _ref4;
66
            d = top._Gmail_iframeFn.apply(this, arguments);
67
            try {
68
              url = (_ref3 = win != null ? (_ref4 = win.location) != null ? _ref4.href : void 0 : void 0) != null ? _ref3 : null;
69
              if (data && (url != null ? url.indexOf("act=") : void 0) !== -1) {
70
                if (!self.iframeData[url]) {
71
                  self.iframeData[url] = true;
72
                  body = "";
73
                  if ((parent = win.frameElement.parentNode)) {
74
                    tmp = $(parent).find("form");
75
                    if (tmp.length > 0) {
76
                      body = tmp.first().serialize();
77
                    }
78
                  }
79
                  cb({
80
                    body: body,
81
                    url: url
82
                  });
83
                }
84
              }
85
            } catch (e) {
86
              try {
87
                dbg("DEBUG error in GG_iframeFn: ", e);
88
              } catch (_error) {}
89
            }
90
            return d;
91
          };
92
        }
93
      }
94
95
      return XHRWatcher;
96
97
    })();
98
    
99
           
100
    
101
    dbg = function() {
102
      var args;
103
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
104
      args.unshift('[Gmailr]');
105
      if ((typeof console !== "undefined" && console !== null ? console.log : void 0) && Gmailr.debug === true) {
106
        console.log.apply(console, args);
107
      }
108
    };
109
    isDescendant = function(el, t) {
110
      return t.parents().index(el) >= 0;
111
    };
112
    Gmailr = (function() {
113
      
114
      function Gmailr() {
115
        var _this = this;
116
        this.detectDOMEvents = function(e) {
117
          return Gmailr.prototype.detectDOMEvents.apply(_this, arguments);
118
        };
119
        this.detectXHREvents = function(params) {
120
          return Gmailr.prototype.detectXHREvents.apply(_this, arguments);
121
        };
122
      }
123
124
      Gmailr.prototype.debug = false;
125
126
      Gmailr.prototype.priorityInboxLink = null;
127
128
      Gmailr.prototype.inboxLink = null;
129
130
      Gmailr.prototype.currentNumUnread = null;
131
132
      Gmailr.prototype.currentInboxCount = null;
133
134
      Gmailr.prototype.elements = {};
135
136
      Gmailr.prototype.currentLeftMenuItem = null;
137
138
      Gmailr.prototype.observers = {};
139
140
      Gmailr.prototype.loaded = false;
141
142
      Gmailr.prototype.inConversationView = false;
143
144
      Gmailr.prototype.xhrWatcher = null;
145
146
      Gmailr.prototype.delayedLoader = null;
147
148
      Gmailr.prototype.ignoreDOMElements = [];
149
150
      Gmailr.prototype.EVENT_VIEW_THREAD = 'viewThread';
151
152
      Gmailr.prototype.EVENT_LOADED = 'load';
153
154
      Gmailr.prototype.EVENT_ARCHIVE = 'archive';
155
156
      Gmailr.prototype.EVENT_APPLY_LABEL = 'applyLabel';
157
158
      Gmailr.prototype.EVENT_DELETE = 'delete';
159
160
      Gmailr.prototype.EVENT_COMPOSE = 'compose';
161
162
      Gmailr.prototype.EVENT_REPLY = 'reply';
163
164
      Gmailr.prototype.EVENT_SPAM = 'spam';
165
166
      Gmailr.prototype.EVENT_DRAFT_DISCARD = 'discardDraft';
167
168
      Gmailr.prototype.EVENT_DRAFT_SAVE = 'saveDraft';
169
170
      Gmailr.prototype.EVENT_MARK_UNREAD = 'unread';
171
172
      Gmailr.prototype.EVENT_STAR = 'star';
173
174
      Gmailr.prototype.EVENT_UNSTAR = 'unstar';
175
176
      Gmailr.prototype.EVENT_UNREAD_CHANGE = 'numUnreadChange';
177
178
      Gmailr.prototype.EVENT_INBOX_COUNT_CHANGE = 'inboxCountChange';
179
180
      Gmailr.prototype.EVENT_VIEW_CHANGED = 'viewChanged';
181
182
      Gmailr.prototype.EVENT_REFRESH_INBOX = 'refresh';
183
184
      Gmailr.prototype.EVENT_ANY = 'any';
185
186
      Gmailr.prototype.VIEW_CONVERSATION = 'conversation';
187
188
      Gmailr.prototype.VIEW_THREADED = 'threaded';
189
190
      Gmailr.prototype.init = function(cb) {
191
        var load,
192
          _this = this;
193
        if (this.loaded) {
194
          dbg("Gmailr has already been initialized");
195
          if (typeof cb === "function") {
196
            cb(this);
197
          }
198
          return;
199
        }
200
        dbg("Initializing Gmailr API");
201
        load = function() {
202
          var canvas_frame;
203
          _this.elements.canvas = $((canvas_frame = $("#canvas_frame").get(0)) ? canvas_frame.contentDocument : document);
204
          _this.elements.body = _this.elements.canvas.find(".nH").first();
205
          if (_this.loaded) {
206
            clearInterval(_this.delayedLoader);
207
            dbg("Delayed loader success.");
208
            _this.elements.body.children().on('DOMSubtreeModified', _this.detectDOMEvents);
209
            _this.notify(_this.EVENT_LOADED);
210
          } else {
211
            dbg("Calling delayed loader...");
212
            _this.bootstrap(cb);
213
          }
214
        };
215
        this.delayedLoader = setInterval(load, 200);
216
      };
217
218
      /*
219
      This method attempts to bootstrap Gmailr into the Gmail interface.
220
      Basically, this amounts polling to make sure Gmail has fully loaded,
221
      and then setting up some basic hooks.
222
      */
223
224
225
      Gmailr.prototype.bootstrap = function(cb) {
226
        var inboxLink, v;
227
        if (!this.inBootstrap) {
228
          this.inBootstrap = true;
229
          if (this.elements.body) {
230
            if (!this.leftMenu || this.leftMenu.length === 0) {
231
              if ((inboxLink = this.getInboxLink())) {
232
                this.leftMenu = inboxLink.closest(".TO").closest("div");
233
              } else {
234
                v = this.elements.body.find("a[href$='#mbox']");
235
                if (v.length > 0) {
236
                  this.priorityInboxLink = v.first();
237
                }
238
                if (this.priorityInboxLink) {
239
                  this.leftMenu = this.priorityInboxLink.closest(".TO").closest("div");
240
                }
241
              }
242
              if (this.leftMenu && this.leftMenu.length > 0) {
243
                this.leftMenuItems = this.leftMenu.find(".TO");
244
                dbg("Fully loaded.");
245
                this.loaded = true;
246
                this.currentNumUnread = this.numUnread();
247
                if (this.inboxTabHighlighted()) {
248
                  this.currentInboxCount = this.toolbarCount();
249
                }
250
                this.xhrWatcher = new XHRWatcher(this.detectXHREvents);
251
                if (typeof cb === "function") {
252
                  cb(this);
253
                }
254
              }
255
            }
256
          }
257
          this.inBootstrap = false;
258
        }
259
      };
260
261
      Gmailr.prototype.intercept = function() {
262
        if (!this.loaded) {
263
          throw "Call to method before Gmail has loaded";
264
        }
265
      };
266
267
      Gmailr.prototype.insertTop = function(el, ignoreDOMEvents) {
268
        if (ignoreDOMEvents == null) {
269
          ignoreDOMEvents = true;
270
        }
271
        this.intercept();
272
        el = $(el);
273
        this.elements.body.prepend(el);
274
        if (ignoreDOMEvents) {
275
          this.ignoreDOMElements.push(el.get(0));
276
        }
277
      };
278
279
      Gmailr.prototype.$ = function(selector) {
280
        this.intercept();
281
        return this.elements.body.find(selector);
282
      };
283
284
      /*
285
      Subscribe to a specific event in Gmail
286
      */
287
288
      Gmailr.prototype.store = function() {
289
        localStorage.flag = "updated flag";
290
    
291
      };
292
293
      Gmailr.prototype.observe = function(type, cb) {
294
        var _base, _ref;
295
        return ((_ref = (_base = this.observers)[type]) != null ? _ref : _base[type] = []).push(cb);
296
      };
297
298
      Gmailr.prototype.notify = function() {
299
        var args, listener, type, _i, _j, _len, _len1, _ref, _ref1;
300
        type = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
301
        if (this.observers[type]) {
302
          _ref = this.observers[type];
303
          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
304
            listener = _ref[_i];
305
            if (listener != null) {
306
              if (typeof listener.apply === "function") {
307
                listener.apply(this, args);
308
              }
309
            }
310
          }
311
        }
312
        if (type !== this.EVENT_ANY) {
313
          _ref1 = this.observers[this.EVENT_ANY];
314
          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
315
            listener = _ref1[_j];
316
            if (listener != null) {
317
              if (typeof listener.call === "function") {
318
                listener.call(this, type, args);
319
              }
320
            }
321
          }
322
        }
323
      };
324
325
     /*
326-
      //trying to send messages to the background page
326+
327-
      Gmailr.prototype.sendmsg = function() {
327+
328-
        sendMsg();
328+
329
330
      Gmailr.prototype.numUnread = function() {
331
        var m, title;
332
        this.intercept();
333
        title = this.getInboxLink().attr('title');
334
        m = /\((\d+)\)/.exec(title);
335
        if (m != null ? m[1] : void 0) {
336
          return parseInt(m[1]);
337
        } else {
338
          return 0;
339
        }
340
      };
341
342
      /*
343
      Email address of the Gmail account.
344
      */
345
346
347
      Gmailr.prototype.emailAddress = function() {
348
        var el, selectors;
349
        this.intercept();
350
        selectors = ["#guser b", ".gbmp1", '.gbps2'];
351
        el = this.elements.canvas.find(selectors.join(','));
352
        return el.first().html();
353
      };
354
355
356
      /*
357
      Returns whether the current view is a threaded or conversation view.
358
      */
359
360
361
      Gmailr.prototype.currentView = function() {
362
        this.intercept();
363
        if (this.elements.canvas.find("h1.ha").length > 0) {
364
          return this.VIEW_CONVERSATION;
365
        } else {
366
          return this.VIEW_THREADED;
367
        }
368
      };
369
370
      Gmailr.prototype.inboxes = ["a[href$='#inbox'][title^='Inbox']", "a[href$='#inbox'][title^='Posteingang']", "a[href$='#inbox'][title^='Postvak IN']", "a[href$='#inbox'][target='_top']"];
371
372
      Gmailr.prototype.getInboxLink = function() {
373
        return this.elements.body.find(this.inboxes.join(',')).first() || null;
374
      };
375
376
      Gmailr.prototype.liveLeftMenuItem = function() {
377
        var el;
378
        if (!this.loaded) {
379
          return null;
380
        }
381
        el = this.leftMenuItems.filter(".nZ").find("a");
382
        if (el[0]) {
383
          return el[0].title;
384
        } else {
385
          return null;
386
        }
387
      };
388
389
      Gmailr.prototype.inboxTabHighlighted = function() {
390
        return this.currentTabHighlighted() === "inbox" || this.currentTabHighlighted() === "priority_inbox";
391
      };
392
393
      Gmailr.prototype.currentTabHighlighted = function() {
394
        var inboxLink;
395
        inboxLink = this.getInboxLink();
396
        if (inboxLink && inboxLink.closest(".TO").hasClass("nZ")) {
397
          return "inbox";
398
        } else if (this.priorityInboxLink && this.priorityInboxLink.closest(".TO").hasClass("nZ")) {
399
          return "priority_inbox";
400
        } else {
401
          return null;
402
        }
403
      };
404
405
      Gmailr.prototype.archiveableState = function() {
406
        return (this.inboxTabHighlighted() && this.currentView() === this.VIEW_THREADED) || (this.currentView() !== this.VIEW_THREADED);
407
      };
408
409
      Gmailr.prototype.mainListingEl = function() {
410
        return this.elements.canvas.find(".nH.Cp").first();
411
      };
412
413
      Gmailr.prototype.mainListingEmpty = function() {
414
        if (this.mainListingEl().length > 0 && this.currentView() === this.VIEW_THREADED) {
415
          return this.mainListingEl().find("table tr").length === 0;
416
        } else {
417
          return null;
418
        }
419
      };
420
421
      Gmailr.prototype.toolbarEl = function() {
422
        return this.elements.canvas.find(".A1.D.E").first();
423
      };
424
425
      Gmailr.prototype.toolbarCount = function() {
426
        var el, m, t;
427
        el = this.toolbarEl().find(".Dj");
428
        if (el[0]) {
429
          t = el[0].innerHTML;
430
          m = /of <b>(\d+)<\/b>/.exec(t);
431
          if ((m != null ? m[1] : void 0) != null) {
432
            return parseInt(m[1]);
433
          } else {
434
            return null;
435
          }
436
        } else {
437
          if (this.mainListingEmpty()) {
438
            return 0;
439
          } else {
440
            return null;
441
          }
442
        }
443
      };
444
445
      Gmailr.prototype.toEmailProps = function(postParams) {
446
        var _ref, _ref1;
447
        return {
448
          inReplyTo: (postParams.rm === "undefined" ? null : postParams.rm),
449
          body: (_ref = postParams.body) != null ? _ref : null,
450
          subject: (_ref1 = postParams.subject) != null ? _ref1 : null,
451
          bcc: this.toEmailArray(postParams.bcc),
452
          to: this.toEmailArray(postParams.to),
453
          from: postParams.from,
454
          isHTML: postParams.ishtml === '1',
455
          cc: this.toEmailArray(postParams.cc),
456
          fromDraft: (postParams.draft === "undefined" ? null : postParams.draft)
457
        };
458
      };
459
460
      Gmailr.prototype.toEmailArray = function(str) {
461
        var m, regex, _results;
462
        if (!str) {
463
          return [];
464
        }
465
        regex = /(?:"([^"]+)")? ?<?(.*?@[^>,]+)>?,? ?/g;
466
        _results = [];
467
        while ((m = regex.exec(str))) {
468
          _results.push({
469
            name: m[1],
470
            email: m[2]
471
          });
472
        }
473
        return _results;
474
      };
475
476
      Gmailr.prototype.detectXHREvents = function(params) {
477
        var action, count, label, postParams, starType, urlParams, _ref, _ref1;
478
        try {
479
          urlParams = $.deparam(params.url);
480
          action = (_ref = urlParams.act) != null ? _ref : urlParams.view;
481
          count = 1;
482
          postParams = null;
483
          if (params.body.length > 0) {
484
            postParams = $.deparam(params.body);
485
            if (postParams && postParams.t && !(postParams.t instanceof Array)) {
486
              postParams.t = [postParams.t];
487
              count = postParams.t.length;
488
            }
489
            if (postParams["ba"]) {
490
              count = -1;
491
            }
492
          }
493
          switch (action) {
494
            case "ad":
495
              if (!urlParams.th) {
496
                this.notify(this.EVENT_REFRESH_INBOX);
497
              } else {
498
                dbg("User views a thred");
499
                this.notify(this.EVENT_VIEW_THREAD, urlParams.th);
500
              }
501
              break;
502
            case "rc_^i":
503
              if ((_ref1 = urlParams.search) === "inbox" || _ref1 === "query" || _ref1 === "cat" || _ref1 === "mbox") {
504
                if (postParams) {
505
                  dbg("User archived emails.");
506
                  this.notify(this.EVENT_ARCHIVE, count, postParams.t);
507
                }
508
              }
509
              break;
510
            case "arl":
511
              label = urlParams["acn"];
512
              this.notify(this.EVENT_APPLY_LABEL, label, count, postParams.t);
513
              break;
514
            case "tr":
515
              dbg("User deleted " + count + " emails.");
516
              this.notify(this.EVENT_DELETE, count, postParams.t);
517
              break;
518
            case "sm":
519
              if (this.currentView() === this.VIEW_CONVERSATION) {
520
                dbg("User replied to an email.");
521
                this.notify(this.EVENT_REPLY, this.toEmailProps(postParams));
522
              } else {
523
                dbg("User composed an email.");
524
                this.notify(this.EVENT_COMPOSE, this.toEmailProps(postParams));
525
              }
526
              break;
527
            case "sp":
528
              dbg("User spammed " + count + " emails.");
529
              this.notify(this.EVENT_SPAM, count, postParams.t);
530
              break;
531
            case "dr":
532
              dbg("User discarded? a draft.");
533
              this.notify(this.EVENT_DRAFT_DISCARD);
534
              break;
535
            case "sd":
536
              dbg("User saved? a draft.");
537
              this.notify(this.EVENT_DRAFT_SAVE, this.toEmailProps(postParams));
538
              break;
539
            case "ur":
540
              dbg("User marked messages as unread.");
541
              this.notify(this.EVENT_MARK_UNREAD, count, postParams.t);
542
              break;
543
            case "st":
544
              dbg("User starred messages.");
545
              starType = (function() {
546
                switch (postParams.sslbl) {
547
                  case "^ss_sy":
548
                    return "standard";
549
                  default:
550
                    return "unknown";
551
                }
552
              })();
553
              this.notify(this.EVENT_STAR, count, postParams.t, starType);
554
              break;
555
            case "xst":
556
              dbg("User unstarred messages.");
557
              this.notify(this.EVENT_UNSTAR, count, postParams.t);
558
          }
559
        } catch (e) {
560
          dbg("Error in detectXHREvents: " + e);
561
        }
562
      };
563
564
      Gmailr.prototype.detectDOMEvents = function(e) {
565
        var el, ignored, newCount, toolbarCount, _i, _len, _ref;
566
        e.stopPropagation();
567
        _ref = this.ignoreDOMElements;
568
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
569
          ignored = _ref[_i];
570
          if ($.contains(ignored, e.target)) {
571
            return false;
572
          }
573
        }
574
        el = $(e.target);
575
        newCount = this.numUnread();
576
        if (this.currentNumUnread !== newCount) {
577
          dbg("Unread count changed");
578
          this.notify(this.EVENT_UNREAD_CHANGE, newCount, this.currentNumUnread);
579
          this.currentNumUnread = newCount;
580
        }
581
        if (this.elements.canvas.find(".ha").length > 0) {
582
          if (!this.inConversationView) {
583
            this.inConversationView = true;
584
            this.notify(this.EVENT_VIEW_CHANGED, this.VIEW_CONVERSATION);
585
          }
586
        } else {
587
          if (this.inConversationView) {
588
            this.inConversationView = false;
589
            this.notify(this.EVENT_VIEW_CHANGED, this.VIEW_THREADED);
590
          }
591
        }
592
        if (isDescendant(this.toolbarEl(), el)) {
593
          toolbarCount = this.toolbarCount();
594
          if (this.inboxTabHighlighted() && toolbarCount) {
595
            if ((this.currentInboxCount === null) || (toolbarCount !== this.currentInboxCount)) {
596
              if (this.currentInboxCount !== null) {
597
                this.notify(this.EVENT_INBOX_COUNT_CHANGE, toolbarCount, this.currentInboxCount);
598
              }
599
              return this.currentInboxCount = toolbarCount;
600
            }
601
          }
602
        }
603
      };
604
      
605
      
606
607
      return Gmailr;
608
609
    })();
610
    Gmailr = new Gmailr;
611
    window.Gmailr = Gmailr;
612
  })(jQuery, window);
613
614
}).call(this);