Revert "Merge "Resolve merge conflicts of a5f0068 to nyc-dev" into nyc-dev"

This reverts commit 6edfbfabad1ddbda00e0fcc713672f6e63acdf44, reversing
changes made to e09b2c16e32cee89d6b5ac29fe5a905b76872179.
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index c4a8150..d88c0e6 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -985,7 +985,7 @@
     }
     // get the selected item's offset from its container nav by measuring the item's offset
     // relative to the document then subtract the container nav's offset relative to the document
-    var selectedOffset = $selected.offset().top - $nav.offset().top + 60;
+    var selectedOffset = $selected.offset().top - $nav.offset().top;
     if (selectedOffset > $nav.height() * .8) { // multiply nav height by .8 so we move up the item
                                                // if it's more than 80% down the nav
       // scroll the item up by an amount equal to 80% the container nav's height
@@ -1328,7 +1328,7 @@
 function changeNavLang(lang) {
   if (lang === 'en') { return; }
 
-  var $links = $("a[" + lang + "-lang],p[" + lang + "-lang]");
+  var $links = $('a[' + lang + '-lang]');
   $links.each(function(){ // for each link with a translation
     var $link = $(this);
     // put the desired language from the attribute as the text
@@ -1386,7 +1386,7 @@
     $(".toggle-content-text:eq(0)", obj).toggle();
     div.removeClass("closed").addClass("open");
     $(".toggle-content-img:eq(0)", div).attr("title", "hide").attr("src", toRoot
-                  + "assets/images/styles/disclosure_up.png");
+                  + "assets/images/triangle-opened.png");
   } else { // if it's open, close it
     toggleMe.slideUp('fast', function() {  // Wait until the animation is done before closing arrow
       $(".toggle-content-text:eq(0)", obj).toggle();
@@ -1394,7 +1394,7 @@
       div.find(".toggle-content").removeClass("open").addClass("closed")
               .find(".toggle-content-toggleme").hide();
       $(".toggle-content-img", div).attr("title", "show").attr("src", toRoot
-                  + "assets/images/styles/disclosure_down.png");
+                  + "assets/images/triangle-closed.png");
     });
   }
   return false;
@@ -2548,13 +2548,12 @@
 function submit_search() {
   var query = document.getElementById('search_autocomplete').value;
   location.hash = 'q=' + query;
-  searchControl.query = query;
-  searchControl.init();
-  searchControl.trackSearchRequest(query);
+  loadSearchResults();
   $("#searchResults").slideDown('slow', setStickyTop);
   return false;
 }
 
+
 function hideResults() {
   $("#searchResults").slideUp('fast', setStickyTop);
   $("#search-close").addClass("hide");
@@ -2563,248 +2562,119 @@
   $("#search_autocomplete").val("").blur();
 
   // reset the ajax search callback to nothing, so results don't appear unless ENTER
-  searchControl.reset();
+  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {});
+
+  // forcefully regain key-up event control (previously jacked by search api)
+  $("#search_autocomplete").keyup(function(event) {
+    return search_changed(event, false, toRoot);
+  });
 
   return false;
 }
 
+
+
 /* ########################################################## */
 /* ################  CUSTOM SEARCH ENGINE  ################## */
 /* ########################################################## */
-var searchControl = null;
-var dacsearch = dacsearch || {};
 
-/**
- * The custom search engine API.
- * @constructor
- */
-dacsearch.CustomSearchEngine = function() {
-  /**
-   * The last response from Google CSE.
-   * @private {Object}
-   */
-  this.resultQuery_ = {};
+var searchControl;
+google.load('search', '1', {"callback" : function() {
+            searchControl = new google.search.SearchControl();
+          } });
 
-  /** @private {?Element} */
-  this.searchResultEl_ = null;
+function loadSearchResults() {
+  document.getElementById("search_autocomplete").style.color = "#000";
 
-  /** @private {?Element} */
-  this.searchInputEl_ = null;
+  searchControl = new google.search.SearchControl();
 
-  /** @private {string} */
-  this.query = '';
-};
+  // use our existing search form and use tabs when multiple searchers are used
+  drawOptions = new google.search.DrawOptions();
+  drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_TABBED);
+  drawOptions.setInput(document.getElementById("search_autocomplete"));
 
-/**
- * Initializes DAC's Google custom search engine.
- * @export
- */
-dacsearch.CustomSearchEngine.prototype.init = function() {
-  this.searchResultEl_ = $('#leftSearchControl');
-  this.searchResultEl_.empty();
-  this.searchInputEl_ = $('#search_autocomplete');
-  this.searchInputEl_.focus().val(this.query);
-  this.getResults_();
-  this.bindEvents_();
-};
+  // configure search result options
+  searchOptions = new google.search.SearcherOptions();
+  searchOptions.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
 
+  // configure each of the searchers, for each tab
+  devSiteSearcher = new google.search.WebSearch();
+  devSiteSearcher.setUserDefinedLabel("All");
+  devSiteSearcher.setSiteRestriction("001482626316274216503:zu90b7s047u");
 
-/**
- * Binds the keyup event to the search input.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.bindEvents_ = function() {
-  this.searchInputEl_.keyup(this.debounce_(function(e) {
-    var code = e.which;
-    if (code != 13) {
-      this.query = this.searchInputEl_.val();
-      location.hash = 'q=' + encodeURI(this.query);
-      this.searchResultEl_.empty();
-      this.getResults_();
-    }
-  }.bind(this), 250));
-};
+  designSearcher = new google.search.WebSearch();
+  designSearcher.setUserDefinedLabel("Design");
+  designSearcher.setSiteRestriction("http://developer.android.com/design/");
 
+  trainingSearcher = new google.search.WebSearch();
+  trainingSearcher.setUserDefinedLabel("Training");
+  trainingSearcher.setSiteRestriction("http://developer.android.com/training/");
 
-/**
- * Resets the search control.
- */
-dacsearch.CustomSearchEngine.prototype.reset = function() {
-  this.query = '';
-  this.searchInputEl_.off('keyup');
-  this.searchResultEl_.empty();
-  this.updateResultTitle_();
-};
+  guidesSearcher = new google.search.WebSearch();
+  guidesSearcher.setUserDefinedLabel("Guides");
+  guidesSearcher.setSiteRestriction("http://developer.android.com/guide/");
 
+  referenceSearcher = new google.search.WebSearch();
+  referenceSearcher.setUserDefinedLabel("Reference");
+  referenceSearcher.setSiteRestriction("http://developer.android.com/reference/");
 
-/**
- * Updates the search query text at the top of the results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.updateResultTitle_ = function() {
-  $("#searchTitle").html("Results for <em>" + this.query + "</em>");
-};
+  googleSearcher = new google.search.WebSearch();
+  googleSearcher.setUserDefinedLabel("Google Services");
+  googleSearcher.setSiteRestriction("http://developer.android.com/google/");
 
+  blogSearcher = new google.search.WebSearch();
+  blogSearcher.setUserDefinedLabel("Blog");
+  blogSearcher.setSiteRestriction("http://android-developers.blogspot.com");
 
-/**
- * Makes the CSE api call and gets the results.
- * @param {number=} opt_start The optional start index.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.getResults_ = function(opt_start) {
-  var lang = getLangPref();
-  // Fix zh-cn to be zh-CN.
-  lang = lang.replace(/-\w+/, function(m) { return m.toUpperCase(); });
-  var cseUrl = 'https://content.googleapis.com/customsearch/v1?';
-  var searchParams = {
-    cx: '000521750095050289010:zpcpi1ea4s8',
-    key: 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8',
-    q: this.query,
-    start: opt_start || 1,
-    num: 6,
-    hl: lang,
-    fields: 'queries,items(pagemap,link,title,htmlSnippet,formattedUrl)'
-  };
+  // add each searcher to the search control
+  searchControl.addSearcher(devSiteSearcher, searchOptions);
+  searchControl.addSearcher(designSearcher, searchOptions);
+  searchControl.addSearcher(trainingSearcher, searchOptions);
+  searchControl.addSearcher(guidesSearcher, searchOptions);
+  searchControl.addSearcher(referenceSearcher, searchOptions);
+  searchControl.addSearcher(googleSearcher, searchOptions);
+  searchControl.addSearcher(blogSearcher, searchOptions);
 
-  $.get(cseUrl + $.param(searchParams), function(data) {
-    this.resultQuery_ = data;
-    this.renderResults_(data);
-    this.updateResultTitle_(this.query);
-  }.bind(this));
-};
+  // configure result options
+  searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
+  searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
+  searchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_SHORT);
+  searchControl.setNoResultsString(google.search.SearchControl.NO_RESULTS_DEFAULT_STRING);
 
+  // upon ajax search, refresh the url and search title
+  searchControl.setSearchStartingCallback(this, function(control, searcher, query) {
+    updateResultTitle(query);
+    var query = document.getElementById('search_autocomplete').value;
+    location.hash = 'q=' + query;
+  });
 
-/**
- * Renders the results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.renderResults_ = function(results) {
-  var el = this.searchResultEl_;
+  // once search results load, set up click listeners
+  searchControl.setSearchCompleteCallback(this, function(control, searcher, query) {
+    addResultClickListeners();
+  });
 
-  if (!results.items) {
-    el.append($('<div>').text('No results'));
-    return;
-  }
+  // draw the search results box
+  searchControl.draw(document.getElementById("leftSearchControl"), drawOptions);
 
-  for (var i = 0; i < results.items.length; i++) {
-    var item = results.items[i];
-    var hasImage = item.pagemap && item.pagemap.cse_thumbnail;
-    var sectionMatch = item.link.match(/developer\.android\.com\/(\w*)/);
-    var section = (sectionMatch && sectionMatch[1]) || 'blog';
+  // get query and execute the search
+  searchControl.execute(decodeURI(getQuery(location.hash)));
 
-    var entry = $('<div>').addClass('dac-custom-search-entry cols');
-
-    if (hasImage) {
-      var image = item.pagemap.cse_thumbnail[0];
-      entry.append($('<div>').addClass('col-1of6')
-        .append($('<div>').addClass('dac-custom-search-image').css(
-        'background-image', 'url(' + image.src + ')')));
-    }
-
-    var linkTitleEl = $('<a>').text(item.title).attr('href', item.link);
-    linkTitleEl.click(function(e) {
-      ga('send', 'event', 'Google Custom Search',
-          'clicked: ' + linkTitleEl.attr('href'),
-          'query: ' + $("#search_autocomplete").val().toLowerCase());
-    });
-
-    var linkUrlEl = $('<a>').addClass('dac-custom-search-link').text(
-        item.formattedUrl).attr('href', item.link);
-    linkUrlEl.click(function(e) {
-      ga('send', 'event', 'Google Custom Search',
-          'clicked: ' + linkUrlEl.attr('href'),
-          'query: ' + $("#search_autocomplete").val().toLowerCase());
-    });
-
-
-    entry.append($('<div>').addClass(hasImage ? 'col-5of6' : 'col-6of6')
-      .append($('<p>').addClass('dac-custom-search-section').text(section))
-      .append(
-        linkTitleEl.wrap('<h2>').parent().addClass('dac-custom-search-title'))
-      .append($('<p>').addClass('dac-custom-search-snippet')
-      .html(item.htmlSnippet.replace(/<br>/g, ''))).append(linkUrlEl));
-
-    el.append(entry);
-  }
-
-  if ($('#dac-custom-search-load-more')) {
-    $('#dac-custom-search-load-more').remove();
-  }
-
-  if (results.queries.nextPage) {
-    var loadMoreButton = $('<button id="dac-custom-search-load-more">')
-      .addClass('dac-custom-search-load-more')
-      .text('Load more')
-      .click(function() {
-        this.loadMoreResults_();
-      }.bind(this));
-
-    el.append(loadMoreButton);
-  }
-};
-
-
-/**
- * Loads more results.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.loadMoreResults_ = function() {
-  this.query = this.resultQuery_.queries.request[0].searchTerms;
-  var start = this.resultQuery_.queries.nextPage[0].startIndex;
-  var loadMoreButton = this.searchResultEl_.find(
-      '#dac-custom-search-load-more');
-  loadMoreButton.text('Loading more...');
-  this.getResults_(start);
-  this.trackSearchRequest(this.query + ' startIndex = ' + start);
-};
-
-
-/**
- * Tracks a search request.
- * @param {string} query The query for the request,
- *                       includes start index if loading more results.
- */
-dacsearch.CustomSearchEngine.prototype.trackSearchRequest = function(query) {
-  ga('send', 'event', 'Google Custom Search Submit', 'submit search query',
-      'query: ' + query);
-};
-
-
-/**
- * Returns a function, that, as long as it continues to be invoked, will not
- * be triggered. The function will be called after it stops being called for
- * N milliseconds.
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to wait before calling the function.
- * @private
- */
-dacsearch.CustomSearchEngine.prototype.debounce_ = function(func, wait) {
-  var timeout;
-  return function() {
-    var context = this, args = arguments;
-    var later = function() {
-      timeout = null;
-      func.apply(context, args);
-    };
-   clearTimeout(timeout);
-   timeout = setTimeout(later, wait);
-  };
-};
+  document.getElementById("search_autocomplete").focus();
+  addTabListeners();
+}
+// End of loadSearchResults
 
 
 google.setOnLoadCallback(function(){
-  searchControl = new dacsearch.CustomSearchEngine();
   if (location.hash.indexOf("q=") == -1) {
     // if there's no query in the url, don't search and make sure results are hidden
     $('#searchResults').hide();
     return;
   } else {
     // first time loading search results for this page
-    searchControl.query = decodeURI(location.hash.split('q=')[1]);
-    searchControl.init();
-    searchControl.trackSearchRequest(searchControl.query);
     $('#searchResults').slideDown('slow', setStickyTop);
     $("#search-close").removeClass("hide");
+    loadSearchResults();
   }
 }, true);
 
@@ -2833,7 +2703,7 @@
 
   // If the hash isn't a search query or there's an error in the query,
   // then adjust the scroll position to account for sticky header, then exit.
-  if ((location.hash.indexOf("q=") == -1) || (searchControl.query == "undefined")) {
+  if ((location.hash.indexOf("q=") == -1) || (query == "undefined")) {
     // If the results pane is open, close it.
     if (!$("#searchResults").is(":hidden")) {
       hideResults();
@@ -2842,11 +2712,65 @@
     return;
   }
 
+  // Otherwise, we have a search to do
+  var query = decodeURI(getQuery(location.hash));
+  searchControl.execute(query);
   $('#searchResults').slideDown('slow', setStickyTop);
   $("#search_autocomplete").focus();
   $("#search-close").removeClass("hide");
+
+  updateResultTitle(query);
 });
 
+function updateResultTitle(query) {
+  $("#searchTitle").html("Results for <em>" + escapeHTML(query) + "</em>");
+}
+
+// forcefully regain key-up event control (previously jacked by search api)
+$("#search_autocomplete").keyup(function(event) {
+  return search_changed(event, false, toRoot);
+});
+
+// add event listeners to each tab so we can track the browser history
+function addTabListeners() {
+  var tabHeaders = $(".gsc-tabHeader");
+  for (var i = 0; i < tabHeaders.length; i++) {
+    $(tabHeaders[i]).attr("id",i).click(function() {
+    /*
+      // make a copy of the page numbers for the search left pane
+      setTimeout(function() {
+        // remove any residual page numbers
+        $('#searchResults .gsc-tabsArea .gsc-cursor-box.gs-bidi-start-align').remove();
+        // move the page numbers to the left position; make a clone,
+        // because the element is drawn to the DOM only once
+        // and because we're going to remove it (previous line),
+        // we need it to be available to move again as the user navigates
+        $('#searchResults .gsc-webResult .gsc-cursor-box.gs-bidi-start-align:visible')
+                        .clone().appendTo('#searchResults .gsc-tabsArea');
+        }, 200);
+      */
+    });
+  }
+  setTimeout(function(){$(tabHeaders[0]).click()},200);
+}
+
+// add analytics tracking events to each result link
+function addResultClickListeners() {
+  $("#searchResults a.gs-title").each(function(index, link) {
+    // When user clicks enter for Google search results, track it
+    $(link).click(function() {
+      ga('send', 'event', 'Google Click', 'clicked: ' + $(this).attr('href'),
+                'query: ' + $("#search_autocomplete").val().toLowerCase());
+    });
+  });
+}
+
+
+function getQuery(hash) {
+  var queryParts = hash.split('=');
+  return queryParts[1];
+}
+
 /* returns the given string with all HTML brackets converted to entities
     TODO: move this to the site's JS library */
 function escapeHTML(string) {
@@ -3447,13 +3371,13 @@
     if ( (expand == null && a.hasClass("closed")) || expand ) {
         list.style.display = "none";
         summary.style.display = "block";
-        trigger.src = toRoot + "assets/images/styles/disclosure_up.png";
+        trigger.src = toRoot + "assets/images/triangle-opened.png";
         a.removeClass("closed");
         a.addClass("opened");
     } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
         list.style.display = "block";
         summary.style.display = "none";
-        trigger.src = toRoot + "assets/images/styles/disclosure_down.png";
+        trigger.src = toRoot + "assets/images/triangle-closed.png";
         a.removeClass("opened");
         a.addClass("closed");
     }
@@ -3823,7 +3747,7 @@
 
     return $el;
   }
-
+  
   function createResponsiveFlowColumn(cardSize) {
     var cardWidth = parseInt(cardSize.match(/(\d+)/)[1], 10);
     var column = $('<div>').addClass('col-' + (cardWidth / 3) + 'of6');
@@ -3864,7 +3788,7 @@
 
       var cardSize = cardSizes[j++ % cardSizes.length];
       cardSize = cardSize.replace(/^\s+|\s+$/,'');
-
+      
       var column = createResponsiveFlowColumn(cardSize).appendTo(cardParent);
 
       // A stack has a third dimension which is the number of stacked items
@@ -4944,11 +4868,6 @@
     this.el.removeClass('dac-active');
     $('body').removeClass('dac-modal-open');
     this.isOpen = false;
-    // When closing the modal for Android Studio downloads, reload the page
-    // because otherwise we might get stuck with post-download dialog state
-    if ($("[data-modal='studio_tos']").length) {
-      location.reload();
-    }
   };
 
   Modal.prototype.open_ = function() {