In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Linked TextField-s

visit 
http://blog.yoz.sk/2010/04/linkedtextfields-class-to-split-text-into-multiple-textfields/
for more
Get Adobe Flash player
by jozefchutka 15 Apr 2010
/**
 * Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1Wtk
 */

// visit 
// http://blog.yoz.sk/2010/04/linkedtextfields-class-to-split-text-into-multiple-textfields/
// for more

package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    
    [SWF(width="465", height="465", frameRate="30", backgroundColor="#ffffff")]
    
    public class Linked extends Sprite
    {
        private var link:LinkedTextFields = new LinkedTextFields();

        public static const HTML:String = "<font size='20'>Lorem ipsum <font " +
                "color='#ff0000'>dolor sit amet</font>, consectetur <font fac" +
                "e='_sans'><b>adipiscing</b> elit. Aliquam ac orci <u>urna, e" +
                "u ornare ue. <b>Nullam <font color='#00ff00'>suscipit, <font" +
                " color='#0000ff'>turpis vitae viverra ultrices</font>, turpi" +
                "s nisl euismod lorem, convallis tristique</font> lectus risu" +
                "s</b> convallis</u> orci. Vitae vestibulum lectus</font> <fo" +
                "nt size='15' color='#999999'>est vel neque. Class aptent tac" +
                "iti <b>sociosqu ad litora <u>torquent</u> per conubia nostra" +
                "</b>, per inceptos eget lorem in mi feugiat sollicitudin at " +
                "quis lacus ultrices accumsan tortor commodo non. Cras tempus" +
                " scelerisq</font></font>";
        
        public function Linked():void
        {
            super();
            
            var textField1:TextField = new TextField();
            textField1.x = 10;
            textField1.y = 10;
            textField1.width = 410;
            textField1.height = 100;
            textField1.border = true;
            textField1.wordWrap = true;
            textField1.multiline = true;
            addChild(textField1);
            
            var textField2:TextField = new TextField();
            textField2.x = 10;
            textField2.y = 120;
            textField2.width = 200;
            textField2.height = 100;
            textField2.border = true;
            textField2.wordWrap = true;
            textField2.multiline = true;
            addChild(textField2);
            
            var textField3:TextField = new TextField();
            textField3.x = 220;
            textField3.y = 120;
            textField3.width = 200;
            textField3.height = 100;
            textField3.border = true;
            textField3.wordWrap = true;
            textField3.multiline = true;
            addChild(textField3);
            
            link.add(textField1);
            link.add(textField3);
            link.add(textField2, 1);
            
            //link.text = TEXT;
            link.text = HTML;
            link.renderHtmlText();
        }
    }
}

import flash.events.EventDispatcher;
import flash.text.TextField;

class LinkedTextFields extends EventDispatcher
{
	public static const DEFAULT_TEXT_DELIMITER:RegExp = /(\s)/;
	public static const DEFAULT_HTML_DELIMITER:RegExp = /([\s<>])/;
	
	public var autoRender:Function = null;
	public var textDelimiter:RegExp;
	public var htmlDelimiter:RegExp;
	
	protected var list:Array = [];
	protected var _text:String;
	
	public function LinkedTextFields(autoRender:Function = null, 
		delimiter:RegExp = null, htmlDelimiter:RegExp = null)
	{
		super();
		
		this.autoRender = autoRender;
		this.textDelimiter = textDelimiter 
			? textDelimiter 
			: DEFAULT_TEXT_DELIMITER;
		this.htmlDelimiter = htmlDelimiter 
			? htmlDelimiter 
			: DEFAULT_HTML_DELIMITER;
	}
	
	public function set text(value:String):void
	{
		_text = value;
		if(autoRender != null)
			autoRender();
	}
	
	public function get text():String
	{
		return _text;
	}
	
	public function add(textField:TextField, index:int = -1):void
	{
		if(index == -1)
			list.push(textField);
		else
			list.splice(index, 0, textField);
		if(autoRender != null)
			autoRender();
	}
	
	public function remove(textField:TextField):void
	{
		var index:int = list.indexOf(textField);
		if(index != -1)
			list.splice(index, 1);
		if(autoRender != null)
			autoRender();
	}
	
	public function renderText():void
	{
		emptyTextFields();
		if(!this.text)
			return;
		
		var chunk:String, prevText:String;
		var chunks:Array = text.split(textDelimiter);
		var textField:TextField = list[0];
		var last:Boolean = !nextTextField(textField);
		
		while(chunks.length)
		{
			chunk = chunks.shift()
			prevText = textField.text;
			textField.appendText(chunk);
			if(!last && textField.maxScrollV > 1)
			{
				textField.text = prevText;
				textField = nextTextField(textField);
				textField.text = chunk;
				if(!nextTextField(textField))
					last = true;
			}
		}
	}
	
	public function renderHtmlText():void
	{
		emptyTextFields();
		if(!this.text)
			return;
		
		var chunk:String, text:String = "", prevText:String;
		var chunks:Array = this.text.split(htmlDelimiter);
		var textField:TextField = list[0];
		var last:Boolean = !nextTextField(textField);
		var tag:String = "", tagName:String, isTag:Boolean, tags:Array = [];
		
		while(chunks.length)
		{
			chunk = chunks.shift();
				
			if(chunk == "<")
				isTag = true;
				
			if(isTag && tag == "<")
			{
				tagName = chunk.toLowerCase();
				if(tagName.substr(0, 1) == "/")
					removeLastTag(tags, tagName.substr(1));
				else
					addTag(tags, tagName);
			}
			
			if(isTag)
				tag += chunk;
				
			if(isTag && chunk == ">")
			{
				isTag = false;
				if(tag.substr(-2) == "/>" || tagName == "br")
					removeLastTag(tags, tagName);
				else if(tag.substr(0, 2) != "</")
					addLastTagDefinition(tags, tag);
				chunk = tag;
				tag = "";
			}
			
			if(isTag)
				continue;
			
			prevText = text;
			text += chunk;
			textField.htmlText = text + writeAllTagClosage(tags);
			
			if(last || textField.maxScrollV <= 1)
				continue;
			
			textField.htmlText = prevText + writeAllTagClosage(tags);
			textField = nextTextField(textField);
			text = writeAllTagDefinitions(tags) + chunk;
			if(!nextTextField(textField))
				last = true;
		}
		
		textField.htmlText = text + writeAllTagClosage(tags);
		
	}
	
	public function emptyTextFields():void
	{
		for each(var textField:TextField in list)
		{
			textField.text = "";
			textField.htmlText = "";
		}
	}
	
	protected function addTag(list:Array, tagName:String):void
	{
		list.push({name:tagName});
	}
	
	protected function addLastTagDefinition(list:Array, definition:String)
		:void
	{
		list[list.length - 1].definition = definition;
	}
	
	protected function writeAllTagDefinitions(list:Array):String
	{
		var definitions:String = "";
		for each(var item:Object in list)
			definitions += item.definition;
		return definitions;
	}
	
	protected function writeAllTagClosage(list:Array):String
	{
		var closage:String = "";
		for(var i:int = list.length - 1; i >= 0; i--)
			closage += "</" + list[i].name + ">";
		return closage;
	}
	
	protected function removeLastTag(list:Array, tagName:String):void
	{
		if(list[list.length - 1].name == tagName)
			list.splice(list.length - 1, 1);
	}
	
	protected function nextTextField(textField:TextField):TextField
	{
		var index:int = list.indexOf(textField);
		if(index == -1 || index + 1 >= list.length)
			return null;
		return list[index + 1];
	}
}