diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js
new file mode 100644
index 00000000..8dafc823
--- /dev/null
+++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js
@@ -0,0 +1,117 @@
+(function() {
+ tinymce.PluginManager.requireLangPack("../../tinymce_ssbuttons");
+ var each = tinymce.each;
+
+ tinymce.create('tinymce.plugins.SSButtons', {
+ /**
+ * Returns information about the plugin as a name/value array.
+ * The current keys are longname, author, authorurl, infourl and version.
+ *
+ * @returns Name/value array containing information about the plugin.
+ * @type Array
+ */
+ getInfo : function() {
+ return {
+ longname : 'Special buttons for SilverStripe CMS',
+ author : 'Sam Minnée',
+ authorurl : 'http://www.siverstripe.com/',
+ infourl : 'http://www.silverstripe.com/',
+ version : "1.0"
+ };
+ },
+
+
+ init : function(ed, url) {
+ /**
+ * These map the action buttons to the IDs of the forms that they open/close
+ */
+ forms = {
+ 'sslink' : 'Form_EditorToolbarLinkForm',
+ 'ssimage' : 'Form_EditorToolbarImageForm',
+ 'ssflash' : 'Form_EditorToolbarFlashForm'
+ };
+
+ ed.addButton('sslink', {title : ed.getLang('tinymce_ssbuttons.insertlink'), cmd : 'sslink', 'class' : 'mce_link'});
+ ed.addButton('ssimage', {title : ed.getLang('tinymce_ssbuttons.insertimage'), cmd : 'ssimage', 'class' : 'mce_image'});
+ ed.addButton('ssflash', {title : ed.getLang('tinymce_ssbuttons.insertflash'), cmd : 'ssflash', 'class' : 'mce_flash', 'image': url + '/img/flash.gif'});
+
+ /**
+ * Show a side panel, hiding others
+ * If showCommand isn't set, then this will simply hide panels
+ */
+ function showSidePanel(showCommand, hideCommands) {
+ hideCommands.each(function(command) {
+ ed.controlManager.setActive(command,false);
+ Element.hide(forms[command]);
+ });
+
+ var showForm = null;
+ if(forms[showCommand]) {
+ showForm = $(forms[showCommand]);
+ showForm.toggle(ed);
+ }
+
+ if(!showForm || showForm.style.display == "none") {
+ ed.controlManager.setActive(showCommand, false);
+ // Can't use $('contentPanel'), as its in a different window
+ window.parent.document.getElementById('contentPanel').style.display = "none";
+ // toggle layout panel
+ jQuery('body.CMSMain').concrete('ss').MainLayout().close('east');
+ } else {
+ ed.controlManager.setActive(showCommand, true);
+ window.parent.document.getElementById('contentPanel').style.display = "block";
+ // toggle layout panel
+ jQuery('body.CMSMain').concrete('ss').MainLayout().resizeAll();
+ jQuery('body.CMSMain').concrete('ss').MainLayout().open('east');
+ }
+ }
+
+ ed.addCommand("ssclosesidepanel", function(ed) {
+ showSidePanel('', [ 'sslink', 'ssimage', 'ssflash' ]);
+ });
+
+ ed.addCommand("sslink", function(ed) {
+ showSidePanel('sslink', [ 'ssimage', 'ssflash' ]);
+ });
+
+ ed.addCommand("ssimage", function(ed) {
+ showSidePanel('ssimage', [ 'sslink', 'ssflash' ]);
+ });
+
+ ed.addCommand("ssflash", function(ed) {
+ showSidePanel('ssflash', [ 'ssimage', 'sslink' ]);
+ });
+
+ ed.onNodeChange.add(function(ed, o) {
+ //$('Form_EditorToolbarLinkForm').updateSelection(ed);
+ //$('Form_EditorToolbarLinkForm').respondToNodeChange(ed);
+ });
+ ed.onKeyUp.add(function(ed, o) {
+ //$('Form_EditorToolbarLinkForm').updateSelection(ed);
+ });
+
+ // resize image containers when the image is resized.
+ if(!tinymce.isOpera && !tinymce.isWebKit) ed.onMouseUp.add(function(ed, o) {
+ var node = ed.selection.getNode();
+ if(node.nodeName == 'IMG' && ed.dom.getParent(node, 'div')) {
+ // we have to delay the resize check here, as this event handler is called before the actual image
+ // resizing is done.
+ setTimeout(function() {
+ var ed = tinyMCE.activeEditor, // we need to redeclare these for IE.
+ node = ed.selection.getNode(),
+ container = ed.dom.getParent(node, 'div');
+
+ if(node.width && node.width != parseInt(ed.dom.getStyle(container, 'width'))) {
+ ed.dom.setStyle(container, 'width', parseInt(node.width));
+ ed.execCommand('mceRepaint');
+ }
+ }, 1);
+ }
+ });
+ }
+ });
+
+
+ // Adds the plugin class to the list of available TinyMCE plugins
+ tinymce.PluginManager.add("../../tinymce_ssbuttons", tinymce.plugins.SSButtons);
+})();
\ No newline at end of file
diff --git a/javascript/tinymce_ssbuttons/img/flash.gif b/javascript/tinymce_ssbuttons/img/flash.gif
new file mode 100644
index 00000000..cb192e6c
Binary files /dev/null and b/javascript/tinymce_ssbuttons/img/flash.gif differ
diff --git a/javascript/tinymce_ssbuttons/langs/de.js b/javascript/tinymce_ssbuttons/langs/de.js
new file mode 100644
index 00000000..0948d6ff
--- /dev/null
+++ b/javascript/tinymce_ssbuttons/langs/de.js
@@ -0,0 +1,5 @@
+tinyMCE.addI18n('de.tinymce_ssbuttons',{
+insertlink: 'Link einfügen',
+insertimage: 'Bild einfügen',
+insertflash: 'Flash Objekt einfügen'
+});
\ No newline at end of file
diff --git a/javascript/tinymce_ssbuttons/langs/en.js b/javascript/tinymce_ssbuttons/langs/en.js
new file mode 100644
index 00000000..91ed8fb0
--- /dev/null
+++ b/javascript/tinymce_ssbuttons/langs/en.js
@@ -0,0 +1,5 @@
+tinyMCE.addI18n('en.tinymce_ssbuttons', {
+insertlink: 'Insert Link',
+insertimage: 'Insert Image',
+insertflash: 'Insert Flash Object'
+});
\ No newline at end of file
diff --git a/javascript/tinymce_ssmacron/editor_plugin_src.js b/javascript/tinymce_ssmacron/editor_plugin_src.js
new file mode 100644
index 00000000..2faef38c
--- /dev/null
+++ b/javascript/tinymce_ssmacron/editor_plugin_src.js
@@ -0,0 +1,40 @@
+(function() {
+ var each = tinymce.each;
+
+ tinymce.create('tinymce.plugins.InsertMacron', {
+ getInfo : function() {
+ return {
+ longname : 'Button to insert macrons',
+ author : 'Hamish Friedlander. Heavily based on charmap that comes with TinyMCE',
+ authorurl : 'http://www.siverstripe.com/',
+ infourl : 'http://www.silverstripe.com/',
+ version : "1.0"
+ };
+ },
+
+
+ init : function(ed, url) {
+ // Register commands
+ ed.addCommand('mceInsertMacron', function() {
+ ed.windowManager.open({
+ file : url + '/macron.htm',
+ width : 350 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)),
+ height : 150 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)),
+ inline : true
+ }, {
+ plugin_url : url
+ });
+ });
+
+ // Register buttons
+ ed.addButton('ssmacron', {
+ title : 'Insert a Macron',
+ cmd : 'mceInsertMacron',
+ image : url + '/img/macron.png'
+ });
+ }
+ });
+
+ // Adds the plugin class to the list of available TinyMCE plugins
+ tinymce.PluginManager.add("../../tinymce_ssmacron", tinymce.plugins.InsertMacron);
+})();
diff --git a/javascript/tinymce_ssmacron/img/macron.png b/javascript/tinymce_ssmacron/img/macron.png
new file mode 100644
index 00000000..80caf6da
Binary files /dev/null and b/javascript/tinymce_ssmacron/img/macron.png differ
diff --git a/javascript/tinymce_ssmacron/js/macron.js b/javascript/tinymce_ssmacron/js/macron.js
new file mode 100644
index 00000000..d404520d
--- /dev/null
+++ b/javascript/tinymce_ssmacron/js/macron.js
@@ -0,0 +1,71 @@
+tinyMCEPopup.requireLangPack();
+
+var charmap = [
+ ['Ā', 'Ā', true, 'A - macron'],
+ ['Ē', 'Ē', true, 'E - macron'],
+ ['Ī', 'Ī', true, 'I - macron'],
+ ['Ō', 'Ō', true, 'O - macron'],
+ ['Ū', 'Ū', true, 'U - macron'],
+ ['ā', 'ā', true, 'a - macron'],
+ ['ē', 'ē', true, 'e - macron'],
+ ['ī', 'ī', true, 'i - macron'],
+ ['ō', 'ō', true, 'o - macron'],
+ ['ū', 'ū', true, 'u - macron']
+];
+
+tinyMCEPopup.onInit.add(function() {
+ tinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML());
+});
+
+function renderCharMapHTML() {
+ var charsPerRow = 5, tdWidth=20, tdHeight=20, i;
+ var html = '
';
+ var cols=-1;
+
+ for (i=0; i'
+ + ''
+ + charmap[i][1]
+ + '';
+ if ((cols+1) % charsPerRow == 0)
+ html += '
';
+ }
+ }
+
+ if (cols % charsPerRow > 0) {
+ var padd = charsPerRow - (cols % charsPerRow);
+ for (var i=0; i ';
+ }
+
+ html += '
';
+
+ return html;
+}
+
+function insertChar(chr) {
+ tinyMCEPopup.execCommand('mceInsertContent', false, '' + chr + ';');
+
+ // Refocus in window
+ if (tinyMCEPopup.isWindow)
+ window.focus();
+
+ tinyMCEPopup.editor.focus();
+ tinyMCEPopup.close();
+}
+
+function previewChar(codeA, codeB, codeN) {
+ var elmV = document.getElementById('codeV');
+ var elmN = document.getElementById('codeN');
+
+ if (codeA=='#160;') {
+ elmV.innerHTML = '__';
+ } else {
+ elmV.innerHTML = '&' + codeA;
+ }
+
+ elmN.innerHTML = codeN;
+}
diff --git a/javascript/tinymce_ssmacron/macron.htm b/javascript/tinymce_ssmacron/macron.htm
new file mode 100644
index 00000000..1fc769e5
--- /dev/null
+++ b/javascript/tinymce_ssmacron/macron.htm
@@ -0,0 +1,31 @@
+
+
+
+ Insert a Macron
+
+
+
+
+
+
+ Insert a Macron |
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+