HtmlFilter Customization
HtmlFilter is the component in C1RichTextBox that transforms HTML strings to C1Documents and back. It's also capable of transforming to and from an intermediate representation of an HTML document called C1HtmlDocument.
When transforming between C1HtmlDocument and C1Document, several events are fired allowing customization of each node that is transformed. These events are:
•ConvertingHtmlNode: this event is fired just before an HTML node is transformed. If marked as handled by the event handler then HtmlFilter assumes the node was transformed and skips it.
•ConvertedHtmlNode: this event is fired after a node was transformed. It can be used to make minor changes to the transformation result.
•ConvertingTextElement: this event is fired just before a C1TextElement is transformed. If marked as handled by the event handler then HtmlFilter assumes the element was transformed and skips it.
•ConvertedTextElement: this event is fired after a C1TextElement is transformed. It can be used to make minor changes to the transformation result.
As an example you can see how the HtmlFilterCustomization sample adds support for GIF images using C1.Silverlight.Imaging. It uses both ConvertingHtmlNode and ConvertingTextElement events. Here is the ConvertingHtmlNode event handler:
Private Sub HtmlFilter_ConvertingHtmlNode(sender As Object, e As ConvertingHtmlNodeEventArgs)
Dim htmlElement = TryCast(e.HtmlNode, C1HtmlElement)
If htmlElement IsNot Nothing AndAlso htmlElement.Name = "img" Then
Dim src As String
If htmlElement.Attributes.TryGetValue("src", src) Then
Dim uri = New Uri("/HtmlFilterCustomization;component/" & src, UriKind.Relative)
Dim resource = Application.GetResourceStream(uri)
If resource IsNot Nothing Then
Dim imageSource = New C1Bitmap(resource.Stream).ImageSource
Dim image = New Image() With { _
Key .Source = imageSource _
}
SetImageSource(image, src)
e.Parent.Children.Add(New C1InlineUIContainer() With { _
Key .Child = image _
})
e.Handled = True
End If
End If
End If
End Sub
•C#
void HtmlFilter_ConvertingHtmlNode(object sender, ConvertingHtmlNodeEventArgs e)
{
var htmlElement = e.HtmlNode as C1HtmlElement;
if (htmlElement != null && htmlElement.Name == "img")
{
string src;
if (htmlElement.Attributes.TryGetValue("src", out src))
{
var uri = new Uri("/HtmlFilterCustomization;component/" + src, UriKind.Relative);
var resource = Application.GetResourceStream(uri);
if(resource != null)
{
var imageSource = new C1Bitmap(resource.Stream).ImageSource;
var image = new Image { Source = imageSource };
SetImageSource(image, src);
e.Parent.Children.Add(new C1InlineUIContainer { Child = image });
e.Handled = true;
}
}
}
}
The first thing the event handler does is cast e.HtmlNode to C1HtmlElement. There are two types that inherit from C1HtmlNode: C1HtmlElement, which represents an HTML element like <img/>, and C1HtmlText, which represents a text node.
Once the C1HtmlNode object has been cast to C1HtmlElement, it's possible to check the tag name, and access its attributes. This is done to see if the element is in fact an IMG tag, and to obtain the SRC attribute. The rest of the code takes core of creating the appropriate element, which is then added to e.Parent. Note that the SRC value is saved as an attached property, to be accessed when exporting.
Once the transformation is done, the handler can set e.Handled to True in order to prevent HtmlFilter from transforming this C1HtmlNode.
The ConvertingTextElement event handler looks like the following:
Private Sub HtmlFilter_ConvertingTextElement(sender As Object, e As ConvertingTextElementEventArgs)
Dim inlineContainer = TryCast(e.TextElement, C1InlineUIContainer)
If inlineContainer IsNot Nothing Then
Dim src = GetImageSource(inlineContainer.Child)
If src IsNot Nothing Then
Dim element = New C1HtmlElement("img")
element.Attributes("src") = src
e.Parent.Add(element)
e.Handled = True
End If
End If
End Sub
•C#
void HtmlFilter_ConvertingTextElement(object sender, ConvertingTextElementEventArgs e)
{
var inlineContainer = e.TextElement as C1InlineUIContainer;
if (inlineContainer != null)
{
var src = GetImageSource(inlineContainer.Child);
if (src != null)
{
var element = new C1HtmlElement("img");
element.Attributes["src"] = src;
e.Parent.Add(element);
e.Handled = true;
}
}
}
This is pretty similar to the other handler, only it transforms a C1TextElement to a C1HtmlElement. Note that the SRC value is recovered from the attached property, and a C1HtmlElement is created with that attribute. As before, the new element is added to e.Parent, and the event is marked as Handled.