Skip to content
Snippets Groups Projects
Commit 201ea5f3 authored by Andreas Gohr's avatar Andreas Gohr
Browse files

improved list handling

Ignore-this: 2e4f3fbfb28917ee66cf3e1925c806d3

This patch adds multiple enhancements to handling lists and indented
code blocks in the editor.

1. Pressing enter when in a list item or code block will keep the indention
   and adds a new list point
2. Pressing space at the start of a list item will indent the item to the
   next level
3. Pressing bckspace at the start of a list item will outdent the item
   to the previous level or delete the list bullet when you are at the
   1st level already
4. A new type of formatting button called formatln is added. It applies
   formatting to several lines. It's used for the list buttons currently
   and makes it possible to convert mutiple lines to a list

This enhncement are currently only tested in Firefox are most likely to
break IE compatibility. A compatibility patch will be submitted later

note: development was part of the ICKE 2.0 project see
      http://www.icke-projekt.de for info

darcs-hash:20090804095707-7ad00-e565c66087c7121188ad7ece8265d9f64f7e6947.gz
parent ad4aaef7
No related branches found
No related tags found
No related merge requests found
......@@ -161,19 +161,19 @@ function toolbar_JSdefines($varname){
'sample' => 'http://example.com|'.$lang['qb_extlink'],
),
array(
'type' => 'format',
'type' => 'formatln',
'title' => $lang['qb_ol'],
'icon' => 'ol.png',
'open' => ' - ',
'close' => '\n',
'close' => '',
'key' => '-',
),
array(
'type' => 'format',
'type' => 'formatln',
'title' => $lang['qb_ul'],
'icon' => 'ul.png',
'open' => ' * ',
'close' => '\n',
'close' => '',
'key' => '.',
),
array(
......
......@@ -186,8 +186,75 @@ function addBtnActionAutohead(btn, props, edid, id)
return true;
}
/**
* Make intended formattings easier to handle
*
* Listens to all key inputs and handle indentions
* of lists and code blocks
*
* Currently handles space, backspce and enter presses
*
* @author Andreas Gohr <andi@splitbrain.org>
* @fixme handle tabs
* @fixme IE compatibility not tested yet
*/
function keyHandler(e){
if(e.keyCode != 13 &&
e.keyCode != 8 &&
e.keyCode != 32) return; //FIXME IE
var field = e.target;
var selection = getSelection(field);
var search = "\n"+field.value.substr(0,selection.start);
var linestart = search.lastIndexOf("\n");
search = search.substr(linestart);
if(e.keyCode == 13){ // Enter //FIXME IE
// keep current indention for lists and code
var match = search.match(/(\n +([*-] ?)?)/);
if(match){
insertAtCarret(field.id,match[1]);
e.preventDefault(); // prevent enter key
}
}else if(e.keyCode == 8){ // Backspace
// unindent lists
var match = search.match(/(\n +)([*-] ?)$/);
if(match){
var spaces = match[1].length-1;
if(spaces > 3){ // unindent one level
field.value = field.value.substr(0,linestart)+
field.value.substr(linestart+2);
selection.start = selection.start - 2;
selection.end = selection.start;
}else{ // delete list point
field.value = field.value.substr(0,linestart)+
field.value.substr(selection.start);
selection.start = linestart;
selection.end = linestart;
}
setSelection(selection);
e.preventDefault(); // prevent backspace
}
}else if(e.keyCode == 32){ // Space
// intend list item
var match = search.match(/(\n +)([*-] )$/);
if(match){
field.value = field.value.substr(0,linestart)+' '+
field.value.substr(linestart);
selection.start = selection.start + 2;
selection.end = selection.start;
setSelection(selection);
e.preventDefault(); // prevent space
}
}
}
//FIXME consolidate somewhere else
addInitEvent(function(){
var field = $('wiki__text');
if(!field) return;
addEvent(field,'keydown',keyHandler);
});
/**
* Determine the current section level while editing
......
......@@ -99,8 +99,8 @@ function setSelection(selection){
* @param string text - the new text to be pasted
* @param objct selecttion - selection object returned by getSelection
* @param int opts.startofs - number of charcters at the start to skip from new selection
* @param int opts.endofs - number of charcters at the end to skip from new selection
* @param bool opts.ofs - set tru if new text should not be selected
* @param int opts.endofs - number of characters at the end to skip from new selection
* @param bool opts.nosel - set true if new text should not be selected
*/
function pasteText(selection,text,opts){
if(!opts) opts = {};
......
......@@ -77,6 +77,40 @@ function tb_format(btn, props, edid) {
return false;
}
/**
* Button action for format buttons
*
* This works exactly as tb_format() except that, if multiple lines
* are selected, each line will be formatted seperately
*
* @param DOMElement btn Button element to add the action to
* @param array props Associative array of button properties
* @param string edid ID of the editor textarea
* @author Gabriel Birke <birke@d-scribe.de>
* @author Andreas Gohr <andi@splitbrain.org>
*/
function tb_formatln(btn, props, edid) {
var sample = props['title'];
if(props['sample']){
sample = props['sample'];
}
sample = fixtxt(sample);
var selection = getSelection($(edid));
if(selection.getLength()) sample = selection.getText();
props['open'] = fixtxt(props['open']);
props['close'] = fixtxt(props['close']);
sample = sample.split("\n").join(props['close']+"\n"+props['open']);
sample = props['open']+sample+props['close'];
pasteText(selection,sample,{nosel: true});
pickerClose();
return false;
}
/**
* Button action for insert buttons
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment