summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2009-08-04 11:57:07 +0200
committerAndreas Gohr <andi@splitbrain.org>2009-08-04 11:57:07 +0200
commit201ea5f3891ddc2bd1841288c6c03916fe3c68dc (patch)
tree410514a6d885750178c10f993f0eaa1bdef1b863
parentad4aaef7a487c01e8448c3371005826b4b51d9fc (diff)
downloadrpg-201ea5f3891ddc2bd1841288c6c03916fe3c68dc.tar.gz
rpg-201ea5f3891ddc2bd1841288c6c03916fe3c68dc.tar.bz2
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
-rw-r--r--inc/toolbar.php8
-rw-r--r--lib/scripts/edit.js69
-rw-r--r--lib/scripts/textselection.js4
-rw-r--r--lib/scripts/toolbar.js34
4 files changed, 108 insertions, 7 deletions
diff --git a/inc/toolbar.php b/inc/toolbar.php
index d4a9b3a94..1f34f3403 100644
--- a/inc/toolbar.php
+++ b/inc/toolbar.php
@@ -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(
diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js
index 267f51194..51a8e3f8e 100644
--- a/lib/scripts/edit.js
+++ b/lib/scripts/edit.js
@@ -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
diff --git a/lib/scripts/textselection.js b/lib/scripts/textselection.js
index f005fa3da..3ebab35e4 100644
--- a/lib/scripts/textselection.js
+++ b/lib/scripts/textselection.js
@@ -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 = {};
diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js
index 1a152b1a7..48a4a4a7e 100644
--- a/lib/scripts/toolbar.js
+++ b/lib/scripts/toolbar.js
@@ -78,6 +78,40 @@ function tb_format(btn, props, edid) {
}
/**
+ * 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
*
* @param DOMElement btn Button element to add the action to