修改调整
This commit is contained in:
395
Assets/Plugins/FairyGUI/Scripts/Utils/Html/HtmlParser.cs
Normal file
395
Assets/Plugins/FairyGUI/Scripts/Utils/Html/HtmlParser.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI.Utils
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class HtmlParser
|
||||
{
|
||||
public static HtmlParser inst = new HtmlParser();
|
||||
|
||||
protected class TextFormat2 : TextFormat
|
||||
{
|
||||
public bool colorChanged;
|
||||
}
|
||||
|
||||
protected List<TextFormat2> _textFormatStack;
|
||||
protected int _textFormatStackTop;
|
||||
protected TextFormat2 _format;
|
||||
protected List<HtmlElement> _elements;
|
||||
protected HtmlParseOptions _defaultOptions;
|
||||
|
||||
static List<string> sHelperList1 = new List<string>();
|
||||
static List<string> sHelperList2 = new List<string>();
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
static void InitializeOnLoad()
|
||||
{
|
||||
inst = new HtmlParser();
|
||||
}
|
||||
#endif
|
||||
|
||||
public HtmlParser()
|
||||
{
|
||||
_textFormatStack = new List<TextFormat2>();
|
||||
_format = new TextFormat2();
|
||||
_defaultOptions = new HtmlParseOptions();
|
||||
}
|
||||
|
||||
virtual public void Parse(string aSource, TextFormat defaultFormat, List<HtmlElement> elements, HtmlParseOptions parseOptions)
|
||||
{
|
||||
if (parseOptions == null)
|
||||
parseOptions = _defaultOptions;
|
||||
|
||||
_elements = elements;
|
||||
_textFormatStackTop = 0;
|
||||
_format.CopyFrom(defaultFormat);
|
||||
_format.colorChanged = false;
|
||||
int skipText = 0;
|
||||
bool ignoreWhiteSpace = parseOptions.ignoreWhiteSpace;
|
||||
bool skipNextCR = false;
|
||||
string text;
|
||||
|
||||
XMLIterator.Begin(aSource, true);
|
||||
while (XMLIterator.NextTag())
|
||||
{
|
||||
if (skipText == 0)
|
||||
{
|
||||
text = XMLIterator.GetText(ignoreWhiteSpace);
|
||||
if (text.Length > 0)
|
||||
{
|
||||
if (skipNextCR && text[0] == '\n')
|
||||
text = text.Substring(1);
|
||||
AppendText(text);
|
||||
}
|
||||
}
|
||||
|
||||
skipNextCR = false;
|
||||
switch (XMLIterator.tagName)
|
||||
{
|
||||
case "b":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.bold = true;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
break;
|
||||
|
||||
case "i":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.italic = true;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
break;
|
||||
|
||||
case "u":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.underline = true;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
break;
|
||||
|
||||
case "strike":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.strikethrough = true;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
break;
|
||||
|
||||
case "sub":
|
||||
{
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.specialStyle = TextFormat.SpecialStyle.Subscript;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
}
|
||||
break;
|
||||
|
||||
case "sup":
|
||||
{
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
_format.specialStyle = TextFormat.SpecialStyle.Superscript;
|
||||
}
|
||||
else
|
||||
PopTextFormat();
|
||||
}
|
||||
break;
|
||||
|
||||
case "font":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
|
||||
_format.size = XMLIterator.GetAttributeInt("size", _format.size);
|
||||
string color = XMLIterator.GetAttribute("color");
|
||||
if (color != null)
|
||||
{
|
||||
string[] parts = color.Split(',');
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
_format.color = ToolSet.ConvertFromHtmlColor(color);
|
||||
_format.gradientColor = null;
|
||||
_format.colorChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_format.gradientColor == null)
|
||||
_format.gradientColor = new Color32[4];
|
||||
_format.gradientColor[0] = ToolSet.ConvertFromHtmlColor(parts[0]);
|
||||
_format.gradientColor[1] = ToolSet.ConvertFromHtmlColor(parts[1]);
|
||||
if (parts.Length > 2)
|
||||
{
|
||||
_format.gradientColor[2] = ToolSet.ConvertFromHtmlColor(parts[2]);
|
||||
if (parts.Length > 3)
|
||||
_format.gradientColor[3] = ToolSet.ConvertFromHtmlColor(parts[3]);
|
||||
else
|
||||
_format.gradientColor[3] = _format.gradientColor[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
_format.gradientColor[2] = _format.gradientColor[0];
|
||||
_format.gradientColor[3] = _format.gradientColor[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (XMLIterator.tagType == XMLTagType.End)
|
||||
PopTextFormat();
|
||||
break;
|
||||
|
||||
case "br":
|
||||
AppendText("\n");
|
||||
break;
|
||||
|
||||
case "img":
|
||||
if (XMLIterator.tagType == XMLTagType.Start || XMLIterator.tagType == XMLTagType.Void)
|
||||
{
|
||||
HtmlElement element = HtmlElement.GetElement(HtmlElementType.Image);
|
||||
element.FetchAttributes();
|
||||
element.name = element.GetString("name");
|
||||
element.format.align = _format.align;
|
||||
_elements.Add(element);
|
||||
}
|
||||
break;
|
||||
|
||||
case "a":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
|
||||
_format.underline = _format.underline || parseOptions.linkUnderline;
|
||||
if (!_format.colorChanged && parseOptions.linkColor.a != 0)
|
||||
_format.color = parseOptions.linkColor;
|
||||
|
||||
HtmlElement element = HtmlElement.GetElement(HtmlElementType.Link);
|
||||
element.FetchAttributes();
|
||||
element.name = element.GetString("name");
|
||||
element.format.align = _format.align;
|
||||
_elements.Add(element);
|
||||
}
|
||||
else if (XMLIterator.tagType == XMLTagType.End)
|
||||
{
|
||||
PopTextFormat();
|
||||
|
||||
HtmlElement element = HtmlElement.GetElement(HtmlElementType.LinkEnd);
|
||||
_elements.Add(element);
|
||||
}
|
||||
break;
|
||||
|
||||
case "input":
|
||||
{
|
||||
HtmlElement element = HtmlElement.GetElement(HtmlElementType.Input);
|
||||
element.FetchAttributes();
|
||||
element.name = element.GetString("name");
|
||||
element.format.CopyFrom(_format);
|
||||
_elements.Add(element);
|
||||
}
|
||||
break;
|
||||
|
||||
case "select":
|
||||
{
|
||||
if (XMLIterator.tagType == XMLTagType.Start || XMLIterator.tagType == XMLTagType.Void)
|
||||
{
|
||||
HtmlElement element = HtmlElement.GetElement(HtmlElementType.Select);
|
||||
element.FetchAttributes();
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
sHelperList1.Clear();
|
||||
sHelperList2.Clear();
|
||||
while (XMLIterator.NextTag())
|
||||
{
|
||||
if (XMLIterator.tagName == "select")
|
||||
break;
|
||||
|
||||
if (XMLIterator.tagName == "option")
|
||||
{
|
||||
if (XMLIterator.tagType == XMLTagType.Start || XMLIterator.tagType == XMLTagType.Void)
|
||||
sHelperList2.Add(XMLIterator.GetAttribute("value", string.Empty));
|
||||
else
|
||||
sHelperList1.Add(XMLIterator.GetText());
|
||||
}
|
||||
}
|
||||
element.Set("items", sHelperList1.ToArray());
|
||||
element.Set("values", sHelperList2.ToArray());
|
||||
}
|
||||
element.name = element.GetString("name");
|
||||
element.format.CopyFrom(_format);
|
||||
_elements.Add(element);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "p":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
PushTextFormat();
|
||||
string align = XMLIterator.GetAttribute("align");
|
||||
switch (align)
|
||||
{
|
||||
case "center":
|
||||
_format.align = AlignType.Center;
|
||||
break;
|
||||
case "right":
|
||||
_format.align = AlignType.Right;
|
||||
break;
|
||||
}
|
||||
if (!IsNewLine())
|
||||
AppendText("\n");
|
||||
}
|
||||
else if (XMLIterator.tagType == XMLTagType.End)
|
||||
{
|
||||
AppendText("\n");
|
||||
skipNextCR = true;
|
||||
|
||||
PopTextFormat();
|
||||
}
|
||||
break;
|
||||
|
||||
case "ui":
|
||||
case "div":
|
||||
case "li":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
{
|
||||
if (!IsNewLine())
|
||||
AppendText("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendText("\n");
|
||||
skipNextCR = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case "html":
|
||||
case "body":
|
||||
//full html
|
||||
ignoreWhiteSpace = true;
|
||||
break;
|
||||
|
||||
case "head":
|
||||
case "style":
|
||||
case "script":
|
||||
case "form":
|
||||
if (XMLIterator.tagType == XMLTagType.Start)
|
||||
skipText++;
|
||||
else if (XMLIterator.tagType == XMLTagType.End)
|
||||
skipText--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipText == 0)
|
||||
{
|
||||
text = XMLIterator.GetText(ignoreWhiteSpace);
|
||||
if (text.Length > 0)
|
||||
{
|
||||
if (skipNextCR && text[0] == '\n')
|
||||
text = text.Substring(1);
|
||||
AppendText(text);
|
||||
}
|
||||
}
|
||||
|
||||
_elements = null;
|
||||
}
|
||||
|
||||
protected void PushTextFormat()
|
||||
{
|
||||
TextFormat2 tf;
|
||||
if (_textFormatStack.Count <= _textFormatStackTop)
|
||||
{
|
||||
tf = new TextFormat2();
|
||||
_textFormatStack.Add(tf);
|
||||
}
|
||||
else
|
||||
tf = _textFormatStack[_textFormatStackTop];
|
||||
tf.CopyFrom(_format);
|
||||
tf.colorChanged = _format.colorChanged;
|
||||
_textFormatStackTop++;
|
||||
}
|
||||
|
||||
protected void PopTextFormat()
|
||||
{
|
||||
if (_textFormatStackTop > 0)
|
||||
{
|
||||
TextFormat2 tf = _textFormatStack[_textFormatStackTop - 1];
|
||||
_format.CopyFrom(tf);
|
||||
_format.colorChanged = tf.colorChanged;
|
||||
_textFormatStackTop--;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsNewLine()
|
||||
{
|
||||
if (_elements.Count > 0)
|
||||
{
|
||||
HtmlElement element = _elements[_elements.Count - 1];
|
||||
if (element != null && element.type == HtmlElementType.Text)
|
||||
return element.text.EndsWith("\n");
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void AppendText(string text)
|
||||
{
|
||||
HtmlElement element;
|
||||
if (_elements.Count > 0)
|
||||
{
|
||||
element = _elements[_elements.Count - 1];
|
||||
if (element.type == HtmlElementType.Text && element.format.EqualStyle(_format))
|
||||
{
|
||||
element.text += text;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element = HtmlElement.GetElement(HtmlElementType.Text);
|
||||
element.text = text;
|
||||
element.format.CopyFrom(_format);
|
||||
_elements.Add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user