function _setOuterHTML()

in trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PPR.js [422:617]


function _setOuterHTML(
  targetDocument,
  targetItem,
  sourceItem
  )
{
  var sourceTagName = sourceItem.tagName;

  if (_agent.isIE || _agent.isSafari)
  {
    var useOuter = true;

    // is this a special IE leaf item that doesn't support outerHTML
    var isLeafItem = ((sourceTagName == "TD")      ||
                      (sourceTagName == "TH")      ||
                      (sourceTagName == "CAPTION"));

    // is this a special IE container item, that doesn't support
    // inner or outerHTML
    var isContainerItem = !isLeafItem &&
      ((sourceTagName == "COL")      ||
       (sourceTagName == "COLGROUP") ||
       (sourceTagName == "TR")       ||
       (sourceTagName == "TFOOT")    ||
       (sourceTagName == "THEAD")    ||
       (sourceTagName == "TBODY"));

    if (isLeafItem || isContainerItem)
    {
      // create an element with the correct attributes
      var newTargetItem = targetDocument.createElement(sourceTagName);

      // Safari has problems with some elements...
      if ((_agent.isSafari)
          && ((sourceTagName == "TR") || (sourceTagName == "TD")))
      {
        if (sourceTagName == "TD")
          newTargetItem.innerHTML = sourceItem.innerHTML;
        else
          targetItem.outerHTML = sourceItem.outerHTML;
      }
      else
        // mergeAttributes, including the id
        newTargetItem.mergeAttributes(sourceItem, false);

      // copy over the content
      if (isLeafItem)
      {
        newTargetItem.innerHTML = sourceItem.innerHTML;
      }
      else
      {
        if (isContainerItem)
        {
          //
          // add all of the cloned child elements
          // firstChild gets the comments as elements. we will
          // need to filter those out.
          //
          var currCell = sourceItem.firstChild;

          while (currCell != null)
          {
            // add the cloned cell.
            // filter out the comment tag.
            while(currCell != null && currCell.tagName == "!")
            {
              currCell = currCell.nextSibling;
            }

            if (currCell != null)
            {
              newTargetItem.appendChild(_setOuterHTML(targetDocument,
                                                      null,
                                                      currCell));
            }

            currCell = currCell.nextSibling;
          }
        }
      }

      // replace the current child with the new child
      if (targetItem)
      {
        if (targetItem["parentNode"])
          targetItem.parentNode.replaceChild(newTargetItem, targetItem);
      }
      else
      {
        targetItem = newTargetItem;
      }
      useOuter = false;
    }

    if (useOuter)
    {
      targetItem.outerHTML = sourceItem.outerHTML;
    }
  }
  else
  {
    // create the new Target item using a namespace to create this item
    // did not work correctly on Mozilla!
    var newTargetItem;

    // treat tr differently, since there is a Mozilla bug regarding innerHTML
    // and tr. It seems to strip out all the tds.
    if (sourceTagName != 'TR')
    {
      newTargetItem = targetDocument.createElement(sourceTagName);

      // Mozilla has a bug with copying innerHTML for the select element (#100175)
      // and it also has a problem when we use cloneNode (the scripts that
      // are in the iframe that get eval'd sometimes don't seem to get eval'd
      // correctly, and we get a missing function error). So, this is what
      // we came up with to work around that.
      if (sourceTagName == 'SELECT')
      {
        // the multiple attribute does not get copied over when we copy over
        // the source attributes, so do it here. This way when we set the
        // selected options below, multiple selections will be allowed.
        if (sourceItem.multiple)
        {
          newTargetItem.multiple = sourceItem.multiple;
        }
        for (var i = 0; i< sourceItem.options.length; i++)
        {
          var sourceOption = sourceItem.options[i];
          var newOption = new Option();

          newOption.value = sourceOption.value;
          newOption.text = sourceOption.text;
          newOption.selected = sourceOption.selected;


          newTargetItem.options[i] = newOption;
        }


      }
      else
      {
        // copy over the inner html
        var sourceInnerHTML = sourceItem.innerHTML;

        if ((sourceInnerHTML != null) && (sourceInnerHTML.length > 0))
        {

          newTargetItem.innerHTML = sourceItem.innerHTML;

        }

      }

      //
      // set the attributes of the source node
      //
      var sourceAttrs = sourceItem.attributes;

      for (var i = 0; i < sourceAttrs.length; i++)
      {
        newTargetItem.setAttribute(sourceAttrs[i].name, sourceAttrs[i].value);
      }


    }
    else
    {
      // for tr, use the importNode function. I'm limiting its
      // use to tr in case it is buggy, and to reduce the cases
      // where it is used. It might be a good thing to use in
      // the future. =-=jmw
      newTargetItem = targetDocument.importNode(sourceItem, true);

    }



    // Replace the current child with the new child.
    // We would like replaceChild(), but this causes problems on
    // Mozilla.  For example, in the PPR validation demo, if we use
    // replaceChild(), the validation demo contents disappear!  Using
    // insertBefore() followed by removeChild() seems to work just
    // fine though...
    // VG - replaceChild seems to work correctly with Gecko 1.5
     targetItem.parentNode.replaceChild(newTargetItem, targetItem);

    //targetItem.parentNode.insertBefore(newTargetItem, targetItem);
    //targetItem.parentNode.removeChild(targetItem);


  }

  return targetItem;
}