summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2011-07-08 00:22:27 +0200
committerAndreas Gohr <andi@splitbrain.org>2011-07-08 00:24:03 +0200
commit2bcca88a344ad5112322fb2533dceefb8757619a (patch)
treeebead8a85aa118a8a0a9b626a35eaf031c834a3b
parent110749cc8c83fb3b492208c80ed1bc351abd1752 (diff)
downloadrpg-2bcca88a344ad5112322fb2533dceefb8757619a.tar.gz
rpg-2bcca88a344ad5112322fb2533dceefb8757619a.tar.bz2
some initial refactoring of the linkwizard
-rw-r--r--lib/scripts/linkwiz.js601
-rw-r--r--lib/scripts/toolbar.js7
2 files changed, 303 insertions, 305 deletions
diff --git a/lib/scripts/linkwiz.js b/lib/scripts/linkwiz.js
index e9a1d71b3..9ad72626d 100644
--- a/lib/scripts/linkwiz.js
+++ b/lib/scripts/linkwiz.js
@@ -1,319 +1,312 @@
+/*jslint sloppy: true, indent: 4, white: true, browser: true, eqeq: true */
+/*global jQuery, DOKU_BASE, LANG, DOKU_UHC, getSelection, pasteText */
+
+
/**
* The Link Wizard
*
* @author Andreas Gohr <gohr@cosmocode.de>
* @author Pierre Spring <pierre.spring@caillou.ch>
*/
-(function($){
- $.fn.extend({
- linkwiz: function(editor) {
-
- var wiz;
- var entry;
- var result;
- var timer;
- var textArea;
- var selected;
- var selection;
-
- /**
- * Initialize the linkwizard by creating the needed HTML
- * and attaching the eventhandlers
- */
- var init = function(textAreaElement){
-
-
- // create HTML Structure
- wiz = document.createElement('div');
- wiz.style.position = 'absolute';
- wiz.id = 'link__wiz';
- wiz.className = 'picker';
- wiz.style.top = (findPosY(textAreaElement)+20)+'px';
- wiz.style.left = (findPosX(textAreaElement)+80)+'px';
- wiz.style.marginLeft = '-10000px';
- wiz.style.marginTop = '-10000px';
-
- wiz.innerHTML =
- '<div id="link__wiz_header">'+
- '<img src="'+DOKU_BASE+'lib/images/close.png" width="16" height="16" align="right" alt="" id="link__wiz_close" />'+
- LANG['linkwiz']+'</div>'+
- '<div>'+LANG['linkto']+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
- '<div id="link__wiz_result"></div>';
- $('#dw__editform')[0].parentNode.appendChild(wiz);
- textArea = textAreaElement;
- result = $('#link__wiz_result')[0];
- entry = $('#link__wiz_entry')[0];
-
- // attach event handlers
- var obj;
- var obj = $('#link__wiz_close')[0];
- obj.onclick = hide;
-
- addEvent(entry,'keyup',onEntry);
- addEvent(result,'click',onResultClick);
-
- $(wiz).draggable({handle: '#link__wiz_header'});
-
- };
-
- /**
- * handle all keyup events in the entry field
- */
- var onEntry = function(e){
- if(e.keyCode == 37 || e.keyCode == 39){ //left/right
- return true; //ignore
- }
- if(e.keyCode == 27){
- hide();
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
- if(e.keyCode == 38){ //Up
- select(selected -1);
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
- if(e.keyCode == 40){ //Down
- select(selected +1);
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
- if(e.keyCode == 13){ //Enter
- if(selected > -1){
- var obj = getResult(selected);
- if(obj){
- var a = $(obj).find('a')[0];
- resultClick(a);
- }
- }else if(entry.value){
- insertLink(entry.value);
- }
-
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
- autocomplete();
- };
-
- /**
- * Get one of the result by index
- *
- * @param int result div to return
- * @returns DOMObject or null
- */
- var getResult = function(num){
- var obj;
- var childs = $(result).find('div');
- var obj = childs[num];
+var linkwiz = {
+ $wiz: null,
+ entry: null,
+ result: null,
+ timer: null,
+ textArea: null,
+ selected: null,
+ selection: null,
+
+ /**
+ * Initialize the linkwizard by creating the needed HTML
+ * and attaching the eventhandlers
+ */
+ init: function($editor){
+ // position relative to the text area
+ var pos = $editor.position();
+ pos.left += 20;
+ pos.right += 80;
+
+ // create HTML Structure
+ linkwiz.$wiz = jQuery(document.createElement('div'))
+ .attr('id','link__wiz')
+ .css({
+ 'position': 'absolute',
+ 'top': pos.left+'px',
+ 'left': pos.top+'px',
+ 'margin-left': '-10000px',
+ 'margin-top': '-10000px'
+ })
+ .html(
+ '<div id="link__wiz_header">'+
+ '<img src="'+DOKU_BASE+'lib/images/close.png" width="16" height="16" align="right" alt="" id="link__wiz_close" />'+
+ LANG.linkwiz+'</div>'+
+ '<div>'+LANG.linkto+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
+ '<div id="link__wiz_result"></div>'
+ )
+ .addClass('picker');
+
+ $editor[0].form.parentNode.appendChild(linkwiz.$wiz[0]);
+ linkwiz.textArea = $editor[0];
+ linkwiz.result = jQuery('#link__wiz_result')[0];
+ linkwiz.entry = jQuery('#link__wiz_entry')[0];
+
+ // attach event handlers
+ jQuery('#link__wiz_close').click(linkwiz.hide);
+ jQuery(linkwiz.entry).keyup(linkwiz.onEntry);
+ jQuery(linkwiz.result).click(linkwiz.onResultClick);
+
+ linkwiz.$wiz.draggable({handle: '#link__wiz_header'});
+ },
+
+ /**
+ * handle all keyup events in the entry field
+ */
+ onEntry: function(e){
+ if(e.keyCode == 37 || e.keyCode == 39){ //left/right
+ return true; //ignore
+ }
+ if(e.keyCode == 27){
+ linkwiz.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 38){ //Up
+ linkwiz.select(linkwiz.selected -1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 40){ //Down
+ linkwiz.select(linkwiz.selected +1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 13){ //Enter
+ if(linkwiz.selected > -1){
+ var obj = linkwiz.getResult(linkwiz.selected);
if(obj){
- return obj;
- }else{
- return null;
- }
- };
-
- /**
- * Select the given result
- */
- var select = function(num){
- if(num < 0){
- deselect();
- return;
+ var a = jQuery(obj).find('a')[0];
+ linkwiz.resultClick(a);
}
+ }else if(linkwiz.entry.value){
+ linkwiz.insertLink(linkwiz.entry.value);
+ }
- var obj = getResult(num);
- if(obj){
- deselect();
- obj.className += ' selected';
-
- // make sure the item is viewable in the scroll view
- // FIXME check IE compatibility
- if(obj.offsetTop > result.scrollTop + result.clientHeight){
- result.scrollTop += obj.clientHeight;
- }else if(obj.offsetTop - result.clientHeight < result.scrollTop){ // this works but isn't quite right, fixes welcome
- result.scrollTop -= obj.clientHeight;
- }
- // now recheck - if still not in view, the user used the mouse to scroll
- if( (obj.offsetTop > result.scrollTop + result.clientHeight) ||
- (obj.offsetTop < result.scrollTop) ){
- obj.scrollIntoView();
- }
-
- selected = num;
- }
- };
-
- /**
- * deselect a result if any is selected
- */
- var deselect = function(){
- if(selected > -1){
- var obj = getResult(selected);
- if(obj){
- obj.className = obj.className.replace(/ ?selected/,'');
- }
- }
- selected = -1;
- };
-
- /**
- * Handle clicks in the result set an dispatch them to
- * resultClick()
- */
- var onResultClick = function(e){
- if(e.target.tagName != 'A') return;
- e.stopPropagation();
- e.preventDefault();
- resultClick(e.target);
- return false;
- };
-
- /**
- * Handles the "click" on a given result anchor
- */
- var resultClick = function(a){
- var id = a.title;
- if(id == '' || id.substr(id.length-1) == ':'){
- entry.value = id;
- autocomplete_exec();
- }else{
- entry.value = id;
- if(a.nextSibling && a.nextSibling.tagName == 'SPAN'){
- insertLink(a.nextSibling.innerHTML);
- }else{
- insertLink('');
- }
- }
- };
-
- /**
- * Insert the id currently in the entry box to the textarea,
- * replacing the current selection or at the curso postion.
- * When no selection is available the given title will be used
- * as link title instead
- */
- var insertLink = function(title){
- if(!entry.value) return;
-
- var sel = getSelection(textArea);
- if(sel.start == 0 && sel.end == 0) sel = selection;
-
- var stxt = sel.getText();
-
- // don't include trailing space in selection
- if(stxt.charAt(stxt.length - 1) == ' '){
- sel.end--;
- var stxt = sel.getText();
- }
-
- if(!stxt && !DOKU_UHC) stxt=title;
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ linkwiz.autocomplete();
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param int result div to return
+ * @returns DOMObject or null
+ */
+ getResult: function(num){
+ var childs = jQuery(linkwiz.result).find('div');
+ var obj = childs[num];
+ if(obj){
+ return obj;
+ }else{
+ return null;
+ }
+ },
+
+ /**
+ * Select the given result
+ */
+ select: function(num){
+ if(num < 0){
+ linkwiz.deselect();
+ return;
+ }
- // prepend colon inside namespaces for non namespace pages
- if(textArea.form['id'].value.indexOf(':') != -1 &&
- entry.value.indexOf(':') == -1){
- entry.value = ':'+entry.value;
- }
+ var obj = linkwiz.getResult(num);
+ if(obj){
+ linkwiz.deselect();
+ obj.className += ' selected';
+
+ // make sure the item is viewable in the scroll view
+ // FIXME check IE compatibility
+ if(obj.offsetTop > linkwiz.result.scrollTop + linkwiz.result.clientHeight){
+ linkwiz.result.scrollTop += obj.clientHeight;
+ }else if(obj.offsetTop - linkwiz.result.clientHeight < linkwiz.result.scrollTop){ // this works but isn't quite right, fixes welcome
+ linkwiz.result.scrollTop -= obj.clientHeight;
+ }
+ // now recheck - if still not in view, the user used the mouse to scroll
+ if( (obj.offsetTop > linkwiz.result.scrollTop + linkwiz.result.clientHeight) ||
+ (obj.offsetTop < linkwiz.result.scrollTop) ){
+ obj.scrollIntoView();
+ }
+
+ linkwiz.selected = num;
+ }
+ },
+
+ /**
+ * deselect a result if any is selected
+ */
+ deselect: function(){
+ if(linkwiz.selected > -1){
+ var obj = linkwiz.getResult(linkwiz.selected);
+ if(obj){
+ obj.className = obj.className.replace(/ ?selected/,'');
+ }
+ }
+ linkwiz.selected = -1;
+ },
+
+ /**
+ * Handle clicks in the result set an dispatch them to
+ * resultClick()
+ */
+ onResultClick: function(e){
+ if(e.target.tagName != 'A') return;
+ e.stopPropagation();
+ e.preventDefault();
+ linkwiz.resultClick(e.target);
+ return false;
+ },
+
+ /**
+ * Handles the "click" on a given result anchor
+ */
+ resultClick: function(a){
+ var id = a.title;
+ if(id == '' || id.substr(id.length-1) == ':'){
+ linkwiz.entry.value = id;
+ linkwiz.autocomplete_exec();
+ }else{
+ linkwiz.entry.value = id;
+ if(a.nextSibling && a.nextSibling.tagName == 'SPAN'){
+ linkwiz.insertLink(a.nextSibling.innerHTML);
+ }else{
+ linkwiz.insertLink('');
+ }
+ }
+ },
+
+ /**
+ * Insert the id currently in the entry box to the textarea,
+ * replacing the current selection or at the cursor position.
+ * When no selection is available the given title will be used
+ * as link title instead
+ */
+ insertLink: function(title){
+ if(!linkwiz.entry.value) return;
+
+ var sel = getSelection(linkwiz.textArea);
+ if(sel.start == 0 && sel.end == 0) sel = linkwiz.selection;
+
+ var stxt = sel.getText();
+
+ // don't include trailing space in selection
+ if(stxt.charAt(stxt.length - 1) == ' '){
+ sel.end--;
+ stxt = sel.getText();
+ }
- var link = '[['+entry.value+'|';
- if(stxt) link += stxt;
- link += ']]';
-
- var so = entry.value.length+3;
- var eo = 2;
-
- pasteText(sel,link,{startofs: so, endofs: eo});
- hide();
- // reset the entry to the parent namespace and remove : at the beginning
- entry.value = entry.value.replace(/(^:)?[^:]*$/, '');
- };
-
- /**
- * Start the page/namespace lookup timer
- *
- * Calls autocomplete_exec when the timer runs out
- */
- var autocomplete = function(){
- if(timer !== null){
- window.clearTimeout(timer);
- timer = null;
- }
+ if(!stxt && !DOKU_UHC) stxt=title;
- timer = window.setTimeout(autocomplete_exec,350);
- };
-
- /**
- * Executes the AJAX call for the page/namespace lookup
- */
- var autocomplete_exec = function(){
- deselect();
- result.innerHTML = '<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />';
-
- // because we need to use POST, we
- // can not use the .load() function.
- $.post(
- DOKU_BASE + 'lib/exe/ajax.php',
- {
- call: 'linkwiz',
- q: entry.value
- },
- function (data) {
- result.innerHTML = data;
- },
- 'html'
- );
- };
-
- /**
- * Clears the result area
- */
- var clear = function(){
- result.innerHTML = 'Search for a matching page name above, or browse through the pages on the right';
- entry.value = '';
- };
-
- /**
- * Show the linkwizard
- */
- var show = function(){
- selection = getSelection(textArea);
- wiz.style.marginLeft = '0px';
- wiz.style.marginTop = '0px';
- entry.focus();
- autocomplete();
- };
-
- /**
- * Hide the link wizard
- */
- var hide = function(){
- wiz.style.marginLeft = '-10000px';
- wiz.style.marginTop = '-10000px';
- textArea.focus();
- };
-
- /**
- * Toggle the link wizard
- */
- var toggle = function(){
- if(wiz.style.marginLeft == '-10000px'){
- show();
- }else{
- hide();
- }
- };
+ // prepend colon inside namespaces for non namespace pages
+ if(linkwiz.textArea.form['id'].value.indexOf(':') != -1 &&
+ linkwiz.entry.value.indexOf(':') == -1){
+ linkwiz.entry.value = ':'+linkwiz.entry.value;
+ }
- init($(editor)[0]);
+ var link = '[['+linkwiz.entry.value+'|';
+ if(stxt) link += stxt;
+ link += ']]';
+
+ var so = linkwiz.entry.value.length+3;
+ var eo = 2;
+
+ pasteText(sel,link,{startofs: so, endofs: eo});
+ linkwiz.hide();
+ // reset the entry to the parent namespace and remove : at the beginning
+ linkwiz.entry.value = linkwiz.entry.value.replace(/(^:)?[^:]*$/, '');
+ },
+
+ /**
+ * Start the page/namespace lookup timer
+ *
+ * Calls autocomplete_exec when the timer runs out
+ */
+ autocomplete: function(){
+ if(linkwiz.timer !== null){
+ window.clearTimeout(linkwiz.timer);
+ linkwiz.timer = null;
+ }
- return this.each(function() {
- $(this).click(function (e) {
- e.preventDefault();
- toggle();
- });
- });
+ linkwiz.timer = window.setTimeout(linkwiz.autocomplete_exec,350);
+ },
+
+ /**
+ * Executes the AJAX call for the page/namespace lookup
+ */
+ autocomplete_exec: function(){
+ linkwiz.deselect();
+ linkwiz.result.innerHTML = '<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />';
+
+ // because we need to use POST, we
+ // can not use the .load() function.
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'linkwiz',
+ q: linkwiz.entry.value
+ },
+ function (data) {
+ linkwiz.result.innerHTML = data;
+ },
+ 'html'
+ );
+ },
+
+ /**
+ * Clears the result area
+ * @fixme localize
+ */
+ clear: function(){
+ linkwiz.result.innerHTML = 'Search for a matching page name above, or browse through the pages on the right';
+ linkwiz.entry.value = '';
+ },
+
+ /**
+ * Show the linkwizard
+ */
+ show: function(){
+ linkwiz.selection = getSelection(linkwiz.textArea);
+ linkwiz.$wiz.css('marginLeft', '0');
+ linkwiz.$wiz.css('marginTop', '0');
+ linkwiz.entry.focus();
+ linkwiz.autocomplete();
+ },
+
+ /**
+ * Hide the link wizard
+ */
+ hide: function(){
+ linkwiz.$wiz.css('marginLeft', '-10000px');
+ linkwiz.$wiz.css('marginTop', '-10000px');
+ linkwiz.textArea.focus();
+ },
+
+ /**
+ * Toggle the link wizard
+ */
+ toggle: function(){
+ if(linkwiz.$wiz.css('marginLeft') == '-10000px'){
+ linkwiz.show();
+ }else{
+ linkwiz.hide();
}
- });
-})(jQuery);
+ }
+
+};
diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js
index c8dfe394d..fc95340f5 100644
--- a/lib/scripts/toolbar.js
+++ b/lib/scripts/toolbar.js
@@ -226,10 +226,15 @@ function addBtnActionPicker(btn, props, edid) {
* @author Andreas Gohr <gohr@cosmocode.de>
*/
function addBtnActionLinkwiz(btn, props, edid) {
- jQuery(btn).linkwiz(jQuery('#' + edid));
+ linkwiz.init(jQuery('#'+edid));
+ jQuery(btn).click(function(){
+ linkwiz.toggle();
+ return false;
+ });
return true;
}
+
/**
* Show/Hide a previosly created picker window
*