Advertisement
Guest User

gmailr.js

a guest
May 28th, 2013
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.       Number of unread messages.
  327.       */
  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);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement