From 5e7a292691951a0fa0a18f06c8b9bcfb509a032d Mon Sep 17 00:00:00 2001 From: Adrian Lang <mail@adrianlang.de> Date: Fri, 9 Sep 2011 22:26:16 +0200 Subject: [PATCH] Various JavaScript improvements, JSLint, jQuery --- lib/exe/js.php | 6 +- lib/plugins/acl/script.js | 2 +- lib/scripts/compatibility.js | 2 +- lib/scripts/cookie.js | 15 +-- lib/scripts/edit.js | 222 ++++++++++++++++------------------- lib/scripts/editor.js | 101 ++++++++-------- lib/scripts/index.js | 3 - lib/scripts/linkwiz.js | 199 +++++++++++++++---------------- lib/scripts/media.js | 3 - lib/scripts/qsearch.js | 3 - lib/scripts/script.js | 7 +- lib/scripts/textselection.js | 7 +- lib/scripts/toolbar.js | 146 ++++++++++------------- lib/scripts/tree.js | 3 - lib/styles/screen.css | 5 + 15 files changed, 337 insertions(+), 387 deletions(-) diff --git a/lib/exe/js.php b/lib/exe/js.php index 33f8c695d..b7f2fd222 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -88,6 +88,7 @@ function js_out(){ // add some global variables print "var DOKU_BASE = '".DOKU_BASE."';"; print "var DOKU_TPL = '".DOKU_TPL."';"; + // FIXME: Move those to JSINFO print "var DOKU_UHN = ".((int) useHeading('navigation')).";"; print "var DOKU_UHC = ".((int) useHeading('content')).";"; @@ -106,10 +107,7 @@ function js_out(){ echo "\n\n/* XXXXXXXXXX end of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n"; } - // init stuff - js_runonstart("addEvent(document,'click',closePopups)"); - js_runonstart("initToolbar('tool__bar','wiki__text',toolbar)"); if($conf['locktime'] != 0){ js_runonstart("dw_locktimer.init(".($conf['locktime'] - 60).",".$conf['usedraft'].")"); } @@ -220,7 +218,7 @@ function js_escape($string){ * @author Andreas Gohr <andi@splitbrain.org> */ function js_runonstart($func){ - echo "addInitEvent(function(){ $func; });".NL; + echo "jQuery(function(){ $func; });".NL; } /** diff --git a/lib/plugins/acl/script.js b/lib/plugins/acl/script.js index 2598bcef8..d912a2407 100644 --- a/lib/plugins/acl/script.js +++ b/lib/plugins/acl/script.js @@ -33,7 +33,7 @@ var dw_acl = { show_sublist, 'html' ); - }, + }, toggle_display: function ($clicky, opening) { $clicky.attr('src', diff --git a/lib/scripts/compatibility.js b/lib/scripts/compatibility.js index 39f703c71..3b027f016 100644 --- a/lib/scripts/compatibility.js +++ b/lib/scripts/compatibility.js @@ -38,7 +38,7 @@ function DEPRECATED_WRAP(func, context) { return function () { DEPRECATED(); return func.apply(context || this, arguments); - } + }; } /** diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js index 4dd77beea..c70d0bb56 100644 --- a/lib/scripts/cookie.js +++ b/lib/scripts/cookie.js @@ -9,7 +9,7 @@ * @author Andreas Gohr <andi@splitbrain.org> * @author Michal Rezler <m.rezler@centrum.cz> */ -DokuCookie = { +var DokuCookie = { data: {}, name: 'DOKU_PREFS', @@ -19,17 +19,18 @@ DokuCookie = { * @author Andreas Gohr <andi@splitbrain.org> */ setValue: function(key,val){ - var text = ''; + var text = [], + _this = this; this.init(); this.data[key] = val; //save the whole data array - jQuery.each(this.data, function (key, val) { - if (DokuCookie.data.hasOwnProperty(key)) { - text += '#'+encodeURIComponent(key)+'#'+encodeURIComponent(val); - } + jQuery.each(_this.data, function (key, val) { + if (_this.data.hasOwnProperty(key)) { + text.push(encodeURIComponent(key)+'#'+encodeURIComponent(val)); + } }); - jQuery.cookie(this.name,text.substr(1), {expires: 365, path: DOKU_BASE}); + jQuery.cookie(this.name, text.join('#'), {expires: 365, path: DOKU_BASE}); }, /** diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js index 816568e92..bfbd698f1 100644 --- a/lib/scripts/edit.js +++ b/lib/scripts/edit.js @@ -14,38 +14,36 @@ * @author Michal Rezler <m.rezler@centrum.cz> */ function createToolButton(icon,label,key,id,classname){ - var $ = jQuery; - var btn = $('<button>'); - var ico = $('<img />'); + var $btn = jQuery(document.createElement('button')), + $ico = jQuery(document.createElement('img')); - // preapare the basic button stuff - btn.attr('class', 'toolbutton'); + // prepare the basic button stuff + $btn.addClass('toolbutton'); if(classname){ - btn.attr('class', 'toolbutton '+classname); + $btn.addClass(classname); } - btn.attr('title', label); + $btn.attr('title', label); if(key){ - btn.attr('title', label + ' ['+key.toUpperCase()+']') + $btn.attr('title', label + ' ['+key.toUpperCase()+']') .attr('accessKey', key); } // set IDs if given if(id){ - btn.attr('id', id); - ico.attr('id', id+'_ico'); + $btn.attr('id', id); + $ico.attr('id', id+'_ico'); } // create the icon and add it to the button - if(icon.substr(0,1) == '/'){ - ico.attr('src', icon); - }else{ - ico.attr('src', DOKU_BASE+'lib/images/toolbar/'+icon); + if(icon.substr(0,1) !== '/'){ + icon = DOKU_BASE + 'lib/images/toolbar/' + icon; } - btn.append(ico); + $ico.attr('src', icon); + $btn.append($ico); - // we have to return a javascript object (for compatibility reasons) - return btn[0]; + // we have to return a DOM object (for compatibility reasons) + return $btn[0]; } /** @@ -63,69 +61,51 @@ function createToolButton(icon,label,key,id,classname){ * @author Andreas Gohr <andi@splitbrain.org> */ function createPicker(id,props,edid){ - var icobase = props['icobase']; - var list = props['list']; - var $ = jQuery; - // create the wrapping div - var picker = $('<div></div>'); + var $picker = jQuery(document.createElement('div')); - var className = 'picker'; + $picker.addClass('picker hidden_with_access_keys'); if(props['class']){ - className += ' '+props['class']; + $picker.addClass(props['class']); } - picker.attr('class', className) - .attr('id', id) - .css('position', 'absolute') - .css('marginLeft', '-10000px') // no display:none, to keep access keys working - .css('marginTop', '-10000px'); + $picker.attr('id', id).css('position', 'absolute'); + + function $makebutton(title) { + var $btn = jQuery(document.createElement('button')) + .addClass('pickerbutton').attr('title', title) + .bind('click', bind(pickerInsert, title, edid)) + .appendTo($picker); + return $btn; + } - for(var key in list){ - if (!list.hasOwnProperty(key)) continue; + jQuery.each(props.list, function (key, item) { + if (!props.list.hasOwnProperty(key)) { + return; + } if(isNaN(key)){ - // associative array -> treat as image/value pairs - var btn = $('<button>'); - btn.attr('class', 'pickerbutton') - .attr('title', key); - - var ico = $('<img>'); - if (list[key].substr(0,1) == '/') { - var src = list[key]; - } else { - var src = DOKU_BASE+'lib/images/'+icobase+'/'+list[key]; + // associative array -> treat as text => image pairs + if (item.substr(0,1) !== '/') { + item = DOKU_BASE+'lib/images/'+props.icobase+'/'+item; } - - ico.attr('src', src); - btn.append(ico); - - btn.bind('click', bind(pickerInsert, key, edid)); - picker.append(btn); - }else if (typeof (list[key]) == 'string'){ + jQuery(document.createElement('img')) + .attr('src', item) + .appendTo($makebutton(key)); + }else if (typeof item == 'string'){ // a list of text -> treat as text picker - var btn = $('<button>'); - btn.attr('class', 'pickerbutton') - .attr('title', list[key]); - - var txt = $(document.createTextNode(list[key])); - btn.append(txt); - - btn.bind('click', bind(pickerInsert, list[key], edid)); - - picker.append(btn); + $makebutton(item).text(item); }else{ // a list of lists -> treat it as subtoolbar - initToolbar(picker,edid,list); - break; // all buttons handled already + initToolbar($picker,edid,props.list); + return false; // all buttons handled already } - } - var body = $('body'); - body.append(picker); + }); + jQuery('body').append($picker); - // we have to return a javascript object (for compatibility reasons) - return picker[0]; + // we have to return a DOM object (for compatibility reasons) + return $picker[0]; } /** @@ -147,9 +127,9 @@ function pickerInsert(text,edid){ * @return boolean If button should be appended * @author Gabriel Birke <birke@d-scribe.de> */ -function addBtnActionSignature(btn, props, edid) { - if(typeof(SIG) != 'undefined' && SIG != ''){ - btn.bind('click', bind(insertAtCarret,edid,SIG)); +function addBtnActionSignature($btn, props, edid) { + if(typeof SIG != 'undefined' && SIG != ''){ + $btn.bind('click', bind(insertAtCarret,edid,SIG)); return true; } return false; @@ -161,24 +141,27 @@ function addBtnActionSignature(btn, props, edid) { * @author Andreas Gohr <gohr@cosmocode.de> */ function currentHeadlineLevel(textboxId){ - var field = $(textboxId); - var selection = getSelection(field); - var search = "\n"+field.value.substr(0,selection.start); - var lasthl = search.lastIndexOf("\n=="); - if(lasthl == -1 && field.form.prefix){ + var field = jQuery('#' + textboxId)[0], + s = false, + opts = [field.value.substr(0,getSelection(field).start)]; + if (field.form.prefix) { // we need to look in prefix context - search = field.form.prefix.value; - lasthl = search.lastIndexOf("\n=="); + opts.push(field.form.prefix.value); } - search = search.substr(lasthl+1,6); - 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; + jQuery.each(opts, function (_, opt) { + // Check whether there is a headline in the given string + var str = "\n" + opt, + lasthl = str.lastIndexOf("\n=="); + if (lasthl !== -1) { + s = str.substr(lasthl+1,6); + return false; + } + }); + if (s === false) { + return 0; + } + return 7 - s.match(/^={2,6}/)[0].length; } @@ -191,21 +174,23 @@ window.textChanged = false; * Delete the draft before leaving the page */ function deleteDraft() { - if (is_opera) return; - if (window.keepDraft) return; + if (is_opera || window.keepDraft) { + return; + } - // remove a possibly saved draft using ajax - var dwform = jQuery('#dw__editform'); - if(dwform.length != 0) { - - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - { - call: 'draftdel', - id: jQuery('#dw__editform input[name=id]').val() - } - ); + var $dwform = jQuery('#dw__editform'); + + if($dwform.length === 0) { + return; } + + // remove a possibly saved draft using ajax + jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', + { + call: 'draftdel', + id: $dwform.find('input[name=id]').val() + } + ); } /** @@ -214,21 +199,24 @@ function deleteDraft() { * * Sets focus to the editbox as well */ -addInitEvent(function () { - var $ = jQuery; - var editform = $('#dw__editform'); - if (editform.length == 0) return; +jQuery(function () { + var $editform = jQuery('#dw__editform'); + if ($editform.length == 0) { + return; + } - var edit_text = $('#wiki__text'); - if (edit_text.length > 0) { - if(edit_text.attr('readOnly')) return; + var $edit_text = jQuery('#wiki__text'); + if ($edit_text.length > 0) { + if($edit_text.attr('readOnly')) { + return; + } // set focus and place cursor at the start - var sel = getSelection(edit_text.get(0)); + var sel = getSelection($edit_text[0]); sel.start = 0; sel.end = 0; setSelection(sel); - edit_text.focus(); + $edit_text.focus(); } var checkfunc = function() { @@ -236,8 +224,8 @@ addInitEvent(function () { summaryCheck(); }; - editform.change(checkfunc); - editform.keydown(checkfunc); + $editform.change(checkfunc); + $editform.keydown(checkfunc); window.onbeforeunload = function(){ if(window.textChanged) { @@ -247,13 +235,13 @@ addInitEvent(function () { window.onunload = deleteDraft; // reset change memory var on submit - $('#edbtn__save').click( + jQuery('#edbtn__save').click( function() { window.onbeforeunload = ''; textChanged = false; } ); - $('#edbtn__preview').click( + jQuery('#edbtn__preview').click( function() { window.onbeforeunload = ''; textChanged = false; @@ -261,9 +249,9 @@ addInitEvent(function () { } ); - var summary = $('#edit__summary'); - summary.change(summaryCheck); - summary.keyup(summaryCheck); + var $summary = jQuery('#edit__summary'); + $summary.change(summaryCheck); + $summary.keyup(summaryCheck); if (textChanged) summaryCheck(); }); @@ -274,11 +262,7 @@ addInitEvent(function () { * @author Andreas Gohr <andi@splitbrain.org> */ function summaryCheck(){ - var sum = jQuery('#edit__summary'); - - if (sum.val() === '') { - sum.attr('class', 'missing'); - } else{ - sum.attr('class', 'edit'); - } + var $sum = jQuery('#edit__summary'), + missing = $sum.val() === ''; + $sum.toggleClass('missing', missing).toggleClass('edit', !missing); } diff --git a/lib/scripts/editor.js b/lib/scripts/editor.js index 6d7f9f4a8..2009ce6af 100644 --- a/lib/scripts/editor.js +++ b/lib/scripts/editor.js @@ -15,11 +15,15 @@ var dw_editor = { */ init: function(){ var $editor = jQuery('#wiki__text'); - if(!$editor.length) return; + if($editor.length === 0) { + return; + } dw_editor.initSizeCtl('#size__ctl',$editor); - if($editor.attr('readOnly')) return; + if($editor.attr('readOnly')) { + return; + } // in Firefox, keypress doesn't send the correct keycodes, // in Opera, the default of keydown can't be prevented @@ -40,34 +44,30 @@ var dw_editor = { * @param selector editor the textarea to control */ initSizeCtl: function(ctlarea,editor){ - var $ctl = jQuery(ctlarea); - var $textarea = jQuery(editor); - if(!$ctl.length || !$textarea.length) return; - - var hgt = DokuCookie.getValue('sizeCtl'); - if(hgt){ - $textarea.css('height', hgt); - }else{ - $textarea.css('height', '300px'); + var $ctl = jQuery(ctlarea), + $textarea = jQuery(editor); + + if($ctl.length === 0 || $textarea.length === 0) { + return; } + $textarea.css('height', DokuCookie.getValue('sizeCtl') || '300px'); + var wrp = DokuCookie.getValue('wrapCtl'); if(wrp){ dw_editor.setWrap($textarea[0], wrp); } // else use default value - var l = document.createElement('img'); - var s = document.createElement('img'); - var w = document.createElement('img'); - l.src = DOKU_BASE+'lib/images/larger.gif'; - s.src = DOKU_BASE+'lib/images/smaller.gif'; - w.src = DOKU_BASE+'lib/images/wrap.gif'; - jQuery(l).click(function(){dw_editor.sizeCtl(editor,100);}); - jQuery(s).click(function(){dw_editor.sizeCtl(editor,-100);}); - jQuery(w).click(function(){dw_editor.toggleWrap(editor);}); - $ctl.append(l); - $ctl.append(s); - $ctl.append(w); + jQuery.each([ + ['larger', function(){dw_editor.sizeCtl(editor,100);}], + ['smaller', function(){dw_editor.sizeCtl(editor,-100);}], + ['wrap', function(){dw_editor.toggleWrap(editor);}], + ], function (_, img) { + jQuery(document.createElement('img')) + .attr('src', DOKU_BASE+'lib/images/' + img[0] + '.gif') + .click(img[1]) + .appendTo($ctl); + }); }, /** @@ -77,9 +77,8 @@ var dw_editor = { * @param int val the relative value to resize in pixel */ sizeCtl: function(editor,val){ - var $textarea = jQuery(editor); - var height = parseInt($textarea.css('height')); - height += val; + var $textarea = jQuery(editor), + height = parseInt($textarea.css('height')) + val; $textarea.css('height', height+'px'); DokuCookie.setValue('sizeCtl',$textarea.css('height')); }, @@ -91,13 +90,10 @@ var dw_editor = { * @param selector editor the textarea to control */ toggleWrap: function(editor){ - var $textarea = jQuery(editor); - var wrap = textarea.attr('wrap'); - if(wrap && wrap.toLowerCase() == 'off'){ - dw_editor.setWrap(textarea[0], 'soft'); - }else{ - dw_editor.setWrap(textarea[0], 'off'); - } + var $textarea = jQuery(editor), + wrap = $textarea.attr('wrap'); + dw_editor.setWrap($textarea[0], + (wrap && wrap.toLowerCase() == 'off') ? 'soft' : 'off'); DokuCookie.setValue('wrapCtl',$textarea.attr('wrap')); }, @@ -134,13 +130,14 @@ var dw_editor = { * @param event e - the key press event object */ keyHandler: function(e){ - if(e.keyCode != 13 && - e.keyCode != 8 && - e.keyCode != 32) return; - var field = e.target; - var selection = getSelection(field); - if(selection.getLength()) return; //there was text selected, keep standard behavior - var search = "\n"+field.value.substr(0,selection.start); + if([8, 13, 32].indexOf(e.keyCode) === -1) { + return; + } + var selection = getSelection(this); + if(selection.getLength() > 0) { + return; //there was text selected, keep standard behavior + } + var search = "\n"+this.value.substr(0,selection.start); var linestart = Math.max(search.lastIndexOf("\n"), search.lastIndexOf("\r")); //IE workaround search = search.substr(linestart); @@ -149,19 +146,19 @@ var dw_editor = { // keep current indention for lists and code var match = search.match(/(\n +([\*-] ?)?)/); if(match){ - var scroll = field.scrollHeight; + var scroll = this.scrollHeight; var match2 = search.match(/^\n +[\*-]\s*$/); // Cancel list if the last item is empty (i. e. two times enter) - if (match2 && field.value.substr(selection.start).match(/^($|\r?\n)/)) { - field.value = field.value.substr(0, linestart) + "\n" + - field.value.substr(selection.start); + if (match2 && this.value.substr(selection.start).match(/^($|\r?\n)/)) { + this.value = this.value.substr(0, linestart) + "\n" + + this.value.substr(selection.start); selection.start = linestart + 1; selection.end = linestart + 1; setSelection(selection); } else { - insertAtCarret(field.id,match[1]); + insertAtCarret(this.id,match[1]); } - field.scrollTop += (field.scrollHeight - scroll); + this.scrollTop += (this.scrollHeight - scroll); e.preventDefault(); // prevent enter key return false; } @@ -172,13 +169,13 @@ var dw_editor = { var spaces = match[1].length-1; if(spaces > 3){ // unindent one level - field.value = field.value.substr(0,linestart)+ - field.value.substr(linestart+2); + this.value = this.value.substr(0,linestart)+ + this.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); + this.value = this.value.substr(0,linestart)+ + this.value.substr(selection.start); selection.start = linestart; selection.end = linestart; } @@ -190,8 +187,8 @@ var dw_editor = { // intend list item var match = search.match(/(\n +)([*-] )$/); if(match){ - field.value = field.value.substr(0,linestart)+' '+ - field.value.substr(linestart); + this.value = this.value.substr(0,linestart)+' '+ + this.value.substr(linestart); selection.start = selection.start + 2; selection.end = selection.start; setSelection(selection); diff --git a/lib/scripts/index.js b/lib/scripts/index.js index 96d4e2fb9..4b67a0b12 100644 --- a/lib/scripts/index.js +++ b/lib/scripts/index.js @@ -1,6 +1,3 @@ -/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, newcap: true, immed: true */ -/*global jQuery, window, DOKU_BASE, DEPRECATED, bind*/ - var dw_index = jQuery('#index__tree').dw_tree({deferInit: true, load_data: function (show_sublist, $clicky) { jQuery.post( diff --git a/lib/scripts/linkwiz.js b/lib/scripts/linkwiz.js index 83653c9bb..6e0a00183 100644 --- a/lib/scripts/linkwiz.js +++ b/lib/scripts/linkwiz.js @@ -1,7 +1,3 @@ -/*jslint sloppy: true, indent: 4, white: true, browser: true, eqeq: true */ -/*global jQuery, DOKU_BASE, LANG, DOKU_UHC, getSelection, pasteText */ - - /** * The Link Wizard * @@ -10,7 +6,7 @@ */ var dw_linkwiz = { $wiz: null, - entry: null, + $entry: null, result: null, timer: null, textArea: null, @@ -28,12 +24,11 @@ var dw_linkwiz = { // create HTML Structure dw_linkwiz.$wiz = jQuery(document.createElement('div')) .attr('id','link__wiz') + .addClass('hidden_with_access_keys') .css({ 'position': 'absolute', 'top': (pos.top+20)+'px', - 'left': (pos.left+80)+'px', - 'margin-left': '-10000px', - 'margin-top': '-10000px' + 'left': (pos.left+80)+'px' }) .html( '<div id="link__wiz_header">'+ @@ -44,15 +39,19 @@ var dw_linkwiz = { ) .addClass('picker'); - $editor[0].form.parentNode.appendChild(dw_linkwiz.$wiz[0]); + $editor.parents('form').parent().append(dw_linkwiz.$wiz); dw_linkwiz.textArea = $editor[0]; dw_linkwiz.result = jQuery('#link__wiz_result')[0]; - dw_linkwiz.entry = jQuery('#link__wiz_entry')[0]; + + // scrollview correction on arrow up/down gets easier + jQuery(dw_linkwiz.result).css('position', 'relative'); + + dw_linkwiz.$entry = jQuery('#link__wiz_entry'); // attach event handlers jQuery('#link__wiz_close').click(dw_linkwiz.hide); - jQuery(dw_linkwiz.entry).keyup(dw_linkwiz.onEntry); - jQuery(dw_linkwiz.result).click(dw_linkwiz.onResultClick); + dw_linkwiz.$entry.keyup(dw_linkwiz.onEntry); + jQuery(dw_linkwiz.result).delegate('a', 'click', dw_linkwiz.onResultClick); dw_linkwiz.$wiz.draggable({handle: '#link__wiz_header'}); }, @@ -84,13 +83,12 @@ var dw_linkwiz = { } if(e.keyCode == 13){ //Enter if(dw_linkwiz.selected > -1){ - var obj = dw_linkwiz.getResult(dw_linkwiz.selected); - if(obj){ - var a = jQuery(obj).find('a')[0]; - dw_linkwiz.resultClick(a); + var $obj = dw_linkwiz.$getResult(dw_linkwiz.selected); + if($obj.length > 0){ + dw_linkwiz.resultClick($obj.find('a')[0]); } - }else if(dw_linkwiz.entry.value){ - dw_linkwiz.insertLink(dw_linkwiz.entry.value); + }else if(dw_linkwiz.$entry.val()){ + dw_linkwiz.insertLink(dw_linkwiz.$entry.val()); } e.preventDefault(); @@ -107,13 +105,18 @@ var dw_linkwiz = { * @returns DOMObject or null */ getResult: function(num){ - var childs = jQuery(dw_linkwiz.result).find('div'); - var obj = childs[num]; - if(obj){ - return obj; - }else{ - return null; - } + DEPRECATED('use dw_linkwiz.$getResult()[0] instead'); + return dw_linkwiz.$getResult()[0] || null; + }, + + /** + * Get one of the results by index + * + * @param int result div to return + * @returns jQuery object + */ + $getResult: function(num) { + return jQuery(dw_linkwiz.result).find('div').eq(num); }, /** @@ -125,26 +128,31 @@ var dw_linkwiz = { return; } - var obj = dw_linkwiz.getResult(num); - if(obj){ - dw_linkwiz.deselect(); - obj.className += ' selected'; - - // make sure the item is viewable in the scroll view - // FIXME check IE compatibility - if(obj.offsetTop > dw_linkwiz.result.scrollTop + dw_linkwiz.result.clientHeight){ - dw_linkwiz.result.scrollTop += obj.clientHeight; - }else if(obj.offsetTop - dw_linkwiz.result.clientHeight < dw_linkwiz.result.scrollTop){ // this works but isn't quite right, fixes welcome - dw_linkwiz.result.scrollTop -= obj.clientHeight; - } - // now recheck - if still not in view, the user used the mouse to scroll - if( (obj.offsetTop > dw_linkwiz.result.scrollTop + dw_linkwiz.result.clientHeight) || - (obj.offsetTop < dw_linkwiz.result.scrollTop) ){ - obj.scrollIntoView(); - } + var $obj = dw_linkwiz.$getResult(num); + if ($obj.length === 0) { + return; + } - dw_linkwiz.selected = num; + 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; }, /** @@ -152,10 +160,7 @@ var dw_linkwiz = { */ deselect: function(){ if(dw_linkwiz.selected > -1){ - var obj = dw_linkwiz.getResult(dw_linkwiz.selected); - if(obj){ - obj.className = obj.className.replace(/ ?selected/,''); - } + dw_linkwiz.$getResult(dw_linkwiz.selected).removeClass('selected'); } dw_linkwiz.selected = -1; }, @@ -165,10 +170,12 @@ var dw_linkwiz = { * resultClick() */ onResultClick: function(e){ - if(e.target.tagName != 'A') return; + if(!jQuery(this).is('a')) { + return; + } e.stopPropagation(); e.preventDefault(); - dw_linkwiz.resultClick(e.target); + dw_linkwiz.resultClick(this); return false; }, @@ -176,17 +183,14 @@ var dw_linkwiz = { * Handles the "click" on a given result anchor */ resultClick: function(a){ - var L = dw_linkwiz; - var id = a.title; - if(id == '' || id.substr(id.length-1) == ':'){ - L.entry.value = id; - L.autocomplete_exec(); + dw_linkwiz.$entry.val(a.title); + if(a.title == '' || a.title.substr(-1) == ':'){ + dw_linkwiz.autocomplete_exec(); }else{ - L.entry.value = id; - if(a.nextSibling && a.nextSibling.tagName == 'SPAN'){ - L.insertLink(a.nextSibling.innerHTML); + if (jQuery(a.nextSibling).is('span')) { + dw_linkwiz.insertLink(a.nextSibling.innerHTML); }else{ - L.insertLink(''); + dw_linkwiz.insertLink(''); } } }, @@ -198,14 +202,18 @@ var dw_linkwiz = { * as link title instead */ insertLink: function(title){ - var L = dw_linkwiz; - var E = L.entry; - if(!E.value) return; + var link = dw_linkwiz.$entry.val(), + sel, stxt; + if(!link) { + return; + } - var sel = getSelection(L.textArea); - if(sel.start == 0 && sel.end == 0) sel = L.selection; + sel = getSelection(dw_linkwiz.textArea); + if(sel.start == 0 && sel.end == 0) { + sel = dw_linkwiz.selection; + } - var stxt = sel.getText(); + stxt = sel.getText(); // don't include trailing space in selection if(stxt.charAt(stxt.length - 1) == ' '){ @@ -213,25 +221,29 @@ var dw_linkwiz = { stxt = sel.getText(); } - if(!stxt && !DOKU_UHC) stxt=title; + if(!stxt && !DOKU_UHC) { + stxt=title; + } // prepend colon inside namespaces for non namespace pages - if(L.textArea.form['id'].value.indexOf(':') != -1 && - E.value.indexOf(':') == -1){ - E.value = ':'+E.value; + if(dw_linkwiz.textArea.form.id.value.indexOf(':') != -1 && + link.indexOf(':') == -1){ + link = ':' + link; } - var link = '[['+E.value+'|'; - if(stxt) link += stxt; + var so = link.length+3; + + link = '[['+link+'|'; + if(stxt) { + link += stxt; + } link += ']]'; - var so = E.value.length+3; - var eo = 2; + pasteText(sel,link,{startofs: so, endofs: 2}); + dw_linkwiz.hide(); - pasteText(sel,link,{startofs: so, endofs: eo}); - L.hide(); - // reset the entry to the parent namespace and remove : at the beginning - E.value = E.value.replace(/(^:)?[^:]*$/, ''); + // reset the entry to the parent namespace + dw_linkwiz.$entry.val(dw_linkwiz.$entry.val().replace(/[^:]*$/, '')); }, /** @@ -252,21 +264,15 @@ var dw_linkwiz = { * Executes the AJAX call for the page/namespace lookup */ autocomplete_exec: function(){ + var $res = jQuery(dw_linkwiz.result); dw_linkwiz.deselect(); - dw_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( + $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.value - }, - function (data) { - dw_linkwiz.result.innerHTML = data; - }, - 'html' + q: dw_linkwiz.$entry.val() + } ); }, @@ -274,33 +280,28 @@ var dw_linkwiz = { * Show the link wizard */ show: function(){ - var L = dw_linkwiz; - L.selection = getSelection(dw_linkwiz.textArea); - L.$wiz.css('marginLeft', '0'); - L.$wiz.css('marginTop', '0'); - L.entry.focus(); - L.autocomplete(); + dw_linkwiz.selection = getSelection(dw_linkwiz.textArea); + dw_linkwiz.$wiz.removeClass('hidden_with_access_keys'); + dw_linkwiz.$entry.focus(); + dw_linkwiz.autocomplete(); }, /** * Hide the link wizard */ hide: function(){ - var L = dw_linkwiz; - L.$wiz.css('marginLeft', '-10000px'); - L.$wiz.css('marginTop', '-10000px'); - L.textArea.focus(); + dw_linkwiz.$wiz.addClass('hidden_with_access_keys'); + dw_linkwiz.textArea.focus(); }, /** * Toggle the link wizard */ toggle: function(){ - if(dw_linkwiz.$wiz.css('marginLeft') == '-10000px'){ + if(dw_linkwiz.$wiz.hasClass('hidden_with_access_keys')){ dw_linkwiz.show(); }else{ dw_linkwiz.hide(); } } - }; diff --git a/lib/scripts/media.js b/lib/scripts/media.js index f4064efd5..e3a000e99 100644 --- a/lib/scripts/media.js +++ b/lib/scripts/media.js @@ -1,6 +1,3 @@ -/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, strict: true, newcap: true, immed: true, sloppy: true, browser: true */ -/*global jQuery, DOKU_BASE, LANG, bind, DokuCookie, opener, confirm*/ - /** * JavaScript functionality for the media management popup * diff --git a/lib/scripts/qsearch.js b/lib/scripts/qsearch.js index f83b7a5a1..c7128b9e3 100644 --- a/lib/scripts/qsearch.js +++ b/lib/scripts/qsearch.js @@ -1,6 +1,3 @@ -/*jslint sloppy: true, plusplus: true, continue: true */ -/*global jQuery, DOKU_BASE, window, document, substr_replace */ - /** * AJAX functions for the pagename quicksearch * diff --git a/lib/scripts/script.js b/lib/scripts/script.js index 8db223d61..5fddb0431 100644 --- a/lib/scripts/script.js +++ b/lib/scripts/script.js @@ -48,8 +48,7 @@ function showLoadBar(){ * @author Andreas Gohr <andi@splitbrain.org> */ function hideLoadBar(id){ - obj = $(id); - if(obj) obj.style.display="none"; + jQuery('#' + id).hide(); } /** @@ -59,4 +58,6 @@ function closePopups(){ jQuery('div.JSpopup').hide(); } - +jQuery(function () { + jQuery(document).click(closePopups); +}); diff --git a/lib/scripts/textselection.js b/lib/scripts/textselection.js index 742338785..bd80e9341 100644 --- a/lib/scripts/textselection.js +++ b/lib/scripts/textselection.js @@ -22,8 +22,7 @@ function selection_class(){ }; this.getText = function(){ - if(!this.obj) return ''; - return this.obj.value.substring(this.start,this.end); + return (!this.obj) ? '' : this.obj.value.substring(this.start,this.end); }; } @@ -188,7 +187,7 @@ function pasteText(selection,text,opts){ * @author Andreas Gohr <andi@splitbrain.org> */ function insertTags(textAreaID, tagOpen, tagClose, sampleText){ - var txtarea = $(textAreaID); + var txtarea = jQuery('#' + textAreaID)[0]; var selection = getSelection(txtarea); var text = selection.getText(); @@ -227,7 +226,7 @@ function insertTags(textAreaID, tagOpen, tagClose, sampleText){ * @author Andreas Gohr <andi@splitbrain.org> */ function insertAtCarret(textAreaID, text){ - var txtarea = $(textAreaID); + var txtarea = jQuery('#' + textAreaID)[0]; var selection = getSelection(txtarea); pasteText(selection,text,{nosel: true}); } diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js index 2306ef5db..6cae9455a 100644 --- a/lib/scripts/toolbar.js +++ b/lib/scripts/toolbar.js @@ -1,4 +1,3 @@ - // used to identify pickers var pickercounter=0; @@ -12,62 +11,55 @@ var pickercounter=0; * @author Andreas Gohr <andi@splitbrain.org> */ function initToolbar(tbid,edid,tb, allowblock){ - var $ = jQuery; + var $toolbar, $edit; if (typeof tbid == 'string') { - var toolbar = $('#' + tbid); + $toolbar = jQuery('#' + tbid); } else { - var toolbar = $(tbid); + $toolbar = jQuery(tbid); } - if(toolbar.length == 0) return; - - var edit = $('#' + edid); - if(edit.length == 0) return; + $edit = jQuery('#' + edid); - if(edit.attr('readOnly')) return; + if ($toolbar.length == 0 || $edit.length == 0 || $edit.attr('readOnly')) { + return; + } if (typeof allowblock === 'undefined') { allowblock = true; } //empty the toolbar area: - toolbar.html(''); - - var cnt = tb.length; + $toolbar.html(''); - for(var i=0; i<cnt; i++){ - if (!allowblock && tb[i].block === true) { - continue; + jQuery.each(tb, function (k, val) { + if (!tb.hasOwnProperty(k) || (!allowblock && val.block === true)) { + return; } - var actionFunc; + var actionFunc, $btn; // create new button (jQuery object) - var btn = $(createToolButton(tb[i]['icon'], - tb[i]['title'], - tb[i]['key'], - tb[i]['id'], - tb[i]['class'])); + $btn = jQuery(createToolButton(val.icon, val.title, val.key, val.id, + val['class'])); // type is a tb function -> assign it as onclick - actionFunc = 'tb_'+tb[i]['type']; - if( $.isFunction(window[actionFunc]) ){ - btn.bind('click', bind(window[actionFunc],btn,tb[i],edid) ); - toolbar.append(btn); - continue; + actionFunc = 'tb_'+val.type; + if( jQuery.isFunction(window[actionFunc]) ){ + $btn.bind('click', bind(window[actionFunc],$btn,val,edid) ); + $toolbar.append($btn); + return; } // type is a init function -> execute it - actionFunc = 'addBtnAction'+tb[i]['type'].charAt(0).toUpperCase()+tb[i]['type'].substring(1); - if( $.isFunction(window[actionFunc]) ){ - if(window[actionFunc](btn, tb[i], edid)){ - toolbar.append(btn); + actionFunc = 'addBtnAction'+val.type.charAt(0).toUpperCase()+val.type.substring(1); + if( jQuery.isFunction(window[actionFunc]) ){ + if(window[actionFunc]($btn, val, edid)){ + $toolbar.append($btn); } - continue; + return; } - alert('unknown toolbar type: '+tb[i]['type']+' '+actionFunc); - } // end for - + alert('unknown toolbar type: '+val.type+' '+actionFunc); + }); } /** @@ -80,13 +72,10 @@ function initToolbar(tbid,edid,tb, allowblock){ * @author Andreas Gohr <andi@splitbrain.org> */ function tb_format(btn, props, edid) { - var sample = props['title']; - if(props['sample']){ - sample = props['sample']; - } + var sample = props.title || props.sample; insertTags(edid, - fixtxt(props['open']), - fixtxt(props['close']), + fixtxt(props.open), + fixtxt(props.close), fixtxt(sample)); pickerClose(); return false; @@ -105,30 +94,27 @@ function tb_format(btn, props, edid) { * @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 sample = props.title || props.sample, + opts, + selection = getSelection(jQuery('#'+edid)[0]); - props['open'] = fixtxt(props['open']); - props['close'] = fixtxt(props['close']); + sample = fixtxt(sample); + props.open = fixtxt(props.open); + props.close = fixtxt(props.close); // is something selected? - var opts; - var selection = getSelection($(edid)); if(selection.getLength()){ sample = selection.getText(); opts = {nosel: true}; }else{ opts = { - startofs: props['open'].length, - endofs: props['close'].length + startofs: props.open.length, + endofs: props.close.length }; } - sample = sample.split("\n").join(props['close']+"\n"+props['open']); - sample = props['open']+sample+props['close']; + sample = sample.split("\n").join(props.close+"\n"+props.open); + sample = props.open+sample+props.close; pasteText(selection,sample,opts); @@ -146,7 +132,7 @@ function tb_formatln(btn, props, edid) { * @author Andreas Gohr <andi@splitbrain.org> */ function tb_insert(btn, props, edid) { - insertAtCarret(edid,fixtxt(props['insert'])); + insertAtCarret(edid,fixtxt(props.insert)); pickerClose(); return false; } @@ -161,9 +147,9 @@ function tb_insert(btn, props, edid) { */ function tb_mediapopup(btn, props, edid) { window.open( - DOKU_BASE+props['url']+encodeURIComponent(NS)+'&edid='+encodeURIComponent(edid), - props['name'], - props['options']); + DOKU_BASE+props.url+encodeURIComponent(NS)+'&edid='+encodeURIComponent(edid), + props.name, + props.options); return false; } @@ -178,16 +164,16 @@ function tb_mediapopup(btn, props, edid) { * @author Andreas Gohr <andi@splitbrain.org> */ function tb_autohead(btn, props, edid){ - var lvl = currentHeadlineLevel(edid); + var lvl = currentHeadlineLevel(edid), + tags; // determine new level - lvl += props['mod']; + lvl += props.mod; if(lvl < 1) lvl = 1; if(lvl > 5) lvl = 5; - var tags = '='; - for(var i=0; i<=5-lvl; i++) tags += '='; - insertTags(edid, tags+' ', ' '+tags+"\n", props['text']); + tags = (new Array(8 - lvl)).join('='); + insertTags(edid, tags+' ', ' '+tags+"\n", props.text); pickerClose(); return false; } @@ -196,19 +182,19 @@ function tb_autohead(btn, props, edid){ /** * Add button action for picker buttons and create picker element * - * @param DOMElement btn Button element to add the action to + * @param jQuery btn Button element to add the action to * @param array props Associative array of button properties * @param string edid ID of the editor textarea * @return boolean If button should be appended * @author Gabriel Birke <birke@d-scribe.de> */ -function addBtnActionPicker(btn, props, edid) { +function addBtnActionPicker($btn, props, edid) { var pickerid = 'picker'+(pickercounter++); createPicker(pickerid, props, edid); - btn.click( + $btn.click( function() { - pickerToggle(pickerid,btn); + pickerToggle(pickerid,$btn); return false; } ); @@ -240,20 +226,11 @@ function addBtnActionLinkwiz(btn, props, edid) { * * @author Andreas Gohr <andi@splitbrain.org> */ -function pickerToggle(pickerid,btn){ - var picker = jQuery('#' + pickerid); - if (picker.css('marginLeft') == '-10000px'){ - var x = findPosX(btn[0]); - var y = findPosY(btn[0]); - - picker.css('left',(x+3)+'px') - .css('top', (y+btn[0].offsetHeight+3)+'px') - .css('marginLeft', '0px') - .css('marginTop', '0px'); - } else { - picker.css('marginLeft', '-10000px') - .css('marginTop', '-10000px'); - } +function pickerToggle(pickerid,$btn){ + var $picker = jQuery('#' + pickerid), + pos = $btn.offset(); + $picker.toggleClass('hidden_with_access_keys') + .offset({left: pos.left+3, top: pos.top+$btn[0].offsetHeight+3}); } /** @@ -262,11 +239,7 @@ function pickerToggle(pickerid,btn){ * @author Andreas Gohr <andi@splitbrain.org> */ function pickerClose(){ - var pobjs = jQuery('#picker'); - for(var i=0; i<pobjs.length; i++){ - pobjs[i].css('marginLeft', '-10000px') - .css('marginTop', '-10000px'); - } + jQuery('.picker').addClass('hidden_with_access_keys'); } @@ -277,3 +250,6 @@ function fixtxt(str){ return str.replace(/\\n/g,"\n"); } +jQuery(function () { + initToolbar('tool__bar','wiki__text',toolbar); +}); diff --git a/lib/scripts/tree.js b/lib/scripts/tree.js index 98d3f55d4..96763053d 100644 --- a/lib/scripts/tree.js +++ b/lib/scripts/tree.js @@ -1,6 +1,3 @@ -/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, newcap: true, immed: true, sloppy: true */ -/*global jQuery, window, DOKU_BASE, DEPRECATED, bind*/ - jQuery.fn.dw_tree = function(overrides) { var dw_tree = { diff --git a/lib/styles/screen.css b/lib/styles/screen.css index 80a161f19..6664c2102 100644 --- a/lib/styles/screen.css +++ b/lib/styles/screen.css @@ -87,3 +87,8 @@ div.notify { .code .st0 { color: #ff0000; } .code .sy0 { color: #66cc66; } +.hidden_with_access_keys { + /* No display: none to keep accesskeys working */ + margin-left: -10000px !important; + margin-top: -10000px !important; +} -- GitLab