diff options
Diffstat (limited to 'lib/scripts')
-rw-r--r-- | lib/scripts/behaviour.js | 125 | ||||
-rw-r--r-- | lib/scripts/compatibility.js | 273 | ||||
-rw-r--r-- | lib/scripts/cookie.js | 71 | ||||
-rw-r--r-- | lib/scripts/delay.js | 1 | ||||
-rw-r--r-- | lib/scripts/edit.js | 88 | ||||
-rw-r--r-- | lib/scripts/editor.js | 127 | ||||
-rw-r--r-- | lib/scripts/events.js | 50 | ||||
-rw-r--r-- | lib/scripts/helpers.js | 165 | ||||
-rw-r--r-- | lib/scripts/jquery/jquery.cookie.js | 111 | ||||
-rw-r--r-- | lib/scripts/locktimer.js | 110 | ||||
-rw-r--r-- | lib/scripts/media.js | 4 | ||||
-rw-r--r-- | lib/scripts/page.js | 141 | ||||
-rw-r--r-- | lib/scripts/script.js | 292 | ||||
-rw-r--r-- | lib/scripts/subscriptions.js | 38 |
14 files changed, 738 insertions, 858 deletions
diff --git a/lib/scripts/behaviour.js b/lib/scripts/behaviour.js index f3fcccdfe..cfdc89157 100644 --- a/lib/scripts/behaviour.js +++ b/lib/scripts/behaviour.js @@ -1,6 +1,3 @@ -/*jslint sloppy: true */ -/*global jQuery, LANG, document, alert */ - /** * Automatic behaviours * @@ -13,11 +10,15 @@ var dw_behaviour = { init: function(){ dw_behaviour.focusMarker(); dw_behaviour.scrollToMarker(); - dw_behaviour.closeMsgOnClick(); dw_behaviour.removeHighlightOnClick(); dw_behaviour.quickSelect(); dw_behaviour.checkWindowsShares(); - dw_behaviour.initTocToggle(); + dw_behaviour.subscription(); + + dw_behaviour.revisionBoxHandler(); + jQuery('#page__revisions input[type=checkbox]').click( + dw_behaviour.revisionBoxHandler + ); }, /** @@ -38,17 +39,6 @@ var dw_behaviour = { }, /** - * Close messages shown by the msg() PHP function by click - */ - closeMsgOnClick: function(){ - jQuery('div.success, div.info, div.error, div.notify').click( - function(e){ - jQuery(e.target).fadeOut('fast'); - } - ); - }, - - /** * Remove all search highlighting when clicking on a highlighted term * * @FIXME would be nice to have it fade out @@ -95,52 +85,97 @@ var dw_behaviour = { }, /** - * Adds the toggle switch to the TOC + * Hide list subscription style if target is a page + * + * @author Adrian Lang <lang@cosmocode.de> + * @author Pierre Spring <pierre.spring@caillou.ch> */ - initTocToggle: function() { - var $header = jQuery('#toc__header'); - if(!$header.length) return; - var $toc = jQuery('#toc__inside'); - - var $clicky = jQuery(document.createElement('span')) - .attr('id','toc__toggle') - .css('cursor','pointer') - .click(function(){ - $toc.slideToggle(); - setClicky(); - }); - $header.prepend($clicky); - - var setClicky = function(){ - if($toc.css('display') == 'none'){ - $clicky.html('<span>+</span>'); - $clicky[0].className = 'toc_open'; - }else{ - $clicky.html('<span>−</span>'); - $clicky[0].className = 'toc_close'; - } - }; + subscription: function(){ + var $form, $list, $digest; + + $form = jQuery('#subscribe__form'); + if (0 === $form.length) return; + + $list = $form.find("input[name='sub_style'][value='list']"); + $digest = $form.find("input[name='sub_style'][value='digest']"); + + $form.find("input[name='sub_target']") + .click( + function () { + var $this = jQuery(this), show_list; + if (!$this.prop('checked')) { + return; + } + + show_list = $this.val().match(/:$/); + $list.parent().dw_toggle(show_list); + if (!show_list && $list.prop('checked')) { + $digest.prop('checked', 'checked'); + } + } + ) + .filter(':checked') + .click(); + }, - setClicky(); + /** + * disable multiple revisions checkboxes if two are checked + * + * @author Andreas Gohr <andi@splitbrain.org> + */ + revisionBoxHandler: function(){ + var $checked = jQuery('#page__revisions input[type=checkbox]:checked'); + var $all = jQuery('#page__revisions input[type=checkbox]'); + + if($checked.length < 2){ + $all.attr('disabled',false); + jQuery('#page__revisions input[type=submit]').attr('disabled',true); + }else{ + $all.attr('disabled',true); + jQuery('#page__revisions input[type=submit]').attr('disabled',false); + for(var i=0; i<$checked.length; i++){ + $checked[i].disabled = false; + if(i>1){ + $checked[i].checked = false; + } + } + } } }; +/** + * Hides elements with a slide animation + * + * @param fn optional callback to run after hiding + * @author Adrian Lang <mail@adrianlang.de> + */ jQuery.fn.dw_hide = function(fn) { return this.slideUp('fast', fn); }; -jQuery.fn.dw_show = function() { - return this.slideDown('fast'); +/** + * Unhides elements with a slide animation + * + * @param fn optional callback to run after hiding + * @author Adrian Lang <mail@adrianlang.de> + */ +jQuery.fn.dw_show = function(fn) { + return this.slideDown('fast', fn); }; -jQuery.fn.dw_toggle = function(bool) { +/** + * Toggles visibility of an element using a slide element + * + * @param bool the current state of the element (optional) + */ +jQuery.fn.dw_toggle = function(bool, fn) { return this.each(function() { var $this = jQuery(this); if (typeof bool === 'undefined') { bool = $this.is(':hidden'); } - $this[bool ? "dw_show" : "dw_hide" ](); + $this[bool ? "dw_show" : "dw_hide" ](fn); }); }; diff --git a/lib/scripts/compatibility.js b/lib/scripts/compatibility.js index 27347972a..39f703c71 100644 --- a/lib/scripts/compatibility.js +++ b/lib/scripts/compatibility.js @@ -1,5 +1,74 @@ -/*jslint sloppy: true */ -/*global dw_index, dw_qsearch, DEPRECATED_WRAP */ +/** + * Mark a JavaScript function as deprecated + * + * This will print a warning to the JavaScript console (if available) in + * Firebug and Chrome and a stack trace (if available) to easily locate the + * problematic function call. + * + * @param msg optional message to print + */ +function DEPRECATED(msg){ + if(!window.console) return; + if(!msg) msg = ''; + + var func; + if(arguments.callee) func = arguments.callee.caller.name; + if(func) func = ' '+func+'()'; + var line = 'DEPRECATED function call'+func+'. '+msg; + + if(console.warn){ + console.warn(line); + }else{ + console.log(line); + } + + if(console.trace) console.trace(); +} + +/** + * Construct a wrapper function for deprecated function names + * + * This function returns a wrapper function which just calls DEPRECATED + * and the new function. + * + * @param func The new function + * @param context Optional; The context (`this`) of the call + */ +function DEPRECATED_WRAP(func, context) { + return function () { + DEPRECATED(); + return func.apply(context || this, arguments); + } +} + +/** + * Handy shortcut to document.getElementById + * + * This function was taken from the prototype library + * + * @link http://prototype.conio.net/ + */ +function $() { + DEPRECATED('Please use the JQuery() function instead.'); + + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} + + + var index = { throbber_delay: dw_index.throbber_delay, @@ -99,6 +168,7 @@ function findPosY(object){ function getElementsByClass(searchClass,node,tag){ DEPRECATED('Use jQuery() instead'); if(node == null) node = document; + if(typeof tag === 'undefined') tag = ''; return jQuery(node).find(tag+'.'+searchClass).toArray(); } @@ -107,3 +177,202 @@ function prependChild(parent,element) { jQuery(parent).prepend(element); } +function addEvent(element, type, handler) { + DEPRECATED('Use jQuery.bind() instead.'); + jQuery(element).bind(type,{},handler); +} + +function removeEvent(element, type, handler) { + DEPRECATED('Use jQuery.unbind() instead.'); + jQuery(element).unbind(type,handler); +} + +function addInitEvent(func) { + DEPRECATED('Use jQuery(<function>) instead'); + jQuery(func); +} + + +function jsEscape(text){ + DEPRECATED('Insert text through jQuery.text() instead of escaping on your own'); + var re=new RegExp("\\\\","g"); + text=text.replace(re,"\\\\"); + re=new RegExp("'","g"); + text=text.replace(re,"\\'"); + re=new RegExp('"',"g"); + text=text.replace(re,'"'); + re=new RegExp("\\\\\\\\n","g"); + text=text.replace(re,"\\n"); + return text; +} + +/** + * Simple function to check if a global var is defined + * + * @author Kae Verens + * @link http://verens.com/archives/2005/07/25/isset-for-javascript/#comment-2835 + */ +function isset(varname){ + DEPRECATED("Use `typeof var !== 'undefined'` instead"); + return(typeof(window[varname])!='undefined'); +} + +/** + * Checks if property is undefined + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isUndefined (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'undefined'` instead"); + return (typeof prop == 'undefined'); +} + +/** + * Checks if property is function + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isFunction (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'function'` instead"); + return (typeof prop == 'function'); +} +/** + * Checks if property is string + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isString (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'string'` instead"); + return (typeof prop == 'string'); +} + +/** + * Checks if property is number + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isNumber (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'number'` instead"); + return (typeof prop == 'number'); +} + +/** + * Checks if property is the calculable number + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isNumeric (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'number' && !isNaN(var) && isFinite(var)` instead"); + return isNumber(prop)&&!isNaN(prop)&&isFinite(prop); +} + +/** + * Checks if property is array + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isArray (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `var instanceof Array` instead"); + return (prop instanceof Array); +} + +/** + * Checks if property is regexp + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isRegExp (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `var instanceof RegExp` instead"); + return (prop instanceof RegExp); +} + +/** + * Checks if property is a boolean value + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isBoolean (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'boolean'` instead"); + return ('boolean' == typeof prop); +} + +/** + * Checks if property is a scalar value (value that could be used as the hash key) + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isScalar (prop /* :Object */) /* :Boolean */ { + DEPRECATED("Use `typeof var === 'string' || (typeof var === 'number' &&" + + " !isNaN(var) && isFinite(var))` instead"); + return isNumeric(prop)||isString(prop); +} + +/** + * Checks if property is empty + * + * @param {Object} prop value to check + * @return {Boolean} true if matched + * @scope public + * @author Ilya Lebedev <ilya@lebedev.net> + */ +function isEmpty (prop /* :Object */) /* :Boolean */ { + DEPRECATED(); + var i; + if (isBoolean(prop)) { + return false; + } else if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) { + return true; + } else if (isString(prop) || isNumber(prop)) { + return !prop; + } else if (Boolean(prop) && false != prop) { + for (i in prop) { + if(prop.hasOwnProperty(i)) { + return false; + } + } + } + return true; +} + +/** + * Get the computed style of a node. + * + * @link https://acidmartin.wordpress.com/2008/08/26/style-get-any-css-property-value-of-an-object/ + * @link http://svn.dojotoolkit.org/src/dojo/trunk/_base/html.js + */ +function gcs(node){ + DEPRECATED('Use jQuery(node).style() instead'); + if(node.currentStyle){ + return node.currentStyle; + }else{ + return node.ownerDocument.defaultView.getComputedStyle(node, null); + } +} + diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js index e7ba620c7..3f3375fa7 100644 --- a/lib/scripts/cookie.js +++ b/lib/scripts/cookie.js @@ -2,7 +2,7 @@ * Handles the cookie used by several JavaScript functions * * Only a single cookie is written and read. You may only save -* sime name-value pairs - no complex types! +* simple name-value pairs - no complex types! * * You should only use the getValue and setValue methods * @@ -10,7 +10,7 @@ * @author Michal Rezler <m.rezler@centrum.cz> */ DokuCookie = { - data: Array(), + data: {}, name: 'DOKU_PREFS', /** @@ -19,21 +19,17 @@ DokuCookie = { * @author Andreas Gohr <andi@splitbrain.org> */ setValue: function(key,val){ + var text = ''; this.init(); this.data[key] = val; - // prepare expire date - var now = new Date(); - this.fixDate(now); - now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); //expire in a year - //save the whole data array - var text = ''; - for(var key in this.data){ - if (!this.data.hasOwnProperty(key)) continue; - text += '#'+escape(key)+'#'+this.data[key]; + jQuery.each(this.data, function (val, key) { + if (this.data.hasOwnProperty(key)) { + text += '#'+encodeURIComponent(key)+'#'+encodeURIComponent(val); } - this.setCookie(this.name,text.substr(1),now,DOKU_BASE); + }); + jQuery.cookie(this.name,text.substr(1), {expires: 365, path: DOKU_BASE}); }, /** @@ -52,51 +48,16 @@ DokuCookie = { * @author Andreas Gohr <andi@splitbrain.org> */ init: function(){ - if(this.data.length) return; - var text = this.getCookie(this.name); + var text, parts, i; + if(!jQuery.isEmptyObject(this.data)) { + return; + } + text = jQuery.cookie(this.name); if(text){ - var parts = text.split('#'); - for(var i=0; i<parts.length; i+=2){ - this.data[unescape(parts[i])] = unescape(parts[i+1]); + parts = text.split('#'); + for(i = 0; i < parts.length; i += 2){ + this.data[decodeURIComponent(parts[i])] = decodeURIComponent(parts[i+1]); } } - }, - - /** - * This sets a cookie by JavaScript - * - * @link http://www.webreference.com/js/column8/functions.html - */ - setCookie: function(name, value, expires_, path_, domain_, secure_) { - var params = { - expires: expires_, - path: path_, - domain: domain_, - secure: secure_ - }; - - jQuery.cookie(name, value, params); - }, - - /** - * This reads a cookie by JavaScript - * - * @link http://www.webreference.com/js/column8/functions.html - */ - getCookie: function(name) { - return unescape(jQuery.cookie(name)); - }, - - /** - * This is needed for the cookie functions - * - * @link http://www.webreference.com/js/column8/functions.html - */ - fixDate: function(date) { - var base = new Date(0); - var skew = base.getTime(); - if (skew > 0){ - date.setTime(date.getTime() - skew); } - } }; diff --git a/lib/scripts/delay.js b/lib/scripts/delay.js index 2ef9f8846..edd53def3 100644 --- a/lib/scripts/delay.js +++ b/lib/scripts/delay.js @@ -51,6 +51,7 @@ Delay.prototype = { }, start: function () { + DEPRECATED('don\'t use the Delay object, use window.timeout with a callback instead'); this.delTimer(); var _this = this; this.timer = timer.add(function () { _this.exec.call(_this); }, diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js index a9623e14d..816568e92 100644 --- a/lib/scripts/edit.js +++ b/lib/scripts/edit.js @@ -156,86 +156,6 @@ function addBtnActionSignature(btn, props, edid) { } /** - * 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 - */ -function keyHandler(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); - var linestart = Math.max(search.lastIndexOf("\n"), - search.lastIndexOf("\r")); //IE workaround - search = search.substr(linestart); - - - if(e.keyCode == 13){ // Enter - // keep current indention for lists and code - var match = search.match(/(\n +([\*-] ?)?)/); - if(match){ - var scroll = field.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); - selection.start = linestart + 1; - selection.end = linestart + 1; - setSelection(selection); - } else { - insertAtCarret(field.id,match[1]); - } - field.scrollTop += (field.scrollHeight - scroll); - e.preventDefault(); // prevent enter key - return false; - } - }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 - return false; - } - }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 - return false; - } - } -} - -/** * Determine the current section level while editing * * @author Andreas Gohr <gohr@cosmocode.de> @@ -303,14 +223,6 @@ addInitEvent(function () { if (edit_text.length > 0) { if(edit_text.attr('readOnly')) return; - // in Firefox, keypress doesn't send the correct keycodes, - // in Opera, the default of keydown can't be prevented - if (is_opera) { - edit_text.keypress(keyHandler); - } else { - edit_text.keydown(keyHandler); - } - // set focus and place cursor at the start var sel = getSelection(edit_text.get(0)); sel.start = 0; diff --git a/lib/scripts/editor.js b/lib/scripts/editor.js index fbdb1d79a..6d7f9f4a8 100644 --- a/lib/scripts/editor.js +++ b/lib/scripts/editor.js @@ -14,10 +14,21 @@ var dw_editor = { * textareas */ init: function(){ - var editor = jQuery('#wiki__text'); - if(!editor.length) return; + var $editor = jQuery('#wiki__text'); + if(!$editor.length) return; + + dw_editor.initSizeCtl('#size__ctl',$editor); + + if($editor.attr('readOnly')) return; + + // in Firefox, keypress doesn't send the correct keycodes, + // in Opera, the default of keydown can't be prevented + if (jQuery.browser.opera) { + $editor.keypress(dw_editor.keyHandler); + } else { + $editor.keydown(dw_editor.keyHandler); + } - dw_editor.initSizeCtl('#size__ctl',editor); }, /** @@ -29,20 +40,20 @@ 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 $ctl = jQuery(ctlarea); + var $textarea = jQuery(editor); + if(!$ctl.length || !$textarea.length) return; var hgt = DokuCookie.getValue('sizeCtl'); if(hgt){ - textarea.css('height', hgt); + $textarea.css('height', hgt); }else{ - textarea.css('height', '300px'); + $textarea.css('height', '300px'); } var wrp = DokuCookie.getValue('wrapCtl'); if(wrp){ - dw_editor.setWrap(textarea[0], wrp); + dw_editor.setWrap($textarea[0], wrp); } // else use default value var l = document.createElement('img'); @@ -54,9 +65,9 @@ var dw_editor = { 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); + $ctl.append(l); + $ctl.append(s); + $ctl.append(w); }, /** @@ -66,11 +77,11 @@ 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')); + var $textarea = jQuery(editor); + var height = parseInt($textarea.css('height')); height += val; - textarea.css('height', height+'px'); - DokuCookie.setValue('sizeCtl',textarea.css('height')); + $textarea.css('height', height+'px'); + DokuCookie.setValue('sizeCtl',$textarea.css('height')); }, /** @@ -80,14 +91,14 @@ var dw_editor = { * @param selector editor the textarea to control */ toggleWrap: function(editor){ - var textarea = jQuery(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'); } - DokuCookie.setValue('wrapCtl',textarea.attr('wrap')); + DokuCookie.setValue('wrapCtl',$textarea.attr('wrap')); }, /** @@ -108,6 +119,86 @@ var dw_editor = { var nxtSib = textarea.nextSibling; parNod.removeChild(textarea); parNod.insertBefore(textarea, nxtSib); + }, + + /** + * 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 + * @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); + var linestart = Math.max(search.lastIndexOf("\n"), + search.lastIndexOf("\r")); //IE workaround + search = search.substr(linestart); + + if(e.keyCode == 13){ // Enter + // keep current indention for lists and code + var match = search.match(/(\n +([\*-] ?)?)/); + if(match){ + var scroll = field.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); + selection.start = linestart + 1; + selection.end = linestart + 1; + setSelection(selection); + } else { + insertAtCarret(field.id,match[1]); + } + field.scrollTop += (field.scrollHeight - scroll); + e.preventDefault(); // prevent enter key + return false; + } + }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 + return false; + } + }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 + return false; + } + } } diff --git a/lib/scripts/events.js b/lib/scripts/events.js deleted file mode 100644 index 796d3cc4c..000000000 --- a/lib/scripts/events.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * The event functions are no longer in use and a mere wrapper around - * jQuery's event handlers. - * - * @deprecated - */ -function addEvent(element, type, handler) { - DEPRECATED('Use jQuery.bind() instead.'); - jQuery(element).bind(type,{},handler); -} - -function removeEvent(element, type, handler) { - DEPRECATED('Use jQuery.unbind() instead.'); - jQuery(element).unbind(type,handler); -} - -function addInitEvent(func) { - DEPRECATED('Use jQuery(<function>) instead'); - jQuery(func); -} - -/** - * Bind variables to a function call creating a closure - * - * Use this to circumvent variable scope problems when creating closures - * inside a loop - * - * @author Adrian Lang <lang@cosmocode.de> - * @fixme Is there a jQuery equivalent? Otherwise move to somewhere else - * @link http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops - * @param functionref fnc - the function to be called - * @param mixed - any arguments to be passed to the function - * @returns functionref - */ -function bind(fnc/*, ... */) { - var Aps = Array.prototype.slice; - // Store passed arguments in this scope. - // Since arguments is no Array nor has an own slice method, - // we have to apply the slice method from the Array.prototype - var static_args = Aps.call(arguments, 1); - - // Return a function evaluating the passed function with the - // given args and optional arguments passed on invocation. - return function (/* ... */) { - // Same here, but we use Array.prototype.slice solely for - // converting arguments to an Array. - return fnc.apply(this, - static_args.concat(Aps.call(arguments, 0))); - }; -} diff --git a/lib/scripts/helpers.js b/lib/scripts/helpers.js index 77e7ffc4a..d6f36967d 100644 --- a/lib/scripts/helpers.js +++ b/lib/scripts/helpers.js @@ -1,134 +1,11 @@ /** - * Differrent helper functions - * - * @author Ilya Lebedev <ilya@lebedev.net> - * @license LGPL - */ -//----------------------------------------------------------------------------- -// Variable/property checks -//----------------------------------------------------------------------------- -/** - * Checks if property is undefined - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isUndefined (prop /* :Object */) /* :Boolean */ { - return (typeof prop == 'undefined'); -} -/** - * Checks if property is function - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isFunction (prop /* :Object */) /* :Boolean */ { - return (typeof prop == 'function'); -} -/** - * Checks if property is string - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isString (prop /* :Object */) /* :Boolean */ { - return (typeof prop == 'string'); -} -/** - * Checks if property is number - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isNumber (prop /* :Object */) /* :Boolean */ { - return (typeof prop == 'number'); -} -/** - * Checks if property is the calculable number - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isNumeric (prop /* :Object */) /* :Boolean */ { - return isNumber(prop)&&!isNaN(prop)&&isFinite(prop); -} -/** - * Checks if property is array - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isArray (prop /* :Object */) /* :Boolean */ { - return (prop instanceof Array); -} -/** - * Checks if property is regexp - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isRegExp (prop /* :Object */) /* :Boolean */ { - return (prop instanceof RegExp); -} -/** - * Checks if property is a boolean value - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isBoolean (prop /* :Object */) /* :Boolean */ { - return ('boolean' == typeof prop); -} -/** - * Checks if property is a scalar value (value that could be used as the hash key) - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public + * Various helper functions */ -function isScalar (prop /* :Object */) /* :Boolean */ { - return isNumeric(prop)||isString(prop); -} -/** - * Checks if property is empty - * - * @param {Object} prop value to check - * @return {Boolean} true if matched - * @scope public - */ -function isEmpty (prop /* :Object */) /* :Boolean */ { - if (isBoolean(prop)) return false; - if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) return true; - if (isString(prop) || isNumber(prop)) return !prop; - if (Boolean(prop)&&false != prop) { - for (var i in prop) if(prop.hasOwnProperty(i)) return false; - } - return true; -} - -/** - * Checks if property is derived from prototype, applies method if it is not exists - * - * @param string property name - * @return bool true if prototyped - * @access public - */ -if ('undefined' == typeof Object.hasOwnProperty) { - Object.prototype.hasOwnProperty = function (prop) { - return !('undefined' == typeof this[prop] || this.constructor && this.constructor.prototype[prop] && this[prop] === this.constructor.prototype[prop]); - }; -} /** * Very simplistic Flash plugin check, probably works for Flash 8 and higher only + * + * @author Andreas Gohr <andi@splitbrain.org> */ function hasFlash(version){ var ver = 0; @@ -136,13 +13,12 @@ function hasFlash(version){ if(navigator.plugins != null && navigator.plugins.length > 0){ ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0]; }else{ - var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); - ver = axo.GetVariable("$version").split(' ')[1].split(',')[0]; + ver = (new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) + .GetVariable("$version").split(' ')[1].split(',')[0]; } }catch(e){ } - if(ver >= version) return true; - return false; + return ver >= version; } /** @@ -163,3 +39,32 @@ function substr_replace(str, replace, start, length) { b1 = (length < 0 ? str.length : a2) + length; return str.substring(0, a2) + replace + str.substring(b1); } + +/** + * Bind variables to a function call creating a closure + * + * Use this to circumvent variable scope problems when creating closures + * inside a loop + * + * @author Adrian Lang <lang@cosmocode.de> + * @link http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops + * @param functionref fnc - the function to be called + * @param mixed - any arguments to be passed to the function + * @returns functionref + */ +function bind(fnc/*, ... */) { + var Aps = Array.prototype.slice, + // Store passed arguments in this scope. + // Since arguments is no Array nor has an own slice method, + // we have to apply the slice method from the Array.prototype + static_args = Aps.call(arguments, 1); + + // Return a function evaluating the passed function with the + // given args and optional arguments passed on invocation. + return function (/* ... */) { + // Same here, but we use Array.prototype.slice solely for + // converting arguments to an Array. + return fnc.apply(this, + static_args.concat(Aps.call(arguments, 0))); + }; +} diff --git a/lib/scripts/jquery/jquery.cookie.js b/lib/scripts/jquery/jquery.cookie.js index 6df1faca2..6a3e394b4 100644 --- a/lib/scripts/jquery/jquery.cookie.js +++ b/lib/scripts/jquery/jquery.cookie.js @@ -1,96 +1,41 @@ /** - * Cookie plugin + * jQuery Cookie plugin * - * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Copyright (c) 2010 Klaus Hartl (stilbuero.de) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ +jQuery.cookie = function (key, value, options) { -/** - * Create a cookie with the given name and value and other optional parameters. - * - * @example $.cookie('the_cookie', 'the_value'); - * @desc Set the value of a cookie. - * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); - * @desc Create a cookie with all available options. - * @example $.cookie('the_cookie', 'the_value'); - * @desc Create a session cookie. - * @example $.cookie('the_cookie', null); - * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain - * used when the cookie was set. - * - * @param String name The name of the cookie. - * @param String value The value of the cookie. - * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. - * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. - * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. - * If set to null or omitted, the cookie will be a session cookie and will not be retained - * when the the browser exits. - * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). - * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). - * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will - * require a secure protocol (like HTTPS). - * @type undefined - * - * @name $.cookie - * @cat Plugins/Cookie - * @author Klaus Hartl/klaus.hartl@stilbuero.de - */ + // key and at least value given, set cookie... + if (arguments.length > 1 && String(value) !== "[object Object]") { + options = jQuery.extend({}, options); -/** - * Get the value of a cookie with the given name. - * - * @example $.cookie('the_cookie'); - * @desc Get the value of a cookie. - * - * @param String name The name of the cookie. - * @return The value of the cookie. - * @type String - * - * @name $.cookie - * @cat Plugins/Cookie - * @author Klaus Hartl/klaus.hartl@stilbuero.de - */ -jQuery.cookie = function(name, value, options) { - if (typeof value != 'undefined') { // name and value given, set cookie - options = options || {}; - if (value === null) { - value = ''; + if (value === null || value === undefined) { options.expires = -1; } - var expires = ''; - if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { - var date; - if (typeof options.expires == 'number') { - date = new Date(); - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); - } else { - date = options.expires; - } - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE - } - // CAUTION: Needed to parenthesize options.path and options.domain - // in the following expressions, otherwise they evaluate to undefined - // in the packed version for some reason... - var path = options.path ? '; path=' + (options.path) : ''; - var domain = options.domain ? '; domain=' + (options.domain) : ''; - var secure = options.secure ? '; secure' : ''; - document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); - } else { // only name given, get cookie - var cookieValue = null; - if (document.cookie && document.cookie != '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = jQuery.trim(cookies[i]); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) == (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setDate(t.getDate() + days); } - return cookieValue; + + value = String(value); + + return (document.cookie = [ + encodeURIComponent(key), '=', + options.raw ? value : encodeURIComponent(value), + options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + options.secure ? '; secure' : '' + ].join('')); } -};
\ No newline at end of file + + // key and possibly options given, get cookie... + options = value || {}; + var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; + return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; +}; diff --git a/lib/scripts/locktimer.js b/lib/scripts/locktimer.js index 60508a8e7..857002abf 100644 --- a/lib/scripts/locktimer.js +++ b/lib/scripts/locktimer.js @@ -1,64 +1,65 @@ /** -* Class managing the timer to display a warning on a expiring lock -*/ -var locktimer = { - sack: null, + * Class managing the timer to display a warning on a expiring lock + */ +var dw_locktimer = { timeout: 0, + draft: false, timerID: null, lasttime: null, msg: '', pageid: '', - init: function(timeout,msg,draft,edid){ - var edit = $(edid); - if(!edit) return; - if(edit.readOnly) return; + /** + * Initialize the lock timer + * + * @param int timeout Lenght of timeout in seconds + * @param bool draft save drafts + */ + init: function(timeout,draft){ //FIXME which elements to pass here? + var $edit = jQuery('#wiki__text'); + if($edit.length === 0 || $edit.attr('readonly')) { + return; + } // init values - this.timeout = timeout*1000; - this.msg = msg; - this.draft = draft; - this.lasttime = new Date(); + dw_locktimer.timeout = timeout*1000; + dw_locktimer.draft = draft; + dw_locktimer.lasttime = new Date(); - if(jQuery('#dw__editform').length == 0) return; - this.pageid = jQuery('#dw__editform input[name=id]').val(); - if(!this.pageid) return; - - if(jQuery('#wiki__text').attr('readonly')) return; + dw_locktimer.pageid = jQuery('#dw__editform input[name=id]').val(); + if(!dw_locktimer.pageid) { + return; + } // register refresh event - jQuery('#dw__editform').keypress( - function() { - locktimer.refresh(); - } - ); + $edit.keypress(dw_locktimer.refresh); // start timer - this.reset(); + dw_locktimer.reset(); }, /** * (Re)start the warning timer */ reset: function(){ - this.clear(); - this.timerID = window.setTimeout("locktimer.warning()", this.timeout); + dw_locktimer.clear(); + dw_locktimer.timerID = window.setTimeout(dw_locktimer.warning, dw_locktimer.timeout); }, /** * Display the warning about the expiring lock */ warning: function(){ - this.clear(); - alert(this.msg); + dw_locktimer.clear(); + alert(LANG.willexpire.replace(/\\n/,"\n")); }, /** * Remove the current warning timer */ clear: function(){ - if(this.timerID !== null){ - window.clearTimeout(this.timerID); - this.timerID = null; + if(dw_locktimer.timerID !== null){ + window.clearTimeout(dw_locktimer.timerID); + dw_locktimer.timerID = null; } }, @@ -68,32 +69,29 @@ var locktimer = { * Called on keypresses in the edit area */ refresh: function(){ - var now = new Date(); - var params = {}; - // refresh every minute only - if(now.getTime() - this.lasttime.getTime() > 30*1000){ - params['call'] = 'lock'; - params['id'] = locktimer.pageid; + var now = new Date(), + params = 'call=lock&id=' + dw_locktimer.pageid + '&'; - if(locktimer.draft && jQuery('#dw__editform textarea[name=wikitext]').length > 0){ - params['prefix'] = jQuery('#dw__editform input[name=prefix]').val(); - params['wikitext'] = jQuery('#dw__editform textarea[name=wikitext]').val(); - params['suffix'] = jQuery('#dw__editform input[name=suffix]').val(); - if(jQuery('#dw__editform input[name=date]').length > 0) { - params['date'] = jQuery('#dw__editform input[name=id]').val(); - } - } + // refresh every minute only + if(now.getTime() - dw_locktimer.lasttime.getTime() <= 30*1000) { + return; + } - jQuery.post( - DOKU_BASE + 'lib/exe/ajax.php', - params, - function (data) { - locktimer.refreshed(data); - }, - 'html' - ); - this.lasttime = now; + // POST everything necessary for draft saving + if(dw_locktimer.draft && jQuery('#dw__editform textarea[name=wikitext]').length > 0){ + params += jQuery('#dw__editform').find('input[name=prefix], ' + + 'textarea[name=wikitext], ' + + 'input[name=suffix], ' + + 'input[name=date]').serialize(); } + + jQuery.post( + DOKU_BASE + 'lib/exe/ajax.php', + params, + dw_locktimer.refreshed, + 'html' + ); + dw_locktimer.lasttime = now; }, /** @@ -104,7 +102,9 @@ var locktimer = { data = data.substring(1); jQuery('#draft__status').html(data); - if(error != '1') return; // locking failed - this.reset(); + if(error != '1') { + return; // locking failed + } + dw_locktimer.reset(); } }; diff --git a/lib/scripts/media.js b/lib/scripts/media.js index f345c3786..7103727c5 100644 --- a/lib/scripts/media.js +++ b/lib/scripts/media.js @@ -178,7 +178,7 @@ var dw_mediamanager = { * @author Dominik Eckelmann <eckelmann@cosmocode.de> * @author Pierre Spring <pierre.spring@caillou.ch> */ - insert: function () { + insert: function (id) { var opts, alignleft, alignright, edid, s; // set syntax options @@ -420,7 +420,7 @@ var dw_mediamanager = { dw_mediamanager.updatehide(); dw_mediamanager.update_resizable(); - addInitEvent(revisionsForm); + dw_behaviour.revisionBoxHandler(); jQuery('#mediamanager__form_sort').find('input[type=submit]').hide(); dw_mediamanager.set_filelist_view(dw_mediamanager.view, false); dw_mediamanager.image_diff(); diff --git a/lib/scripts/page.js b/lib/scripts/page.js new file mode 100644 index 000000000..e4033b76d --- /dev/null +++ b/lib/scripts/page.js @@ -0,0 +1,141 @@ +/** + * Page behaviours + * + * This class adds various behaviours to the rendered page + */ +dw_page = { + /** + * initialize page behaviours + */ + init: function(){ + dw_page.sectionHighlight(); + jQuery('a.fn_top').mouseover(dw_page.footnoteDisplay); + dw_page.initTocToggle(); + }, + + /** + * Highlight the section when hovering over the appropriate section edit button + * + * @author Andreas Gohr <andi@splitbrain.org> + */ + sectionHighlight: function() { + jQuery('form.btn_secedit') + .mouseover(function(){ + var $tgt = jQuery(this).parent(), + nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2]; + + // Walk the DOM tree up (first previous siblings, then parents) + // until boundary element + while($tgt.length > 0 && !$tgt.hasClass('sectionedit' + nr)) { + // $.last gives the DOM-ordered last element: + // prev if present, else parent. + $tgt = $tgt.prev().add($tgt.parent()).last(); + $tgt.addClass('section_highlight'); + } + }) + .mouseout(function(){ + jQuery('.section_highlight').removeClass('section_highlight'); + }); + }, + + /** + * Create/get a insitu popup used by the footnotes + * + * @param target - the DOM element at which the popup should be aligned at + * @param popup_id - the ID of the (new) DOM popup + * @return the Popup JQuery object + */ + insituPopup: function(target, popup_id) { + // get or create the popup div + var $fndiv = jQuery('#' + popup_id); + + // popup doesn't exist, yet -> create it + if($fndiv.length === 0){ + $fndiv = jQuery(document.createElement('div')) + .attr('id', popup_id) + .addClass('insitu-footnote JSpopup') + .mouseleave(function () {jQuery(this).hide();}); + jQuery('div.dokuwiki:first').append($fndiv); + } + + // position() does not support hidden elements + $fndiv.show().position({ + my: 'left top', + at: 'left center', + of: target + }).hide(); + + return $fndiv; + }, + + /** + * Display an insitu footnote popup + * + * @author Andreas Gohr <andi@splitbrain.org> + * @author Chris Smith <chris@jalakai.co.uk> + */ + footnoteDisplay: function () { + var content = jQuery(jQuery(this).attr('href')) // Footnote text anchor + .closest('div.fn').html(); + + if (content === null){ + return; + } + + // strip the leading content anchors and their comma separators + content = content.replace(/((^|\s*,\s*)<sup>.*?<\/sup>)+\s*/gi, ''); + + // prefix ids on any elements with "insitu__" to ensure they remain unique + content = content.replace(/\bid=(['"])([^"']+)\1/gi,'id="insitu__$2'); + + // now put the content into the wrapper + dw_page.insituPopup(this, 'insitu__fn').html(content).show(); + }, + + /** + * Adds the toggle switch to the TOC + */ + initTocToggle: function() { + var $header, $clicky, $toc, $tocul, setClicky; + $header = jQuery('#toc__header'); + if(!$header.length) { + return; + } + $toc = jQuery('#toc__inside'); + $tocul = $toc.children('ul.toc'); + + setClicky = function(hiding){ + if(hiding){ + $clicky.html('<span>+</span>'); + $clicky[0].className = 'toc_open'; + }else{ + $clicky.html('<span>−</span>'); + $clicky[0].className = 'toc_close'; + } + }; + + $clicky = jQuery(document.createElement('span')) + .attr('id','toc__toggle'); + $header.css('cursor','pointer') + .click(function () { + var hidden; + + // Assert that $toc instantly takes the whole TOC space + $toc.css('height', $toc.height()).show(); + + hidden = $tocul.stop(true, true).is(':hidden'); + + setClicky(!hidden); + + // Start animation and assure that $toc is hidden/visible + $tocul.dw_toggle(hidden, function () { + $toc.toggle(hidden); + }); + }) + .prepend($clicky); + + setClicky(); + } +}; + +jQuery(dw_page.init); diff --git a/lib/scripts/script.js b/lib/scripts/script.js index 33916a92e..8db223d61 100644 --- a/lib/scripts/script.js +++ b/lib/scripts/script.js @@ -4,53 +4,6 @@ if ('function' === typeof jQuery && 'function' === typeof jQuery.noConflict) { } /** - * Mark a JavaScript function as deprecated - * - * This will print a warning to the JavaScript console (if available) in - * Firebug and Chrome and a stack trace (if available) to easily locate the - * problematic function call. - * - * @param msg optional message to print - */ -function DEPRECATED(msg){ - if(!window.console) return; - if(!msg) msg = ''; - - var func; - if(arguments.callee) func = arguments.callee.caller.name; - if(func) func = ' '+func+'()'; - var line = 'DEPRECATED function call'+func+'. '+msg; - - if(console.warn){ - console.warn(line); - }else{ - console.log(line); - } - - if(console.trace) console.trace(); -} - -/** - * Construct a wrapper function for deprecated function names - * - * This function returns a wrapper function which just calls DEPRECATED - * and the new function. - * - * @param func The new function - * @param context Optional; The context (`this`) of the call - */ -function DEPRECATED_WRAP(func, context) { - return function () { - DEPRECATED(); - return func.apply(context || this, arguments); - } -} - -/** - * Some of these scripts were taken from wikipedia.org and were modified for DokuWiki - */ - -/** * Some browser detection */ var clientPC = navigator.userAgent.toLowerCase(); // Get client info @@ -66,87 +19,6 @@ if (clientPC.indexOf('opera')!=-1) { } /** - * Handy shortcut to document.getElementById - * - * This function was taken from the prototype library - * - * @link http://prototype.conio.net/ - */ -function $() { - DEPRECATED('Please use the JQuery() function instead.'); - - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} - -/** - * Simple function to check if a global var is defined - * - * @author Kae Verens - * @link http://verens.com/archives/2005/07/25/isset-for-javascript/#comment-2835 - */ -function isset(varname){ - return(typeof(window[varname])!='undefined'); -} - -/** - * Get the computed style of a node. - * - * @link https://acidmartin.wordpress.com/2008/08/26/style-get-any-css-property-value-of-an-object/ - * @link http://svn.dojotoolkit.org/src/dojo/trunk/_base/html.js - */ -function gcs(node){ - if(node.currentStyle){ - return node.currentStyle; - }else{ - return node.ownerDocument.defaultView.getComputedStyle(node, null); - } -} - -/** - * Escape special chars in JavaScript - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -function jsEscape(text){ - var re=new RegExp("\\\\","g"); - text=text.replace(re,"\\\\"); - re=new RegExp("'","g"); - text=text.replace(re,"\\'"); - re=new RegExp('"',"g"); - text=text.replace(re,'"'); - re=new RegExp("\\\\\\\\n","g"); - text=text.replace(re,"\\n"); - return text; -} - -/** - * This function escapes some special chars - * @deprecated by above function - */ -function escapeQuotes(text) { - var re=new RegExp("'","g"); - text=text.replace(re,"\\'"); - re=new RegExp('"',"g"); - text=text.replace(re,'"'); - re=new RegExp("\\n","g"); - text=text.replace(re,"\\n"); - return text; -} - -/** * Prints a animated gif to show the search is performed * * Because we need to modify the DOM here before the document is loaded @@ -180,104 +52,6 @@ function hideLoadBar(id){ if(obj) obj.style.display="none"; } - -/** - * Create JavaScript mouseover popup - */ -function insitu_popup(target, popup_id) { - - // get or create the popup div - var fndiv = $(popup_id); - if(!fndiv){ - fndiv = document.createElement('div'); - fndiv.id = popup_id; - fndiv.className = 'insitu-footnote JSpopup dokuwiki'; - - // autoclose on mouseout - ignoring bubbled up events - addEvent(fndiv,'mouseout',function(e){ - var p = e.relatedTarget || e.toElement; - while (p && p !== this) { - p = p.parentNode; - } - if (p === this) { - return; - } - // okay, hide it - this.style.display='none'; - }); - getElementsByClass('dokuwiki', document.body, 'div')[0].appendChild(fndiv); - } - - var non_static_parent = fndiv.parentNode; - while (non_static_parent != document && gcs(non_static_parent)['position'] == 'static') { - non_static_parent = non_static_parent.parentNode; - } - - var fixed_target_parent = target; - while (fixed_target_parent != document && gcs(fixed_target_parent)['position'] != 'fixed') { - fixed_target_parent = fixed_target_parent.parentNode; - } - - // position the div and make it visible - if (fixed_target_parent != document) { - // the target has position fixed, that means the footnote needs to be fixed, too - fndiv.style.position = 'fixed'; - } else { - fndiv.style.position = 'absolute'; - } - - if (fixed_target_parent != document || non_static_parent == document) { - fndiv.style.left = findPosX(target)+'px'; - fndiv.style.top = (findPosY(target)+target.offsetHeight * 1.5) + 'px'; - } else { - fndiv.style.left = (findPosX(target) - findPosX(non_static_parent)) +'px'; - fndiv.style.top = (findPosY(target)+target.offsetHeight * 1.5 - findPosY(non_static_parent)) + 'px'; - } - - fndiv.style.display = ''; - return fndiv; -} - -/** - * Display an insitu footnote popup - * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Chris Smith <chris@jalakai.co.uk> - */ -function footnote(e){ - var fndiv = insitu_popup(e.target, 'insitu__fn'); - - // locate the footnote anchor element - var a = $("fn__" + e.target.id.substr(5)); - if (!a){ return; } - - // anchor parent is the footnote container, get its innerHTML - var content = new String (a.parentNode.parentNode.innerHTML); - - // strip the leading content anchors and their comma separators - content = content.replace(/<sup>.*<\/sup>/gi, ''); - content = content.replace(/^\s+(,\s+)+/,''); - - // prefix ids on any elements with "insitu__" to ensure they remain unique - content = content.replace(/\bid=(['"])([^"']+)\1/gi,'id="insitu__$2'); - - // now put the content into the wrapper - fndiv.innerHTML = content; -} - -/** - * Add the event handlers to footnotes - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -addInitEvent(function(){ - var elems = getElementsByClass('fn_top',null,'a'); - for(var i=0; i<elems.length; i++){ - addEvent(elems[i],'mouseover',function(e){footnote(e);}); - } -}); - - /** * Handler to close all open Popups */ @@ -285,70 +59,4 @@ function closePopups(){ jQuery('div.JSpopup').hide(); } -function revisionsForm(){ - var revForm = $('page__revisions'); - if (!revForm) return; - var elems = revForm.elements; - var countTicks = 0; - for (var i=0; i<elems.length; i++) { - var input1 = elems[i]; - if (input1.type=='checkbox') { - addEvent(input1,'click',function(e){ - if (this.checked) countTicks++; - else countTicks--; - for (var j=0; j<elems.length; j++) { - var input2 = elems[j]; - if (countTicks >= 2) input2.disabled = (input2.type=='checkbox' && !input2.checked); - else input2.disabled = (input2.type!='checkbox'); - } - }); - input1.checked = false; // chrome reselects on back button which messes up the logic - } else if(input1.type=='submit'){ - input1.disabled = true; - } - } -} - - -/** - * disable multiple revisions checkboxes if two are checked - * - * @author Anika Henke <anika@selfthinker.org> - */ -addInitEvent(revisionsForm); - - -/** - * Highlight the section when hovering over the appropriate section edit button - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -addInitEvent(function(){ - var btns = getElementsByClass('btn_secedit',document,'form'); - for(var i=0; i<btns.length; i++){ - addEvent(btns[i],'mouseover',function(e){ - var tgt = this.parentNode; - var nr = tgt.className.match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2]; - do { - tgt = tgt.previousSibling; - } while (tgt !== null && typeof tgt.tagName === 'undefined'); - if (tgt === null) return; - while(typeof tgt.className === 'undefined' || - tgt.className.match('(\\s+|^)sectionedit' + nr + '(\\s+|$)') === null) { - if (typeof tgt.className !== 'undefined') { - tgt.className += ' section_highlight'; - } - tgt = (tgt.previousSibling !== null) ? tgt.previousSibling : tgt.parentNode; - } - if (typeof tgt.className !== 'undefined') tgt.className += ' section_highlight'; - }); - - addEvent(btns[i],'mouseout',function(e){ - var secs = getElementsByClass('section_highlight'); - for(var j=0; j<secs.length; j++){ - secs[j].className = secs[j].className.replace(/section_highlight/g,''); - } - }); - } -}); diff --git a/lib/scripts/subscriptions.js b/lib/scripts/subscriptions.js deleted file mode 100644 index b7bffb158..000000000 --- a/lib/scripts/subscriptions.js +++ /dev/null @@ -1,38 +0,0 @@ -/*jslint sloppy: true */ -/*global jQuery */ -/** - * Hide list subscription style if target is a page - * - * @author Adrian Lang <lang@cosmocode.de> - * @author Pierre Spring <pierre.spring@caillou.ch> - */ -jQuery(function () { - var $form, $list, $digest; - - $form = jQuery('#subscribe__form'); - - if (0 === $form.length) { - return; - } - - $list = $form.find("input[name='sub_style'][value='list']"); - $digest = $form.find("input[name='sub_style'][value='digest']"); - - $form.find("input[name='sub_target']") - .click( - function () { - var $this = jQuery(this), show_list; - if (!$this.prop('checked')) { - return; - } - - show_list = $this.val().match(/:$/); - $list.parent().dw_toggle(show_list); - if (!show_list && $list.prop('checked')) { - $digest.prop('checked', 'checked'); - } - } - ) - .filter(':checked') - .click(); -}); |