summaryrefslogtreecommitdiff
path: root/lib/scripts
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2006-05-19 18:50:23 +0200
committerAndreas Gohr <andi@splitbrain.org>2006-05-19 18:50:23 +0200
commit3df72098bbc205fa4bd4735d52d2626baad93548 (patch)
tree105ca14ca3ff596ad4c7d20a1985aeb02c5f7caa /lib/scripts
parenta219c1f00349b720d262939fec3e7baf19a63402 (diff)
downloadrpg-3df72098bbc205fa4bd4735d52d2626baad93548.tar.gz
rpg-3df72098bbc205fa4bd4735d52d2626baad93548.tar.bz2
new mediamanager
This patch adds a completely rewritten media popup. The following noteworthy changes were made: - media manager uses a collapsible namespace tree - media manager uses AJAX if available - media manager popup can be kept open when selecting a media file - only one template is used for the media manager :!: Template - Editable image metadata is configured in conf/mediameta.php now - The JS cookie mechanism was enhanced to store key/value pairs - Language strings can be exported to JS in js.php darcs-hash:20060519165023-7ad00-4932b4553fc919aa4a8b8187958b823acf4f8cee.gz
Diffstat (limited to 'lib/scripts')
-rw-r--r--lib/scripts/cookie.js111
-rw-r--r--lib/scripts/edit.js5
-rw-r--r--lib/scripts/media.js191
-rw-r--r--lib/scripts/script.js130
-rw-r--r--lib/scripts/tw-sack.js28
5 files changed, 365 insertions, 100 deletions
diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js
new file mode 100644
index 000000000..c236eeb79
--- /dev/null
+++ b/lib/scripts/cookie.js
@@ -0,0 +1,111 @@
+/**
+ * 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!
+ *
+ * You should only use the getValue and setValue methods
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+DokuCookie = {
+ data: Array(),
+ name: 'DOKU_PREFS',
+
+ /**
+ * Save a value to the cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ setValue: function(key,val){
+ DokuCookie.init();
+ DokuCookie.data[key] = val;
+
+ // prepare expire date
+ var now = new Date();
+ DokuCookie.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 DokuCookie.data){
+ text += '#'+escape(key)+'#'+DokuCookie.data[key];
+ }
+ DokuCookie.setCookie(DokuCookie.name,text.substr(1),now,DOKU_BASE);
+ },
+
+ /**
+ * Get a Value from the Cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ getValue: function(key){
+ DokuCookie.init();
+ return DokuCookie.data[key];
+ },
+
+ /**
+ * Loads the current set cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ init: function(){
+ if(DokuCookie.data.length) return;
+ var text = DokuCookie.getCookie(DokuCookie.name);
+ if(text){
+ var parts = text.split('#');
+ for(var i=0; i<parts.length; i+=2){
+ DokuCookie.data[unescape(parts[i])] = unescape(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 curCookie = name + "=" + escape(value) +
+ ((expires) ? "; expires=" + expires.toGMTString() : "") +
+ ((path) ? "; path=" + path : "") +
+ ((domain) ? "; domain=" + domain : "") +
+ ((secure) ? "; secure" : "");
+ document.cookie = curCookie;
+ },
+
+ /**
+ * This reads a cookie by JavaScript
+ *
+ * @link http://www.webreference.com/js/column8/functions.html
+ */
+ getCookie: function(name) {
+ var dc = document.cookie;
+ var prefix = name + "=";
+ var begin = dc.indexOf("; " + prefix);
+ if (begin == -1) {
+ begin = dc.indexOf(prefix);
+ if (begin !== 0){ return null; }
+ } else {
+ begin += 2;
+ }
+ var end = document.cookie.indexOf(";", begin);
+ if (end == -1){
+ end = dc.length;
+ }
+ return unescape(dc.substring(begin + prefix.length, end));
+ },
+
+ /**
+ * 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/edit.js b/lib/scripts/edit.js
index a8cf33594..48464017e 100644
--- a/lib/scripts/edit.js
+++ b/lib/scripts/edit.js
@@ -125,8 +125,9 @@ function showPicker(pickerid,btn){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function initToolbar(tbid,edid,tb){
- if(!document.getElementById){ return; }
- var toolbar = document.getElementById(tbid);
+ var toolbar = $(tbid);
+ if(!toolbar) return;
+
var cnt = tb.length;
for(var i=0; i<cnt; i++){
// create new button
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
new file mode 100644
index 000000000..f7c709907
--- /dev/null
+++ b/lib/scripts/media.js
@@ -0,0 +1,191 @@
+/**
+ * JavaScript functionalitiy for the media management popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+media = {
+ keepopen: false,
+
+ /**
+ * Attach event handlers to all "folders" below the given element
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ treeattach: function(obj){
+ if(!obj) return;
+
+ var items = obj.getElementsByTagName('li');
+ for(var i=0; i<items.length; i++){
+ var elem = items[i];
+
+ // attach action to make the +/- clickable
+ var clicky = elem.getElementsByTagName('img')[0];
+ clicky.style.cursor = 'pointer';
+ addEvent(clicky,'click',function(event){ return media.toggle(event,this); });
+
+ // attach action load folder list via AJAX
+ var link = elem.getElementsByTagName('a')[0];
+ link.style.cursor = 'pointer';
+ addEvent(link,'click',function(event){ return media.list(event,this); });
+ }
+ },
+
+ /**
+ * Attach the image selector action to all links below the given element
+ * also add the action to autofill the "upload as" field
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ selectorattach: function(obj){
+ if(!obj) return;
+
+ var items = getElementsByClass('select',obj,'a');
+ for(var i=0; i<items.length; i++){
+ var elem = items[i];
+ elem.style.cursor = 'pointer';
+ addEvent(elem,'click',function(event){ return media.select(event,this); });
+ }
+
+ var file = $('upload__file');
+ if(!file) return;
+ addEvent(file,'change',media.suggest);
+ },
+
+ /**
+ * Creates a checkbox for keeping the popup on selection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ attachkeepopen: function(obj){
+ if(!obj) return;
+
+ var cbox = document.createElement('input');
+ cbox.type = 'checkbox';
+ cbox.id = 'media__keepopen';
+ if(DokuCookie.getValue('keepopen')){
+ cbox.checked = true;
+ }
+ addEvent(cbox,'change',function(event){ return media.togglekeepopen(event,this); });
+
+ var clbl = document.createElement('label');
+ clbl.htmlFor = 'media__keepopen';
+ clbl.innerHTML = LANG['keepopen'];
+
+ obj.appendChild(cbox);
+ obj.appendChild(clbl);
+ },
+
+ /**
+ * Toggles the keep open state
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ togglekeepopen: function(event,cb){
+ if(cb.checked){
+ DokuCookie.setValue('keepopen',1);
+ media.keepopen = true;
+ }else{
+ DokuCookie.setValue('keepopen','');
+ media.keepopen = false;
+ }
+ },
+
+ /**
+ * Insert the clicked image into the opener's textarea
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ select: function(event,link){
+ var id = link.name.substr(2);
+
+ if(!opener){
+ alert(LANG['idtouse']+"\n:"+id);
+ return false;
+ }
+ opener.insertTags('wiki__text','{{'+id+'|','}}','');
+
+ if(!media.keepopen) window.close();
+ return false;
+ },
+
+ /**
+ * list the content of a namespace using AJAX
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ list: function(event,link){
+ // prepare an AJAX call to fetch the subtree
+ var ajax = new sack(DOKU_BASE + 'lib/exe/ajax.php');
+ ajax.AjaxFailedAlert = '';
+ ajax.encodeURIString = false;
+ if(ajax.failed) return true;
+
+ cleanMsgArea();
+
+ var content = $('media__content');
+ content.innerHTML = '<img src="'+DOKU_BASE+'lib/images/loading.gif" alt="..." class="load" />';
+
+ ajax.elementObj = content;
+ ajax.afterCompletion = function(){ media.selectorattach(content); };
+ ajax.runAJAX(link.search.substr(1)+'&call=medialist');
+ return false;
+ },
+
+
+ /**
+ * Open or close a subtree using AJAX
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ toggle: function(event,clicky){
+ var listitem = clicky.parentNode;
+
+ // if already open, close by removing the sublist
+ var sublists = listitem.getElementsByTagName('ul');
+ if(sublists.length){
+ listitem.removeChild(sublists[0]);
+ clicky.src = DOKU_BASE+'lib/images/plus.gif';
+ return false;
+ }
+
+ // get the enclosed link (is always the first one)
+ var link = listitem.getElementsByTagName('a')[0];
+
+ // prepare an AJAX call to fetch the subtree
+ var ajax = new sack(DOKU_BASE + 'lib/exe/ajax.php');
+ ajax.AjaxFailedAlert = '';
+ ajax.encodeURIString = false;
+ if(ajax.failed) return true;
+
+ //prepare the new ul
+ var ul = document.createElement('ul');
+ //fixme add classname here
+ listitem.appendChild(ul);
+ ajax.elementObj = ul;
+ ajax.afterCompletion = function(){ media.treeattach(ul); };
+ ajax.runAJAX(link.search.substr(1)+'&call=medians');
+ clicky.src = DOKU_BASE+'lib/images/minus.gif';
+ return false;
+ },
+
+ /**
+ * Prefills the wikiname.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ suggest: function(){
+ var file = $('upload__file');
+ var name = $('upload__name');
+ if(!file || !name) return;
+
+ var text = file.value;
+ text = text.substr(text.lastIndexOf('/')+1);
+ text = text.substr(text.lastIndexOf('\\')+1);
+ name.value = text;
+ }
+
+}
+
+addInitEvent(function(){media.treeattach($('media__tree'));});
+addInitEvent(function(){media.selectorattach($('media__content'));});
+addInitEvent(function(){media.attachkeepopen($('media__opts'));});
diff --git a/lib/scripts/script.js b/lib/scripts/script.js
index bd7af48da..df12a29fb 100644
--- a/lib/scripts/script.js
+++ b/lib/scripts/script.js
@@ -78,6 +78,30 @@ function isset(varname){
}
/**
+ * Select elements by their class name
+ *
+ * @author Dustin Diaz <dustin [at] dustindiaz [dot] com>
+ * @link http://www.dustindiaz.com/getelementsbyclass/
+ */
+function getElementsByClass(searchClass,node,tag) {
+ var classElements = new Array();
+ if ( node == null )
+ node = document;
+ if ( tag == null )
+ tag = '*';
+ var els = node.getElementsByTagName(tag);
+ var elsLen = els.length;
+ var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
+ for (i = 0, j = 0; i < elsLen; i++) {
+ if ( pattern.test(els[i].className) ) {
+ classElements[j] = els[i];
+ j++;
+ }
+ }
+ return classElements;
+}
+
+/**
* Get the X offset of the top left corner of the given object
*
* @link http://www.quirksmode.org/index.html?/js/findpos.html
@@ -186,31 +210,6 @@ function hideLoadBar(id){
if(obj) obj.style.display="none";
}
-/*
- * Insert the selected filename and close the window
- *
- * @see http://www.alexking.org/index.php?content=software/javascript/content.php
- */
-function mediaSelect(file){
- opener.insertTags('wiki__text','{{'+file+'|','}}','');
- window.close();
-}
-
-/**
- * For the upload Dialog. Prefills the wikiname.
- */
-function suggestWikiname(){
- var form = $('dw__upload');
- if(!form) return;
-
- var file = form.elements.upload.value;
-
- file = file.substr(file.lastIndexOf('/')+1);
- file = file.substr(file.lastIndexOf('\\')+1);
-
- form.elements.id.value = file;
-}
-
/**
* Adds the toggle switch to the TOC
*/
@@ -255,55 +254,6 @@ function toggleToc() {
}
/*
- * This sets a cookie by JavaScript
- *
- * @see http://www.webreference.com/js/column8/functions.html
- */
-function setCookie(name, value, expires, path, domain, secure) {
- var curCookie = name + "=" + escape(value) +
- ((expires) ? "; expires=" + expires.toGMTString() : "") +
- ((path) ? "; path=" + path : "") +
- ((domain) ? "; domain=" + domain : "") +
- ((secure) ? "; secure" : "");
- document.cookie = curCookie;
-}
-
-/*
- * This reads a cookie by JavaScript
- *
- * @see http://www.webreference.com/js/column8/functions.html
- */
-function getCookie(name) {
- var dc = document.cookie;
- var prefix = name + "=";
- var begin = dc.indexOf("; " + prefix);
- if (begin == -1) {
- begin = dc.indexOf(prefix);
- if (begin !== 0){ return null; }
- } else {
- begin += 2;
- }
- var end = document.cookie.indexOf(";", begin);
- if (end == -1){
- end = dc.length;
- }
- return unescape(dc.substring(begin + prefix.length, end));
-}
-
-/*
- * This is needed for the cookie functions
- *
- * @see http://www.webreference.com/js/column8/functions.html
- */
-function fixDate(date) {
- var base = new Date(0);
- var skew = base.getTime();
- if (skew > 0){
- date.setTime(date.getTime() - skew);
- }
-}
-
-/*
* This enables/disables checkboxes for acl-administration
*
* @author Frank Schubert <frank@schokilade.de>
@@ -374,24 +324,25 @@ function fnt(id, e, evt) {
* Add the edit window size controls
*/
function initSizeCtl(ctlid,edid){
- if(!document.getElementById){ return; }
+ if(!document.getElementById){ return; }
var ctl = $(ctlid);
var textarea = $(edid);
+ if(!ctl || !textarea) return;
- var hgt = getCookie('DokuWikisizeCtl');
- if(hgt === null || hgt === ''){
- textarea.style.height = '300px';
- }else{
+ var hgt = DokuCookie.getValue('sizeCtl');
+ if(hgt){
textarea.style.height = hgt;
+ }else{
+ textarea.style.height = '300px';
}
var l = document.createElement('img');
var s = document.createElement('img');
l.src = DOKU_BASE+'lib/images/larger.gif';
s.src = DOKU_BASE+'lib/images/smaller.gif';
- addEvent(l,'click',function(){sizeCtl(edid,100);});
- addEvent(s,'click',function(){sizeCtl(edid,-100);});
+ addEvent(l,'click',function(){sizeCtl(edid,100);});
+ addEvent(s,'click',function(){sizeCtl(edid,-100);});
ctl.appendChild(l);
ctl.appendChild(s);
}
@@ -405,10 +356,7 @@ function sizeCtl(edid,val){
height += val;
textarea.style.height = height+'px';
- var now = new Date();
- fixDate(now);
- now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); //expire in a year
- setCookie('DokuWikisizeCtl',textarea.style.height,now);
+ DokuCookie.setValue('sizeCtl',textarea.style.height);
}
/**
@@ -432,3 +380,15 @@ function scrollToMarker(){
var obj = $('scroll__here');
if(obj) obj.scrollIntoView();
}
+
+/**
+ * Remove messages
+ */
+function cleanMsgArea(){
+ var elems = getElementsByClass('(success|info|error)',document,'div');
+ if(elems){
+ for(var i=0; i<elems.length; i++){
+ elems[i].style.display = 'none';
+ }
+ }
+}
diff --git a/lib/scripts/tw-sack.js b/lib/scripts/tw-sack.js
index 0c7e81bf1..cfcbe0ea9 100644
--- a/lib/scripts/tw-sack.js
+++ b/lib/scripts/tw-sack.js
@@ -15,6 +15,7 @@ function sack(file){
this.onLoaded = function() { };
this.onInteractive = function() { };
this.onCompletion = function() { };
+ this.afterCompletion = function() { };
this.createAJAX = function() {
try {
@@ -30,10 +31,10 @@ function sack(file){
this.xmlhttp = new XMLHttpRequest();
}
if (!this.xmlhttp){
- this.failed = true;
+ this.failed = true;
}
};
-
+
this.setVar = function(name, value){
if (this.URLString.length < 3){
this.URLString = name + "=" + value;
@@ -41,12 +42,12 @@ function sack(file){
this.URLString += "&" + name + "=" + value;
}
};
-
+
this.encVar = function(name, value){
var varString = encodeURIComponent(name) + "=" + encodeURIComponent(value);
return varString;
};
-
+
this.encodeURLString = function(string){
varArray = string.split('&');
for (i = 0; i < varArray.length; i++){
@@ -58,25 +59,25 @@ function sack(file){
}
return varArray.join('&');
};
-
+
this.runResponse = function(){
eval(this.response);
};
-
+
this.runAJAX = function(urlstring){
this.responseStatus = new Array(2);
- if(this.failed && this.AjaxFailedAlert){
- alert(this.AjaxFailedAlert);
+ if(this.failed && this.AjaxFailedAlert){
+ alert(this.AjaxFailedAlert);
} else {
- if (urlstring){
+ if (urlstring){
if (this.URLString.length){
- this.URLString = this.URLString + "&" + urlstring;
+ this.URLString = this.URLString + "&" + urlstring;
} else {
- this.URLString = urlstring;
+ this.URLString = urlstring;
}
}
if (this.encodeURIString){
- var timeval = new Date().getTime();
+ var timeval = new Date().getTime();
this.URLString = this.encodeURLString(this.URLString);
this.setVar("rndval", timeval);
}
@@ -93,7 +94,7 @@ function sack(file){
try {
this.xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
} catch (e) {}
- }
+ }
this.xmlhttp.onreadystatechange = function() {
switch (self.xmlhttp.readyState){
@@ -122,6 +123,7 @@ function sack(file){
self.elementObj.innerHTML = self.response;
}
}
+ self.afterCompletion();
self.URLString = "";
break;
}