github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/make/tools/droiddoc/templates-pdk/assets/android-developer-docs.js (about)

     1  var resizePackagesNav;
     2  var classesNav;
     3  var devdocNav;
     4  var sidenav;
     5  var content;
     6  var HEADER_HEIGHT = 117;
     7  var cookie_namespace = 'android_developer';
     8  var NAV_PREF_TREE = "tree";
     9  var NAV_PREF_PANELS = "panels";
    10  var nav_pref;
    11  var toRoot;
    12  var isMobile = false; // true if mobile, so we can adjust some layout
    13  var isIE6 = false; // true if IE6
    14  
    15  // TODO: use $(document).ready instead
    16  function addLoadEvent(newfun) {
    17    var current = window.onload;
    18    if (typeof window.onload != 'function') {
    19      window.onload = newfun;
    20    } else {
    21      window.onload = function() {
    22        current();
    23        newfun();
    24      }
    25    }
    26  }
    27  
    28  var agent = navigator['userAgent'].toLowerCase();
    29  // If a mobile phone, set flag and do mobile setup
    30  if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod
    31      (agent.indexOf("blackberry") != -1) ||
    32      (agent.indexOf("webos") != -1) ||
    33      (agent.indexOf("mini") != -1)) {        // opera mini browsers
    34    isMobile = true;
    35    addLoadEvent(mobileSetup);
    36  // If not a mobile browser, set the onresize event for IE6, and others
    37  } else if (agent.indexOf("msie 6") != -1) {
    38    isIE6 = true;
    39    addLoadEvent(function() {
    40      window.onresize = resizeAll;
    41    });
    42  } else {
    43    addLoadEvent(function() {
    44      window.onresize = resizeHeight;
    45    });
    46  }
    47  
    48  function mobileSetup() {
    49    $("body").css({'overflow':'auto'});
    50    $("html").css({'overflow':'auto'});
    51    $("#body-content").css({'position':'relative', 'top':'0'});
    52    $("#doc-content").css({'overflow':'visible', 'border-left':'3px solid #DDD'});
    53    $("#side-nav").css({'padding':'0'});
    54    $("#nav-tree").css({'overflow-y': 'auto'});
    55  }
    56  
    57  /* loads the lists.js file to the page.
    58  Loading this in the head was slowing page load time */
    59  addLoadEvent( function() {
    60    var lists = document.createElement("script");
    61    lists.setAttribute("type","text/javascript");
    62    lists.setAttribute("src", toRoot+"reference/lists.js");
    63    document.getElementsByTagName("head")[0].appendChild(lists);
    64  } );
    65  
    66  addLoadEvent( function() {
    67    $("pre:not(.no-pretty-print)").addClass("prettyprint");
    68    prettyPrint();
    69  } );
    70  
    71  function setToRoot(root) {
    72    toRoot = root;
    73    // note: toRoot also used by carousel.js
    74  }
    75  
    76  function restoreWidth(navWidth) {
    77    var windowWidth = $(window).width() + "px";
    78    content.css({marginLeft:parseInt(navWidth) + 6 + "px"}); //account for 6px-wide handle-bar
    79  
    80    if (isIE6) {
    81      content.css({width:parseInt(windowWidth) - parseInt(navWidth) - 6 + "px"}); // necessary in order for scrollbars to be visible
    82    }
    83  
    84    sidenav.css({width:navWidth});
    85    resizePackagesNav.css({width:navWidth});
    86    classesNav.css({width:navWidth});
    87    $("#packages-nav").css({width:navWidth});
    88  }
    89  
    90  function restoreHeight(packageHeight) {
    91    var windowHeight = ($(window).height() - HEADER_HEIGHT);
    92    var swapperHeight = windowHeight - 13;
    93    $("#swapper").css({height:swapperHeight + "px"});
    94    sidenav.css({height:windowHeight + "px"});
    95    content.css({height:windowHeight + "px"});
    96    resizePackagesNav.css({maxHeight:swapperHeight + "px", height:packageHeight});
    97    classesNav.css({height:swapperHeight - parseInt(packageHeight) + "px"});
    98    $("#packages-nav").css({height:parseInt(packageHeight) - 6 + "px"}); //move 6px to give space for the resize handle
    99    devdocNav.css({height:sidenav.css("height")});
   100    $("#nav-tree").css({height:swapperHeight + "px"});
   101  }
   102  
   103  function readCookie(cookie) {
   104    var myCookie = cookie_namespace+"_"+cookie+"=";
   105    if (document.cookie) {
   106      var index = document.cookie.indexOf(myCookie);
   107      if (index != -1) {
   108        var valStart = index + myCookie.length;
   109        var valEnd = document.cookie.indexOf(";", valStart);
   110        if (valEnd == -1) {
   111          valEnd = document.cookie.length;
   112        }
   113        var val = document.cookie.substring(valStart, valEnd);
   114        return val;
   115      }
   116    }
   117    return 0;
   118  }
   119  
   120  function writeCookie(cookie, val, section, expiration) {
   121    if (val==undefined) return;
   122    section = section == null ? "_" : "_"+section+"_";
   123    if (expiration == null) {
   124      var date = new Date();
   125      date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
   126      expiration = date.toGMTString();
   127    }
   128    document.cookie = cookie_namespace + section + cookie + "=" + val + "; expires=" + expiration+"; path=/";
   129  }
   130  
   131  function init() {
   132    $("#side-nav").css({position:"absolute",left:0});
   133    content = $("#doc-content");
   134    resizePackagesNav = $("#resize-packages-nav");
   135    classesNav = $("#classes-nav");
   136    sidenav = $("#side-nav");
   137    devdocNav = $("#devdoc-nav");
   138  
   139    var cookiePath = "";
   140    if (location.href.indexOf("/reference/") != -1) {
   141      cookiePath = "reference_";
   142    } else if (location.href.indexOf("/guide/") != -1) {
   143      cookiePath = "guide_";
   144    } else if (location.href.indexOf("/sdk/") != -1) {
   145      cookiePath = "sdk_";
   146    } else if ((location.href.indexOf("/resources/") != -1) || 
   147               (location.href.indexOf("/training/") != -1)) {
   148      cookiePath = "resources_";
   149    }
   150  
   151    if (!isMobile) {
   152      $("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizePackagesHeight(); } });
   153      $("#side-nav").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
   154      var cookieWidth = readCookie(cookiePath+'width');
   155      var cookieHeight = readCookie(cookiePath+'height');
   156      if (cookieWidth) {
   157        restoreWidth(cookieWidth);
   158      } else if ($("#side-nav").length) {
   159        resizeWidth();
   160      }
   161      if (cookieHeight) {
   162        restoreHeight(cookieHeight);
   163      } else {
   164        resizeHeight();
   165      }
   166    }
   167  
   168    if (devdocNav.length) { // only dev guide, resources, and sdk
   169      tryPopulateResourcesNav();
   170      highlightNav(location.href);
   171    }
   172  }
   173  
   174  function tryPopulateResourcesNav() {
   175    var sampleList = $('#devdoc-nav-sample-list');
   176    var articleList = $('#devdoc-nav-article-list');
   177    var tutorialList = $('#devdoc-nav-tutorial-list');
   178    var topicList = $('#devdoc-nav-topic-list');
   179  
   180    if (!topicList.length || !ANDROID_TAGS || !ANDROID_RESOURCES)
   181      return;
   182  
   183    var topics = [];
   184    for (var topic in ANDROID_TAGS['topic']) {
   185      topics.push({name:topic,title:ANDROID_TAGS['topic'][topic]});
   186    }
   187    topics.sort(function(x,y){ return (x.title < y.title) ? -1 : 1; });
   188    for (var i = 0; i < topics.length; i++) {
   189      topicList.append(
   190          $('<li>').append(
   191            $('<a>')
   192              .attr('href', toRoot + "resources/browser.html?tag=" + topics[i].name)
   193              .append($('<span>')
   194                .addClass('en')
   195                .html(topics[i].title)
   196              )
   197            )
   198          );
   199    }
   200  
   201    var _renderResourceList = function(tag, listNode) {
   202      var resources = [];
   203      var tags;
   204      var resource;
   205      var i, j;
   206      for (i = 0; i < ANDROID_RESOURCES.length; i++) {
   207        resource = ANDROID_RESOURCES[i];
   208        tags = resource.tags || [];
   209        var hasTag = false;
   210        for (j = 0; j < tags.length; j++)
   211          if (tags[j] == tag) {
   212            hasTag = true;
   213            break;
   214          }
   215        if (!hasTag)
   216          continue;
   217        resources.push(resource);
   218      }
   219      //resources.sort(function(x,y){ return (x.title.en < y.title.en) ? -1 : 1; });
   220      for (i = 0; i < resources.length; i++) {
   221        resource = resources[i];
   222        var listItemNode = $('<li>').append(
   223            $('<a>')
   224              .attr('href', toRoot + "resources/" + resource.path)
   225              .append($('<span>')
   226                .addClass('en')
   227                .html(resource.title.en)
   228              )
   229            );
   230        tags = resource.tags || [];
   231        for (j = 0; j < tags.length; j++) {
   232          if (tags[j] == 'new') {
   233            listItemNode.get(0).innerHTML += '&nbsp;<span class="new">new!</span>';
   234            break;
   235          } else if (tags[j] == 'updated') {
   236            listItemNode.get(0).innerHTML += '&nbsp;<span class="new">updated!</span>';
   237            break;
   238          }
   239        }
   240        listNode.append(listItemNode);
   241      }
   242    };
   243  
   244    _renderResourceList('sample', sampleList);
   245    _renderResourceList('article', articleList);
   246    _renderResourceList('tutorial', tutorialList);
   247  }
   248  
   249  function highlightNav(fullPageName) {
   250    var lastSlashPos = fullPageName.lastIndexOf("/");
   251    var firstSlashPos;
   252    if (fullPageName.indexOf("/guide/") != -1) {
   253      firstSlashPos = fullPageName.indexOf("/guide/");
   254    } else if (fullPageName.indexOf("/sdk/") != -1) {
   255      firstSlashPos = fullPageName.indexOf("/sdk/");
   256    } else if (fullPageName.indexOf("/resources/") != -1) {
   257      firstSlashPos = fullPageName.indexOf("/resources/");
   258    } else if (fullPageName.indexOf("/training/") != -1) {
   259      firstSlashPos = fullPageName.indexOf("/training/");
   260    }
   261    if (lastSlashPos == (fullPageName.length - 1)) { // if the url ends in slash (add 'index.html')
   262      fullPageName = fullPageName + "index.html";
   263    }
   264  
   265    // get the path and page name from the URL (such as 'guide/topics/graphics/index.html')
   266    var htmlPos = fullPageName.indexOf(".html");
   267    var pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5); // +5 advances past ".html"
   268    // find instances of the page name in the side nav
   269    var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
   270    // if there's no match, then let's backstep through the directory until we find an index.html
   271    // page that matches our ancestor directories (only for dev guide and resources)
   272    if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) ||
   273                    (fullPageName.indexOf("/resources/") != -1))) {
   274      lastBackstep = pathPageName.lastIndexOf("/");
   275      while (link.length == 0) {
   276        backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
   277        link = $("#devdoc-nav a[href$='"+ pathPageName.slice(0, backstepDirectory +
   278                        1)+"index.html']");
   279        lastBackstep = pathPageName.lastIndexOf("/", lastBackstep - 1);
   280        if (lastBackstep == 0) break;
   281      }
   282    }
   283  
   284    // add 'selected' to the <li> or <div> that wraps this <a>
   285    link.parent().addClass('selected');
   286  
   287    // if we're in a toggleable root link (<li class=toggle-list><div><a>)
   288    if (link.parent().parent().hasClass('toggle-list')) {
   289      toggle(link.parent().parent(), false); // open our own list
   290      // then also check if we're in a third-level nested list that's toggleable
   291      if (link.parent().parent().parent().is(':hidden')) {
   292        toggle(link.parent().parent().parent().parent(), false); // open the super parent list
   293      }
   294    }
   295    // if we're in a normal nav link (<li><a>) and the parent <ul> is hidden
   296    else if (link.parent().parent().is(':hidden')) {
   297      toggle(link.parent().parent().parent(), false); // open the parent list
   298      // then also check if the parent list is also nested in a hidden list
   299      if (link.parent().parent().parent().parent().is(':hidden')) {
   300        toggle(link.parent().parent().parent().parent().parent(), false); // open the super parent list
   301      }
   302    }
   303  }
   304  
   305  /* Resize the height of the nav panels in the reference,
   306   * and save the new size to a cookie */
   307  function resizePackagesHeight() {
   308    var windowHeight = ($(window).height() - HEADER_HEIGHT);
   309    var swapperHeight = windowHeight - 13; // move 13px for swapper link at the bottom
   310    resizePackagesNav.css({maxHeight:swapperHeight + "px"});
   311    classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
   312  
   313    $("#swapper").css({height:swapperHeight + "px"});
   314    $("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
   315  
   316    var basePath = getBaseUri(location.pathname);
   317    var section = basePath.substring(1,basePath.indexOf("/",1));
   318    writeCookie("height", resizePackagesNav.css("height"), section, null);
   319  }
   320  
   321  /* Resize the height of the side-nav and doc-content divs,
   322   * which creates the frame effect */
   323  function resizeHeight() {
   324    var docContent = $("#doc-content");
   325  
   326    // Get the window height and always resize the doc-content and side-nav divs
   327    var windowHeight = ($(window).height() - HEADER_HEIGHT);
   328    docContent.css({height:windowHeight + "px"});
   329    $("#side-nav").css({height:windowHeight + "px"});
   330  
   331    var href = location.href;
   332    // If in the reference docs, also resize the "swapper", "classes-nav", and "nav-tree"  divs
   333    if (href.indexOf("/reference/") != -1) {
   334      var swapperHeight = windowHeight - 13;
   335      $("#swapper").css({height:swapperHeight + "px"});
   336      $("#classes-nav").css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
   337      $("#nav-tree").css({height:swapperHeight + "px"});
   338  
   339    // Also resize the "devdoc-nav" div
   340    } else if ($("#devdoc-nav").length) {
   341      $("#devdoc-nav").css({height:sidenav.css("height")});
   342    }
   343  
   344    // Hide the "Go to top" link if there's no vertical scroll
   345    if ( parseInt($("#jd-content").css("height")) <= parseInt(docContent.css("height")) ) {
   346      $("a[href='#top']").css({'display':'none'});
   347    } else {
   348      $("a[href='#top']").css({'display':'inline'});
   349    }
   350  }
   351  
   352  /* Resize the width of the "side-nav" and the left margin of the "doc-content" div,
   353   * which creates the resizable side bar */
   354  function resizeWidth() {
   355    var windowWidth = $(window).width() + "px";
   356    var sidenav = $("#side-nav");
   357    if (sidenav.length) {
   358      var sidenavWidth = sidenav.css("width");
   359    } else {
   360      var sidenavWidth = 0;
   361    }
   362    content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px"}); //account for 6px-wide handle-bar
   363  
   364    if (isIE6) {
   365      content.css({width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"}); // necessary in order to for scrollbars to be visible
   366    }
   367  
   368    resizePackagesNav.css({width:sidenavWidth});
   369    classesNav.css({width:sidenavWidth});
   370    $("#packages-nav").css({width:sidenavWidth});
   371  
   372    if (sidenav.length) { // Must check if the nav exists because IE6 calls resizeWidth() from resizeAll() for all pages
   373      var basePath = getBaseUri(location.pathname);
   374      var section = basePath.substring(1,basePath.indexOf("/",1));
   375      section = section.indexOf("training") != -1 ? "resources" : section;
   376      writeCookie("width", sidenavWidth, section, null);
   377    }
   378  }
   379  
   380  /* For IE6 only,
   381   * because it can't properly perform auto width for "doc-content" div,
   382   * avoiding this for all browsers provides better performance */
   383  function resizeAll() {
   384    resizeHeight();
   385    resizeWidth();
   386  }
   387  
   388  function getBaseUri(uri) {
   389    var intlUrl = (uri.substring(0,6) == "/intl/");
   390    if (intlUrl) {
   391      base = uri.substring(uri.indexOf('intl/')+5,uri.length);
   392      base = base.substring(base.indexOf('/')+1, base.length);
   393        //alert("intl, returning base url: /" + base);
   394      return ("/" + base);
   395    } else {
   396        //alert("not intl, returning uri as found.");
   397      return uri;
   398    }
   399  }
   400  
   401  function requestAppendHL(uri) {
   402  //append "?hl=<lang> to an outgoing request (such as to blog)
   403    var lang = getLangPref();
   404    if (lang) {
   405      var q = 'hl=' + lang;
   406      uri += '?' + q;
   407      window.location = uri;
   408      return false;
   409    } else {
   410      return true;
   411    }
   412  }
   413  
   414  function loadLast(cookiePath) {
   415    var location = window.location.href;
   416    if (location.indexOf("/"+cookiePath+"/") != -1) {
   417      return true;
   418    }
   419    var lastPage = readCookie(cookiePath + "_lastpage");
   420    if (lastPage) {
   421      window.location = lastPage;
   422      return false;
   423    }
   424    return true;
   425  }
   426  
   427  $(window).unload(function(){
   428    var path = getBaseUri(location.pathname);
   429    if (path.indexOf("/reference/") != -1) {
   430      writeCookie("lastpage", path, "reference", null);
   431    } else if (path.indexOf("/guide/") != -1) {
   432      writeCookie("lastpage", path, "guide", null);
   433    } else if ((path.indexOf("/resources/") != -1) || (path.indexOf("/training/") != -1)) {
   434      writeCookie("lastpage", path, "resources", null);
   435    }
   436  });
   437  
   438  function toggle(obj, slide) {
   439    var ul = $("ul:first", obj);
   440    var li = ul.parent();
   441    if (li.hasClass("closed")) {
   442      if (slide) {
   443        ul.slideDown("fast");
   444      } else {
   445        ul.show();
   446      }
   447      li.removeClass("closed");
   448      li.addClass("open");
   449      $(".toggle-img", li).attr("title", "hide pages");
   450    } else {
   451      ul.slideUp("fast");
   452      li.removeClass("open");
   453      li.addClass("closed");
   454      $(".toggle-img", li).attr("title", "show pages");
   455    }
   456  }
   457  
   458  function buildToggleLists() {
   459    $(".toggle-list").each(
   460      function(i) {
   461        $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
   462        $(this).addClass("closed");
   463      });
   464  }
   465  
   466  function getNavPref() {
   467    var v = readCookie('reference_nav');
   468    if (v != NAV_PREF_TREE) {
   469      v = NAV_PREF_PANELS;
   470    }
   471    return v;
   472  }
   473  
   474  function chooseDefaultNav() {
   475    nav_pref = getNavPref();
   476    if (nav_pref == NAV_PREF_TREE) {
   477      $("#nav-panels").toggle();
   478      $("#panel-link").toggle();
   479      $("#nav-tree").toggle();
   480      $("#tree-link").toggle();
   481    }
   482  }
   483  
   484  function swapNav() {
   485    if (nav_pref == NAV_PREF_TREE) {
   486      nav_pref = NAV_PREF_PANELS;
   487    } else {
   488      nav_pref = NAV_PREF_TREE;
   489      init_default_navtree(toRoot);
   490    }
   491    var date = new Date();
   492    date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
   493    writeCookie("nav", nav_pref, "reference", date.toGMTString());
   494  
   495    $("#nav-panels").toggle();
   496    $("#panel-link").toggle();
   497    $("#nav-tree").toggle();
   498    $("#tree-link").toggle();
   499  
   500    if ($("#nav-tree").is(':visible')) scrollIntoView("nav-tree");
   501    else {
   502      scrollIntoView("packages-nav");
   503      scrollIntoView("classes-nav");
   504    }
   505  }
   506  
   507  function scrollIntoView(nav) {
   508    var navObj = $("#"+nav);
   509    if (navObj.is(':visible')) {
   510      var selected = $(".selected", navObj);
   511      if (selected.length == 0) return;
   512      if (selected.is("div")) selected = selected.parent(); // when the selected item is a parent
   513  
   514      var scrolling = document.getElementById(nav);
   515      var navHeight = navObj.height();
   516      var offsetTop = selected.position().top;
   517  
   518      // handle nested items
   519      if (selected.parent().parent().is(".toggle-list")) {
   520        selected = selected.parent().parent();
   521        // handle second level nested items
   522        if (selected.parent().parent().is(".toggle-list")) {
   523          selected = selected.parent().parent();
   524        }
   525        offsetTop += selected.position().top;
   526      }
   527  
   528      // 180px from the bottom of the list is the threshold
   529      if(offsetTop > navHeight - 180) {
   530        scrolling.scrollTop = offsetTop - navHeight + 180;
   531      }
   532    }
   533  }
   534  
   535  function changeTabLang(lang) {
   536    var nodes = $("#header-tabs").find("."+lang);
   537    for (i=0; i < nodes.length; i++) { // for each node in this language
   538      var node = $(nodes[i]);
   539      node.siblings().css("display","none"); // hide all siblings
   540      if (node.not(":empty").length != 0) { //if this languages node has a translation, show it
   541        node.css("display","inline");
   542      } else { //otherwise, show English instead
   543        node.css("display","none");
   544        node.siblings().filter(".en").css("display","inline");
   545      }
   546    }
   547  }
   548  
   549  function changeNavLang(lang) {
   550    var nodes = $("#side-nav").find("."+lang);
   551    for (i=0; i < nodes.length; i++) { // for each node in this language
   552      var node = $(nodes[i]);
   553      node.siblings().css("display","none"); // hide all siblings
   554      if (node.not(":empty").length != 0) { // if this languages node has a translation, show it
   555        node.css("display","inline");
   556      } else { // otherwise, show English instead
   557        node.css("display","none");
   558        node.siblings().filter(".en").css("display","inline");
   559      }
   560    }
   561  }
   562  
   563  function changeDocLang(lang) {
   564    changeTabLang(lang);
   565    changeNavLang(lang);
   566  }
   567  
   568  function changeLangPref(lang, refresh) {
   569    var date = new Date();
   570    expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000))); // keep this for 50 years
   571    //alert("expires: " + expires)
   572    writeCookie("pref_lang", lang, null, expires);
   573    //changeDocLang(lang);
   574    if (refresh) {
   575      l = getBaseUri(location.pathname);
   576      window.location = l;
   577    }
   578  }
   579  
   580  function loadLangPref() {
   581    var lang = readCookie("pref_lang");
   582    if (lang != 0) {
   583      $("#language").find("option[value='"+lang+"']").attr("selected",true);
   584    }
   585  }
   586  
   587  function getLangPref() {
   588    var lang = $("#language").find(":selected").attr("value");
   589    if (!lang) {
   590      lang = readCookie("pref_lang");
   591    }
   592    return (lang != 0) ? lang : 'en';
   593  }
   594  
   595  
   596  /* Used to hide and reveal supplemental content, such as long code samples.
   597     See the companion CSS in android-developer-docs.css */
   598  function toggleContent(obj) {
   599    var div = $(obj.parentNode.parentNode);
   600    var toggleMe = $(".toggle-content-toggleme",div);
   601    if (div.hasClass("closed")) { // if it's closed, open it
   602      toggleMe.slideDown();
   603      $(".toggle-content-text", obj).toggle();
   604      div.removeClass("closed").addClass("open");
   605      $(".toggle-content-img", div).attr("title", "hide").attr("src", toRoot + "assets/images/triangle-opened.png");
   606    } else { // if it's open, close it
   607      toggleMe.slideUp('fast', function() {  // Wait until the animation is done before closing arrow
   608        $(".toggle-content-text", obj).toggle();
   609        div.removeClass("open").addClass("closed");
   610        $(".toggle-content-img", div).attr("title", "show").attr("src", toRoot + "assets/images/triangle-closed.png");
   611      });
   612    }
   613    return false;
   614  }