summaryrefslogtreecommitdiff
path: root/lib/scripts
diff options
context:
space:
mode:
authorKate Arzamastseva <pshns@ukr.net>2011-08-25 15:01:15 +0300
committerKate Arzamastseva <pshns@ukr.net>2011-08-25 15:01:15 +0300
commit47e84e7a9713558efde9ea83063d3e0830651622 (patch)
tree8416e23249ee823249a98c8a0fbf88cfe26b80d7 /lib/scripts
parent80525638759a0bfe0ca5d83d9b06430f0d94c2ac (diff)
parent1c5f7481f4e685ad3ffe9ba48ed47ed75196e64a (diff)
downloadrpg-47e84e7a9713558efde9ea83063d3e0830651622.tar.gz
rpg-47e84e7a9713558efde9ea83063d3e0830651622.tar.bz2
merging
Diffstat (limited to 'lib/scripts')
-rw-r--r--lib/scripts/behaviour.js125
-rw-r--r--lib/scripts/compatibility.js273
-rw-r--r--lib/scripts/cookie.js71
-rw-r--r--lib/scripts/delay.js1
-rw-r--r--lib/scripts/edit.js88
-rw-r--r--lib/scripts/editor.js127
-rw-r--r--lib/scripts/events.js50
-rw-r--r--lib/scripts/helpers.js165
-rw-r--r--lib/scripts/jquery/jquery.cookie.js111
-rw-r--r--lib/scripts/locktimer.js110
-rw-r--r--lib/scripts/media.js4
-rw-r--r--lib/scripts/page.js141
-rw-r--r--lib/scripts/script.js292
-rw-r--r--lib/scripts/subscriptions.js38
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>&minus;</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,'&quot;');
+ 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>&minus;</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,'&quot;');
- 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,'&quot;');
- 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();
-});