brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · c3ae286 Raw
192 lines · javascript
1// expand/collapse button (expander) is added if height of a cell content 2// exceeds CLIP_HEIGHT px.3var CLIP_HEIGHT = 135;4 5// Height in pixels of an expander image.6var EXPANDER_HEIGHT = 13;7 8// Path to images for an expander.9var imgPath = "./images/expandcollapse/";10 11// array[group][cell] of { 'height', 'expanded' }.12// group: a number; cells of the same group belong to the same table row.13// cell: a number; unique index of a cell in a group.14// height: a number, px; original height of a cell in a table.15// expanded: boolean; is a cell expanded or collapsed?16var CellsInfo = [];17 18// Extracts group and cell indices from an id of the form identifier_group_cell.19function getCellIdx(id) {20  var idx = id.substr(id.indexOf("_") + 1).split("_");21  return { 'group': idx[0], 'cell': idx[1] };22}23 24// Returns { 'height', 'expanded' } info for a cell with a given id.25function getCellInfo(id) { 26  var idx = getCellIdx(id); 27  return CellsInfo[idx.group][idx.cell]; 28}29 30// Initialization, add nodes, collect info.31function initExpandCollapse() {32  if (!document.getElementById)33    return;34 35  var groupCount = 0;36 37  // Examine all table rows in the document.38  var rows = document.body.getElementsByTagName("tr");39  for (var i=0; i<rows.length; i+=1) {40 41    var cellCount=0, newGroupCreated = false;42 43    // Examine all divs in a table row.44    var divs = rows[i].getElementsByTagName("div");45    for (var j=0; j<divs.length; j+=1) {46 47      var expandableDiv = divs[j];48 49      if (expandableDiv.className.indexOf("expandable") == -1)50        continue;51 52      if (expandableDiv.offsetHeight <= CLIP_HEIGHT)53        continue;54 55      // We found a div wrapping a cell content whose height exceeds 56      // CLIP_HEIGHT.57      var originalHeight = expandableDiv.offsetHeight;58      // Unique postfix for ids for generated nodes for a given cell.59      var idxStr = "_" + groupCount + "_" + cellCount;60      // Create an expander and an additional wrapper for a cell content.61      //62      //                                --- expandableDiv ----63      //  --- expandableDiv ---         | ------ data ------ |64      //  |    cell content   |   ->    | |  cell content  | | 65      //  ---------------------         | ------------------ |66      //                                | ---- expander ---- |67      //                                ----------------------68      var data = document.createElement("div");69      data.className = "data";70      data.id = "data" + idxStr;71      data.innerHTML = expandableDiv.innerHTML;72      with (data.style) { height = (CLIP_HEIGHT - EXPANDER_HEIGHT) + "px";73                          overflow = "hidden" }74 75      var expander = document.createElement("img");76      with (expander.style) { display = "block"; paddingTop = "5px"; }77      expander.src = imgPath + "ellipses_light.gif";78      expander.id = "expander" + idxStr;79 80      // Add mouse calbacks to expander.81      expander.onclick = function() {82        expandCollapse(this.id);83        // Hack for Opera - onmouseout callback is not invoked when page 84        // content changes dynamically and mouse pointer goes out of an element.85        this.src = imgPath + 86                   (getCellInfo(this.id).expanded ? "arrows_light.gif"87                                                  : "ellipses_light.gif");88      }89      expander.onmouseover = function() { 90        this.src = imgPath + 91                   (getCellInfo(this.id).expanded ? "arrows_dark.gif"92                                                  : "ellipses_dark.gif");93      }94      expander.onmouseout = function() { 95        this.src = imgPath + 96                   (getCellInfo(this.id).expanded ? "arrows_light.gif"97                                                  : "ellipses_light.gif");98      }99 100      expandableDiv.innerHTML = "";101      expandableDiv.appendChild(data);102      expandableDiv.appendChild(expander);103      expandableDiv.style.height = CLIP_HEIGHT + "px";104      expandableDiv.id = "cell"+ idxStr;105 106      // Keep original cell height and its ecpanded/cpllapsed state.107      if (!newGroupCreated) {108        CellsInfo[groupCount] = [];109        newGroupCreated = true;110      }111      CellsInfo[groupCount][cellCount] = { 'height' : originalHeight,112                                           'expanded' : false };113      cellCount += 1;114    }115    groupCount += newGroupCreated ? 1 : 0;116  }117}118 119function isElemTopVisible(elem) {120  var body = document.body,121      html = document.documentElement,122      // Calculate expandableDiv absolute Y coordinate from the top of body.123      bodyRect = body.getBoundingClientRect(),124      elemRect = elem.getBoundingClientRect(),125      elemOffset = Math.floor(elemRect.top - bodyRect.top),126      // Calculate the absoute Y coordinate of visible area.127      scrollTop = html.scrollTop || body && body.scrollTop || 0;128  scrollTop -= html.clientTop; // IE<8129 130  131  if (elemOffset < scrollTop)132    return false;133 134  return true;135}136 137// Invoked when an expander is pressed; expand/collapse a cell.138function expandCollapse(id) {139  var cellInfo = getCellInfo(id);140  var idx = getCellIdx(id);141 142  // New height of a row.143  var newHeight;144  // Smart page scrolling may be done after collapse.145  var mayNeedScroll;146 147  if (cellInfo.expanded) {148    // Cell is expanded - collapse the row height to CLIP_HEIGHT.149    newHeight = CLIP_HEIGHT;150    mayNeedScroll = true;151  }152  else {153    // Cell is collapsed - expand the row height to the cells original height.154    newHeight = cellInfo.height;155    mayNeedScroll = false;156  }157 158  // Update all cells (height and expanded/collapsed state) in a row according 159  // to the new height of the row.160  for (var i = 0; i < CellsInfo[idx.group].length; i++) {161    var idxStr = "_" + idx.group + "_" + i;162    var expandableDiv = document.getElementById("cell" + idxStr);163    expandableDiv.style.height = newHeight + "px";164    var data = document.getElementById("data" + idxStr);165    var expander = document.getElementById("expander" + idxStr);166    var state = CellsInfo[idx.group][i];167 168    if (state.height > newHeight) {169      // Cell height exceeds row height - collapse a cell.170      data.style.height = (newHeight - EXPANDER_HEIGHT) + "px";171      expander.src = imgPath + "ellipses_light.gif";172      CellsInfo[idx.group][i].expanded = false;173    } else {174      // Cell height is less then or equal to row height - expand a cell.175      data.style.height = "";176      expander.src = imgPath + "arrows_light.gif";177      CellsInfo[idx.group][i].expanded = true;178    }179  }180 181  if (mayNeedScroll) {182    var idxStr = "_" + idx.group + "_" + idx.cell;183    var clickedExpandableDiv = document.getElementById("cell" + idxStr);184    // Scroll page up if a row is collapsed and the rows top is above the 185    // viewport. The amount of scroll is the difference between a new and old 186    // row height.187    if (!isElemTopVisible(clickedExpandableDiv)) {188      window.scrollBy(0, newHeight - cellInfo.height);189    }190  }191}192