29 November, 2012

Umbraco using Safari insert image in tinymce (RTE)

Some of our new customers are using Safari, and they have stumbled upon some issues around using the Umbraco rich-text-editor (TinyMCE v3), they have problems with inserting images and macros.

We googled the problem a little, surely we couldent be the only Umbraco hosting company, which have end-clients using the Safari browser in the backend of Umbraco. But the top hits on google only revealed that there definitely was and is and long existing bug in Umbraco when it comes to the tinymce editor.

The specific problem our clients was facing was that when trying to insert an image or macro the editor just rendered out the text "mce_marker" in the spot where they where trying to insert the element.

We are currently running an Umbraco install with a few custom patches that have yet to be implemented in the most resent versions of the Umbraco core + we are running MySQL as our db. So it's not that simple just to upgrade to the next release without testing, even though some forum entries state that the bug might be fixed in the most recent release, however I can not a resolved item in Umbraco issue tracker:
issues with mce_marker
Issue: can't paste into tinymce with Safari
Issue: can't insert youtube video in Umbraco (not sure if it applies to all browsers)
And of course the frequent dead link to the old issue tracker.

None of the issues was marked as resolved, so of to open the source and see where the underlying bug was happening. The bug was actually happening in the Safari plugin code for tinymce, but unfortunatly I'm not working on a Mac, so it was a little difficult to debug exactly why it was happening, but have a look at the file your-umbraco-site.com/umbacro_client/tinymce3/plugins/safari/editor_plugin_src.js - Line #116-117
both these lines use the "mce_marker" text as a reference to where the html that needs inserting should be placed in the tinymce html. And this is the only place in the entire Umbraco source that there exists a text called "mce_marker".

So how to fix it ?
I firstly checked if the bug was any where to be found on the TinyMCE forums and issue trackers, and I found this bug in tinymce that is a almost identical description of my clients bug. Basicly it states that the bug did exist and that actually the tinymce safari plugin had been removed more than a year before the last entry, so sometime around 2010-09-09 (unfortunately I could not find the version number of tinymce where the plugin was removed). But...

Hmmm, did Umbraco really not upgrade tinymce since 2010 (2 years ago), I looked into the tinymce implementation in umbraco and found that the file : 
your-umbraco-site.com/umbacro_client/tinymce3/tiny_mce_src.js - Line #6-10
contains the date 2011-03-10, so it seems the tinymce was updated after the Safari plugin was removed, but still the Safari plugin was included and loading in Umbraco, but properly it was no longer needed.

So I tacked down the code where the plugin is loaded in the file: \components\editorControls\tinyMCE3\TinyMCE.cs - Line #99-103
The code looks like this:

// safari compatibility
if (HttpContext.Current.Request.Browser.Browser.ToLower().Contains("safari"))
        _plugins += ",safari";

So to sum up there are two possible solutions to this bug, both are tested on a install and seems to be working fine.
  1. Remove the contents of the files (dont delete them it will cause loading errors) and remember to do a backup of the files first.
    This solution does not require any modifications to the umbraco source code and hence rebuilding of the core modules, and can be used as a "in-place" fix.
  2. Uncomment line 99-103 in the file \components\editorControls\tinyMCE3\TinyMCE.cs and rebuild the umbraco.editorControls.dll, this will ensure that the plugin is not loaded.
    You can download a patch file here that can fix the changeset "
Hope it helps you :-) and as always just ping me if you need help with this

04 November, 2012

De-serialize to class with private or no empty constructor

When transferring DTO objects around in .NET sometimes you need to deserialize data to an object with no or private/internal empty constructors. What I have normally done is adding a public empty constructor to my own classes that just does nothing, but I always deemed it as an ugly hack, and have marked them all with TODO comments in the code...

Today I stumbled upon a this method in .NET FormatterServices.GetUninitializedObject that actually can instantiate a class without using any of the constructors in the class. The best part is that it works in all .NET versions, because we are targeting our DTO objects for .NET Framework 2.0 to ensure compatibility with all our clients.

I found these detailed guides about using the method: