summaryrefslogtreecommitdiff
path: root/platform/www/lib/scripts/linkwiz.js
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/scripts/linkwiz.js')
-rw-r--r--platform/www/lib/scripts/linkwiz.js339
1 files changed, 339 insertions, 0 deletions
diff --git a/platform/www/lib/scripts/linkwiz.js b/platform/www/lib/scripts/linkwiz.js
new file mode 100644
index 0000000..d82ca96
--- /dev/null
+++ b/platform/www/lib/scripts/linkwiz.js
@@ -0,0 +1,339 @@
+/**
+ * The Link Wizard
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+var dw_linkwiz = {
+ $wiz: null,
+ $entry: null,
+ result: null,
+ timer: null,
+ textArea: null,
+ selected: null,
+ selection: null,
+
+ /**
+ * Initialize the dw_linkwizard by creating the needed HTML
+ * and attaching the eventhandlers
+ */
+ init: function($editor){
+ // position relative to the text area
+ var pos = $editor.position();
+
+ // create HTML Structure
+ if(dw_linkwiz.$wiz)
+ return;
+ dw_linkwiz.$wiz = jQuery(document.createElement('div'))
+ .dialog({
+ autoOpen: false,
+ draggable: true,
+ title: LANG.linkwiz,
+ resizable: false
+ })
+ .html(
+ '<div>'+LANG.linkto+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
+ '<div id="link__wiz_result"></div>'
+ )
+ .parent()
+ .attr('id','link__wiz')
+ .css({
+ 'position': 'absolute',
+ 'top': (pos.top+20)+'px',
+ 'left': (pos.left+80)+'px'
+ })
+ .hide()
+ .appendTo('.dokuwiki:first');
+
+ dw_linkwiz.textArea = $editor[0];
+ dw_linkwiz.result = jQuery('#link__wiz_result')[0];
+
+ // scrollview correction on arrow up/down gets easier
+ jQuery(dw_linkwiz.result).css('position', 'relative');
+
+ dw_linkwiz.$entry = jQuery('#link__wiz_entry');
+ if(JSINFO.namespace){
+ dw_linkwiz.$entry.val(JSINFO.namespace+':');
+ }
+
+ // attach event handlers
+ jQuery('#link__wiz .ui-dialog-titlebar-close').on('click', dw_linkwiz.hide);
+ dw_linkwiz.$entry.keyup(dw_linkwiz.onEntry);
+ jQuery(dw_linkwiz.result).on('click', 'a', dw_linkwiz.onResultClick);
+ },
+
+ /**
+ * 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){ //Escape
+ dw_linkwiz.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 38){ //Up
+ dw_linkwiz.select(dw_linkwiz.selected -1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 40){ //Down
+ dw_linkwiz.select(dw_linkwiz.selected +1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 13){ //Enter
+ if(dw_linkwiz.selected > -1){
+ var $obj = dw_linkwiz.$getResult(dw_linkwiz.selected);
+ if($obj.length > 0){
+ dw_linkwiz.resultClick($obj.find('a')[0]);
+ }
+ }else if(dw_linkwiz.$entry.val()){
+ dw_linkwiz.insertLink(dw_linkwiz.$entry.val());
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ dw_linkwiz.autocomplete();
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param num int result div to return
+ * @returns DOMObject or null
+ */
+ getResult: function(num){
+ DEPRECATED('use dw_linkwiz.$getResult()[0] instead');
+ return dw_linkwiz.$getResult()[0] || null;
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param num int result div to return
+ * @returns jQuery object
+ */
+ $getResult: function(num) {
+ return jQuery(dw_linkwiz.result).find('div').eq(num);
+ },
+
+ /**
+ * Select the given result
+ */
+ select: function(num){
+ if(num < 0){
+ dw_linkwiz.deselect();
+ return;
+ }
+
+ var $obj = dw_linkwiz.$getResult(num);
+ if ($obj.length === 0) {
+ return;
+ }
+
+ dw_linkwiz.deselect();
+ $obj.addClass('selected');
+
+ // make sure the item is viewable in the scroll view
+
+ //getting child position within the parent
+ var childPos = $obj.position().top;
+ //getting difference between the childs top and parents viewable area
+ var yDiff = childPos + $obj.outerHeight() - jQuery(dw_linkwiz.result).innerHeight();
+
+ if (childPos < 0) {
+ //if childPos is above viewable area (that's why it goes negative)
+ jQuery(dw_linkwiz.result)[0].scrollTop += childPos;
+ } else if(yDiff > 0) {
+ // if difference between childs top and parents viewable area is
+ // greater than the height of a childDiv
+ jQuery(dw_linkwiz.result)[0].scrollTop += yDiff;
+ }
+
+ dw_linkwiz.selected = num;
+ },
+
+ /**
+ * deselect a result if any is selected
+ */
+ deselect: function(){
+ if(dw_linkwiz.selected > -1){
+ dw_linkwiz.$getResult(dw_linkwiz.selected).removeClass('selected');
+ }
+ dw_linkwiz.selected = -1;
+ },
+
+ /**
+ * Handle clicks in the result set an dispatch them to
+ * resultClick()
+ */
+ onResultClick: function(e){
+ if(!jQuery(this).is('a')) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ dw_linkwiz.resultClick(this);
+ return false;
+ },
+
+ /**
+ * Handles the "click" on a given result anchor
+ */
+ resultClick: function(a){
+ dw_linkwiz.$entry.val(a.title);
+ if(a.title == '' || a.title.substr(a.title.length-1) == ':'){
+ dw_linkwiz.autocomplete_exec();
+ }else{
+ if (jQuery(a.nextSibling).is('span')) {
+ dw_linkwiz.insertLink(a.nextSibling.innerHTML);
+ }else{
+ dw_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){
+ var link = dw_linkwiz.$entry.val(),
+ sel, stxt;
+ if(!link) {
+ return;
+ }
+
+ sel = DWgetSelection(dw_linkwiz.textArea);
+ if(sel.start == 0 && sel.end == 0) {
+ sel = dw_linkwiz.selection;
+ }
+
+ stxt = sel.getText();
+
+ // don't include trailing space in selection
+ if(stxt.charAt(stxt.length - 1) == ' '){
+ sel.end--;
+ stxt = sel.getText();
+ }
+
+ if(!stxt && !DOKU_UHC) {
+ stxt=title;
+ }
+
+ // prepend colon inside namespaces for non namespace pages
+ if(dw_linkwiz.textArea.form.id.value.indexOf(':') != -1 &&
+ link.indexOf(':') == -1){
+ link = ':' + link;
+ }
+
+ var so = link.length;
+ var eo = 0;
+ if(dw_linkwiz.val){
+ if(dw_linkwiz.val.open) {
+ so += dw_linkwiz.val.open.length;
+ link = dw_linkwiz.val.open+link;
+ }
+ link += '|';
+ so += 1;
+ if(stxt) {
+ link += stxt;
+ }
+ if(dw_linkwiz.val.close) {
+ link += dw_linkwiz.val.close;
+ eo = dw_linkwiz.val.close.length;
+ }
+ }
+
+ pasteText(sel,link,{startofs: so, endofs: eo});
+ dw_linkwiz.hide();
+
+ // reset the entry to the parent namespace
+ var externallinkpattern = new RegExp('^((f|ht)tps?:)?//', 'i'),
+ entry_value;
+ if (externallinkpattern.test(dw_linkwiz.$entry.val())) {
+ if (JSINFO.namespace) {
+ entry_value = JSINFO.namespace + ':';
+ } else {
+ entry_value = ''; //reset whole external links
+ }
+ } else {
+ entry_value = dw_linkwiz.$entry.val().replace(/[^:]*$/, '')
+ }
+ dw_linkwiz.$entry.val(entry_value);
+ },
+
+ /**
+ * Start the page/namespace lookup timer
+ *
+ * Calls autocomplete_exec when the timer runs out
+ */
+ autocomplete: function(){
+ if(dw_linkwiz.timer !== null){
+ window.clearTimeout(dw_linkwiz.timer);
+ dw_linkwiz.timer = null;
+ }
+
+ dw_linkwiz.timer = window.setTimeout(dw_linkwiz.autocomplete_exec,350);
+ },
+
+ /**
+ * Executes the AJAX call for the page/namespace lookup
+ */
+ autocomplete_exec: function(){
+ var $res = jQuery(dw_linkwiz.result);
+ dw_linkwiz.deselect();
+ $res.html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />')
+ .load(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'linkwiz',
+ q: dw_linkwiz.$entry.val()
+ }
+ );
+ },
+
+ /**
+ * Show the link wizard
+ */
+ show: function(){
+ dw_linkwiz.selection = DWgetSelection(dw_linkwiz.textArea);
+ dw_linkwiz.$wiz.show();
+ dw_linkwiz.$entry.focus();
+ dw_linkwiz.autocomplete();
+
+ // Move the cursor to the end of the input
+ var temp = dw_linkwiz.$entry.val();
+ dw_linkwiz.$entry.val('');
+ dw_linkwiz.$entry.val(temp);
+ },
+
+ /**
+ * Hide the link wizard
+ */
+ hide: function(){
+ dw_linkwiz.$wiz.hide();
+ dw_linkwiz.textArea.focus();
+ },
+
+ /**
+ * Toggle the link wizard
+ */
+ toggle: function(){
+ if(dw_linkwiz.$wiz.css('display') == 'none'){
+ dw_linkwiz.show();
+ }else{
+ dw_linkwiz.hide();
+ }
+ }
+};