function appendTreeElements(aPOuter, aT, aProcess)
{
  let treeBytes = aT._amount;
  let rootStringLength = aT.toString().length;
  let isExplicitTree = aT._unsafeName == 'explicit';

  /**
   * Appends the elements for a particular tree, without a heading.
   *
   * @param aP
   *        The parent DOM node.
   * @param aUnsafeNames
   *        An array of the names forming the path to aT.
   * @param aT
   *        The tree.
   * @param aTreelineText1
   *        The first part of the treeline for this entry and this entry's
   *        children.
   * @param aTreelineText2a
   *        The second part of the treeline for this entry.
   * @param aTreelineText2b
   *        The second part of the treeline for this entry's children.
   * @param aParentStringLength
   *        The length of the formatted byte count of the top node in the tree.
   */
  function appendTreeElements2(aP, aUnsafeNames, aT, aTreelineText1,
                               aTreelineText2a, aTreelineText2b,
                               aParentStringLength)
  {
    function appendN(aS, aC, aN)
    {
      for (let i = 0; i < aN; i++) {
        aS += aC;
      }
      return aS;
    }

    // Indent more if this entry is narrower than its parent.
    let valueText = aT.toString();
    let extraTreelineLength =
      Math.max(aParentStringLength - valueText.length, 0);
    if (extraTreelineLength > 0) {
      aTreelineText2a =
        appendN(aTreelineText2a, kHorizontal, extraTreelineLength);
      aTreelineText2b =
        appendN(aTreelineText2b, " ",         extraTreelineLength);
    }
    let treelineText = aTreelineText1 + aTreelineText2a;
    appendElementWithText(aP, "span", "treeline", treelineText);

    // Generate the percentage;  detect and record invalid values at the same
    // time.
    let percText;
    let tIsInvalid = false;
    if (aT._amount === treeBytes) {
      percText = " (100.0%)";
    } else {
      if (!(0 <= aT._amount && aT._amount <= treeBytes)) {
        tIsInvalid = true;
        let unsafePath = aUnsafeNames.join("/");
        gUnsafePathsWithInvalidValuesForThisProcess.push(unsafePath);
        reportAssertionFailure("Invalid value for " +
                               flipBackslashes(unsafePath));
      }
      let num = 100 * aT._amount / treeBytes;
      let numText = num.toFixed(2);
      percText = (0 <= num && num < 10 ? " (0" : " (") + numText + "%)";
    }

    // For non-leaf nodes, the entire sub-tree is put within a span so it can
    // be collapsed if the node is clicked on.
    let d;
    let sep;
    let showSubtrees;
    if (aT._kids) {
      // Determine if we should show the sub-tree below this entry;  this
      // involves reinstating any previous toggling of the sub-tree.
      let unsafePath = aUnsafeNames.join("/");
      let safeTreeId = aProcess + ":" + flipBackslashes(unsafePath);
      showSubtrees = !aT._hideKids;
      if (gShowSubtreesBySafeTreeId[safeTreeId] !== undefined) {
        showSubtrees = gShowSubtreesBySafeTreeId[safeTreeId];
      }
      d = appendElement(aP, "span", "hasKids");
      d.id = safeTreeId;
      d.onclick = toggle;
      sep = showSubtrees ? kShowKidsSep : kHideKidsSep;
    } else {
      assert(!aT._hideKids, "leaf node with _hideKids set")
      sep = kNoKidsSep;
      d = aP;
    }

    appendMrValueSpan(d, valueText, tIsInvalid);
    appendElementWithText(d, "span", "mrPerc", percText);
    appendElementWithText(d, "span", "mrSep", sep);

    appendMrNameSpan(d, aT._description, aT._unsafeName,
                     tIsInvalid, aT._nMerged);

    // In non-verbose mode, invalid nodes can be hidden in collapsed sub-trees.
    // But it's good to always see them, so force this.
    if (!gVerbose && tIsInvalid) {
      expandPathToThisElement(d);
    }

    if (aT._kids) {
      // The 'kids' class is just used for sanity checking in toggle().
      d = appendElement(aP, "span", showSubtrees ? "kids" : "kids hidden");

      let kidTreelineText1 = aTreelineText1 + aTreelineText2b;
      for (let i = 0; i < aT._kids.length; i++) {
        let kidTreelineText2a, kidTreelineText2b;
        if (i < aT._kids.length - 1) {
          kidTreelineText2a = kVerticalAndRight_Right_Right;
          kidTreelineText2b = kVertical_Space_Space;
        } else {
          kidTreelineText2a = kUpAndRight_Right_Right;
          kidTreelineText2b = "   ";
        }
        aUnsafeNames.push(aT._kids[i]._unsafeName);
        appendTreeElements2(d, aUnsafeNames, aT._kids[i], kidTreelineText1,
                            kidTreelineText2a, kidTreelineText2b,
                            valueText.length);
        aUnsafeNames.pop();
      }
    }
  }

  appendSectionHeader(aPOuter, kSectionNames[aT._unsafeName]);
 
  let pre = appendElement(aPOuter, "pre", "entries");
  appendTreeElements2(pre, [aT._unsafeName], aT, "", "", "", rootStringLength);
  appendTextNode(aPOuter, "\n");  // gives nice spacing when we cut and paste
}
/**
 * Appends the elements for the tree, including its heading.
 *
 * @param aPOuter
 *        The parent DOM node.
 * @param aT
 *        The tree.
 * @param aProcess
 *        The process the tree corresponds to.
 */
Appends the elements for the tree, including its heading.
@param aPOuter
The parent DOM node.
@param aT
The tree.
@param aProcess
The process the tree corresponds to.
Appends the elements for the tree including its heading . @param aPOuter The parent DOM node . @param aT The tree . @param aProcess The process the tree corresponds to .
function appendTreeElements(aPOuter, aT, aProcess)
{
  let treeBytes = aT._amount;
  let rootStringLength = aT.toString().length;
  let isExplicitTree = aT._unsafeName == 'explicit';
  function appendTreeElements2(aP, aUnsafeNames, aT, aTreelineText1,
                               aTreelineText2a, aTreelineText2b,
                               aParentStringLength)
  {
    function appendN(aS, aC, aN)
    {
      for (let i = 0; i < aN; i++) {
        aS += aC;
      }
      return aS;
    }
    let valueText = aT.toString();
    let extraTreelineLength =
      Math.max(aParentStringLength - valueText.length, 0);
    if (extraTreelineLength > 0) {
      aTreelineText2a =
        appendN(aTreelineText2a, kHorizontal, extraTreelineLength);
      aTreelineText2b =
        appendN(aTreelineText2b, " ",         extraTreelineLength);
    }
    let treelineText = aTreelineText1 + aTreelineText2a;
    appendElementWithText(aP, "span", "treeline", treelineText);
    let percText;
    let tIsInvalid = false;
    if (aT._amount === treeBytes) {
      percText = " (100.0%)";
    } else {
      if (!(0 <= aT._amount && aT._amount <= treeBytes)) {
        tIsInvalid = true;
        let unsafePath = aUnsafeNames.join("/");
        gUnsafePathsWithInvalidValuesForThisProcess.push(unsafePath);
        reportAssertionFailure("Invalid value for " +
                               flipBackslashes(unsafePath));
      }
      let num = 100 * aT._amount / treeBytes;
      let numText = num.toFixed(2);
      percText = (0 <= num && num < 10 ? " (0" : " (") + numText + "%)";
    }
    let d;
    let sep;
    let showSubtrees;
    if (aT._kids) {
      let unsafePath = aUnsafeNames.join("/");
      let safeTreeId = aProcess + ":" + flipBackslashes(unsafePath);
      showSubtrees = !aT._hideKids;
      if (gShowSubtreesBySafeTreeId[safeTreeId] !== undefined) {
        showSubtrees = gShowSubtreesBySafeTreeId[safeTreeId];
      }
      d = appendElement(aP, "span", "hasKids");
      d.id = safeTreeId;
      d.onclick = toggle;
      sep = showSubtrees ? kShowKidsSep : kHideKidsSep;
    } else {
      assert(!aT._hideKids, "leaf node with _hideKids set")
      sep = kNoKidsSep;
      d = aP;
    }
    appendMrValueSpan(d, valueText, tIsInvalid);
    appendElementWithText(d, "span", "mrPerc", percText);
    appendElementWithText(d, "span", "mrSep", sep);
    appendMrNameSpan(d, aT._description, aT._unsafeName,
                     tIsInvalid, aT._nMerged);
    if (!gVerbose && tIsInvalid) {
      expandPathToThisElement(d);
    }
    if (aT._kids) {
      d = appendElement(aP, "span", showSubtrees ? "kids" : "kids hidden");
      let kidTreelineText1 = aTreelineText1 + aTreelineText2b;
      for (let i = 0; i < aT._kids.length; i++) {
        let kidTreelineText2a, kidTreelineText2b;
        if (i < aT._kids.length - 1) {
          kidTreelineText2a = kVerticalAndRight_Right_Right;
          kidTreelineText2b = kVertical_Space_Space;
        } else {
          kidTreelineText2a = kUpAndRight_Right_Right;
          kidTreelineText2b = "   ";
        }
        aUnsafeNames.push(aT._kids[i]._unsafeName);
        appendTreeElements2(d, aUnsafeNames, aT._kids[i], kidTreelineText1,
                            kidTreelineText2a, kidTreelineText2b,
                            valueText.length);
        aUnsafeNames.pop();
      }
    }
  }
  appendSectionHeader(aPOuter, kSectionNames[aT._unsafeName]);
  let pre = appendElement(aPOuter, "pre", "entries");
  appendTreeElements2(pre, [aT._unsafeName], aT, "", "", "", rootStringLength);
  appendTextNode(aPOuter, "\n");  
}
function appendTreeElements ( aPOuter , aT , aProcess ) { let treeBytes = aT . _amount ; let rootStringLength = aT . toString ( ) . length ; let isExplicitTree = aT . _unsafeName == 'explicit' ; function appendTreeElements2 ( aP , aUnsafeNames , aT , aTreelineText1 , aTreelineText2a , aTreelineText2b , aParentStringLength ) { function appendN ( aS , aC , aN ) { for ( let i = 0 ; i < aN ; i ++ ) { aS += aC ; } return aS ; } let valueText = aT . toString ( ) ; let extraTreelineLength = Math . max ( aParentStringLength - valueText . length , 0 ) ; if ( extraTreelineLength > 0 ) { aTreelineText2a = appendN ( aTreelineText2a , kHorizontal , extraTreelineLength ) ; aTreelineText2b = appendN ( aTreelineText2b , " " , extraTreelineLength ) ; } let treelineText = aTreelineText1 + aTreelineText2a ; appendElementWithText ( aP , "span" , "treeline" , treelineText ) ; let percText ; let tIsInvalid = false ; if ( aT . _amount === treeBytes ) { percText = " (100.0%)" ; } else { if ( ! ( 0 <= aT . _amount && aT . _amount <= treeBytes ) ) { tIsInvalid = true ; let unsafePath = aUnsafeNames . join ( "/" ) ; gUnsafePathsWithInvalidValuesForThisProcess . push ( unsafePath ) ; reportAssertionFailure ( "Invalid value for " + flipBackslashes ( unsafePath ) ) ; } let num = 100 * aT . _amount / treeBytes ; let numText = num . toFixed ( 2 ) ; percText = ( 0 <= num && num < 10 ? " (0" : " (" ) + numText + "%)" ; } let d ; let sep ; let showSubtrees ; if ( aT . _kids ) { let unsafePath = aUnsafeNames . join ( "/" ) ; let safeTreeId = aProcess + ":" + flipBackslashes ( unsafePath ) ; showSubtrees = ! aT . _hideKids ; if ( gShowSubtreesBySafeTreeId [ safeTreeId ] !== undefined ) { showSubtrees = gShowSubtreesBySafeTreeId [ safeTreeId ] ; } d = appendElement ( aP , "span" , "hasKids" ) ; d . id = safeTreeId ; d . onclick = toggle ; sep = showSubtrees ? kShowKidsSep : kHideKidsSep ; } else { assert ( ! aT . _hideKids , "leaf node with _hideKids set" ) sep = kNoKidsSep ; d = aP ; } appendMrValueSpan ( d , valueText , tIsInvalid ) ; appendElementWithText ( d , "span" , "mrPerc" , percText ) ; appendElementWithText ( d , "span" , "mrSep" , sep ) ; appendMrNameSpan ( d , aT . _description , aT . _unsafeName , tIsInvalid , aT . _nMerged ) ; if ( ! gVerbose && tIsInvalid ) { expandPathToThisElement ( d ) ; } if ( aT . _kids ) { d = appendElement ( aP , "span" , showSubtrees ? "kids" : "kids hidden" ) ; let kidTreelineText1 = aTreelineText1 + aTreelineText2b ; for ( let i = 0 ; i < aT . _kids . length ; i ++ ) { let kidTreelineText2a , kidTreelineText2b ; if ( i < aT . _kids . length - 1 ) { kidTreelineText2a = kVerticalAndRight_Right_Right ; kidTreelineText2b = kVertical_Space_Space ; } else { kidTreelineText2a = kUpAndRight_Right_Right ; kidTreelineText2b = "   " ; } aUnsafeNames . push ( aT . _kids [ i ] . _unsafeName ) ; appendTreeElements2 ( d , aUnsafeNames , aT . _kids [ i ] , kidTreelineText1 , kidTreelineText2a , kidTreelineText2b , valueText . length ) ; aUnsafeNames . pop ( ) ; } } } appendSectionHeader ( aPOuter , kSectionNames [ aT . _unsafeName ] ) ; let pre = appendElement ( aPOuter , "pre" , "entries" ) ; appendTreeElements2 ( pre , [ aT . _unsafeName ] , aT , "" , "" , "" , rootStringLength ) ; appendTextNode ( aPOuter , "\n" ) ; }
Appends the elements for the tree, including its heading.
Appends the elements for the tree including its heading .
/**
   * Appends the elements for a particular tree, without a heading.
   *
   * @param aP
   *        The parent DOM node.
   * @param aUnsafeNames
   *        An array of the names forming the path to aT.
   * @param aT
   *        The tree.
   * @param aTreelineText1
   *        The first part of the treeline for this entry and this entry's
   *        children.
   * @param aTreelineText2a
   *        The second part of the treeline for this entry.
   * @param aTreelineText2b
   *        The second part of the treeline for this entry's children.
   * @param aParentStringLength
   *        The length of the formatted byte count of the top node in the tree.
   */ // Indent more if this entry is narrower than its parent. // Generate the percentage;  detect and record invalid values at the same // time. // For non-leaf nodes, the entire sub-tree is put within a span so it can // be collapsed if the node is clicked on. // Determine if we should show the sub-tree below this entry;  this // involves reinstating any previous toggling of the sub-tree. // In non-verbose mode, invalid nodes can be hidden in collapsed sub-trees. // But it's good to always see them, so force this. // The 'kids' class is just used for sanity checking in toggle(). // gives nice spacing when we cut and paste