diff options
author | Andreas Gohr <andi@splitbrain.org> | 2009-05-15 19:30:45 +0200 |
---|---|---|
committer | Andreas Gohr <andi@splitbrain.org> | 2009-05-15 19:30:45 +0200 |
commit | bbca79d883e9dbd29f59556a7e12322da7e9b02a (patch) | |
tree | 7efbbbc53e5ea05a1f286f2ec822e31091beb8d0 /lib | |
parent | df97eaac223e8e3c1cbd6f1474bc72a9ace9d51e (diff) | |
download | rpg-bbca79d883e9dbd29f59556a7e12322da7e9b02a.tar.gz rpg-bbca79d883e9dbd29f59556a7e12322da7e9b02a.tar.bz2 |
start of toolbar javascript refactoring
Ignore-this: 81ef7a71e6910751bf5d6c1b592978c4
darcs-hash:20090515173045-7ad00-e62f075dab9ec4dfa555554f4f50792ceccb97d7.gz
Diffstat (limited to 'lib')
-rw-r--r-- | lib/exe/js.php | 1 | ||||
-rw-r--r-- | lib/scripts/edit.js | 176 | ||||
-rw-r--r-- | lib/scripts/toolbar.js | 161 |
3 files changed, 211 insertions, 127 deletions
diff --git a/lib/exe/js.php b/lib/exe/js.php index 7ba777928..26323e9b0 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -51,6 +51,7 @@ function js_out(){ ); if($edit){ if($write){ + $files[] = DOKU_INC.'lib/scripts/toolbar.js'; $files[] = DOKU_INC.'lib/scripts/edit.js'; } $files[] = DOKU_INC.'lib/scripts/media.js'; diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js index c3265c477..34305c53d 100644 --- a/lib/scripts/edit.js +++ b/lib/scripts/edit.js @@ -153,6 +153,8 @@ function initToolbar(tbid,edid,tb){ { if(eval(actionFunc+"(btn, tb[i], edid, i)")) toolbar.appendChild(btn); + }else{ + alert('unknown type: '+tb[i]['type']); } } // end for } @@ -258,144 +260,64 @@ function addBtnActionMediapopup(btn, props) return true; } +function addBtnActionAutohead(btn, props, edid, id) +{ + eval("btn.onclick = function(){"+ + "insertHeadline('"+edid+"',"+props['mod']+",'"+jsEscape(props['text'])+"'); "+ + "return false};"); + return true; +} + + + + /** - * Format selection - * - * Apply tagOpen/tagClose to selection in textarea, use sampleText instead - * of selection if there is none. Copied and adapted from phpBB + * Determine the current section level while editing * - * @author phpBB development team - * @author MediaWiki development team - * @author Andreas Gohr <andi@splitbrain.org> - * @author Jim Raynor <jim_raynor@web.de> + * @author Andreas Gohr <gohr@cosmocode.de> */ -function insertTags(edid,tagOpen, tagClose, sampleText) { - var txtarea = document.getElementById(edid); - // IE - if(document.selection && !is_gecko) { - var theSelection = document.selection.createRange().text; - var replaced = true; - if(!theSelection){ - replaced = false; - theSelection=sampleText; - } - txtarea.focus(); - - // This has change - var text = theSelection; - if(theSelection.charAt(theSelection.length - 1) == " "){// exclude ending space char, if any - theSelection = theSelection.substring(0, theSelection.length - 1); - r = document.selection.createRange(); - r.text = tagOpen + theSelection + tagClose + " "; - } else { - r = document.selection.createRange(); - r.text = tagOpen + theSelection + tagClose; - } - if(!replaced){ - r.moveStart('character',-text.length-tagClose.length); - r.moveEnd('character',-tagClose.length); - } - r.select(); - // Mozilla - } else if(txtarea.selectionStart || txtarea.selectionStart == '0') { - replaced = false; - var startPos = txtarea.selectionStart; - var endPos = txtarea.selectionEnd; - if(endPos - startPos){ replaced = true; } - var scrollTop=txtarea.scrollTop; - var myText = (txtarea.value).substring(startPos, endPos); - if(!myText) { myText=sampleText;} - if(myText.charAt(myText.length - 1) == " "){ // exclude ending space char, if any - subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " "; - } else { - subst = tagOpen + myText + tagClose; - } - txtarea.value = txtarea.value.substring(0, startPos) + subst + - txtarea.value.substring(endPos, txtarea.value.length); - txtarea.focus(); - - //set new selection - if(replaced){ - var cPos=startPos+(tagOpen.length+myText.length+tagClose.length); - txtarea.selectionStart=cPos; - txtarea.selectionEnd=cPos; - }else{ - txtarea.selectionStart=startPos+tagOpen.length; - txtarea.selectionEnd=startPos+tagOpen.length+myText.length; - } - txtarea.scrollTop=scrollTop; - // All others - } else { - var copy_alertText=alertText; - var re1=new RegExp("\\$1","g"); - var re2=new RegExp("\\$2","g"); - copy_alertText=copy_alertText.replace(re1,sampleText); - copy_alertText=copy_alertText.replace(re2,tagOpen+sampleText+tagClose); - - if (sampleText) { - text=prompt(copy_alertText); - } else { - text=""; - } - if(!text) { text=sampleText;} - text=tagOpen+text+tagClose; - //append to the end - txtarea.value += "\n"+text; - - // in Safari this causes scrolling - if(!is_safari) { - txtarea.focus(); +function currentHeadlineLevel(textboxId){ + var field = $(textboxId); + var selection = getSelection(field); + var search = field.value.substr(0,selection.start); + var lasthl = search.lastIndexOf("\n=="); + if(lasthl == -1 && field.form.prefix){ + // we need to look in prefix context + search = field.form.prefix.value; + lasthl = search.lastIndexOf("\n=="); } + search = search.substr(lasthl+1,6); - } - // reposition cursor if possible - if (txtarea.createTextRange){ - txtarea.caretPos = document.selection.createRange().duplicate(); - } + if(search == '======') return 1; + if(search.substr(0,5) == '=====') return 2; + if(search.substr(0,4) == '====') return 3; + if(search.substr(0,3) == '===') return 4; + if(search.substr(0,2) == '==') return 5; + + return 0; } -/* - * Insert the given value at the current cursor position +/** + * Insert a new headline based on the current section level * - * @see http://www.alexking.org/index.php?content=software/javascript/content.php + * @param string textboxId - the edit field ID + * @param int mod - the headline modificator ( -1, 0, 1) + * @param string text - the sample text passed to insertTags */ -function insertAtCarret(edid,value){ - var field = document.getElementById(edid); - - //IE support - if (document.selection) { - field.focus(); - sel = document.selection.createRange(); - sel.text = value; - - //MOZILLA/NETSCAPE support - }else if (field.selectionStart || field.selectionStart == '0') { - var startPos = field.selectionStart; - var endPos = field.selectionEnd; - var scrollTop = field.scrollTop; - field.value = field.value.substring(0, startPos) + - value + - field.value.substring(endPos, field.value.length); - - field.focus(); - var cPos=startPos+(value.length); - field.selectionStart=cPos; - field.selectionEnd=cPos; - field.scrollTop=scrollTop; - } else { - field.value += "\n"+value; - } - // reposition cursor if possible - if (field.createTextRange){ - field.caretPos = document.selection.createRange().duplicate(); - } - if(value){ - window.textChanged = true; - summaryCheck(); - } -} +function insertHeadline(textboxId,mod,text){ + var lvl = currentHeadlineLevel(textboxId); + // determine new level + lvl += mod; + if(lvl < 1) lvl = 1; + if(lvl > 5) lvl = 5; + + var tags = '='; + for(var i=0; i<=5-lvl; i++) tags += '='; + insertTags(textboxId, tags+' ', ' '+tags+"\n", text); +} + /** * global var used for not saved yet warning */ diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js new file mode 100644 index 000000000..f31e12887 --- /dev/null +++ b/lib/scripts/toolbar.js @@ -0,0 +1,161 @@ +/** + * selection prototype + * + * Object that capsulates the selection in a textarea. Returned by getSelection. + */ +function selection_class(){ + this.start = 0; + this.end = 0; + this.obj = null; + this.rangeCopy = null; + + this.getLength = function(){ + return this.end - this.start; + }; + + this.getText = function(){ + if(!this.obj) return ''; + return this.obj.value.substring(this.start,this.end); + } +} + +/** + * Get current selection/cursor position in a given textArea + * + * @link http://groups.drupal.org/node/1210 + * @returns object - a selection object + */ +function getSelection(textArea) { + var sel = new selection_class(); + + sel.obj = textArea; + sel.start = textArea.value.length; + sel.end = textArea.value.length; + + textArea.focus(); + if(document.getSelection) { // Mozilla et al. + sel.start = textArea.selectionStart; + sel.end = textArea.selectionEnd; + } else if(document.selection) { // MSIE + // The current selection + var range = document.selection.createRange(); + sel.rangeCopy = range.duplicate(); + // Select all text + sel.rangeCopy.moveToElementText(textArea); + // Now move 'dummy' end point to end point of original range + sel.rangeCopy.setEndPoint( 'EndToEnd', range ); + // Now we can calculate start and end points + sel.start = sel.rangeCopy.text.length - range.text.length; + sel.end = sel.start + range.text.length; + } + return sel; +} + +/** + * Set the selection + * + * You need to get a selection object via getSelection() first, then modify the + * start and end properties and pass it back to this function. + * + * @link http://groups.drupal.org/node/1210 + * @param object selection - a selection object as returned by getSelection() + */ +function setSelection(selection){ + if(document.getSelection){ // FF + // what a pleasure in FF ;) + selection.obj.setSelectionRange(selection.start,selection.end); + } else if(document.selection) { // IE + // count number of newlines in str to work around stupid IE selection bug + var countNL = function(str) { + var m = str.split("\n"); + if (!m || !m.length) return 0; + return m.length-1; + }; + var fix = countNL(selection.obj.value.substring(0,selection.start)); + + selection.rangeCopy.collapse(true); + selection.rangeCopy.moveStart('character',selection.start - fix); + selection.rangeCopy.moveEnd('character',selection.end - selection.start); + selection.rangeCopy.select(); + } +} + +/** + * Inserts the given text at the current cursor position or replaces the current + * selection + * + * @author Andreas Gohr <andi@splitbrain.org> + * @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 + */ +function pasteText(selection,text,opts){ + if(!opts) opts = {}; + // replace the content + selection.obj.value = + selection.obj.value.substring(0, selection.start) + text + + selection.obj.value.substring(selection.end, selection.obj.value.length); + + // set new selection + selection.end = selection.start + text.length; + + // modify the new selection if wanted + if(opts.startofs) selection.start += opts.startofs; + if(opts.endofs) selection.end -= opts.endofs; + + // no selection wanted? set cursor to end position + if(opts.nosel) selection.start = selection.end; + + setSelection(selection); +} + + +/** + * Format selection + * + * Apply tagOpen/tagClose to selection in textarea, use sampleText instead + * of selection if there is none. + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function insertTags(textAreaID, tagOpen, tagClose, sampleText){ + var txtarea = document.getElementById(textAreaID); + + var selection = getSelection(txtarea); + var text = selection.getText(); + + // don't include trailing space in selection + if(text.charAt(text.length - 1) == ' '){ + selection.end--; + text = selection.getText(); + } + + // nothing selected, use the sample text + if(!text) text = sampleText; + + // surround with tags + text = tagOpen + text + tagClose; + + // prepare options + var opts = { + startofs: tagOpen.length, + endofs: tagClose.length + }; + + // do it + pasteText(selection,text,opts); +} + +/** + * Wraps around pasteText() for backward compatibility + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function insertAtCarret(textAreaID, text){ + var txtarea = document.getElementById(textAreaID); + var selection = getSelection(txtarea); + pasteText(selection,text,{nosel: true}); +} + |