Apr 30

This post is the part II of Enhance SharePoint rich text field. I want to share some of the pitfalls we encounter when working with a RichTextField in compatible mode.
When saving your content, SharePoint clean (a bit?) your html and may erase some parts of it because it allows only a restrictive list of HTML tags.
We choose the compatible mode for that reason: cleaning the garbage such as IMG, TABLE, DIV, SCRIPT, OBJECT … and some attributes.

But TinyMCE manages the Html differently. For example, we will set the word over in underline:

TinyMCE generates:

The quick brown fox jumps <span style="text-decoration:underline;">over</span> the lazy dog

HTML accepted by SharePoint:

The quick brown fox jumps <u>over</u> the lazy dog

 

The same problem occurs with colored text, background color, relative URL, and URL that do not start with http(s):// (www.google.be is refused but not http://www.google.be).

Look like we should need to perform some cleanup before the postback.

 

When to clean?

There is no way to change the field's value by C#. The cleaning code process is a black box and you don't have access to override that behavior. So let's look at client side.
In the generated HTML source of a <SharePoint:SaveButton>, we have:

<input type="button" name="…$diidIOSaveItem" value="OK" onclick="if (!PreSaveItem()) return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(…)" id="… " accesskey="O" class="ms-ButtonHeightWidth" target="_self" />

<input type="button" name="…$diidIOSaveItem" value="OK" onclick="if (!PreSaveItem()) return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(…)" id="… " accesskey="O" class="ms-ButtonHeightWidth" target="_self" />

 

And PreSaveItem definition is (in FORM.JS):

function PreSaveItem()
{
  if
("function"==typeof(PreSaveAction))
  {
    return PreSaveAction();
  }
  return
true;
}

 

Nice! We can declare a function named PreSaveAction and it will be called before the PostBack. We can do some client-side validation too and cancels the postback if we want. But that's out of scope, we only want to alter the textarea's value.
Warning: pay attention you don't already declare PreSaveAction in your code!

Using TinyMCE's API, we fetch the registered editors and test a flag I declared in the MOSSBASIC config array.

var MOSSBASIC = {
   …
     sp_compatible: true
}

function
PreSaveAction() {
   var
c, ed, eds = tinyMCE.editors;
   for
(var ctrl in eds){
     ed = tinyMCE.get(ctrl);
     if
(ed.settings.sp_compatible === undefined) continue;
     c = cleanRTF(ed.getContent());

     byid(ctrl + "_spSave").value = c; <-
this is the hidden field containing the saved stream used by SP

   }
}

 

How to clean

The clean process consists in some regex stuff. Nothing really interesting here…

function cleanRTF(html) {
    if (html.length > 0) {
      // reformat some tag
     
html = html.replace(new RegExp("<span\\sstyle=\"text-decoration:\\sunderline;\">(.+)</span>", "i"), '<u>$1</u>');
      html = html.replace(new RegExp("<span\\sstyle=\"color:\\s(.+);\">(.+)</span>", "i"), '<font color=\"$1\">$2</font>');
      html = html.replace(new RegExp("<span\\sstyle=\"background-color:\\s(.+)\">(.+)</span>", "i"), '<font style=\"background-color:$1\">$2</font>');
      // clean dirty tag added by tinymce and refused by SP
      html = html.replace(/dirty_moz="(?:.+?)(?:")/g, '');
      html = html.replace(/(?:mce_href|mce_src)="(?:.+?)(?:")/g, '');
      // SP accepts only absolute url. We add http:// prefix to all relative urls
      html = html.replace(/href="([^"]+)"/g, 'href="http://$1"');
     
html = html.replace(/http:\/\/http:\/\//g, "http://");
  }
  return
html;
}

 

Relative Links

This feature is provided by TinyMCE. When inserting a new link, if you insert "Agro/Document Library/readme.doc", TinyMCE will try to convert it to a relative path that can result in "../Document Library/readme.doc". That links will be replaced by a blank link by SharePoint.

You can disable that TinyMCE's option with relative_urls: false.

Office Garbage

As a side note, I want to talk about the Word 2007 font style garbage that occurs when pasting text from MS Word… a plugin exists but is still under construction by the Moxie team. Check it at: http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste

 

Download updated version of sptinymce.js:  sptinymce.js (3.47 kb)

Tags:

Comments

Olivier

Posted on Thursday, 30 April 2009 05:04

I have updated the attachment of my previous post. You can download the entire package there.

seo

Posted on Friday, 31 July 2009 03:21

Excellent post.This was actually what I was looking for, and I am glad that I finally came here! This for sharing and keep up the good work...

Facelift Pennsylvania

Posted on Thursday, 20 August 2009 17:54

Thanks for the info. I just used it on my project. Very good post!

Kevin

Posted on Friday, 26 February 2010 12:37

Reading good posts of other bloggers enable me to reduce my boredom as I am able to learn some other people's experience.  Thanks for posting this.

Comments are closed