Spoodoo.com

Convert Script-Editor-Webpart-Textarea to a real code editor with CodeMirror.js

This is a mobile optimized version of this page, view original page.

I use the Script Editor Webpart very often and what always bothers me is that there is no proper code formatting in the textarea. So after some messing around with the CodeMirror-editor (a text editor implemented in JavaScript), I came up with a piece of code which will convert the textarea of a Script Editor Webpart to a real code editor including syntax-highlighting, proper indenting, fullscreen-editing, search, etc..

Before:

After:

Getting this up and running is pretty easy, it just needs two files which you have to download and a piece of code in your masterpage.

First you should download the following two files:
1. codemirror-compressed.js (contains codemirror.js itself and several modes and addons, v5.8)
2. codemirror.css (stylesheet, combination of codemirror.css, dialog.css and fullscreen.css and some custom CSS)

codemirror-compressed.js comes bundled with the following modes and addons (which, for me, is a selection of the the most useful addons):

Add-onsModes
– active-line.js
– dialog.js
– fullscreen.js
– mark-selection.js
– match-highlighter.js
– matchbrackets.js
– matchtags.js
– search.js
– searchcursor.js
– xml-fold.js
– css.js
– htmlmixed.js
– javascript.js
– xml.js

If you want to create your own bundle you can go do that here: http://codemirror.net/doc/compress.html. But please note that this will require customizations to the provided code.

Once downloaded upload the two files to your SharePoint and add the following code before the closing body-tag in your masterpage:


<link rel="stylesheet" href="codemirror.css"/>
<script type="text/javascript">
jQuery(document).ready(function(){
	if (jQuery("#MSOLayout_InDesignMode").val() || jQuery("#_wikiPageMode").val()){
		var js = document.createElement("script");
		js.type = "text/javascript";
		js.src = "codemirror-compressed.js";
		document.getElementsByTagName('head')[0].appendChild(js);
		var myCodeMirror = null
		var listenerAtatched = false
		setInterval(function(){
			var textArea = jQuery("#embeddingText")
			if(textArea.length > 0 && typeof CodeMirror == "function"){
				if(textArea.is(":visible")){
					var mode	  = {
										name:        "htmlmixed",
										scriptTypes:[{matches: /\/x-handlebars-template|\/x-mustache/i,  mode: null},
													 {matches: /(text|application)\/(x-)?vb(a|script)/i, mode: "javascript"}]
									}
					var extraKeys = {
										"F11":    function(cm) {cm.setOption("fullScreen", !cm.getOption("fullScreen"));},
										"Esc":    function(cm) {if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);},
										"Ctrl-J": "toMatchingTag"
									}
						myCodeMirror = CodeMirror.fromTextArea(jQuery("#embeddingText")[0], {
						mode:                      mode,
						selectionPointer:          true,
						lineNumbers:               true,
						matchBrackets:             true,
						styleActiveLine:           true,
						extraKeys:                 extraKeys,
						highlightSelectionMatches: {showToken: /\w/},
						matchTags:                 {bothTags: true},
						tabSize:                   4,
						indentUnit:                4,
						indentWithTabs:            true,
						styleSelectedText:         true
					});
					jQuery(myCodeMirror.display.wrapper).css({"height":"100px","border":"1px solid lightgrey","min-height":"100px"})
					jQuery(myCodeMirror.display.wrapper).bind("input keyup paste",function(){
						var textArea = myCodeMirror.getTextArea()
						var evt = document.createEvent("HTMLEvents");
						evt.initEvent("keyup", false, true);
						textArea.dispatchEvent(evt);
						myCodeMirror.save()
					})
				} else {
					if(jQuery('.CodeMirror.CodeMirror-fullscreen').length == 0){
						jQuery(myCodeMirror.display.wrapper).css('height', 'calc(100% - 120px - ' + jQuery('.ms-rte-embeddialog-preview').css('height') + ')')
					}
				}
			}
		},1000)
	}
})
</script>

Adjust the paths in line 1 and line 7 and everything should be set up. In line 5-8 I implemented some ondemand-loading of codemirror-compressed.js since it is quite big (218KB). With this code it only is loaded when the page you are on is in edit-mode. The rest of the code checks periodically for the SEWP-textarea and once it is visible it converts it into a CodeMirror-textarea.

And here is a list of shortcuts that you can use:

General
ShortcutFunction
F11
ESC
CTRL-J
Enter fullscreen-mode
Leave fullscreen-mode
Jump between opening and closing html-tag
Search
ShortcutFunction
Ctrl-F
Ctrl-G
Shift-Ctrl-G
Shift-Ctrl-F
Shift-Ctrl-R
Alt-F
Start searching
Find next
Find previous
Replace
Replace all
Persistent search (dialog doesn’t autoclose, enter to find next, shift-enter to find previous)

And finally a little animation showing the fullscreen-function, matching and highlighting:

Please note that this solution requires jQuery!

Questions and comments below.