This repository has been archived by the owner on Sep 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
RichTextResolver.cs
129 lines (107 loc) · 4.8 KB
/
RichTextResolver.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web;
using CMS.EventLog;
using CMS.Helpers;
using CMS.SiteProvider;
using Newtonsoft.Json.Linq;
namespace LeeConlin.Kentico12.MVC.WidgetResolver
{
public class RichTextResolver : IRichTextResolver
{
public IWidgetResolver WidgetResolver { get; }
public IWidgetRegistry WidgetRegistry { get; }
private const string WIDGET_REGEX = @"\{\^widget\|(.+?)\^\}";
private const string WIDGET_INTERNAL_REGEX = @"^\(([a-zA-Z0-9]+)\)(.+)$";
public RichTextResolver(IWidgetResolver widgetResolver, IWidgetRegistry widgetRegistry)
{
WidgetResolver = widgetResolver;
WidgetRegistry = widgetRegistry;
}
// TODO Finish implementing Resolve
// TODO Add caching
//
/// <inheritdoc />
public IRichTextData Resolve(string richText,
UnknownWidgetBehaviour unknownWidgetBehaviour = UnknownWidgetBehaviour.WriteErrorInline)
{
var rt = new RichTextData();
var lastStartIndex = 0;
var match = Regex.Match(richText, WIDGET_REGEX);
while (match.Success)
{
var widgetText = match.Groups[1].Value;
var widgetObj = ParseWidgetText(widgetText);
// Get any text prior to the widget
var rawHtml = richText.Substring(lastStartIndex, richText.IndexOf(match.Value, StringComparison.Ordinal) - lastStartIndex);
rt.Add(new RichTextHtml(rawHtml));
var codename = widgetObj.Property("name").Value.ToString();
var type = WidgetRegistry.GetWidgetType(codename);
if (!unknownWidgetBehaviour.HasFlag(UnknownWidgetBehaviour.Ignore))
{
if (unknownWidgetBehaviour.HasFlag(UnknownWidgetBehaviour.WriteErrorInline) && type == null)
{
rt.Add(new RichTextHtml(
$"<div style=\"border: 1px solid #f00; padding: 5px; margin: 5px; background: #fff; color: #f00\"><p>Widget of type '{codename}' is not a valid and registered MVC widget.</p></div>"));
}
if (unknownWidgetBehaviour.HasFlag(UnknownWidgetBehaviour.WriteErrorToLog) && type == null)
{
EventLogProvider.LogWarning("RichTextResolver::Resolve", "UNKNOWN_WIDGET", null,
SiteContext.CurrentSiteID,
$"Widget of type '{codename}' is not a valid and registered MVC widget.");
}
if (unknownWidgetBehaviour.HasFlag(UnknownWidgetBehaviour.ThrowException) && type == null)
{
throw new Exception($"Widget of type '{codename}' is not a valid and registered MVC widget.");
}
}
if (type != null)
{
rt.Add(WidgetResolver.Resolve(widgetObj, type));
}
lastStartIndex = lastStartIndex + rawHtml.Length + match.Value.Length;
match = match.NextMatch();
}
var lastRawHtml = richText.Substring(lastStartIndex);
rt.Add(new RichTextHtml(lastRawHtml));
return rt;
}
private JObject ParseWidgetText(string widgetText)
{
var obj = new JObject();
var split = widgetText.Split('|');
foreach (var field in split)
{
var match = Regex.Match(field, WIDGET_INTERNAL_REGEX);
if (match.Success)
{
if (match.Groups.Count < 3) continue;
var fieldName = match.Groups[1].Value;
var value = match.Groups[2].Value;
if (int.TryParse(value, NumberStyles.Integer, null, out int iVal))
{
obj.Add(fieldName, iVal);
}
else if (decimal.TryParse(value, NumberStyles.Float, null, out decimal dVal))
{
obj.Add(fieldName, dVal);
}
else if (bool.TryParse(value, out bool bVal))
{
obj.Add(fieldName, bVal);
}
else
{
// Otherwise just add it as a string
obj.Add(fieldName, HttpUtility.UrlDecode(value));
/**
* Kentico seems to URL Encode the entire contents of strings in widgets.
*/
}
}
}
return obj;
}
}
}