xref: /aosp_15_r20/sdk/templates/docs/default.js (revision 1789df15502f1991eff51ff970dce5df8404dd56)
1*1789df15SXin Li/*
2*1789df15SXin Li * Copyright 2012 The Android Open Source Project
3*1789df15SXin Li *
4*1789df15SXin Li * Licensed under the Apache License, Version 2.0 (the "License");
5*1789df15SXin Li * you may not use this file except in compliance with the License.
6*1789df15SXin Li * You may obtain a copy of the License at
7*1789df15SXin Li *
8*1789df15SXin Li *     http://www.apache.org/licenses/LICENSE-2.0
9*1789df15SXin Li *
10*1789df15SXin Li * Unless required by applicable law or agreed to in writing, software
11*1789df15SXin Li * distributed under the License is distributed on an "AS IS" BASIS,
12*1789df15SXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*1789df15SXin Li * See the License for the specific language governing permissions and
14*1789df15SXin Li * limitations under the License.
15*1789df15SXin Li */
16*1789df15SXin Li
17*1789df15SXin Li$(document).ready(function() {
18*1789df15SXin Li  prettyPrint();
19*1789df15SXin Li  preventParentScrolls('nav');
20*1789df15SXin Li
21*1789df15SXin Li  var sluggify_ = function(s) {
22*1789df15SXin Li    return (s || '').replace(/ /g, '-').replace(/[^\w-]/g, '').toLowerCase();
23*1789df15SXin Li  };
24*1789df15SXin Li
25*1789df15SXin Li  $('h2, h3, h4.includetoc').each(function() {
26*1789df15SXin Li    $(this).attr('id', 'toc_' + sluggify_($(this).data('tocid') || $(this).data('toctitle') || $(this).text()));
27*1789df15SXin Li    $(this).click(function() {
28*1789df15SXin Li      smoothScrollToId($(this).attr('id'));
29*1789df15SXin Li    });
30*1789df15SXin Li  });
31*1789df15SXin Li
32*1789df15SXin Li  var buildNav_ = function(queries, $contentRoot, $navRoot) {
33*1789df15SXin Li    if (!queries || !queries.length) {
34*1789df15SXin Li      return;
35*1789df15SXin Li    }
36*1789df15SXin Li
37*1789df15SXin Li    $contentRoot.find(queries[0]).each(function() {
38*1789df15SXin Li      var $navNode = $('<div>')
39*1789df15SXin Li          .text($(this).html())
40*1789df15SXin Li          .appendTo($navRoot);
41*1789df15SXin Li      buildNav_(queries.splice(1), $(this), $navNode);
42*1789df15SXin Li    });
43*1789df15SXin Li  };
44*1789df15SXin Li
45*1789df15SXin Li  buildNav();
46*1789df15SXin Li});
47*1789df15SXin Li
48*1789df15SXin Lifunction buildNav() {
49*1789df15SXin Li  var currentLevel = 2;
50*1789df15SXin Li  var $currentParent = $('nav');
51*1789df15SXin Li  var $currentNode = null;
52*1789df15SXin Li
53*1789df15SXin Li  $('#page-content').find('h2, h3, h4.includetoc').each(function() {
54*1789df15SXin Li    var level = $(this).get(0).tagName.substring(1);
55*1789df15SXin Li
56*1789df15SXin Li    if (level < currentLevel) {
57*1789df15SXin Li      // ascend
58*1789df15SXin Li      for (var i = 0; i < (currentLevel - level); i++) {
59*1789df15SXin Li        $currentParent = $currentParent.parents('div.children, nav').first();
60*1789df15SXin Li      }
61*1789df15SXin Li
62*1789df15SXin Li    } else if (level > currentLevel) {
63*1789df15SXin Li      // descend
64*1789df15SXin Li      $currentParent = $('<div>')
65*1789df15SXin Li          .addClass('children')
66*1789df15SXin Li          .appendTo($currentNode);
67*1789df15SXin Li    }
68*1789df15SXin Li
69*1789df15SXin Li    var tocId = $(this).attr('id');
70*1789df15SXin Li    var navId = tocId.replace(/toc_/, 'nav_');
71*1789df15SXin Li
72*1789df15SXin Li    $interactionNode = $('<span>')
73*1789df15SXin Li        .html($(this).data('toctitle') || $(this).html())
74*1789df15SXin Li        .data('target', tocId)
75*1789df15SXin Li        .click(function() {
76*1789df15SXin Li          smoothScrollToId($(this).data('target'));
77*1789df15SXin Li        });
78*1789df15SXin Li
79*1789df15SXin Li    $currentNode = $('<div>')
80*1789df15SXin Li        .attr('id', navId)
81*1789df15SXin Li        .addClass('item')
82*1789df15SXin Li        .append($interactionNode)
83*1789df15SXin Li        .appendTo($currentParent);
84*1789df15SXin Li
85*1789df15SXin Li    currentLevel = level;
86*1789df15SXin Li  });
87*1789df15SXin Li
88*1789df15SXin Li  var headerPositionCache = [];
89*1789df15SXin Li  var rebuildHeaderPositionCache_ = function() {
90*1789df15SXin Li    headerPositionCache = [];
91*1789df15SXin Li    $('#page-content').find('h2, h3, h4.includetoc').each(function() {
92*1789df15SXin Li      headerPositionCache.push({
93*1789df15SXin Li        id: $(this).attr('id').replace(/toc_/, 'nav_'),
94*1789df15SXin Li        top: $(this).offset().top
95*1789df15SXin Li      });
96*1789df15SXin Li    });
97*1789df15SXin Li  };
98*1789df15SXin Li
99*1789df15SXin Li  var updateSelectedNavPosition_ = function() {
100*1789df15SXin Li    $('nav .item').removeClass('selected');
101*1789df15SXin Li    var scrollTop = $(window).scrollTop();
102*1789df15SXin Li    for (var i = headerPositionCache.length - 1; i >= 0; i--) {
103*1789df15SXin Li      if (scrollTop >= headerPositionCache[i].top) {
104*1789df15SXin Li        $('#' + headerPositionCache[i].id).addClass('selected');
105*1789df15SXin Li        break;
106*1789df15SXin Li      }
107*1789df15SXin Li    }
108*1789df15SXin Li  };
109*1789df15SXin Li
110*1789df15SXin Li  rebuildHeaderPositionCache_();
111*1789df15SXin Li  $(window).resize(function() {
112*1789df15SXin Li    rebuildHeaderPositionCache_();
113*1789df15SXin Li    updateSelectedNavPosition_();
114*1789df15SXin Li  });
115*1789df15SXin Li
116*1789df15SXin Li  $(window).scroll(function() {
117*1789df15SXin Li    updateSelectedNavPosition_();
118*1789df15SXin Li  });
119*1789df15SXin Li}
120*1789df15SXin Li
121*1789df15SXin Lifunction smoothScrollToId(id) {
122*1789df15SXin Li  var $target = $('#' + id);
123*1789df15SXin Li  $('body').animate({ scrollTop: $target.offset().top }, 200, 'swing', function() {
124*1789df15SXin Li    document.location.hash = id;
125*1789df15SXin Li  });
126*1789df15SXin Li}
127*1789df15SXin Li
128*1789df15SXin Li// Based on http://stackoverflow.com/questions/5802467/prevent-scrolling-of-parent-element
129*1789df15SXin Lifunction preventParentScrolls($el) {
130*1789df15SXin Li  $($el).on('DOMMouseScroll mousewheel', function(ev) {
131*1789df15SXin Li    var $this = $(this),
132*1789df15SXin Li        scrollTop = this.scrollTop,
133*1789df15SXin Li        scrollHeight = this.scrollHeight,
134*1789df15SXin Li        height = $this.height(),
135*1789df15SXin Li        delta = (ev.type == 'DOMMouseScroll' ?
136*1789df15SXin Li            ev.originalEvent.detail * -40 :
137*1789df15SXin Li            ev.originalEvent.wheelDelta),
138*1789df15SXin Li        up = delta > 0;
139*1789df15SXin Li
140*1789df15SXin Li    if (!up && -delta > scrollHeight - height - scrollTop) {
141*1789df15SXin Li      // Scrolling down, but this will take us past the bottom.
142*1789df15SXin Li      $this.scrollTop(scrollHeight);
143*1789df15SXin Li    } else if (up && delta > scrollTop) {
144*1789df15SXin Li      // Scrolling up, but this will take us past the top.
145*1789df15SXin Li      $this.scrollTop(0);
146*1789df15SXin Li    } else {
147*1789df15SXin Li      $this.scrollTop(scrollTop - delta);
148*1789df15SXin Li    }
149*1789df15SXin Li
150*1789df15SXin Li    ev.stopPropagation();
151*1789df15SXin Li    ev.preventDefault();
152*1789df15SXin Li    ev.returnValue = false;
153*1789df15SXin Li    return false;
154*1789df15SXin Li  });
155*1789df15SXin Li}