/* Copyright (C) 2001-2002 PIRONET AG, Germany
Author: Konstantin Breu, PIRONET NDH
$Id: quickeditcontrol.js,v 1.4.2.30 2005/11/11 09:54:34 kbreu Exp $
* /

/*********************************************************
 (1) This js-file contains js-functions controlling the
 quickedit feature implemented in quickedit.js.
 quickeditcontrol.js is linked in
 SAMPLE_3FRAME_LIGHT_NAVIGATE.sysrc.template.
 See SAMPLE_3FRAME_LIGHT_NAVIGATE.sysrc.template, quickedit.js

 (2) All global variables and functions have the prefix "qe"
 in order to avoid name conflicts with existing javascript/
 jscript functions/variables. The global variables can
 be changed in the onload method of the navigate template
 or in jscode AFTER the link to quickeditcontrol.js in
 the navigate template to customize the quickedit behavior,
 or finally set variables like qeBaseHref.
 See SAMPLE_3FRAME_LIGHT_NAVIGATE.sysrc.template.

 (3) some of the functions are calling functions in
 quickedit.js. => Changes in one of the script
 files may cause the need of appropriate changes in the
 other script file!
 *********************************************************/

var qeRunning = false;
var qeContentWindow = "top.cont";
var qeStartText = "Start Quickedit";
var qeEndText = "End Quickedit";
var qeDescriptionLabel = "Description";
var qeNameLabel = "Name";
var qeCatchwordsLabel = "Catchwords";
var qeShowFutureVersionQuestion = "There exists already a draft version for this page. You have to change to the draft version in order to start quickedit. Do you want to call the draft version?";
var qeFutureVersionExistsError = "There exists already a draft version for this page. The current page layout does not support the loading/editing of this draft version. Please use the Edit Center to edit the future version.";
var qeTakeJobQuestion = "The page is currently part of a pending workflow job for you. You first have to take the job, then you can start the quickedit mode. Do you want to take the job?";
var qeBaseHref = "/servlet/PB/";
var tidyCOMInitialized = false;
var qeMetaDataShowing = false;
var qeMode = "edit"; //other modes: "addsibling", "addchild"
var qeNamePrefix = "";
var qeUseOrigMetaData = true;
var qeCustomMetaDataName = "";
var qeFillEmptyQETags = false;
var qeFillEmptyQETagTEXT = false;
var qeFillEmptyQETagMULTITEXT = false;
var qeFillValue = "&nbsp;";

function qeToggleMetaData(show) {
  var contentWindow = eval(qeContentWindow);
  var metaDataCheckbox = document.all["qeCheckboxMetaData"];

  if(show==null) {
    show = !qeMetaDataShowing;
  }

  if(qeMetaDataShowing && show==false) {
    try {
      var spnMetaData = contentWindow.document.all["spnMetaData"];
      qeMetaDataShowing = false;
      if(spnMetaData!=null) {
        spnMetaData.style.display = "none";

        try {
          if(document.all["qeCurentPageNameLabel"] != null) {
            document.all["qeCurentPageNameLabel"].innerText = spnMetaData.all["qePbName"].value;
          }
        }
        catch(except) {

        }
        contentWindow.SAVETOPBFORM.pbname.value = qeEscapeUnicode(spnMetaData.all["qePbName"].value);
        contentWindow.SAVETOPBFORM.pbdescription.value = qeEscapeUnicode(spnMetaData.all["qePbDescription"].value);
        contentWindow.SAVETOPBFORM.pbcatchwords.value = qeEscapeUnicode(spnMetaData.all["qePbCatchwords"].value);
        if(typeof(qeCustomizedMetaDataCopyFromVisibleFormToHiddenForm)=="function") {
          qeCustomizedMetaDataCopyFromVisibleFormToHiddenForm(contentWindow, spnMetaData);
        }

        if(metaDataCheckbox!=null) {
          metaDataCheckbox.checked = false;
        }
      }
    }
    catch(except) {

    }
  }
  else if(qeMetaDataShowing==false && show==true) {
    try {
      var spnMetaData = contentWindow.document.all["spnMetaData"];
      qeMetaDataShowing = true;
      if(spnMetaData==null) {
        var customParts = "";
        if(typeof(qeCustomizedMetaDataCreateVisibleForm)=="function") {
          customParts = qeCustomizedMetaDataCreateVisibleForm();
        }

        var divAfter = contentWindow.qePageContent;
        if(divAfter.toolbarID!=null) {
          var toolbar = contentWindow.document.getElementById(divAfter.toolbarID);
          if(toolbar!=null) {
            divAfter = toolbar;
          }
        }


        divAfter.insertAdjacentHTML("beforeBegin",
        '<p id="spnMetaData" style="border: 1px solid threeddarkshadow; background-color: threedface;">'+
        '<table width="100%" border=0 cellpadding=2 cellspacing=0>'+
        '<tr class="qeCustomClassMetaName"><td style="color: windowtext">'+qeNameLabel+'</td><td valign="top" width="99%"><input type="text" id="qePbName" name="qePbName" value="" style="width: 100%"></td></tr>'+
        '<tr class="qeCustomClassMetaDescription"><td valign="top" style="color: windowtext">'+qeDescriptionLabel+'</td><td valign="top" width="99%"><textarea id="qePbDescription" name="qePbDescription" value="" style="width: 100%; height: 100px;"></textarea></td></tr>'+
        '<tr class="qeCustomClassMetaCatchwords"><td style="color: windowtext">'+qeCatchwordsLabel+'</td><td valign="top" width="99%"><input type="text" id="qePbCatchwords" name="qePbCatchwords" value="" style="width: 100%;"></td></tr>'+
        customParts+
        '<tr><td><img src="/empty.gif" height="1" width="1"></td><td><img src="/empty.gif" width="150" height="1"></td></tr>'+
        '</table></p>');
        spnMetaData = contentWindow.document.all["spnMetaData"];
      }
      spnMetaData.all["qePbName"].value = qeUnescapeUnicode(contentWindow.SAVETOPBFORM.pbname.value);
      spnMetaData.all["qePbDescription"].value = qeUnescapeUnicode(contentWindow.SAVETOPBFORM.pbdescription.value);
      spnMetaData.all["qePbCatchwords"].value = qeUnescapeUnicode(contentWindow.SAVETOPBFORM.pbcatchwords.value);

      if(typeof(qeCustomizedMetaDataCopyFromHiddenFormToVisibleForm)=="function") {
        qeCustomizedMetaDataCopyFromHiddenFormToVisibleForm(contentWindow, spnMetaData);
      }

      contentWindow.document.all["spnMetaData"].style.display = "";
      if(metaDataCheckbox!=null) {
        metaDataCheckbox.checked = true;
      }
    }
    catch(except) {

    }
  }

}

function qeFillEmptyTags(contentWindow) {
  if (qeFillEmptyQETags) {
    var allCollection = contentWindow.qePageContent.all;
    var i;
    var j;
    var qeTextTags = new Array("H1", "H2", "H3", "H4", "H5", "H6", "B", "STRONG", "NOBR", "SPAN", "I", "EM", "U");
    var qeMultiTextTags = new Array("P", "DIV");

    if (qeFillEmptyQETagTEXT) {
      for (j=0;j<qeTextTags.length;j++) {
        var tags = allCollection.tags(qeTextTags[j]);
        for(i=0; i<tags.length; i++) {
          if(  tags[i].getAttribute("qe")=="yes" && tags[i].getAttribute("qetype")=="text" && tags[i].innerHTML.length == 0) {
            tags[i].innerHTML = qeFillValue;
          }
        }
      }
    }

    if (qeFillEmptyQETagMULTITEXT) {
      for (j=0;j<qeMultiTextTags.length;j++) {
        var tags = allCollection.tags(qeMultiTextTags[j]);
        for(i=0; i<tags.length; i++) {
          if(  tags[i].getAttribute("qe")=="yes" && tags[i].getAttribute("qetype")=="multitext" && tags[i].innerHTML.length == 0) {
            tags[i].innerHTML = qeFillValue;
          }
        }
      }
    }

  } else {
     return;
  }
}

// starts / stops the quickedit mode including saving / checking out/in
function qeToggleQuickedit(id, languageid, tidyCOM, showMetaData) {
  qeRemoveSearchHighlight();

  var contentWindow = eval(qeContentWindow);

  if(qeRunning) { //end quickedit mode => save + checkin

    qeToggleMetaData(false);
    contentWindow.qeEndEdit(false);
    qeMakeTagsCompatible();
    contentWindow.SAVETOPBFORM.LANGUAGEID.value = languageid;
    qeFillEmptyTags(contentWindow);
    contentWindow.SAVETOPBFORM.CONTENT.value = qePostTidyReplace(qeConvertTidy(qeReplaceSpecialChars(contentWindow.qePageContent.innerHTML), false, tidyCOM));
    contentWindow.SAVETOPBFORM.submit();
    qePanel.style.display = "none";
    qeMainPanel.innerHTML = qeStartText;
    qeRunning = false;

  }
  else { //start quickedit mode

    // is there the fuction qeStartEdit in qeContentWindow?
    if(typeof(contentWindow.qeStartEdit)!="function") {
      qeAlertEntityString("Error! Cannot start quickedit mode. Possible reasons: " +
      "content frame does not display the page content; wrong quickedit integration.");
      return false;
    }

    if(!qeCheckForFutureVersion(id, languageid)) {
      return false;
    }

    // Step 1: try to check out the page

    var xmldom = new ActiveXObject("Microsoft.XMLDOM");
    xmldom.async = false;
    xmldom.validateOnParse = false;

    // maybe the session is expired. In this case, the load call will throw an exception
    try {
      xmldom.load("../../menu/"+id+"_equickedit_pcheckout_xlogin/index.html?QEMODE="+qeMode+"&ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
    }
    catch(except1) {
      // session maybe expired => try second load
      try {
        xmldom.load("../../menu/"+id+"_equickedit_pcheckout_xlogin/index.html?QEMODE="+qeMode+"&ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
      }
      catch(except2) {
      }
    }

    // look for result
    if(xmldom.parseError==0) {
      var root = xmldom.documentElement;

      var result = root.getElementsByTagName("RESULTNUM");
      if(result.length>0) {
        if(result[0].text=="0") {
          //every thing ok, activate quickedit

          try {
            var qeLinkPreviewTag = document.all["qeLinkPreview"];
            var qeLinkEditTag = document.all["qeLinkEdit"];
            qeUpdateTags(qeLinkEditTag, qeLinkPreviewTag);

          }
          catch(except) {

          }

          contentWindow.qeStartEdit();

          qePanel.style.display = "";
          qeMainPanel.innerHTML = qeEndText;
          qeRunning = true;

          var pageName = "";
          var pageDescription = "";
          var pageCatchwords = "";

          var customFields = null;

          if(qeUseOrigMetaData) {
            pageName = qeNamePrefix + root.getElementsByTagName("NAME")[0].text;
            pageDescription = root.getElementsByTagName("DESCRIPTION")[0].text;
            pageCatchwords = root.getElementsByTagName("CATCHWORDS")[0].text;

            if(typeof(qeCustomizedMetaDataGetObjectFromXMLData)=="function") {
              customFields = qeCustomizedMetaDataGetObjectFromXMLData(qeUseOrigMetaData, root, id, languageid);
            }

          }
          else {
            pageName = qeCustomMetaDataName;
            if(typeof(qeCustomizedMetaDataGetObjectFromXMLData)=="function") {
              customFields = qeCustomizedMetaDataGetObjectFromXMLData(qeUseOrigMetaData, root, id, languageid);
            }
          }

          try {
            contentWindow.SAVETOPBFORM.pbname.value = qeEscapeUnicode(pageName);
            contentWindow.SAVETOPBFORM.pbdescription.value = qeEscapeUnicode(pageDescription);
            contentWindow.SAVETOPBFORM.pbcatchwords.value = qeEscapeUnicode(pageCatchwords);

            if(typeof(qeCustomizedMetaDataFillHiddenFormWithData)=="function") {
              qeCustomizedMetaDataFillHiddenFormWithData(contentWindow, customFields);
            }

            if(showMetaData==true) {
              qeToggleMetaData(true);
            }

          }
          catch(except) {

          }
        }
        else {
          qeAlertEntityString("Fehler: " + result[0].text);
        }
      }
      else {
        qeAlertEntityString("Fehler beim Auschecken, Server lieferte ungueltige Antwort.");
      }
    }
    else {
      qeAlertEntityString("Fehler beim Auschecken, Server lieferte nicht-wohlgeformte Antwort.");
    }
  }
  return false;
}

// looks whether there is already a future version
// stored. If this is the case, then editing is only possible if
// the pagetype supports the workflow/future version integration
function qeCheckForFutureVersion(id, languageid) {
  if(qeMode != "edit") {
    return true;
  }

  var contentWindow = eval(qeContentWindow);
  if(typeof(contentWindow.wfFutureVersionSupport)!="undefined" &&
  contentWindow.wfFutureVersionSupport == true) {
    if(contentWindow.wfFutureVersionExists==true &&
       contentWindow.wfDoSeeFutureVersion==false) {
      if(qeConfirmEntityString(qeShowFutureVersionQuestion)) {
        contentWindow.wfViewDraftVersion();
        return false;
      }
      else {
        return false;
      }
    }
    else if(contentWindow.wfIsPendingJob == true) {
      if(qeConfirmEntityString(qeTakeJobQuestion)) {
        contentWindow.wfEditJob();
      }
      else {
        return false;
      }
    }
    else {
      return true;
    }
  }
  else {
    if(qeFutureVersionExists(id, languageid)) {
      qeAlertEntityString(qeFutureVersionExistsError);
      return false;
    }
    else {
      return true;
    }
  }
}

function qeFutureVersionExists(id, languageid) {

  var xmldom = new ActiveXObject("Microsoft.XMLDOM");
  xmldom.async = false;
  xmldom.validateOnParse = false;

  // maybe the session is expired. In this case, the load call will throw an exception
  try {
    xmldom.load("../../menu/"+id+"_equickedit_pfutureversioninfo_xlogin/index.html?ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
  }
  catch(except1) {
    // session maybe expired => try second load
    try {
      xmldom.load("../../menu/"+id+"_equickedit_pfutureversioninfo_xlogin/index.html?ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
    }
    catch(except2) {
    }
  }

  // look for result
  if(xmldom.parseError==0) {
    var root = xmldom.documentElement;

    var result = root.getElementsByTagName("futureversionexists");
    if(result.length>0) {
      if(result[0].text=="false") {
        return false;
      }
      else {
        return true;;
      }
    }
    else {
      qeAlertEntityString("Fehler bei Ueberpruefung auf Draftversion, Server lieferte ungueltige Antwort.");
      return null;
    }
  }
  else {
    qeAlertEntityString("Fehler bei Ueberpruefung auf Draftversion, Server lieferte nicht-wohlgeformte Antwort.");
    return null;
  }


}

function qeInitTidy(tidyCOM) {
  try {
    if(!tidyCOMInitialized) {
      tidyCOMInitialized = true;
      if(tidyCOM == null) {
        return;
      }

      var doInit = true;

      var xmldom = new ActiveXObject("Microsoft.XMLDOM");
      xmldom.async = false;
      xmldom.validateOnParse = false;
      // maybe the session is expired. In this case, the load call will throw an exception
      try {
        xmldom.load("../../menu/-1_eactivex-edit_ppagexml_xlogin_yno/index.html?ID=-1&ACTION=GET_TIDYOPTIONS&ContentType=text/xml");
      }
      catch(except) {
        // session maybe expired => try second load
        try {
          xmldom.load("../../menu/-1_eactivex-edit_ppagexml_xlogin_yno/index.html?ID=-1&ACTION=GET_TIDYOPTIONS&ContentType=text/xml");
        }
        catch(except) {
          doInit = false;
          tidyCOMInitialized = false;

        }
      }
      if(doInit) {
        var root = xmldom.documentElement;
        var options = root.getElementsByTagName("option");
        var i;
        for(i=0; i<options.length; i++) {
          var optName = options[i].attributes.getNamedItem("name").nodeValue;
          var optValue = options[i].attributes.getNamedItem("value").nodeValue;
          try {
            tidyCOM.Options[optName] = optValue;
          }
          catch(except) {
            //qeAlertEntityString("Error at initializing tidyCOM; optName: " + optName + ", optValue: " + optValue + "; description: " + except.description);
          }
        }
      }




    }
  }
  catch(except2) {

  }

}

function qeConvertTidy(code, containsWholePage, tidyCOM) {
  if(tidyCOM==null) {
    return code;
  }

  qeInitTidy(tidyCOM);


  if(!containsWholePage) {

    var boundary = "****jhfjagakfgakljfashaksjfkjgaskjsa****";
    var code2 = boundary + code + boundary;


    try {
      var result = tidyCOM.TidyMemToMem(code2);
      if(tidyCOM.TotalErrors > 0) {
        return code;
      }
      result = result.substring(result.indexOf(boundary)+boundary.length, result.lastIndexOf(boundary));

      if(result.indexOf(boundary)>=0) {
        return code;
      }
      if(result.length/code.length < 0.5) {
        return code;
      }
      if(result.length == 0) {
        return code;
      }

      return result;
    }
    catch(except) {
      return code;
    }
  }

  else {

    try {
      var result = tidyCOM.TidyMemToMem(code);
      if(tidyCOM.TotalErrors > 0) {
        return code;
      }

      if(result.length/code.length < 0.5) {
        return code;
      }
      if(result.length == 0) {
        return code;
      }

      return result;
    }
    catch(except) {
      return code;
    }
  }

}

function qeUpdateTags(activeTag, inactiveTag) {
  if(activeTag!=null && inactiveTag!=null) {
    activeTag.isactive = "true";
    activeTag.className = "qePblink qePbActivelink";
    inactiveTag.removeAttribute("isactive");
    inactiveTag.className = "qePblink";
  }
}


function qeRemoveSearchHighlight() {
  try {
    eval(qeContentWindow).pbhighlight_showOricCode(eval(qeContentWindow));
  }
  catch(except) {
  }
}

// switches to the quickedit view
function qeStartQuickedit() {
  qeRemoveSearchHighlight();

  eval(qeContentWindow).qeStartEdit();
  qePanel.style.display = "";

  try {
    var qeLinkPreviewTag = document.all["qeLinkPreview"];
    var qeLinkEditTag = document.all["qeLinkEdit"];
    qeUpdateTags(qeLinkEditTag, qeLinkPreviewTag);

  }
  catch(except) {

  }

  return false;
}

// switches to the preview
function qeShowPreview() {
  eval(qeContentWindow).qeEndEdit(false);
  qePanel.style.display = "";

  try {
    var qeLinkPreviewTag = document.all["qeLinkPreview"];
    var qeLinkEditTag = document.all["qeLinkEdit"];
    qeUpdateTags(qeLinkPreviewTag, qeLinkEditTag);

  }
  catch(except) {

  }

  return false;
}

function qeAutoStart(count) {
  qeRemoveSearchHighlight();

  if(count==null) count = 0;
  count++;

  var contentWindow = null;
  try {
    contentWindow = eval(qeContentWindow);
  }
  catch(except) {
    contentWindow = null;
  }

  if(count>50) {
    if(typeof(contentWindow.qeStartEdit)!="function") {
      return;
    }
  }

  if(contentWindow==null || contentWindow.qe_window_loaded!=true) {
    window.setTimeout("qeAutoStart("+count+");", 100);
    return;
  }

  return qeToggleQuickedit(contentWindow.qePageId, contentWindow.qePageLanguageId, null, true);
}

// cancels the quickedit mode. Page will
// be checked it, content reloaded
function qeCancelQuickedit(id, languageid) {

  if(typeof(qeCancelQuickedit_handler)=="function") {
    if(!qeCancelQuickedit_handler(id, languageid, 0)) {
      return false;
    }
  }


  var contentWindow = eval(qeContentWindow);

  var metaDataCheckbox = document.all["qeCheckboxMetaData"];
  qeMetaDataShowing = false;
  if(metaDataCheckbox!=null) {
    metaDataCheckbox.checked = false;
  }


  qePanel.style.display = "none";
  qeMainPanel.innerHTML = qeStartText;
  qeRunning = false;
  contentWindow.qeEndEdit(false);

  if(qeMode=="edit") {
    var xmldom = new ActiveXObject("Microsoft.XMLDOM");
    xmldom.async = false;
    xmldom.validateOnParse = false;
    // maybe the session is expired. In this case, the load call will throw an exception
    try {
      xmldom.load("../../menu/"+id+"_equickedit_pcheckin_xlogin/index.html?ACTION=nopublish&ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
    }
    catch(except) {
      // session maybe expired => try second load
      try {
        xmldom.load("../../menu/"+id+"_equickedit_pcheckin_xlogin/index.html?ACTION=nopublish&ID="+id+"&LANGUAGE-ID="+languageid+"&ContentType=text/xml");
      }
      catch(except) {

      }
    }
  }

  if(typeof(qeCancelQuickedit_handler)=="function") {
    qeCancelQuickedit_handler(id, languageid, 2);
  }

  contentWindow.document.location.reload();

  if(typeof(qeCancelQuickedit_handler)=="function") {
    qeCancelQuickedit_handler(id, languageid, 1);
  }

  return false;
}

/**
functions for changing the code in order
to displayed well in Netscape 4.

qeMakeTagsCompatible: converts the code for saving the
 html source code
- add conversion in this method, if some conversions
are missing
- call this method before you access the html source code
for saving to PB or disc or displaying in a sourcecode view
- call the single conversion methods before accessing
the special tags like hr, table, img and so on
*/

function qeMakeTagsCompatible() {
  var contentWindow = eval(qeContentWindow);
  var hrtags = eval(qeContentWindow).qePageContent.all.tags("HR");
  var i;
  for (i=0; i<hrtags.length; i++) {
    qeMakeHrTagCompatible(hrtags(i));
  }
  var imagtags = contentWindow.qePageContent.all.tags("IMG");
  for (i=0; i<imagtags.length; i++) {
    qeMakeImageTagCompatible(imagtags(i));
  }
  var tabletags = contentWindow.qePageContent.all.tags("TABLE");
  for (i=0; i<tabletags.length; i++) {
    qeMakeTableTagCompatible(tabletags(i));
  }
  var fonttags = contentWindow.qePageContent.all.tags("FONT");
  for (i=0; i<fonttags.length; i++) {
    qeMakeFontTagCompatible(fonttags(i));
  }
}

function qeMakeFontTagCompatible(tag) {
  if(tag.getAttribute("size").length == 1 &&
     (tag.size == "1" ||
      tag.size == "2" ||
      tag.size == "3" ||
      tag.size == "4" ||
      tag.size == "5" ||
      tag.size == "6" ||
      tag.size == "7")
     ) {
    tag.className = "font"+tag.size;
  }
  else {
    tag.removeAttribute("className");
  }
}

function qeMakeImageTagCompatible(tag) {
  qeMakeHeightAndWidthTagCompatible(tag);
  qeMakeSourceCompatible(tag);
}

function qeMakeSourceCompatible(tag) {
  var imgsrc = tag.src;
  var showurl1 = window.location.protocol+"//"+window.location.host+qeBaseHref+"show/";
  var showurl2 = window.location.protocol+"//"+window.location.hostname+qeBaseHref+"show/";
  var serverurl1 = window.location.protocol+"//"+window.location.hostname
  imgsrc = imgsrc.replace(showurl1, "../../show/").replace(showurl2, "../../show/").replace(serverurl1, "");
  tag.src = imgsrc;

}

function qeMakeHrTagCompatible(tag) {
 if(tag.style.width!='') {
   tag.width = tag.style.width;
 }
 if(tag.style.height!='') {
   tag.size = tag.style.height;
 }
 tag.style.width = '';
 tag.style.height = '';
}

function qeMakeTableTagCompatible(tag) {
  qeMakeHeightAndWidthTagCompatible(tag);
}

function qeMakeHeightAndWidthTagCompatible(tag) {
 if(tag.style.width!='') {
   tag.width = parseInt(tag.style.width);
 }
 if(tag.style.height!='') {
   tag.height = parseInt(tag.style.height);
 }
 tag.style.width = '';
 tag.style.height = '';
}

function qePostTidyReplace(str) {
  try {
    str = str.replace(new RegExp("&#8364;", "g"), "&euro;");
    str = str.replace(new RegExp("&#160;", "g"), "&nbsp;");
    return str;
  }
  catch(except) {
    return str;
  }
}

// replaces special characters by numeric entities
function qeReplaceSpecialChars(content) {

  var str = content;
  var reg = new RegExp("([^\u0000-\u0080])", "");
  var i=0;
  var arr;
  while ((arr = reg.exec(str)) != null) {
    i++;
    if(i>10000) break;
    if(RegExp.lastIndex > 0) {
      str = str.substring(0, RegExp.lastIndex-1) +
      "&#" + RegExp.$1.charCodeAt(0) + ";" + str.substring(RegExp.lastIndex);
    }
    else break;
  }

  return str;

}

function qeUnescapeUnicode(string) {
  var str = string;
  var reg = new RegExp("%u([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])", "");
  var i=0;
  var arr;
  while ((arr = reg.exec(str)) != null) {
    i++;
    if(i>100000) break;
    if(RegExp.lastIndex > 0) {
      str = str.substring(0, RegExp.lastIndex-6) +
      qeFromHex(RegExp.$1) + str.substring(RegExp.lastIndex);
    }
    else break;
  }

  return str;
}

function qeEscapeUnicode(string) {
  var str = string;
  var reg = new RegExp("([^\u0000-\u0080])", "");
  var i=0;
  var arr;
  while ((arr = reg.exec(str)) != null) {
    i++;
    if(i>100000) break;
    if(RegExp.lastIndex > 0) {
      str = str.substring(0, RegExp.lastIndex-1) +
      "%u" + qeGetHex(RegExp.$1.charCodeAt(0), 4) + str.substring(RegExp.lastIndex);
    }
    else break;
  }

  return str;

}

function qeFromHex(str) {
  return String.fromCharCode(eval("0x"+str));
}

function qeGetHex(charCode, lenMin) {
  var result = charCode.toString(16);
  while(result.length<lenMin) {
    result = "0" + result;
  }
  return result;
}

function qeDecodeNumericEntities(content) {
  var res = "";
  for(i=0; i<content.length; i++) {
    if(content.substring(i, i+1)=="&") {
      var value = qeGetNumericEntityValue(content, i);
      if(value==null) {
        res += "&";
      }
      else {
        res = res + value.string;
        i+=value.entityLength+2;
      }
    }
    else {
      res = res + content.substring(i, i+1);
    }
  }
  return res;
}

function qeGetNumericEntityValue(string, position) {
  if(string.substring(position+1, position+2)!="#") {
    return null;
  }

  var string2 = string.substring(position+1);
  var posSemiColon = string2.indexOf(";");
  if(posSemiColon<0) {
    return null;
  }

  var sequence = string2.substring(1, posSemiColon);
  if(sequence.length==0) {
    return null;
  }

  var i;
  for(i=0; i<sequence.length; i++) {
    if(("0123456789").indexOf(sequence.substring(i, i+1)) < 0) {
      return null;
    }
  }

  var newObject = new Object;
  newObject.entityLength = sequence.length;
  newObject.string = String.fromCharCode(parseInt(sequence));

  return newObject;

}

function qeConfirmEntityString(string) {
  return confirm(qeDecodeNumericEntities(string));
}

function qeAlertEntityString(string) {
  alert(qeDecodeNumericEntities(string));
}
