forked from: Linked TextField-s

by jozefchutka forked from Linked TextField-s (diff: 134)
visit 
http://blog.yoz.sk/2010/04/linkedtextfields-class-to-split-text-into-multiple-textfields/
for more
♥2 | Line 273 | Modified 2010-04-15 17:25:03 | MIT License
play

ActionScript3 source code

/**
 * Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hjTb
 */

// forked from jozefchutka's Linked TextField-s
// visit 
// http://blog.yoz.sk/2010/04/linkedtextfields-class-to-split-text-into-multiple-textfields/
// for more

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.AntiAliasType;
    import flash.text.GridFitType;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    
    [SWF(width="465", height="465", frameRate="30", backgroundColor="#ffffff")]
    
    public class Linked2 extends Sprite
    {
        private var link:LinkedTextFields = new LinkedTextFields();
        
        public static const HTML:String = "<p><font size='16' color='#000000'" + 
                "><b>Lorem ipsum dolor sit amet, consec</b></font></p><p><fon" + 
                "t size='13'>Vestibulum aliquam mi et metus tristique ferment" + 
                "um</font></p>" +
                "<p>Tetur adipiscing elit. Vivamus mas purus ac diam bibendum" +
                " vitae rhoncus sapien posuere. Vestibulum gravida midat vel " +
                "pis cursus sit amet interdum eros egestas. Nunc fermentum ul" + 
                "tricies velit, non dictum est venenatis ultricies. Pellentes" +
                "que vehicula lectus nec nibh mollis pellentesque. Aenean vit" +
                "ae tortor lectus. Nulla imperdiet erat nec sapien ornare ut " +
                "laoreet sem venenatis. Mauris ipsum augue, lacinia sed solli" +
                "citudin interdum, rutrum ornare nisl. Nulla interdum lorem a" +
                "ccumsan leo tincidunt adipiscing. Nunc egestas blandit nibh," +
                " ultrices accumsan tortor commodo non. Cras tempus scelerisq" +
                "ue ullamcorper.</p><p>Nullam velit lacus, facils vel pharetr" +
                "a in, lacinia vitae purus. Sed nisl lorem, lacinia a molesti" +
                "e eu, pretium at justo. Nulla facilisi. Maecenas sagittis te" +
                "llus quis sapien vestibulum gravida. Suspendisse potenti. Cu" +
                "rabitur at felis et nisl tincidunt condimentum ut nec eros. " +
                "Pellentesque neque magna, venenatis sit amet bibendum eget, " +
                "cursus eu sapien. Nulla malesuada convallis felis nec congue" +
                ". Sed lorem massa, egestas a pharetra commodo, consectetur i" +
                "mperdiet odio. Nullam nec neque ac metus ultrices commodo. M" +
                "aecenas a lorem sed augue tincidunt tincidunt. Nam lobortis " +
                "vestibulum massa, ut viverra leo venenatis a. Praesent scele" +
                "risque, velit non tempor euismod, tellus nulla aliquam nisi," +
                " vitae vestibulum lectus est vel neque. Class aptent taciti " +
                "sociosqu ad litora torquent per conubia nostra, per inceptos" +
                " himenaeos. Proin eleifend turpis vel lectus vehicula accums" +
                "an. Vestibulum aliquam mi et metus tristique fermentum. Null" +
                "a eget lorem in mi feugiat sollicitudin at quis lacus.</p>";
        
        public function Linked2():void
        {
            super();
            
            var textField:TextField;
            
            textField = new TextField();
            textField.x = textField.y = 12;
            textField.width = 441;
            textField.height = 176;
            textField.text = HTML;
            textField.border = true;
            textField.wordWrap = true;
            textField.multiline = true;
            textField.type = TextFieldType.INPUT;
            textField.addEventListener(Event.CHANGE, textChange);
            addChild(textField);
            
            textField = createTextField();
            textField.x = 12;
            textField.y = 200;
            textField.width = 441;
            textField.height = 45;
            addChild(textField);
            link.add(textField);
            
            textField = createTextField();
            textField.x = 12;
            textField.y = 245;
            addChild(textField);
            link.add(textField);
            
            textField = createTextField();
            textField.x = 163;
            textField.y = 245;
            addChild(textField);
            link.add(textField);
            
            textField = createTextField();
            textField.x = 314;
            textField.y = 245;
            addChild(textField);
            link.add(textField);
            
            link.autoRender = link.renderHtmlText;
            link.text = HTML;
        }
        
        private function createTextField():TextField
        {
            var format:TextFormat = new TextFormat("_sans", 11, 0x999999);
            format.align = TextFormatAlign.JUSTIFY;
            
            var textField:TextField = new TextField();
            textField.width = 139;
            textField.height = 203;
            textField.wordWrap = true;
            textField.multiline = true;
            textField.selectable = false;
            textField.defaultTextFormat = format;
            textField.antiAliasType = AntiAliasType.ADVANCED;
            textField.gridFitType = GridFitType.PIXEL;
            return textField;
        }
        
        private function textChange(event:Event):void
        {
            link.text = TextField(event.currentTarget).text;
        }
    }
}

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("text");
		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();
			if(chunk == "\r")
				chunk = "\n";
			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("htmlText");
		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(type:String = "text"):void
	{
		for each(var textField:TextField in list)
			textField[type == "text" ? type : "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];
	}
}