<!-- Copyright 2002, 2003 Macromedia, Inc. All rights reserved. -->
<html xmlns:MMString="http://www.macromedia.com/schemes/data/string/">
<head>
<title><MMString:loadString id="EditTextOnly/title" /></title>
<script language="JavaScript">

var DEBUG = false; //set to true to see page translations
var DISPLAY_SHIELDS = true; //will display shields if ETO or Protect Scripts is enabled

//EditTextOnly translator
//
//This translator provides 3 services: it displays shields for all "server" code,
//may protect scripts and other advanced tags, and it can protect
//everything that is not basic text and text formatting.
//The latter two options are preferences set in Contribute Administer Website,
//under the role Editing panel.
//
//Lock tags are placed around non-editable tag runs, which excludes basic formatting tags
//such as <P>, <B> etc. and text runs. For example, a document containing:
//
//  <html>
//  <body>
//    abc
//    <img src="foo.gif">
//    def
//  </body>
//  </html>
//
//becomes
//
//  <html>
//  <body>
//    abc
//    <MM:BeginLock unremovable type="MM_EDITTEXTONLY" orig="...">"><img src="foo.gif"><MM:EndLock>
//    def
//  </body>
//  </html>
//
//Thus the document is uneditable except for the text runs. Because of the "unremovable" attribute,
//the locked regions cannot be selected or deleted.
//
//Can be forced to run by calling:
//  dw.getDocumentDOM().runTranslator("Edit Text Only");

//--------------------- GLOBAL CONSTANTS --------------------------

//valid tags for text runs (always wrap with spaces, and make lower case)
//note that "a" tags are a special case, and are locked under ETO if used as named anchors.
var TEXT_TAGS = " a b br big blink blockquote caption center cite code dd del div dfn dl dt em form font "+
                " h1 h2 h3 h4 h5 h6 html head i ins kbd label legend li listing nobr o:p ol p plaintext "+
                " pre q s samp small span strike strong sub sup title tt u ul var wbr ";

//tags to lock if protecting code
var CODE_TAGS = " script ";
var FORM_TAGS = " form input select textarea button ";
var CF_TAG_PREFIX  = "cf";   //separate because we check for tags that start with cf: <cf*
var ASP_TAG_PREFIX = "asp";  //check for tags that start with asp: <asp:*
var ASP_TAGS       = " alternatingitemstyle alternatingitemtemplate columns contentstemplate edititemstyle"  //used by ASP .Net apps
                   + " edititemtemplate failuretemplate footerstyle footertemplate headerstyle"
                   + " headertemplate itemstyle itemtemplate pagerstyle parameter selecteditemstyle"
                   + " selecteditemtemplate separatortemplate successtemplate tablestyle ";
var TAGS_TO_LOCK_ENTIRELY = " script select textarea cfquery cfsavecontent ";

//tag/attributes to check (lock if these tag/attributes contain pattern strings)
var DYN_ATTRIBS            = " src alt href ";  //attributes to check
var DYN_ATTRIB_TAGS        = " img input a ";   //all tags that should be checked
var DYN_ATTRIB_TAGS_BLOCK  = " a ";      //subset of tags that are block tags (entirety may be locked)
var DYN_ATTRIB_QUICKSEARCH = "<"; //quick test if attrib is dynamic (if it has a <, probably dynamic)
var DYN_ATTRIB_PATTERNS    = new Array("<%","<?","<cf","<asp","<jsp"); //simple dynamic indicators

var VALID_REGIONS = " body ";  //only translate within these tags

//strings used to create new locks, and recognize existing ones
var TRANSLATORID    = "MM_EDITTEXTONLY";
var BEGINLOCKTAG    = "MM:BeginLock";
var ENDLOCKTAG      = "MM:EndLock";
var OLDLOCKTAG      = "MMTInstance:Editable";
var OLDTEMPLBEGIN   = "<!-- InstanceBeginEditable"; //tags for identifying DW template region bounds
var OLDTEMPLEND     = "<!-- InstanceEndEditable";
var NEWTEMPLBEGIN   = "<!-- TemplateBeginEditable";
var NEWTEMPLEND     = "<!-- TemplateEndEditable";
var BEGINLOCKTAG_LOWERCASE  = BEGINLOCKTAG.toLowerCase();
var ENDLOCKTAG_LOWERCASE    = ENDLOCKTAG.toLowerCase();
var OLDLOCKTAG_LOWERCASE    = OLDLOCKTAG.toLowerCase();

//Translation tags to be placed around every non-editable region. Resulting tags:
//  <MM:BeginLock type="MM_EDITTEXTONLY" orig="<foo>"><foo><MM:EndLock>
var BEGINLOCK1   = '<'+BEGINLOCKTAG+' type="'+TRANSLATORID+'" orig="';
var BEGINLOCK2   = '">';
var ENDLOCK      = '<'+ENDLOCKTAG+'>';

//indexes for remembering which shields to display
var SHIELD_GENERIC = 1;
var SHIELD_SCRIPT  = 2;
var SHIELD_CF      = 3;
var SHIELD_CFDATA  = 4;
var SHIELD_ASP     = 5;

//array of shield images
var SHIELDS = new Array(10);
SHIELDS[SHIELD_GENERIC] = '<img src="' + dw.getConfigurationPath() + '/Translators/images/shieldGeneric.gif">';
SHIELDS[SHIELD_SCRIPT]  = '<img src="' + dw.getConfigurationPath() + '/Translators/images/shieldScript.gif">';
SHIELDS[SHIELD_CF]      = '<img src="' + dw.getConfigurationPath() + '/Translators/images/shieldCf.gif">';
SHIELDS[SHIELD_CFDATA]  = '<img src="' + dw.getConfigurationPath() + '/Translators/images/shieldCfData.gif">';
SHIELDS[SHIELD_ASP]     = '<img src="' + dw.getConfigurationPath() + '/Translators/images/shieldASP.gif">';


//-------------------- DREAMWEAVER APIs ------------------------------

function translateMarkup(docNameStr, siteRootStr, docStr)
{

  // do not run this translator for xml files.
  if( docNameStr.length < 3 ) 
    return "";  
  var extension = docNameStr.substr(docNameStr.length-3,docNameStr.length) ; //.toLowerCase();
  extension = extension.toLowerCase();
  if( extension == "xml") return "";
      
   
  
  var preTransLength = docStr.length;  //remember original length

  //determine what to lock
  var alreadyTranslated = (docStr.indexOf(TRANSLATORID) != (-1));
  var lockNonText = !alreadyTranslated && editTextOnlyEnabled();
  var lockCode    = !alreadyTranslated && codeLockEnabled();
  var lockSSIs    = !alreadyTranslated && ssiLockEnabled();

  if (DEBUG) alert("Starting Edit Text Only ("+lockNonText+")/ Protect Code ("+lockCode+") translator.");

  //run the parser to translate doc
  var callBack = new EditRgnCallback(docStr, lockNonText, lockCode);
  dreamweaver.scanActiveContentSourceString(docStr, callBack, true);
  callBack.buildOutstr();
  if (callBack.isValid)
  {
    docStr = callBack.getDocString();        //get new doc string from callback mechanism
  }

  if (lockNonText)
  { //set unremovable on ALL locks on the page
    docStr = docStr.replace(RegExp("(<"+BEGINLOCKTAG+")","gi"),"$1 unremovable");
  }
  else
  {
    if (lockCode)
    { //set unremovable for MY locks
      var newLock = BEGINLOCK1.replace(/type=/i,"unremovable type=");
      docStr = docStr.replace(RegExp(BEGINLOCK1,"gi"),newLock);
    }
    if (lockSSIs)
    { //set unremovable on all SSI locks on the page
      docStr = docStr.replace(RegExp('(translatorClass="MM_SSI")','gi'),'unremovable $1');
    }
  }

  if (DEBUG) alert(callBack.isValid?("ETO translation:\n"+docStr):("Parser failed or didn't find anything!:\n"+docStr));

  if (docStr.length != preTransLength)  //doc has changed if length different
  {
    return docStr;  //only return if doc changed
  }
}



function getTranslatorInfo()
{
  if (DEBUG && editTextOnlyEnabled()) alert("Loading Edit Text Only translator");
  var returnArray = new Array(8);
  returnArray[0] = TRANSLATORID;	  // The translatorClass
  returnArray[1] = "Edit Text Only";// The title
  returnArray[2] = "0"; 					  // The number of extensions
  returnArray[3] = "0";             // The number of expressions"
  returnArray[4] = "allFiles";      // translate all files
  returnArray[5] = "8";            // priority order to apply translator

  return returnArray;
}



//---------------- LOCAL CLASSES ---------------------


//***** CLASS EditRgnCallback *************

function EditRgnCallback(theInStr, translateAllNonText, isCodeLockEnabled)
{
  // properties
  this.inStr = theInStr;
  this.docArray = new Array();//the resulting array after translation (call getDocString() to get)

  this.transAll = translateAllNonText;  //set to true if "Modify Text Only" flag is set
  this.curTag    = "";           //trailing var which remembers which single tag we're in
  this.curOffset = "";           //trailing var which remembers which single tag offset
  this.noBodyTag = (this.inStr.search(/<body/i) == -1);   //flag true if no body tag in document
  this.canTranslate = this.noBodyTag;  //normally, start false until in BODY tag. If no BODY, start immediately
  this.isValid = false;
  this.editable = this.noBodyTag;// normally, start false. If no BODY, start immediately
  this.regions = new Array(); //stack of regions that are editable, used to build locks
  this.inCFOUTPUT = false;    //indicates if we are within a CFOUTPUT tag
  this.lockCode = isCodeLockEnabled;
  this.noTranslateBlock = ""; //used to remember when we're in a block that shouldn't be translated

  this.displayShields = DISPLAY_SHIELDS;
  this.shields = new Array(); //hash array for indicating locations that should display shields
}

// methods
EditRgnCallback.prototype.text          = EditRgnCallback_text;
EditRgnCallback.prototype.directive     = EditRgnCallback_directive;
EditRgnCallback.prototype.openTagBegin  = EditRgnCallback_openTagBegin;
EditRgnCallback.prototype.openTagEnd    = EditRgnCallback_openTagEnd;
EditRgnCallback.prototype.closeTagBegin = EditRgnCallback_closeTagBegin;
EditRgnCallback.prototype.attribute     = EditRgnCallback_attribute;

EditRgnCallback.prototype.buildOutstr   = EditRgnCallback_buildOutstr;
EditRgnCallback.prototype.getDocString  = EditRgnCallback_getDocString;
EditRgnCallback.prototype.isValidRegion = EditRgnCallback_isValidRegion;
EditRgnCallback.prototype.isCodeTag     = EditRgnCallback_isCodeTag;
EditRgnCallback.prototype.isTextTag     = EditRgnCallback_isTextTag;
EditRgnCallback.prototype.setShields    = EditRgnCallback_setShields;

/*
//Add these someday if needed
EditRgnCallback.prototype.closeTagEnd   = EditRgnCallback_closeTagEnd;
EditRgnCallback.prototype.restartParse  = EditRgnCallback_restartParse;
*/


//Text Run Begin
//At the beginning of any text run, if canTranslate (in BODY but not in MM:BeginLock/MM:EndLock), and not
//already editable, set to editable and remember offset.
//The exception is if we're within <CFOUTPUT> tags, and we find data, such as #RS1.foo# (then lock it)
function EditRgnCallback_text(code, offset)
{
  if (this.canTranslate)
  {
    //If in a CFOUTPUT, and found data in #s, such as #Recordset1.field1#, and not already locked, start lock
    if (this.inCFOUTPUT && code.length>2 && code.charAt(0)=="#" && code.charAt(code.length-1)=="#")
    {
      if (this.displayShields) this.shields[String(offset)] = SHIELD_CFDATA;
      if (this.editable)
      {
        this.editable = false;
        this.regions.push(offset);  //begin lock
      }
      else if (this.displayShields)
      { //stop and start lock so that special shield will be displayed
        this.regions.push(offset);  //end lock
        this.regions.push(offset);  //begin lock
      }
    }
    else if (!this.editable)     //if text & not editable region, make it editable
    {
      this.editable = true;
      this.regions.push(offset);
    }
  }

  return true;
}


//Directive (only use for server markup)
//At the beginning of server directive, if canTranslate and not locked, start lock.
function EditRgnCallback_directive(code, offset)
{
  //if server directive (ASP, JSP, PHP, or comment w/ CF tag) & editable region, end it
  if (this.canTranslate)
  {
    if (this.editable && code.length)
    {
        // mgore 29Nov2006: php includes support. mark php includes pattern as
        // editable, so that the server side includes translator gets a chance.
        if (code.search(/<\?(?:php)?\s*(?:include|require|virtual)(?:_once)?\s*(?:\(\s*)?["']([^"']*)["']\s*(?:\)\s*)?;?\s*\?>/i) != -1)
        {
            this.editable = true;
            // mgore 12Dec2006: dont push offsets, they mark the regions that should be locked!
        }
        else
        {
            if (code.indexOf("<%")==0 || code.indexOf("<?")==0)
            {
                this.editable = false;
                this.regions.push(offset);  //begin lock
                if (this.noBodyTag && this.regions.length == 1) //special case if starts with lockable stuff
                {
                    this.regions.push(offset);  //need to start lock, since first region ignored
                }
            }
            else if (code.indexOf("<!-")==0 && code.search(/<\/{0,1}cf/i)!=-1)  //if comment containing <cf or </cf
            {
                this.editable = false;
                this.regions.push(offset);  //begin lock
                if (this.noBodyTag && this.regions.length == 1) //special case if starts with lockable stuff
                {
                    this.regions.push(offset);  //need to start lock, since first region ignored
                }

                if (this.displayShields)
                    this.shields[String(offset)] = SHIELD_CF;
            }
        }
    }

    //added the following chunk to fix bug 169146. Allows typing before end of editable region
    //if not editable, but found end of editable region, close off the lock.
    //to fix bug 171165: we should never overlap locks with a template boundary, so end lock if any.
    else if (!this.editable && code.length && (code.indexOf(NEWTEMPLBEGIN) != -1 || code.indexOf(NEWTEMPLEND) != -1
             || code.indexOf(OLDTEMPLBEGIN) != -1 || code.indexOf(OLDTEMPLEND) != -1))
    {
      this.editable = true;
      this.regions.push(offset); //end lock
    }
  }

  return true;
}


//Open Tag Begin
//        text tag: if in lock, end lock.
//    not text tag: if not in lock, begin lock.
//MM:BeginLock tag: if in lock, end lock. Either way, stop translating.
function EditRgnCallback_openTagBegin(tag, offset)
{
  tag = tag.toLowerCase(); //force to lowercase
  this.curTag = tag;
  this.curOffset = offset;
  if (this.canTranslate)
  {
    if (this.isTextTag(tag, offset))   //if starting text tag...
    {
      if (!this.editable) //  and in locked region...
      {
        this.editable = true;
        this.regions.push(offset); //    end lock
      }
    }
    else                           //else it's not a text tag.
    {
      if (tag == BEGINLOCKTAG_LOWERCASE)
      {                            //  else if MM:BeginLock tag...
        if (!this.editable)        //    and in locked region...
        {
          this.regions.push(offset); //    end lock.
        }
        this.editable = false;
        this.canTranslate = false; //    stop translating.
      }
      else if (this.editable && (this.transAll || this.isCodeTag(tag, offset))) //  if not in locked region...
      {
        //Script Tags inserted for flash should be editable
        var tailString = this.inStr.substr(offset+5);
        var scriptTagIndex = tailString.search("script");

        var scriptStr = this.inStr.substr(offset, offset+5+scriptTagIndex);

        if( !scriptStr || scriptStr.search("swfobject.register") == -1)
        {
          this.editable = false;
          this.regions.push(offset);    //begin a new lock.
          if (this.regions.length == 1) //special case if body starts with lockable stuff
          {
            this.regions.push(offset);  //need to start lock, since first region ignored
          }
        }
      }
      else if (!this.editable && !this.transAll && !this.isCodeTag(tag, offset)) //  special case for directives
      {
        this.editable = true;
        this.regions.push(offset); //    end lock
      }
      else if (!this.editable && this.isCodeTag(tag, offset)) // If directive, just mark for shield
      {
        this.regions.push(offset);
        this.regions.push(offset);
      } //Lock some tags entirely
      if (TAGS_TO_LOCK_ENTIRELY.indexOf(" "+tag+" ") != -1)
      { //if we should lock everything in this tag (such as SCRIPT)
        this.canTranslate = false;   //shut off translator until closed
        this.noTranslateBlock = tag; //remember tag we're in
      }
    }
  }
  return true;
}


//Open Tag End
//        body tag: enable translation, remember offset
//  MM:EndLock tag: resume translation
function EditRgnCallback_openTagEnd(offset)
{
  if (this.isValidRegion(this.curTag)) { //if ended valid region tag, such as <body>, start translation
    this.canTranslate = true;
    this.editable = true;        //assume editable
  }
  else if (this.curTag == ENDLOCKTAG_LOWERCASE)
  {
    this.canTranslate = true;    //start translating again
    this.editable = true;        //assume editable
  }
  if (this.curTag == "cfoutput") this.inCFOUTPUT = true;
  this.curTag = "";
  return true;
}


//Close Tag Begin
//         </body> tag: stop translating, close any locks
//  non-text close tag: if not in lock, start lock
function EditRgnCallback_closeTagBegin(tag, offset)
{
  tag = tag.toLowerCase(); //force to lowercase
  if (this.isValidRegion(tag))         //special case: if ending BODY
  {
    this.canTranslate = false;     //stop translating
    if (!this.editable)            //if editable
    {
      this.regions.push(offset);   //close editable region
    }
    this.regions.push(offset);     //remember last location
    this.editable = false;
  }
  else if (this.canTranslate)
  {
    if (this.transAll || this.isCodeTag(tag, offset))
    {
      if (this.editable)      //if not in lock
      {
        if (!this.isTextTag(tag, offset))  //if hit non-text close tag...
        {
          this.editable = false;                                    //  begin new lock
          this.regions.push(offset);
        }
      }
      else if (this.isTextTag(tag, offset)) //if in lock, but hit editable close tag
      {
        this.editable = true;      //end lock. This allows typing at then end of locks etc.
        this.regions.push(offset);
      }
    }
    else if (!this.editable)
    {
       this.editable = true;      //end lock. This allows typing at the end of locks etc.
       this.regions.push(offset);
    }
  }
  if (tag == this.noTranslateBlock)  //if in a no-translate block
  {
    this.canTranslate = true;
    this.noTranslateBlock = "";      //clear flag
  }
  if (tag == "cfoutput") this.inCFOUTPUT = false;
  this.curTag = "";
  return true;
}


//Callback for attributes. Currently used for locking dynamic images & links, and layers.
//If currently protecting code and we found an img or input tag with dynamic src, href
//start lock before image tag. If in ETO mode and we find style="position:absolute", lock it too.
function EditRgnCallback_attribute(attribName, attribValue)
{
  if (this.editable && this.canTranslate && this.lockCode)      //if not in lock (&& only if locking code)
  {
    attribName = attribName.toLowerCase(); //force to lowercase

    if (DYN_ATTRIBS.indexOf(" "+attribName+" ") != -1       //if attribute we care about (such as SRC)
     && DYN_ATTRIB_TAGS.indexOf(" "+this.curTag+" ") != -1) //and if tag we care about (such as IMG)
    {
      var isDynamic = false;
      attribValue = attribValue.toLowerCase(); //force to lowercase

      if (attribValue.indexOf(DYN_ATTRIB_QUICKSEARCH) != -1)  //if quicksearch found
      {
        for (var i=0; i<DYN_ATTRIB_PATTERNS.length; i++)      //check for each dynamic pattern
        {
          if (attribValue.indexOf(DYN_ATTRIB_PATTERNS[i]) != -1)  //if pattern found
          {
            isDynamic = true;
            break;
          }
        }
      }

      else if (attribName != "alt")  //check attribs other than alt
      { //check for CF variables (#RS.value#), found if >1 # sign
        var i = attribValue.match(/#/g);  //find first #
        //dynamic if foo.htm?#rs.val# or foo.htm##someAnchor?#rs.val#
        //but not dynamic if foo.htm##someAnchor
        if (i && i.length>1 && !(i.length==2 && attribValue.indexOf("##")!=-1)) isDynamic = true;
      }

      if (isDynamic)
      {
        this.editable = false;
        this.regions.push(this.curOffset);    //begin a new lock before curTag

        //special case: if block tag (such as A), stop translating until we find close block
        if (DYN_ATTRIB_TAGS_BLOCK.indexOf(" "+this.curTag+" ") != -1)
        {
          this.canTranslate = false;           //stop translating
          this.noTranslateBlock = this.curTag; //remember tag name
        }
      }
    }
    //If ETO, search for layers: if style="position:absolute..", lock it
    else if (this.transAll && attribName=="style" && attribValue.search(/position\s*:\s*absolute/i)!=-1)
    {
      this.editable = false;
      this.regions.push(this.curOffset);    //begin a new lock before curTag
    }
    //If ETO, and found named anchor - <a name="foo"> - lock it (we don't lock regular links).
    //Note that this will also lock links that are named (if has name && href, also locks it).
    else if (this.transAll && this.curTag=="a" && attribName=="name")
    {
      this.editable = false;
      this.regions.push(this.curOffset);    //begin a new lock before curTag
    }
  }
  return true;
}



//Build Out String
//Given the this.regions array of start/stop offsets, recreate document
//by inserting beginlock/endlock tags.
function EditRgnCallback_buildOutstr()
{
  var endPos, shieldNum = null;
  this.docArray = new Array();  //for performance reasons, we recreate the document as an array

  //if document has no close-body tag, push end of doc on stack so locks close
  if (this.inStr.search(/<\/body/i) == -1)
  {
    this.regions.push(this.inStr.length); //always add final region to stack
    if (this.regions.length > 1 && this.regions.length % 2 != 0)
    { //if not an even number of regions, add extra one to close
      this.regions.push(this.inStr.length);
    }
  }

  //special case: shift one out if extra
  if (this.regions.length > 1 && this.regions.length % 2 != 0)
  {
    this.regions.unshift(this.regions[0]);
  }

  if (this.regions.length > 1 && this.regions.length % 2 == 0)
  {
    this.docArray.push(this.inStr.substring(0,this.regions[1]));  //grab first chunk
    for (var i=1; i<this.regions.length-1; i++)
    {
      if (i%2 == 0)  //alternate begin/end locks
      {
        //This condition was added so that dynamic shields show up within locks. If we see
        //a pair of regions that are the same, don't begin/end a new lock: just add shield image.
        //(always begin/end locks if not locking code so we can edit between shields)
        if (!this.lockCode || this.regions[i] != this.regions[i+1] || i >= this.regions.length-2)
        {
          this.docArray.push(ENDLOCK);    //add close lock tag
        }
        this.docArray.push(this.inStr.substring(this.regions[i],this.regions[i+1])); //add next chunk
      }
      else
      {
        //This condition was added so that dynamic shields show up within locks. If we saw
        //a pair of regions that are the same, don't begin/end a new lock: just add shield image.
        //(always begin/end locks if not locking code so we can edit between shields)
        //Always add lock the very first time (i<=1).
        if (!this.lockCode || i <= 1 || this.regions[i] != this.regions[i-1])
        {
          //If regions that follow this one are the same, we need to step over those regions here
          //and add them to the orig attribute.
          endPos = i+1;
          if (this.lockCode)
          { //skip over matching regions by adding them to the orig attribute
            while (endPos<this.regions.length-3 && this.regions[endPos]==this.regions[endPos+1]) endPos+=2;
          }

          // Fix for bug 184858: Javascript document.write statement corrupted on save/publish
          //  Added code to encode ampersand characters within the orig property as well.
          this.docArray.push(
            BEGINLOCK1 +
            escape(this.inStr.substring(this.regions[i],this.regions[endPos])).replace(/&/g,"%26") +
            BEGINLOCK2);
        }
        if (this.displayShields)
        { //if there's a special shield image to display for this lock (such as CF), insert it here
          shieldNum = (this.shields[String(this.regions[i])]);
          if (shieldNum) this.docArray.push(SHIELDS[shieldNum]);   //add shield image to docArray
          if (!shieldNum || shieldNum != SHIELD_CFDATA)
          { //Add the regular text except if Cold Fusion data
            this.docArray.push(this.inStr.substring(this.regions[i],this.regions[i+1])); //add next chunk
          }
		  else
		  { // CF data -- need to push any text after the #...# chunk.
		  	var curChunk = this.inStr.substring(this.regions[i],this.regions[i+1]);

			// Since this is CF data, it should start with a '#'.
			if (curChunk.length && curChunk.charAt(0) == '#')
			{
			  // Find the second '#' that indicates the end of the CF data.
			  var endPos = curChunk.indexOf('#', 1);

			  // If the second '#' isn't at the very end of the chunk, push the
			  // rest of the chunk.
			  if (endPos >= 1 && endPos < curChunk.length - 1)
			  {
			  	this.docArray.push(curChunk.substring(endPos + 1));
		      }
			}
		  }
        }
        else
        { //Add the regular text
          this.docArray.push(this.inStr.substring(this.regions[i],this.regions[i+1])); //add next chunk
        }
      }
    }
    this.docArray.push(this.inStr.substring(this.regions[this.regions.length-1],this.inStr.length));
    this.isValid = true;
  }
  else
  {
    this.docArray.push(this.inStr);
    this.isValid = false;
  }
}


//Returns the new document string that was built by buildOutStr
function EditRgnCallback_getDocString()
{
  return this.docArray.join("");  //join the array of strings to form one giant string
}


//Determine if tag is valid region to inspect (such as BODY tag). Ignores TITLE for example.
function EditRgnCallback_isValidRegion(tag)
{
  return (VALID_REGIONS.indexOf(" "+tag+" ") != -1);
}



//Determine if tag is a text tag. If not, set shields to display for scripts
function EditRgnCallback_isTextTag(tag, offset)
{
  var retVal = false;

  //if in list of text tags
  retVal = (TEXT_TAGS.indexOf(" "+tag+" ") != -1);

  //if not a text tag, set shields to indicate scripts
  if (!retVal && this.displayShields) this.setShields(tag,offset);

  return retVal;
}


//Determine if tag is code, such as server tags, SCRIPT, form tags etc.
//Remember tag locations to display shields.
function EditRgnCallback_isCodeTag(tag, offset)
{
  var retVal = this.setShields(tag,offset);  //create shields for all server code, all the time
  if (!retVal && this.lockCode)              //otherwise if locking code, translate FORMS etc.
  {
    if (FORM_TAGS.indexOf(" "+tag+" ") != -1) //if tag is form tag or element
    {
      retVal = true;
    }
  }
  return retVal;
}



//Given a tag that may require a shield to display (such as CF, SCRIPT, or unknown XXX:YYY)
//add to array so that it will be translated as a yellow code shield.
//It's presumed that the tag passed in is lowercase.
function EditRgnCallback_setShields(tag, offset)
{
  var retVal = false;
  if (tag.indexOf(CF_TAG_PREFIX) == 0 && tag != "cfinclude")  //if Cold Fusion tag (but not CFINCLUDE)
  {
    if (this.displayShields) this.shields[String(offset)] = SHIELD_CF;
    retVal = true;
  }
  else if (tag.indexOf(ASP_TAG_PREFIX) == 0 || ASP_TAGS.indexOf(" "+tag+" ") != -1)  //if ASP .Net tag
  {
    if (this.displayShields) this.shields[String(offset)] = SHIELD_ASP;
    retVal = true;
  }
  else if (CODE_TAGS.indexOf(" "+tag+" ") != -1) //if tag is script
  {
    //Special case for script tags for Flash
    var tailString = this.inStr.substr(offset+5);
    var scriptTagIndex = tailString.search("script");

    var scriptStr = this.inStr.substr(offset, offset+5+scriptTagIndex);

    if(!scriptStr || (scriptStr.search("swfobject.register") == -1 && scriptStr.search("Spry.Widget") == -1))
    {
  
      if (this.displayShields)
      {
        this.shields[String(offset)] = SHIELD_SCRIPT;
        retVal = true;
      }
    }
    retVal = false;
  } //if tag has special chars, such as asp:foo, and not template tag
  else if (tag.search(/[^\w\d]/) != -1 && tag!=ENDLOCKTAG_LOWERCASE && tag!=OLDLOCKTAG_LOWERCASE)
  {
    if (this.displayShields) this.shields[String(offset)] = SHIELD_GENERIC;
    retVal = true;
  }
  return retVal;
}


//***** END CLASS EditRgnCallback *************


//--------------------- LOCAL FUNCTIONS ------------------------------


function editTextOnlyEnabled()
{
  //test preference
  var retVal = false;
  var DOM = dw.getDocumentDOM();
  if (DOM) {
    retVal = (DOM.getCCSharedSetting_TextOnlyInNonTemplates());
  }
  return retVal;
}


function codeLockEnabled()
{
  var retVal = false;
  var DOM = dw.getDocumentDOM();
  if (DOM) {
    retVal = (!DOM.getCCSharedSetting_CanDeleteCode() || editTextOnlyEnabled());
  }
  return retVal;
}


function ssiLockEnabled()
{
  var retVal = false;
  var DOM = dw.getDocumentDOM();
  if (DOM) {
    retVal = (!DOM.getCCSharedSetting_CanDeleteCode() || editTextOnlyEnabled());
  }
  return retVal;
}

//--------------------- END JAVASCRIPT ------------------------------
</script>
</head>
<body>
</body>
</html>
