Files
Umbraco-CMS/src/umbraco.editorControls/tinymce/tinyMCEImageHelper.cs
Shannon Deminick e2d806f5d9 Merge with 4.11.5
2013-02-22 20:00:10 +06:00

147 lines
6.6 KiB
C#

using System;
using System.Collections;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.Files;
using umbraco.IO;
namespace umbraco.editorControls.tinymce
{
internal class tinyMCEImageHelper
{
public static string cleanImages(string html)
{
var allowedAttributes = UmbracoSettings.ImageAllowedAttributes.ToLower().Split(',').ToList();
//Always add src as it's essential to output any image at all
if (allowedAttributes.Contains("src") == false)
allowedAttributes.Add("src");
const string pattern = @"<img [^>]*>";
var tags = Regex.Matches(html + " ", pattern, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match tag in tags)
{
if (tag.Value.ToLower().IndexOf("umbraco_macro", StringComparison.Ordinal) == -1)
{
var cleanTag = "<img";
// gather all attributes
// TODO: This should be replaced with a general helper method - but for now we'll wanna leave umbraco.dll alone for this patch
var ht = new Hashtable();
var matches = Regex.Matches(tag.Value.Replace(">", " >"), "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"|(?<attributeName>\\S*)=(?<attributeValue>[^\"|\\s]*)\\s", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match attributeSet in matches)
{
ht.Add(attributeSet.Groups["attributeName"].Value.ToLower(),
attributeSet.Groups["attributeValue"].Value);
}
// If rel attribute exists and if it's different from current sizing we should resize the image!
if (helper.FindAttribute(ht, "rel") != "")
{
// if size has changed resize image serverside
var newDims = helper.FindAttribute(ht, "rel").Split(",".ToCharArray());
if (newDims.Length > 0 && (newDims[0] != helper.FindAttribute(ht, "width") || newDims[1] != helper.FindAttribute(ht, "height")))
{
try
{
int newWidth;
int newHeight;
string newSrc;
cleanTag += DoResize(ht, out newWidth, out newHeight, out newSrc);
ht["src"] = newSrc;
}
catch (Exception err)
{
cleanTag += " src=\"" + helper.FindAttribute(ht, "src") + "\"";
if (helper.FindAttribute(ht, "width") != "")
{
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
}
LogHelper.Error<tinyMCEImageHelper>("Error resizing image in editor", err);
}
}
else
{
if (helper.FindAttribute(ht, "width") != "")
{
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
}
}
}
else
{
if (helper.FindAttribute(ht, "width") != "")
{
cleanTag += " width=\"" + helper.FindAttribute(ht, "width") + "\"";
cleanTag += " height=\"" + helper.FindAttribute(ht, "height") + "\"";
}
}
// Build image tag
foreach (var attr in allowedAttributes)
{
if (helper.FindAttribute(ht, attr) != "")
{
var attrValue = helper.FindAttribute(ht, attr);
cleanTag += " " + attr + "=\"" + attrValue + "\"";
}
}
if (bool.Parse(GlobalSettings.EditXhtmlMode))
cleanTag += "/";
cleanTag += ">";
html = html.Replace(tag.Value, cleanTag);
}
}
return html;
}
private static string DoResize(IDictionary attributes, out int finalWidth, out int finalHeight, out string newSrc)
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var orgSrc = HttpContext.Current.Server.HtmlDecode(helper.FindAttribute(attributes, "src").Replace("%20", " "));
var orgDim = helper.FindAttribute(attributes, "rel").Split(",".ToCharArray());
var orgWidth = float.Parse(orgDim[0]);
var orgHeight = float.Parse(orgDim[1]);
var newWidth = int.Parse(helper.FindAttribute(attributes, "width"));
var newHeight = int.Parse(helper.FindAttribute(attributes, "height"));
newSrc = "";
if (orgHeight > 0 && orgWidth > 0 && orgSrc != "")
{
// Check dimensions
if (Math.Abs(orgWidth / newWidth) > Math.Abs(orgHeight / newHeight))
{
newHeight = (int)Math.Round(newWidth * (orgHeight / orgWidth));
}
else
{
newWidth = (int)Math.Round(newHeight * (orgWidth / orgHeight));
}
var orgPath = fs.GetRelativePath(orgSrc);
if (fs.FileExists(orgPath))
{
var uf = new UmbracoFile(orgPath);
newSrc = uf.Resize(newWidth, newHeight);
}
}
finalWidth = newWidth;
finalHeight = newHeight;
return " width=\"" + newWidth + "\" height=\"" + newHeight + "\"";
}
}
}