browser/base/content/newtab/sites.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #ifdef 0
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #endif
     7 /**
     8  * This class represents a site that is contained in a cell and can be pinned,
     9  * moved around or deleted.
    10  */
    11 function Site(aNode, aLink) {
    12   this._node = aNode;
    13   this._node._newtabSite = this;
    15   this._link = aLink;
    17   this._render();
    18   this._addEventHandlers();
    19 }
    21 Site.prototype = {
    22   /**
    23    * The site's DOM node.
    24    */
    25   get node() this._node,
    27   /**
    28    * The site's link.
    29    */
    30   get link() this._link,
    32   /**
    33    * The url of the site's link.
    34    */
    35   get url() this.link.url,
    37   /**
    38    * The title of the site's link.
    39    */
    40   get title() this.link.title,
    42   /**
    43    * The site's parent cell.
    44    */
    45   get cell() {
    46     let parentNode = this.node.parentNode;
    47     return parentNode && parentNode._newtabCell;
    48   },
    50   /**
    51    * Pins the site on its current or a given index.
    52    * @param aIndex The pinned index (optional).
    53    */
    54   pin: function Site_pin(aIndex) {
    55     if (typeof aIndex == "undefined")
    56       aIndex = this.cell.index;
    58     this._updateAttributes(true);
    59     gPinnedLinks.pin(this._link, aIndex);
    60   },
    62   /**
    63    * Unpins the site and calls the given callback when done.
    64    */
    65   unpin: function Site_unpin() {
    66     if (this.isPinned()) {
    67       this._updateAttributes(false);
    68       gPinnedLinks.unpin(this._link);
    69       gUpdater.updateGrid();
    70     }
    71   },
    73   /**
    74    * Checks whether this site is pinned.
    75    * @return Whether this site is pinned.
    76    */
    77   isPinned: function Site_isPinned() {
    78     return gPinnedLinks.isPinned(this._link);
    79   },
    81   /**
    82    * Blocks the site (removes it from the grid) and calls the given callback
    83    * when done.
    84    */
    85   block: function Site_block() {
    86     if (!gBlockedLinks.isBlocked(this._link)) {
    87       gUndoDialog.show(this);
    88       gBlockedLinks.block(this._link);
    89       gUpdater.updateGrid();
    90     }
    91   },
    93   /**
    94    * Gets the DOM node specified by the given query selector.
    95    * @param aSelector The query selector.
    96    * @return The DOM node we found.
    97    */
    98   _querySelector: function Site_querySelector(aSelector) {
    99     return this.node.querySelector(aSelector);
   100   },
   102   /**
   103    * Updates attributes for all nodes which status depends on this site being
   104    * pinned or unpinned.
   105    * @param aPinned Whether this site is now pinned or unpinned.
   106    */
   107   _updateAttributes: function (aPinned) {
   108     let control = this._querySelector(".newtab-control-pin");
   110     if (aPinned) {
   111       control.setAttribute("pinned", true);
   112       control.setAttribute("title", newTabString("unpin"));
   113     } else {
   114       control.removeAttribute("pinned");
   115       control.setAttribute("title", newTabString("pin"));
   116     }
   117   },
   119   /**
   120    * Renders the site's data (fills the HTML fragment).
   121    */
   122   _render: function Site_render() {
   123     let url = this.url;
   124     let title = this.title || url;
   125     let tooltip = (title == url ? title : title + "\n" + url);
   127     let link = this._querySelector(".newtab-link");
   128     link.setAttribute("title", tooltip);
   129     link.setAttribute("href", url);
   130     this._querySelector(".newtab-title").textContent = title;
   131     this.node.setAttribute("type", this.link.type);
   133     if (this.isPinned())
   134       this._updateAttributes(true);
   135     // Capture the page if the thumbnail is missing, which will cause page.js
   136     // to be notified and call our refreshThumbnail() method.
   137     this.captureIfMissing();
   138     // but still display whatever thumbnail might be available now.
   139     this.refreshThumbnail();
   140   },
   142   /**
   143    * Captures the site's thumbnail in the background, but only if there's no
   144    * existing thumbnail and the page allows background captures.
   145    */
   146   captureIfMissing: function Site_captureIfMissing() {
   147     if (gPage.allowBackgroundCaptures && !this.link.imageURI) {
   148       BackgroundPageThumbs.captureIfMissing(this.url);
   149     }
   150   },
   152   /**
   153    * Refreshes the thumbnail for the site.
   154    */
   155   refreshThumbnail: function Site_refreshThumbnail() {
   156     let thumbnail = this._querySelector(".newtab-thumbnail");
   157     if (this.link.bgColor) {
   158       thumbnail.style.backgroundColor = this.link.bgColor;
   159     }
   160     let uri = this.link.imageURI || PageThumbs.getThumbnailURL(this.url);
   161     thumbnail.style.backgroundImage = "url(" + uri + ")";
   162   },
   164   /**
   165    * Adds event handlers for the site and its buttons.
   166    */
   167   _addEventHandlers: function Site_addEventHandlers() {
   168     // Register drag-and-drop event handlers.
   169     this._node.addEventListener("dragstart", this, false);
   170     this._node.addEventListener("dragend", this, false);
   171     this._node.addEventListener("mouseover", this, false);
   173     // Specially treat the sponsored icon to prevent regular hover effects
   174     let sponsored = this._querySelector(".newtab-control-sponsored");
   175     sponsored.addEventListener("mouseover", () => {
   176       this.cell.node.setAttribute("ignorehover", "true");
   177     });
   178     sponsored.addEventListener("mouseout", () => {
   179       this.cell.node.removeAttribute("ignorehover");
   180     });
   181   },
   183   /**
   184    * Speculatively opens a connection to the current site.
   185    */
   186   _speculativeConnect: function Site_speculativeConnect() {
   187     let sc = Services.io.QueryInterface(Ci.nsISpeculativeConnect);
   188     let uri = Services.io.newURI(this.url, null, null);
   189     sc.speculativeConnect(uri, null);
   190   },
   192   /**
   193    * Record interaction with site using telemetry.
   194    */
   195   _recordSiteClicked: function Site_recordSiteClicked(aIndex) {
   196     if (Services.prefs.prefHasUserValue("browser.newtabpage.rows") ||
   197         Services.prefs.prefHasUserValue("browser.newtabpage.columns") ||
   198         aIndex > 8) {
   199       // We only want to get indices for the default configuration, everything
   200       // else goes in the same bucket.
   201       aIndex = 9;
   202     }
   203     Services.telemetry.getHistogramById("NEWTAB_PAGE_SITE_CLICKED")
   204                       .add(aIndex);
   206     // Specially count clicks on directory tiles
   207     let typeIndex = DirectoryLinksProvider.linkTypes.indexOf(this.link.type);
   208     if (typeIndex != -1) {
   209       Services.telemetry.getHistogramById("NEWTAB_PAGE_DIRECTORY_TYPE_CLICKED")
   210                         .add(typeIndex);
   211     }
   212   },
   214   /**
   215    * Handles site click events.
   216    */
   217   onClick: function Site_onClick(aEvent) {
   218     let {button, target} = aEvent;
   219     if (target.classList.contains("newtab-link") ||
   220         target.parentElement.classList.contains("newtab-link")) {
   221       // Record for primary and middle clicks
   222       if (button == 0 || button == 1) {
   223         this._recordSiteClicked(this.cell.index);
   224       }
   225       return;
   226     }
   228     // Only handle primary clicks for the remaining targets
   229     if (button != 0) {
   230       return;
   231     }
   233     aEvent.preventDefault();
   234     if (aEvent.target.classList.contains("newtab-control-block"))
   235       this.block();
   236     else if (target.classList.contains("newtab-control-sponsored"))
   237       gPage.showSponsoredPanel(target);
   238     else if (this.isPinned())
   239       this.unpin();
   240     else
   241       this.pin();
   242   },
   244   /**
   245    * Handles all site events.
   246    */
   247   handleEvent: function Site_handleEvent(aEvent) {
   248     switch (aEvent.type) {
   249       case "mouseover":
   250         this._node.removeEventListener("mouseover", this, false);
   251         this._speculativeConnect();
   252         break;
   253       case "dragstart":
   254         gDrag.start(this, aEvent);
   255         break;
   256       case "dragend":
   257         gDrag.end(this, aEvent);
   258         break;
   259     }
   260   }
   261 };

mercurial