Monkey Patching and SharePoint / Office 365

This post is a prelude for the one to follow in which I will show an application of this technique that overrides the workspace sizing routine in SharePoint 2010.

JavaScript is a wonderful language. It is easily accessible to anyone who understands C style syntax. This includes C# developers. However JavaScript is a dynamic language. In my experience most C# developers write poor JavaScript in a style that is appropriate to C#. However, getting the most out of SharePoint requires a good understanding of JavaScript and I am not talking about using jQuery or the Client Object Model. I am talking about fundamentals!

This is especially important if you are working in a sandbox environment like Office 365. It is very difficult (and often impossible) to fully achieve your UI goals given the restrictions of the sandbox architecture on the server side. However, with a good command of client side technologies, especially JavaScript, you can overcome many of these limitations.

The problem is that most of the really interesting components in SharePoint’s JavaScript libraries are undocumented. Furthermore, the chances are good that if you make heavy use of what I am about to show you, you will be disappointed when you have to fix your work when the next version of SharePoint drops and these undocumented libraries change. So, consider that fair warning – this is a powerful technique, but one with serious risks over time!

As Wikipedia tells us: ‘A monkey patch is a way to extend or modify the run-time code of dynamic languages without altering the original source code. This process has also been described as "duck punching".’

In JavaScript a function is a type and you can do things to functions that C# just doesn’t allow. You can assign them to variables, pass them as arguments, and even change their values.

For example (see it here on jsFiddle):

function sayHi() {
alert('Hi!');
}


function doFunction(func) {
func();
}


doFunction(sayHi);

 

 

This may be one of the longest Hello World style examples you can write! In it the function sayHi is invoked via the doFunction function by passing sayHi as an argument.

Now, imagine that sayHi is actually part of one of SharePoint 2010’s JavaScript libraries and you don’t like how it works. In a farm deployment scenario you could (but never, ever should) just open the file in the SharePoint root and change it. This is not an option in sandbox mode because you have no access to the actual script file. This is where monkey patching comes in.

Consider this example (see it here on jsFiddle):

function sayHi() {
alert('Hi!');
}


function doFunction(func) {
func();
}


var oldSayHi = sayHi;
sayHi = function() {
alert('What is the opposite of bye?');
oldSayHi();
}


doFunction(sayHi);

 

In this version the code copies the pointer to the original sayHi function into a new variable and then changes the value of the variable sayHi to a new function that shows a different alert before calling the original version and you get two alerts. This, in a nutshell, is what monkey patching is all about. With it you can replace an existing function completely or do custom pre/post processing as shown in the example above.

To get a feel for what you might do with this technique, add the following script via a Content Editor Web Part to the home page of a stock team site and then add a new Shared Document by clicking the link.

if (typeof NewItem2 != 'undefined') {
    var oNI2 NewItem2;
    NewItem2 this.NewItem2;
}


NewItem2 function(eventurl) {
    alert('NewItem2 called');
    oNI2(eventurl);
};

 

You should see something similar to the following.

For those of you who inherit nightmares because of misuse of this technique; I’m sorry!

Happy coding!
–Doug

Author: Doug Ware