
Edit this page
(last edited May 22, 2010)
Open Wiki | Sand Box | Create Page | User Preferences | Recent Changes | Title Index | Random Page | Find Page | Help
» Help On Formatting
» Scripting News
» Sand Box
» All The News/Aggregation
» Wiki Editor
See now the Open Wiki NG tracker item for this where all the real Open Wiki developement is taking place
WikiEditor
Paul Robertson 27 March 2004
WikiEditor
Why?
Use this in your Wiki
How implemented
Something borrowed
Work required
What has been done so far
The code
Integrating the Code with OpenWiki
Integration with OpenWiki
Put editor at top and bottom of textarea
Setting width of menu to match textarea width set through preferences.
Make the WikiEditor an option through preferences
Add save, preview and cancel options to the menu.
Additional Features
Bug fix
Spell check
Find in page and Find / Replace
Initializing at the end of the textarea
Populating drop down menu?s from OpenWiki
Adding useful menu items to a 'right click' menu
Perhaps adding keyboard accelerators for some of the functions.
Adding an 'emotions' pop up with emotions available in OpenWiki
Adding support for the rest of the OpenWiki mark up codes, i.e. numbered lists etc.
Making it easier to link to other Wiki pages.
Put in context help
Fit & Finish
Tidy up presentation, see RichText editor for an example of how the editor could look
Rationalise the use of buttons
Mozilla Compatibility
Comments
WikiEditor
Why?
Open Wiki is designed to be the ultimate yellow sticky note (Post it) (see Open Wiki intro) and it is one of the better Wiki implementations around. Adding content needs to be easy and the use of plain text is certainly a good start. However, Open Wiki markup is slightly cryptic. A simple editor that lets you paste in the necessary markup code would help. I have started work on one; see here for the prototype. This editor is not designed for HTML style markup as used in Edit WYSIWYG Wiki's.
Unfortunately I am a lame programmer and xsl confuses the heck out of me. My attempt to get the code I have written integrated with Open Wiki has failed so far but I don’t believe that there is too much wrong. I invite other users of Open Wiki to pick up the cudgels and get this code working (or suggest a suitable alternative)
The code is attached to this page.
Adopted the "eating my own dogfood" approach, this entry was written using Wiki Editor.
I am disappointed that no one has jumped in to show me
what needs to be done to get this code running properly!
The ANSWERS have arrived!!! ;) ( Thanks for the great start )
Paul Robertson 29 January 2004
Use this in your Wiki
Download Source from http://www.kiddo.co.nz/wiki/wikieditor.html
Source Zip contains: editor.css and htmledit_test.html (and toolber GIFs)
- Put the editor.css file with the other css files at <yourwikidir>\ow\css
- Add a reference to the editor.css file in mystyle.xsl
<link rel="stylesheet" type="text/css" href="ow/css/editor.css" />
- Start a subdirectory for the Wiki Editor icons in <yourwikidir>\ow\images\editicons
- Put the icons in the directory.
- Modify the following template in ow.xsl:
<xsl:template match="/ow:wiki" mode="edit">
- Cut and paste functions from htmledit_test.html into the script
- Cut and paste the <div id="toolbar"> contents from htmledit_test.html above the <textarea id="text" name="text"... tag
- Update img src links in the toolbar div to point to your toolbar graphics
Thanks Paul and all, works great! -- Oddible 04Jun05
How implemented
Something borrowed
I drew on code from all over, but mainly the O?Reilly Network article by Meg Houriham at http://www.oreillynet.com/pub/a/javascript/2001/12/21/js_toolbar.html
I followed her lead and used JavaScript? strings to put together the Wiki markup tags required.
The more sophisticated Rich Text Editor at http://richtext.sourceforge.net/ has much useful code not used yet.
I Googled for any code I couldn?t work out myself but found the Webmonkey tutorial ? Thau?s Javascript Tutorial on forms very helpful.
This article was also very useful: The Select Element
The idea to use the SELECTED attribute of an OPTION element to show what is the default choice is taken from http://www.faqts.com/knowledge_base/view.phtml/aid/6025
Work required
What has been done so far
See here for a page with the code as it is running. http://www.kiddo.co.nz/wiki/wikieditor.html
The code
The following extracts are based on the current version of the code, kudos to Michael Meyers and Ola and others
The buttons are a series of images with the mouseover() etc events controlling the CSS changes and the onclick() event the formatting actions.
<form name="f">
<div id="toolbar">
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="insert_code('<BR>');"
src="code.gif"
width="20" height="21"
align="middle"
alt="Line break">
</img>
The insert_code() function is one of a handful that insert the Open Wiki markup.
// function insert_code(v)
// Inserts wiki code at selected point
function insert_code(v) {
var str = document.selection.createRange().text;
document.f.text.focus();
var sel = document.selection.createRange();
//sel.text = v + " ";
sel.text = unescape(v);
return;
}
Since first writing the above I have taken note of the helpful comments of others and updated the code. Two examples follow;
// function format_sel(s,e)
// Inserts Wiki markup around selected text
function format_sel(s,e) {
var str = document.selection.createRange().text;
//added to remove white space at start or end
reg=/^ *(\S.*\S) *$/;
str=str.replace(reg,"$1");
document.f.text.focus();
var sel = document.selection.createRange();
//sel.text = s + str + e ;
sel.text = unescape(s) + str + unescape(e) ;
return;
}
I have added some regex stuff to take out leading and trailing spaces. This was necessary as when you 'double click' some text to select it, IE has a habit of selecting a white space or two outside the selection.
//
// from various places, funtion to turn selected text into leading capitals.
//
function capitalise() {
var str = document.selection.createRange().text;
document.f.text.focus();
var sel = document.selection.createRange();
str=str.toLowerCase();
str=str.replace(/\b\w+\b/g, function(word) {
return word.substring(0,1).toUpperCase()+ word.substring(1);
});
sel.text=str
return;
}
The above function is to help with a particular problem we have, turning all caps text into leading caps.
The function would be even more useful if it 'cycled' through leading caps, all caps, all lower case like Word does...
Other changes made since the first iteration of the code include:
- Changed the line break and new line code to put a new line into the textarea, ie
onclick="insert_code('\n----\n');"
Integrating the Code with OpenWiki
I tried have now successfully integrated it with Open Wiki by:
- Putting the editor.css file with the other css files at C:\OpenWiki\owbase\ow\css
- Adding a reference to the editor.css file in mystyle.xsl
- Starting a subdirectory for the Wiki Editor icons in C:\OpenWiki\owbase\ow\images\editicons
- Putting the icons in the directory.
Putting the resulting html including the JavaScript?(in a <script> element)
through the HTML Tidy page
with xml as the desired output.
Pasting the html code in ow.xsl just before the textarea in the
editing section of the code, and the JavaScript? at the end of the code section
(changed path names to point to image files as necessary).
- Modified code to make it xsl friendly.
This isnnt working and I need thanks for the help.
Once integrated I have some other features I want to implement as below.
Anyway, suggestions please?
This is a great start. I was able to get it all working fairly easily. (Using the code from http://www.kiddo.co.nz/wiki/wikieditor.html and not the files attached) The .xsl cannot have any nested < or >. In order to get the code you listed above to work chage it as follows:
<form name="f">
<div id="toolbar">
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="insert_code(' %3CBR%3E ');"
src="code.gif"
width="20" height="21"
align="middle"
alt="Line break">
Use this tecnique throughout your code.
-
- %3C = < when unescape'ed
-
- %3E = > when unescape'ed
function insert_code(v) {
var str = document.selection.createRange().text;
document.f.text.focus();
var sel = document.selection.createRange();
sel.text = unescape(v) + " ";
return;
}
Also:
- Change if (what.selectedIndex > 1); to if (what.selectedIndex != 1); every where in the .js file.
- the image tags MUST have a closing... add </img> after each.
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="format_sel('^^','^^');"
src="UI_superscript.gif"
align="middle"
alt="click to make text superscripted"></img>
- Change the select options as well:
<select class="select" name="macros" style="width:300px;" align="middle" onChange="dd_insertcode(this);">
<OPTGROUP LABEL="macros" >
<option value="" selected>Macro's</options>
</OPTGROUP>
<OPTGROUP LABEL="Search macros">
<option value="%3CFullSearch /%3E">Full text search</option>
<option value="%3CFullSearch(",")%3E">Full text search - parameters</option>
<option value="%3CGlossary(,)%3E">Glossary</option>
<option value="%3CTextSearch(,)%3E">Text in pages search</option>
<option value="%3CTitleIndex /%3E">Index of pages in Wiki</option>
<option value="%3CTitleSearch /%3E">Title search </option>
<option value="%3CTitleSearch(",")%3E">Title search - parameters</option>
</OPTGROUP>
.
.
.
- use %3C and %3E for javascript strings containing "< and >"
- use closing tags for <option> </option>
- use closing tags for <OPTGROUP > </OPTGROUP>
- change dd_insertcode() to unescape what.value before using it.
I think that is all of it. The placement of the code in the .xsl files is as you suggested. I removed the spell checking code. It will not work if your security settings are set too tight. (They are for our Wiki, and I've allready tryed to get spell checking working ) Also, I have played with the ActiveXObject?("Word.Application") and spell checking before and discovered that it tends to leave multiple copies of word running in the background ( check your running programs after a few spell checks).
- Michael Meyers
I added some new functionality for Indent, Unindent, bullet, and numbered list... Just add in the appropriate places.
Additional functionality for script.js
function indent_line( s){
var new_s="";
if ( s.match(/^\s+$/) ) return s;
if ( s.match(/^\s*:|^\s*\*\s|^\s*[0-9]+\.|^\s*[a-z]+\.|^\s*;/) ){
new_s = " " + s;
}else{
new_s = " : " + s;
}
return new_s;
}
function dd_indent()
{
var str = document.selection.createRange().text;
var sel = document.selection.createRange();
if ( !str.length ) return;
if ( str.indexOf( "\n" ) == -1 ){
sel.text = indent_line( str ) + "\n";
return;
}
var new_str = "";
str += "\n";
pos = str.indexOf( "\n" );
do {
line = str.substring( 0, pos );
new_str += indent_line( line );
str = str.substring( pos+1 , str.length );
pos = str.indexOf( "\n" );
}while( pos != -1 );
// process remainder
if ( str.length != 0 ) {
new_str += indent_line( str ) ;
}else{
new_str += "\n";
}
sel.text = new_str;
}
function unindent_line( s){
var new_s="";
if ( s.match(/^(\s+)/) ){
len = RegExp.$1.length ;
if ( len == 1 ) {
if( s.match(/^ |^\t/) ) {
new_s = new_s = s.substring( 1, s.length );
}else{
new_s = s;
}
}else if ( len == 2 ){
new_s = s.substring( 1, s.length );
}else{
new_s = s.substring( 2, s.length );
}
}else{
new_s = s;
}
return new_s;
}
function dd_unindent()
{
var str = document.selection.createRange().text;
var sel = document.selection.createRange();
if ( !str.length ) return;
if ( str.indexOf( "\n" ) == -1 ){
sel.text = unindent_line( str ) + "\n";
return;
}
var new_str = "";
str += "\n";
pos = str.indexOf( "\n" );
do {
line = str.substring( 0, pos );
new_str += unindent_line( line );
str = str.substring( pos+1 , str.length );
pos = str.indexOf( "\n" );
}while( pos != -1 );
// process remainder
if ( str.length != 0 ) {
new_str += unindent_line( str ) ;
}else{
new_str += "\n";
}
sel.text = new_str;
}
// re-clicking button cycles through styles 1. --> a. --> 1. ect...
function number_list( s){
var new_s="";
if ( s.match(/^(\s+):/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "1." + s.substring( len + 1 , s.length );
}else if( s.match(/^(\s+)\*\s/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "1." + s.substring( len + 1 , s.length );
}else if( s.match(/^(\s+)([0-9]+)\./) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "a" + s.substring( len + RegExp.$2.length , s.length );
}else if( s.match(/^(\s+)([a-z]+)\./) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "1" + s.substring( len + RegExp.$2.length , s.length );
}else if( s.match(/^(\s+);/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "1." + s.substring( len + 1 , s.length );
}else{
new_s = " 1. " + s;
}
return new_s;
}
function dd_numberlist()
{
var str = document.selection.createRange().text;
var sel = document.selection.createRange();
if ( !str.length ) return;
if ( str.indexOf( "\n" ) == -1 ){
sel.text = number_list( str ) + "\n";
return;
}
var new_str = "";
str += "\n";
pos = str.indexOf( "\n" );
do {
line = str.substring( 0, pos );
new_str += number_list( line );
str = str.substring( pos+1 , str.length );
pos = str.indexOf( "\n" );
}while( pos != -1 );
// process remainder
if ( str.length != 0 ) {
new_str += number_list( str ) ;
}else{
new_str += "\n";
}
sel.text = new_str;
}
function bullet_list( s){
var new_s="";
if ( s.match(/^(\s+):/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "*" + s.substring( len + 1 , s.length );
}else if( s.match(/^(\s+)\*\s/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "*" + s.substring( len + 1 , s.length );
}else if( s.match(/^(\s+)([0-9]+\.#?[0-9]*)/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "*" + s.substring( len + RegExp.$2.length , s.length );
}else if( s.match(/^(\s+)([a-z]+\.#?[0-9]*)/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "*" + s.substring( len + RegExp.$2.length, s.length );
}else if( s.match(/^(\s+);/) ){
len = RegExp.$1.length ;
new_s = RegExp.$1 + "*" + s.substring( len + 1 , s.length );
}else{
new_s = " * " + s;
}
return new_s;
}
function dd_bulletlist()
{
var str = document.selection.createRange().text;
var sel = document.selection.createRange();
if ( !str.length ) return;
if ( str.indexOf( "\n" ) == -1 ){
sel.text = bullet_list( str ) + "\n";
return;
}
var new_str = "";
str += "\n";
pos = str.indexOf( "\n" );
do {
line = str.substring( 0, pos );
new_str += bullet_list( line );
str = str.substring( pos+1 , str.length );
pos = str.indexOf( "\n" );
}while( pos != -1 );
// process remainder
if ( str.length != 0 ) {
new_str += bullet_list( str ) ;
}else{
new_str += "\n";
}
sel.text = new_str;
}
Buttons for new functionality
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="dd_indent();"
src="UI_indent.gif"
width="24" height="25"
align="middle"
alt="Indent"></img>
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="dd_unindent();"
src="UI_outdent.gif"
width="24" height="25"
align="middle"
alt="Un-indent"></img>
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="dd_numberlist();"
src="UI_numberlist.gif"
width="24" height="25"
align="middle"
alt="Number"></img>
<img class="button"
onmouseover="mouseover(this);"
onmouseout="mouseout(this);"
onmousedown="mousedown(this);"
onmouseup="mouseup(this);"
onclick="dd_bulletlist();"
src="UI_bulletlist.gif"
width="24" height="25"
align="middle"
alt="Bullet"></img>
- Michael Meyers
Integration with OpenWiki
I would like to add the following features
Put editor at top and bottom of textarea
Or else it scrolls out of view.
Setting width of menu to match textarea width set through preferences.
Make the WikiEditor an option through preferences
Add save, preview and cancel options to the menu.
Additional Features
Bug fix
IE 5.5 onwards sometimes displays a stale copy of the textarea, so that text from a previous editing session is displayed. I have taken to refreshing the page before editing.
Anyone have a fix for this? It might be necessary to 'refresh' the textarea as part of inialising the editing view.
I fixed this on the client, see Internet Explorer6 Wont Let Me Edit Wiki Pages
This may be a better fix which involves changing the Wiki code http://www.openwiki.com/ow.asp?OpenWiki%2FBugs#h85
Spell check
See the following starting point (spellold()) that relies on MS Word being installed. The cut and paste functions are not working properly, I suspect it is a scripting security issue in my browser (IE6). I have tried using WSH as per the example , and MS execCommand() as used in other MS based editors (see spell()). Both approaches not working.
function spellold()
{
var tempval=eval(document.f.text);
tempval.focus();
tempval.select();
if (document.all&©toclip==1){
therange=tempval.createTextRange();
therange.execCommand("Copy");
window.status="Contents highlighted and copied to clipboard!";
setTimeout("window.status=''",1800);
}
oWord = new ActiveXObject ("Word.Application");
oWord.Visible = true;
oWord.Documents.Add();
oWord.Selection.Paste();
oWord.ActiveDocument.CheckSpelling();
oWord.Selection.WholeStory();
oWord.Selection.Copy();
oWord.ActiveDocument.Close(0);
oWord.Quit();
var tempval=eval(document.f.text);
tempval.focus();
tempval.select();
therange=tempval.createTextRange();
therange.execCommand("Paste");
function spell_old()
{
oShell=new ActiveXObject ("WScript.Shell");
oShell.SendKeys ("^c"); //copy
oWord = new ActiveXObject ("Word.Application");
oWord.Visible = true;
oWord.Documents.Add();
oWord.Selection.Paste();
oWord.ActiveDocument.CheckSpelling();
oWord.Selection.WholeStory();
oWord.Selection.Copy();
oWord.ActiveDocument.Close(0);
oWord.Quit();
var nRet = oShell.Popup ("Apply changes?\nClick OK to replace all selected text.", 0, "Spell Check Complete", 33);
if (nRet==1) {oShell.SendKeys ("^v");}
See Select and Copy form element script for a fuction that at least copies all the text in the textarea....
It would be preferable to use a server based spell check instead of this Word kludge. See http://spellerpages.sourceforge.net/ I haven't looked at the solution used by Rich Text Editor .
Find in page and Find / Replace
It is awkward jumping to a particular part of the textrange, especially if it is near the end. The brower find feature is OK, but it would be preferable to have this built in. Similarly, a search / replace function would be great.
See here for a code eg http://www.dynamicdrive.com/dynamicindex11/findpage.htm
I envisage a popup with the options like in Word.
Initializing at the end of the textarea
It is annoying that the edit page always opens with the flashing cursor at the top, when you usually want to add something to the bottom of the page. It should be reasonably straightforward to make a selection out of the textarea as part of initialising the page, and then position the caret at the end ready for editing.
A more sophisticated option would be to save the position of the caret / cursor when the text is saved as a cookie ( or with one of MS?s other options) and then put the cursor back there when you next try and edit.
Populating drop down menu?s from OpenWiki
I.e. getting the Inter Wiki names from the table of these names in the Open Wiki database.
Adding useful menu items to a 'right click' menu
Having the most commonly used editing features available through a 'right click' context menu would be helpful. See here for an e.g. of the code. http://markl.f2o.org/Right_Click_Menu.html
Perhaps adding keyboard accelerators for some of the functions.
Adding an 'emotions' pop up with emotions available in OpenWiki
This is part of many html editors, i.e. see this feature in the Rich Text Editor
Adding support for the rest of the OpenWiki mark up codes, i.e. numbered lists etc.
Again, see the features in the Rich Text Editor
Making it easier to link to other Wiki pages.
Its all very well that you can enter any Camel Case word and generate a link to a new Wiki page. But when you want to link to a specific page and you can?t remember its name you find yourself in a bind. At present I open another browser page (Control + N in IE) and search for the other page, switch back to the page I was working on and add the appropriate link. This is too awkward.
One idea is to generate a list of Wiki pages on the fly from that you can choose from, much like the pop up page of emotions some editors provide.
Put in context help
Perhaps DHTML type tool tips. Doesn't seem to be a way to add tool tips to <select> <option> elements though in IE as they don't fire a mouseover() event.
[1] [2]
Anyway, smart DHTML tooltips like this would be grand [3]
A thought would be to display the relevant page from Open Wiki which has the help information in a popup page...
Fit & Finish
Tidy up presentation, see RichText editor for an example of how the editor could look
Rationalise the use of buttons
Ie put the subscript and superscript functions into the heading drop down.
Help!!! (and thanks so far)
Mozilla Compatibility
I added some javascript to make script.js work in mozilla.
Actually, that's not entirely true. Things like bold and italic work. The copy functionality does not work (yet). Mozilla doesn't support document.selection. This means that for every instance of the line:
var sel = document.selection.createRange();
it needs to be replaced with an if statement and mozilla code in addition to the IE code. What I did instead was write a getSelection() function that figures out what should be done. Each time the selected text is necessary, just call that function and it will work. The drop downs work in mozilla now too.
This code:
var sel = document.selection.createRange();
sel.text = v + " ";
Is IE specific and can be replaced with:
insertTag(document.f.text,v + " ")
or if the tag needs to be wrapped instead of inserted:
//var sel = document.selection.createRange();
//sel.text = v + " " + str + " " + v ;
wrapTag(document.f.text, v + " ", " " + v )
This is all under the assumption that mozilla support is important (which to me, it is).
- Ola (2/4/3)
Comments
Umm.. this looks very cool. But none of the links to your demo are working. When you fix, would you email me at matt@lig.net. Thanks
Fixed now
Paul Robertson
This looks GREAT! But from programmers' point of view, since they are used to write codes, a few Wiki markup won't kill them anyway, so an editor just for inserting code seems to be not that necessary...
- Ng Ming Hong (13 Jan 2004)
We use Open Wiki at our office as a KnowledgeManagement? tool so I want to make it very easy to add content... Anyway, even us programmers can benefit from being reminded of the syntax etc for OpenWikiMarkup? and OpenWikiMacros? ...
Paul Robertson (13 january 2004)
Same here. No one used the wiki I set up until I plugged this toolbar into it. Now they all code with the wikiscript anyway but needed a handholding to get them over the threshold.
-- Oddible 2004Jun10
What about something like FCKeditor, something completly transparent for the user.
- RA (26 Jan 2004)
No FCKeditor. It only works for IE. I think it would be better to use the rich text editing capability of IE and Mozilla. That is a wrapper class that hide the difference between IE and Mozilla's rich text editing funtions.
- Ng Ming Hong (30 Jan 2004)
My concept is a really basic editor to add OpenWikiMarkup?. A RichText? editor is only any good if the text is being entered into a WYSIWYGWiki
Paul Robertson 30 1 2004
After doing all that, I realized we'd probably be better off customizing this. It sounds like that's what's really wanted anyway. - Ola
Please, take a look on Wiki Edit.
-- RomanIvanov? (28 Mar 2004)
This wysiwyg editor looks great, but the Zip seems to be unavailable. Is there an alternative download site?
Thanks a lot guys. This info. is very usefull for all of us.
Or at least, this article was authored in Word, then pasted into the WikiEditor to be Wikified before being posted here…


