Im SharePoint habe ich den bisher immer vermisst. Das hat nun ein ende: Ich habe eine Sandbox-Solution erstellt, die die Dateien des Syntax Highlighter im SharePoint (auf SiteCollectioin-Ebene) bereitstellt und zusätzlich ein Feature (auf Web-Ebene) dass jede angezeigte Seite nach Syntax Highlighter-Formatierungen durchsucht und die entsprechenden Dateien dynamisch lädt.
Dafür habe ich das folgende js-File verwendet:
if (!!window.Type) {
//this is 'normal'
Type.registerNamespace('SpSyntaxHighlighter');
} else {
//this happend on i.e. EditBlog.aspx
window.SpSyntaxHighlighter = window.SpSyntaxHighlighter || {};
}
SpSyntaxHighlighter.shAutoConfig = [[ 'applescript' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushAppleScript.js'],
[ 'actionscript3', 'as3' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushAS3.js'],
[ 'bash', 'shell' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushBash.js'],
[ 'coldfusion','cf' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushColdFusion.js'],
[ 'cpp', 'c' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCpp.js'],
[ 'c#', 'c-sharp', 'csharp' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCSharp.js'],
[ 'css' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCss.js'],
[ 'delphi', 'pascal', 'pas' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushDelphi.js'],
[ 'diff', 'patch' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushDiff.js'],
[ 'erl', 'erlang' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushErlang.js'],
[ 'groovy' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushGroovy.js'],
[ 'java' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJava.js'],
[ 'jfx', 'javafx' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJavaFX.js'],
[ 'js', 'jscript', 'javascript' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJScript.js'],
[ 'perl', 'Perl', 'pl' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPerl.js'],
[ 'php' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPhp.js'],
[ 'text', 'plain' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPlain.js'],
[ 'powershell', 'ps' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPowerShell.js'],
[ 'py', 'python' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPython.js'],
[ 'ruby', 'rails', 'ror', 'rb' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushRuby.js'],
[ 'sass', 'scss' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushSass.js'],
[ 'scala' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushScala.js'],
[ 'sql' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushSql.js'],
[ 'vb', 'vbnet' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushVb.js'],
[ 'xml', 'xhtml', 'xslt', 'html' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushXml.js']];
SpSyntaxHighlighter.canApplySyntaxHighlighter = function () {
/// Check, if SyntaxHighlighter should be applied. I.e. returns false, if something is in edit mode..
/// fals, if loading of SyntaxHighlighter should be disabled
var rteFields = document.getElementsByClassName('ms-rtefield');
// check if page is in edit-mode or edit-form or something..
// do not (!) modify source in an editor - because that will lead to the modification being saved...
if (rteFields.length > 0) {
SP.UI.Notify.addNotification('Edit-Mode detected. SyntaxHighlighter disabled.', false);
return false;
}
return true;
};
SpSyntaxHighlighter.addEvent = function (elm, evt, func) {
if (elm.addEventListener) {
elm.addEventListener(evt, func);
} else if (elm.attachEvent) {
elm.attachEvent('on' + evt, func);
} else {
elm['on' + evt] = func;
}
};
SpSyntaxHighlighter.removeEvent = function (elm, evt, func) {
if (elm.removeEventListener) {
elm.removeEventListener(evt, func);
} else if (elm.detachEvent) {
elm.detachEvent('on' + evt, func);
} else {
elm['on' + evt] = null;
}
};
SpSyntaxHighlighter.loadScript = function (url, successHandler, errorHandler) {
var script = document.createElement('script'),
loaded, error;
script.src = url;
script.type = 'text/javascript';
script.language = 'javascript';
loaded = function () {
SpSyntaxHighlighter.removeEvent(script, 'load', loaded);
SpSyntaxHighlighter.removeEvent(script, 'error', error);
if (successHandler) {
successHandler(script);
}
};
error = function () {
SpSyntaxHighlighter.removeEvent(script, 'load', loaded);
SpSyntaxHighlighter.removeEvent(script, 'error', error);
if (errorHandler) {
errorHandler();
}
};
SpSyntaxHighlighter.addEvent(script, 'load', loaded);
SpSyntaxHighlighter.addEvent(script, 'error', error);
document.body.appendChild(script);
};
SpSyntaxHighlighter.loadCss = function (url) {
var link = document.createElement('link');
link.href = url;
link.type = 'text/css';
link.rel = 'stylesheet';
document.head.appendChild(link);
};
SpSyntaxHighlighter.loadBrushes = function(success) {
// replaces shAutoloader.js - I dont like the way it works...
var oldHighlight = SyntaxHighlighter.highlight,
highlightCalled = false,
elements = SyntaxHighlighter.findElements(),
processes = [{
id: 'loadBrushes',
done: false
}],
chechAllDone = function () {
var done = true,
i;
for (i = 0; i < processes.length; i += 1) {
if (!(processes[i].done)) {
done = false;
break;
}
}
if(done){
// everything is done. finish here...
SyntaxHighlighter.highlight = oldHighlight;
if(highlightCalled !== false) {
SyntaxHighlighter.highlight.call(SyntaxHighlighter, highlightCalled);
}
if (!!success) {
success();
}
}
},
buildBrushes = function(){
var cfg = SpSyntaxHighlighter.shAutoConfig,
brushes = {},
cfgLine,
url,
i,j;
for(i=0; i< cfg.length; i+=1) {
cfgLine = cfg[i];
url = cfgLine[cfgLine.length-1];
for(j=(cfgLine.length-2); j >= 0; j -=1) {
brushes[cfgLine[j]] = url;
}
}
return brushes;
},
brushes = buildBrushes(),
processing = function(id) {
var i;
for(i=0; i < processes.length; i+=1) {
if(id === processes[i].id) {
return processes[i];
}
}
return false;
},
i,
alias,
url;
SyntaxHighlighter.highlight = function (parm) {
// dont call highlight while Im searching
highlightCalled = parm;
};
// now process the elements..
for(i=0; i < elements.length; i+=1) {
alias = elements[i].params.brush;
url = brushes[alias];
if(!url) {
if(console && console.log){
console.log('no brush defined for alias: '+ alias);
}
continue;
}
if(!!processing(url)){
continue;
}
processes.push({
id: url,
done: false
});
if (!!window.SyntaxHighlighter.vars.discoveredBrushes) {
if (!!window.SyntaxHighlighter.vars.discoveredBrushes[alias]) {
// this brush was already loaded & discovered by SyntaxHighlighter. Theres nothing more to do...
processing(url).done = true;
continue;
}
}
(function() {
var urlClosure = url;
SpSyntaxHighlighter.loadScript(urlClosure, function () {
processing(urlClosure).done = true;
chechAllDone();
});
})();
}
// finished..
processing('loadBrushes').done = true;
chechAllDone();
};
SpSyntaxHighlighter.runSyntaxHighlighter = function () {
///
/// Re-Run SyntaxHighlighter, make sure SyntaxHighlighter was loaded before calling.
/// i.e. call loadSyntaxHighlighter first.
/// this functions does nothing, if an RichTextEditor is opened in the page!
///
if (!SpSyntaxHighlighter.canApplySyntaxHighlighter()) return;
SpSyntaxHighlighter.loadBrushes(function () {
SyntaxHighlighter.vars.discoveredBrushes = null; // let SyntaxHighlighter re-run brush-discovery
window.setTimeout(SyntaxHighlighter.highlight.bind(SyntaxHighlighter), 50);
});
};
SpSyntaxHighlighter.loadSyntaxHighlighter = function () {
var csspath = '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/styles/',
scriptpath = '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/',
shTheme = 'shThemeDefault.css', //Possible Themes: shThemeDefault.css, shThemeDjango.css, shThemeEclipse.css, shThemeEmacs.css, shThemeFadeToGrey.css, shThemeMDUltra.css, shThemeMidnight.css, shThemeRDark.css
loadSyntaxHighlighter = function () {
// add SyntaxHighlighter, styles and autoloader, then run autoloader
SpSyntaxHighlighter.loadCss(csspath + 'shCore.css');
SpSyntaxHighlighter.loadCss(csspath + shTheme);
SpSyntaxHighlighter.loadScript(scriptpath + 'shCore.js', function () {
SpSyntaxHighlighter.SyntaxHighlighter = window.SyntaxHighlighter;
SpSyntaxHighlighter.runSyntaxHighlighter();
});
},
siteLoadFialed = function (err) {
if (console && console.log) {
console.log('accessing siteCollecion failed. ');
console.log('err was: ' + err);
console.log('execution aborted. :-(');
}
// this is the end of it. sadly.
},
siteLoadSucceded = function () {
var siteCollectionUrl = siteCollection.get_url(),
i, len, brushCfg, brushPath;
// fix up paths...
csspath = csspath.replace('~siteCollection', siteCollectionUrl);
scriptpath = scriptpath.replace('~siteCollection', siteCollectionUrl);
len = SpSyntaxHighlighter.shAutoConfig.length;
for (i = 0; i < len; i += 1) {
brushCfg = SpSyntaxHighlighter.shAutoConfig[i];
brushPath = brushCfg[brushCfg.length - 1];
brushCfg[brushCfg.length - 1] = brushPath.replace('~siteCollection', siteCollectionUrl);
}
// now start loading SyntaxHighlighter
loadSyntaxHighlighter();
},
siteCollection,
clientContext = SP.ClientContext.get_current(),
highlightable = document.getElementsByTagName('pre');
// check if syntaxHighlighter ist needed
if (highlightable.length < 1) return;
if (!SpSyntaxHighlighter.canApplySyntaxHighlighter()) return;
// load siteCollectionData then continue
siteCollection = clientContext.get_site();
clientContext.load(siteCollection);
clientContext.executeQueryAsync(siteLoadSucceded, siteLoadFialed);
};
SpSyntaxHighlighter.preLoadSyntaxHighlighter = function () {
if (!!SpSyntaxHighlighter.SyntaxHighlighter) {
//weve been here before :-)
window.SyntaxHighlighter = SpSyntaxHighlighter.SyntaxHighlighter;
SpSyntaxHighlighter.runSyntaxHighlighter();
return;
}
// load all from scratch...
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', SpSyntaxHighlighter.loadSyntaxHighlighter);
};
SpSyntaxHighlighter.register = function () {
var thisUrl;
SpSyntaxHighlighter.preLoadSyntaxHighlighter();
if (!!window._spPageContextInfo) {
thisUrl = '~siteCollection/SiteAssets/SpSyntaxHighlighter/ShLoader.js'.replace('~siteCollection/', window._spPageContextInfo.siteServerRelativeUrl);
window.RegisterModuleInit(thisUrl, SpSyntaxHighlighter.preLoadSyntaxHighlighter);
}
};
//Simulate LoadAfterUi=true
window._spBodyOnLoadFunctionNames.push('SpSyntaxHighlighter.register');
Teile des Skriptes (z.B. die Verfügbaren "brushes") lasse ich dabei auto-generieren mittels eines T4-Templates.
Die Sourcen für das ganze habe ich auf bitbucket.