summaryrefslogtreecommitdiff
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
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
-rw-r--r--conf/mediameta.php57
-rw-r--r--inc/html.php2
-rw-r--r--inc/lang/en/lang.php5
-rw-r--r--inc/media.php484
-rw-r--r--inc/search.php1
-rw-r--r--inc/template.php250
-rw-r--r--inc/toolbar.php4
-rw-r--r--lib/exe/ajax.php36
-rw-r--r--lib/exe/js.php23
-rw-r--r--lib/exe/media.php183
-rw-r--r--lib/exe/mediamanager.php53
-rw-r--r--lib/images/fileicons/gif.pngbin0 -> 881 bytes
-rw-r--r--lib/images/fileicons/jpeg.pngbin0 -> 881 bytes
-rw-r--r--lib/images/fileicons/jpg.pngbin0 -> 881 bytes
-rw-r--r--lib/images/fileicons/png.pngbin0 -> 881 bytes
-rw-r--r--lib/images/fileicons/swf.pngbin0 -> 818 bytes
-rw-r--r--lib/images/fileicons/tar.pngbin0 -> 734 bytes
-rw-r--r--lib/images/fileicons/txt.pngbin462 -> 489 bytes
-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
-rw-r--r--lib/tpl/default/media.css115
-rw-r--r--lib/tpl/default/media.php54
-rw-r--r--lib/tpl/default/mediaedit.php87
-rw-r--r--lib/tpl/default/mediamanager.php (renamed from lib/tpl/default/mediaref.php)29
-rw-r--r--lib/tpl/default/style.ini3
28 files changed, 1210 insertions, 641 deletions
diff --git a/conf/mediameta.php b/conf/mediameta.php
new file mode 100644
index 000000000..1ad2587ee
--- /dev/null
+++ b/conf/mediameta.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * This configures which meta data will be editable through
+ * the media manager. Each field of the array is an array with the
+ * following contents:
+ * fieldname - Where data will be saved (EXIF or IPTC field)
+ * label - key to lookup in the $lang var, if not found printed as is
+ * htmltype - 'text' or 'textarea'
+ * lookups - array additional fields to lookup the data (EXIF or IPTC fields)
+ *
+ * The fields are not ordered continously to make inserting additional items
+ * in between simpler.
+ *
+ * This is a PHP snippet, so PHP syntax applies.
+ *
+ * Note: $fields is not a global variable and will not be available to any
+ * other functions or templates later
+ *
+ * You may extend or overwrite this variable in a optional
+ * conf/mediameta.local.php file
+ *
+ * For a list of available EXIF/IPTC fields refer to
+ * http://wiki.splitbrain.org/wiki:tpl:detail.php
+ */
+
+
+$fields = array(
+ 10 => array('Iptc.Headline',
+ 'img_title',
+ 'text'),
+
+ 20 => array('Iptc.Caption',
+ 'img_caption',
+ 'textarea',
+ array('Exif.UserComment',
+ 'Exif.TIFFImageDescription',
+ 'Exif.TIFFUserComment')),
+
+ 30 => array('Iptc.Byline',
+ 'img_artist',
+ 'text',
+ array('Exif.TIFFArtist',
+ 'Exif.Artist',
+ 'Iptc.Credit')),
+
+ 40 => array('Iptc.CopyrightNotice',
+ 'img_copyr',
+ 'text',
+ array('Exif.TIFFCopyright',
+ 'Exif.Copyright')),
+
+ 50 => array('Iptc.Keywords',
+ 'img_keywords',
+ 'text',
+ array('Exif.Category')),
+);
+
diff --git a/inc/html.php b/inc/html.php
index 928da9cef..5dbfcd921 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -191,7 +191,7 @@ function html_backtomedia_button($params,$akey=''){
global $conf;
global $lang;
- $ret = '<form class="button" method="get" action="'.DOKU_BASE.'lib/exe/media.php"><div class="no">';
+ $ret = '<form class="button" method="get" action="'.DOKU_BASE.'lib/exe/mediamanager.php"><div class="no">';
reset($params);
while (list($key, $val) = each($params)) {
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index c1aa6bd6c..7d067ee25 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -91,7 +91,7 @@ $lang['notsavedyet'] = 'Unsaved changes will be lost.\nReally continue?';
$lang['rssfailed'] = 'An error occured while fetching this feed: ';
$lang['nothingfound']= 'Nothing was found.';
-$lang['mediaselect'] = 'Mediafile Selection';
+$lang['mediaselect'] = 'Mediafiles';
$lang['fileupload'] = 'Mediafile Upload';
$lang['uploadsucc'] = 'Upload successful';
$lang['uploadfail'] = 'Upload failed. Maybe wrong permissions?';
@@ -103,6 +103,9 @@ $lang['mediainuse'] = 'The file "%s" hasn\'t been deleted - it is still in use.
$lang['namespaces'] = 'Namespaces';
$lang['mediafiles'] = 'Available files in';
+$lang['js']['keepopen'] = 'Keep window open on selection';
+$lang['js']['idtouse'] = 'Please use the following ID to reference this file:';
+
$lang['reference'] = 'References for';
$lang['ref_inuse'] = 'The file can\'t be deleted, because it\'s still used by the following pages:';
$lang['ref_hidden'] = 'Some references are on pages you don\'t have permission to read';
diff --git a/inc/media.php b/inc/media.php
new file mode 100644
index 000000000..39f76e311
--- /dev/null
+++ b/inc/media.php
@@ -0,0 +1,484 @@
+<?php
+/**
+ * All output and handler function needed for the media management popup
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+if(!defined('NL')) define('NL',"\n");
+
+require_once(DOKU_INC.'inc/html.php');
+require_once(DOKU_INC.'inc/search.php');
+require_once(DOKU_INC.'inc/JpegMeta.php');
+
+/**
+ * Lists pages which currently use a media file selected for deletion
+ *
+ * References uses the same visual as search results and share
+ * their CSS tags except pagenames won't be links.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+function media_filesinuse($data,$id){
+ global $lang;
+ echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>';
+ echo '<p>'.hsc($lang['ref_inuse']).'</p>';
+
+ $hidden=0; //count of hits without read permission
+ usort($data,'sort_search_fulltext');
+ foreach($data as $row){
+ if(auth_quickaclcheck($row['id']) >= AUTH_READ){
+ echo '<div class="search_result">';
+ echo '<span class="mediaref_ref">'.$row['id'].'</span>';
+ echo ': <span class="search_cnt">'.$row['count'].' '.$lang['hits'].'</span><br />';
+ echo '<div class="search_snippet">'.$row['snippet'].'</div>';
+ echo '</div>';
+ }else
+ $hidden++;
+ }
+ if ($hidden){
+ print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>';
+ }
+}
+
+/**
+ * Handles the saving of image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_metasave($id,$auth,$data){
+ if($auth < AUTH_UPLOAD) return false;
+ global $lang;
+ $src = mediaFN($id);
+
+ $meta = new JpegMeta($src);
+ $meta->_parseAll();
+
+ foreach($data as $key => $val){
+ $val=trim($val);
+ if(empty($val)){
+ $meta->deleteField($key);
+ }else{
+ $meta->setField($key,$val);
+ }
+ }
+
+ if($meta->save()){
+ msg($lang['metasaveok'],1);
+ return $id;
+ }else{
+ msg($lang['metasaveerr'],-1);
+ return false;
+ }
+}
+
+/**
+ * Display the form to edit image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_metaform($id,$auth){
+ if($auth < AUTH_UPLOAD) return false;
+ global $lang;
+
+ // load the field descriptions
+ static $fields = null;
+ if(is_null($fields)){
+ include(DOKU_CONF.'mediameta.php');
+ if(@file_exists(DOKU_CONF.'mediameta.local.php')){
+ include(DOKU_CONF.'mediameta.local.php');
+ }
+ }
+
+ $src = mediaFN($id);
+
+ // output
+ echo '<h1>'.hsc(noNS($id)).'</h1>'.NL;
+ echo '<form action="'.DOKU_BASE.'lib/exe/mediamanager.php" accept-charset="utf-8" method="post" class="meta">'.NL;
+ echo '<input type="hidden" name="img" value="'.hsc($id).'" />'.NL;
+ foreach($fields as $key => $field){
+ // get current value
+ $tags = array($field[0]);
+ if(is_array($field[3])) $tags = array_merge($tags,$field[3]);
+ $value = tpl_img_getTag($tags,'',$src);
+
+ // prepare attributes
+ $p = array();
+ $p['class'] = 'edit';
+ $p['id'] = 'meta__'.$key;
+ $p['name'] = 'meta['.$field[0].']';
+
+ // put label
+ echo '<div class="metafield">';
+ echo '<label for="meta__'.$key.'">';
+ echo ($lang[$field[1]]) ? $lang[$field[1]] : $field[1];
+ echo '</label>';
+
+ // put input field
+ if($field[2] == 'text'){
+ $p['value'] = $value;
+ $p['type'] = 'text';
+ $att = buildAttributes($p);
+ echo "<input $att/>".NL;
+ }else{
+ $att = buildAttributes($p);
+ echo "<textarea $att>".formText($value).'</textarea>'.NL;
+ }
+ echo '</div>'.NL;
+ }
+ echo '<div class="buttons">'.NL;
+ echo '<input name="do[save]" type="submit" value="'.$lang['btn_save'].
+ '" title="ALT+S" accesskey="s" class="button" />'.NL;
+ echo '<input name="do[cancel]" type="submit" value="'.$lang['btn_cancel'].
+ '" title="ALT+C" accesskey="c" class="button" />'.NL;
+ echo '</form>'.NL;
+ echo '</div>';
+}
+
+/**
+ * Handles media file deletions
+ *
+ * If configured, checks for media references before deletion
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return mixed false on error, true on delete or array with refs
+ */
+function media_delete($id,$auth){
+ if($auth < AUTH_DELETE) return false;
+ global $conf;
+ global $lang;
+
+ $mediareferences = array();
+ if($conf['refcheck']){
+ search($mediareferences,$conf['datadir'],'search_reference',array('query' => $id));
+ }
+
+ if(!count($mediareferences)){
+ $file = mediaFN($id);
+ if(@unlink($file)){
+ msg(str_replace('%s',noNS($id),$lang['deletesucc']),1);
+ io_sweepNS($id,'mediadir');
+ return true;
+ }
+ //something went wrong
+ msg(str_replace('%s',$file,$lang['deletefail']),-1);
+ return false;
+ }elseif(!$conf['refshow']){
+ msg(str_replace('%s',noNS($id),$lang['mediainuse']),0);
+ return false;
+ }
+
+ return $mediareferences;
+}
+
+/**
+ * Handles media file uploads
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return mixed false on error, id of the new file on success
+ */
+function media_upload($ns,$auth){
+ if($auth < AUTH_UPLOAD) return false;
+ require_once(DOKU_INC.'inc/confutils.php');
+ global $lang;
+ global $conf;
+
+ // get file
+ $id = $_POST['id'];
+ $file = $_FILES['upload'];
+ // get id
+ if(empty($id)) $id = $file['name'];
+ $id = cleanID($ns.':'.$id); //FIXME handle relative and absolute names here
+ // get filename
+ $fn = mediaFN($id);
+
+ // get filetype regexp
+ $types = array_keys(getMimeTypes());
+ $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types);
+ $regex = join('|',$types);
+
+ // because a temp file was created already
+ if(preg_match('/\.('.$regex.')$/i',$fn)){
+ //check for overwrite
+ if(@file_exists($fn) && (!$_POST['ow'] || $auth < AUTH_DELETE)){
+ msg($lang['uploadexist'],0);
+ return false;
+ }
+ // prepare directory
+ io_makeFileDir($fn);
+ if(move_uploaded_file($file['tmp_name'], $fn)) {
+ // set the correct permission here
+ if($conf['fperm']) chmod($fn, $conf['fperm']);
+ msg($lang['uploadsucc'],1);
+ return $id;
+ }else{
+ msg($lang['uploadfail'],-1);
+ }
+ }else{
+ msg($lang['uploadwrong'],-1);
+ }
+ return false;
+}
+
+
+
+/**
+ * List all files in a given Media namespace
+ */
+function media_filelist($ns,$auth=null,$jump=''){
+ global $conf;
+ global $lang;
+ $ns = cleanID($ns);
+
+ // check auth our self if not given (needed for ajax calls)
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ echo '<h1>:'.hsc($ns).'</h1>'.NL;
+
+ if($auth < AUTH_READ){
+ // FIXME: print permission warning here instead?
+ echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL;
+ return;
+ }
+
+ media_uploadform($ns, $auth);
+
+ $dir = utf8_encodeFN(str_replace(':','/',$ns));
+ $data = array();
+ search($data,$conf['mediadir'],'search_media',array(),$dir);
+
+ if(!count($data)){
+ echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL;
+ return;
+ }
+
+ foreach($data as $item){
+ media_printfile($item,$auth,$jump);
+ }
+}
+
+/**
+ * Print action links for a file depending on filetype
+ * and available permissions
+ *
+ * @todo contains inline javascript
+ */
+function media_fileactions($item,$auth){
+ global $lang;
+
+ // no actions if not writable
+ if(!$item['writable']) return;
+
+ // delete button
+ if($auth >= AUTH_DELETE){
+ $ask = addslashes($lang['del_confirm']).'\\n';
+ $ask .= addslashes($item['id']);
+
+ echo ' <a href="'.DOKU_BASE.'lib/exe/mediamanager.php?delete='.rawurlencode($item['id']).'" '.
+ 'onclick="return confirm(\''.$ask.'\')" onkeypress="return confirm(\''.$ask.'\')">'.
+ '<img src="'.DOKU_BASE.'lib/images/trash.png" alt="'.$lang['btn_delete'].'" '.
+ 'title="'.$lang['btn_delete'].'" class="btn" /></a>';
+ }
+
+ // edit button
+ if($auth >= AUTH_UPLOAD && $item['isimg'] && $item['meta']->getField('File.Mime') == 'image/jpeg'){
+ echo ' <a href="'.DOKU_BASE.'lib/exe/mediamanager.php?edit='.rawurlencode($item['id']).'">'.
+ '<img src="'.DOKU_BASE.'lib/images/pencil.png" alt="'.$lang['metaedit'].'" '.
+ 'title="'.$lang['metaedit'].'" class="btn" /></a>';
+ }
+
+}
+
+/**
+ * Formats and prints one file in the list
+ */
+function media_printfile($item,$auth,$jump){
+ // Prepare zebra coloring
+ // I always wanted to use this variable name :-D
+ static $twibble = 1;
+ $twibble *= -1;
+ $zebra = ($twibble == -1) ? 'odd' : 'even';
+
+ // Automatically jump to recent action
+ if($jump == $item['id']) {
+ $jump = ' id="scroll__here" ';
+ }else{
+ $jump = '';
+ }
+
+ // Prepare fileicons
+ list($ext,$mime) = mimetype($item['file']);
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
+ $class = 'select mediafile mf_'.$class;
+
+ // Prepare filename
+ $file = utf8_decodeFN($item['file']);
+
+ // Prepare info
+ $info = '';
+ if($item['isimg']){
+ $info .= (int) $item['meta']->getField('File.Width');
+ $info .= '&#215;';
+ $info .= (int) $item['meta']->getField('File.Height');
+ $info .= ' ';
+ }
+ $info .= filesize_h($item['size']);
+
+ // ouput
+ echo '<div class="'.$zebra.'"'.$jump.'>'.NL;
+ echo '<a name="h_'.$item['id'].'" class="'.$class.'">'.$file.'</a> ';
+ echo '<span class="info">('.$info.')</span>'.NL;
+ media_fileactions($item,$auth);
+ if($item['isimg']) media_printimgdetail($item);
+ echo '<div class="clearer"></div>'.NL;
+ echo '</div>'.NL;
+}
+
+/**
+ * Prints a thumbnail and metainfos
+ */
+function media_printimgdetail($item){
+ // prepare thumbnail
+ $w = (int) $item['meta']->getField('File.Width');
+ $h = (int) $item['meta']->getField('File.Height');
+ if($w>120 || $h>120){
+ $ratio = $item['meta']->getResizeRatio(120);
+ $w = floor($w * $ratio);
+ $h = floor($h * $ratio);
+ }
+ $src = ml($item['id'],array('w'=>$w,'h'=>$h));
+ $p = array();
+ $p['width'] = $w;
+ $p['height'] = $h;
+ $p['alt'] = $item['id'];
+ $p['class'] = 'thumb';
+ $att = buildAttributes($p);
+
+ // output
+ echo '<div class="detail">';
+ echo '<div class="thumb">';
+ echo '<a name="d_'.$item['id'].'" class="select">';
+ echo '<img src="'.$src.'" '.$att.' />';
+ echo '</a>';
+ echo '</div>';
+
+ //read EXIF/IPTC data
+ echo '<p>';
+ $t = $item['meta']->getField('IPTC.Headline');
+ if($t) echo '<strong>'.htmlspecialchars($t).'</strong><br />';
+
+ $t = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment',
+ 'EXIF.TIFFImageDescription',
+ 'EXIF.TIFFUserComment'));
+ if($t) echo htmlspecialchars($t).'<br />';
+
+ $t = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category'));
+ if($t) echo '<em>'.htmlspecialchars($t).'</em>';
+ echo '</p>';
+ echo '</div>';
+}
+
+/**
+ * Print the media upload form if permissions are correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_uploadform($ns, $auth){
+ global $lang;
+
+ if($auth < AUTH_UPLOAD) return; //fixme print info on missing permissions?
+
+ ?>
+ <form action="<?php echo DOKU_BASE?>lib/exe/mediamanager.php"
+ method="post" enctype="multipart/form-data" class="upload">
+ <input type="hidden" name="ns" value="<?php echo hsc($ns)?>" />
+
+ <?php echo $lang['txt_upload']?>:
+ <input type="file" name="upload" class="edit" id="upload__file" /><br />
+
+ <?php echo $lang['txt_filename']?>:
+ <input type="text" name="id" class="edit" id="upload__name" />
+ <input type="submit" class="button" value="<?php echo $lang['btn_upload']?>" accesskey="s" />
+
+ <?php if($auth >= AUTH_DELETE){?>
+ <br />
+ <label for="dw__ow">
+ <input type="checkbox" name="ow" value="1" id="dw__ow" /><?php echo $lang['txt_overwrt']?>
+ </label>
+ <?php }?>
+ </form>
+ <?php
+}
+
+
+
+/**
+ * Build a tree outline of available media namespaces
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_nstree($ns){
+ global $conf;
+
+ // currently selected namespace
+ $ns = cleanID($ns);
+ if(empty($ns)){
+ $ns = dirname(str_replace(':','/',$ID));
+ if($ns == '.') $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = array();
+ search($data,$conf['mediadir'],'search_index',array('ns' => $ns));
+
+ // wrap a list with the root level around the other namespaces
+ $item = array( 'level' => 0, 'id' => '', 'open' =>'true', 'label' => ':*');
+
+ echo '<ul class="idx">';
+ echo media_nstree_li($item);
+ echo media_nstree_item($item);
+ echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li');
+ echo '</li>';
+ echo '</ul>';
+}
+
+/**
+ * Userfunction for html_buildlist
+ *
+ * Prints a media namespace tree item
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_nstree_item($item){
+ $pos = strrpos($item['id'], ':');
+ $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0);
+ if(!$item['label']) $item['label'] = $label;
+
+ $ret = '';
+ $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">';
+ $ret .= $item['label'];
+ $ret .= '</a>';
+ return $ret;
+}
+
+/**
+ * Userfunction for html_buildlist
+ *
+ * Prints a media namespace tree item opener
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_nstree_li($item){
+ $class='media level'.$item['level'];
+ if($item['open']){
+ $class .= ' open';
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ }else{
+ $class .= ' closed';
+ $img = DOKU_BASE.'lib/images/plus.gif';
+ }
+ return '<li class="'.$class.'">'.
+ '<img src="'.$img.'" alt="*" />';
+}
diff --git a/inc/search.php b/inc/search.php
index 5f1ae6f1a..3c473daee 100644
--- a/inc/search.php
+++ b/inc/search.php
@@ -207,6 +207,7 @@ function search_media(&$data,$base,$file,$type,$lvl,$opts){
$info['file'] = basename($file);
$info['size'] = filesize($base.'/'.$file);
+ $info['writable'] = is_writable($base.'/'.$file);
if(preg_match("/\.(jpe?g|gif|png)$/",$file)){
$info['isimg'] = true;
require_once(DOKU_INC.'inc/JpegMeta.php');
diff --git a/inc/template.php b/inc/template.php
index 1af735382..7a7e751a9 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -210,7 +210,11 @@ function tpl_metaheaders($alt=true){
// load javascript
$js_edit = ($ACT=='edit' || $ACT=='preview' || $ACT=='recover') ? 1 : 0;
$js_write = ($INFO['writable']) ? 1 : 0;
- if($js_edit && $js_write){
+ if(defined('DOKU_MEDIAMANAGER')){
+ $js_edit = 1;
+ $js_write = 0;
+ }
+ if(($js_edit && $js_write) || defined('DOKU_MEDIAMANAGER')){
ptln('<script type="text/javascript" charset="utf-8">',$it);
ptln("NS='".$INFO['namespace']."';",$it+2);
if($conf['useacl'] && $_SERVER['REMOTE_USER']){
@@ -666,183 +670,6 @@ function tpl_pageinfo(){
}
/**
- * Print a list of namespaces containing media files
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function tpl_medianamespaces(){
- global $conf;
-
- $data = array();
- search($data,$conf['mediadir'],'search_namespaces',array());
- print html_buildlist($data,'idx',media_html_list_namespaces);
-}
-
-/**
- * Print a list of mediafiles in the current namespace
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function tpl_mediafilelist(){
- global $conf;
- global $lang;
- global $NS;
- global $AUTH;
- $dir = utf8_encodeFN(str_replace(':','/',$NS));
-
- $data = array();
- search($data,$conf['mediadir'],'search_media',array(),$dir);
-
- if(!count($data)){
- ptln('<div class="nothing">'.$lang['nothingfound'].'</div>');
- return;
- }
-
- ptln('<ul>',2);
- foreach($data as $item){
- if(!$item['isimg']){
- // add file icons
- list($ext,$mime) = mimetype($item['file']);
- $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
- $class = ' class="mediafile mf_'.$class.'"';
- }else{
- $class = '';
- }
-
- ptln('<li><div class="li">',4);
- ptln('<a href="javascript:mediaSelect(\':'.$item['id'].'\')"'.$class.'>'.
- utf8_decodeFN($item['file']).
- '</a>',6);
-
- //prepare deletion button
- if($AUTH >= AUTH_DELETE){
- $ask = addslashes($lang['del_confirm']).'\\n';
- $ask .= addslashes($item['id']);
-
- $del = '<a href="'.DOKU_BASE.'lib/exe/media.php?delete='.rawurlencode($item['id']).'" '.
- 'onclick="return confirm(\''.$ask.'\')" onkeypress="return confirm(\''.$ask.'\')">'.
- '<img src="'.DOKU_BASE.'lib/images/del.png" alt="'.$lang['btn_delete'].'" '.
- 'title="'.$lang['btn_delete'].'" /></a>';
- }else{
- $del = '';
- }
-
- if($item['isimg']){
- $w = (int) $item['meta']->getField('File.Width');
- $h = (int) $item['meta']->getField('File.Height');
-
- ptln('('.$w.'&#215;'.$h.' '.filesize_h($item['size']).')',6);
- ptln($del.'<br />',6);
- ptln('<div class="imagemeta">',6);
-
- //build thumbnail
- print '<a href="javascript:mediaSelect(\':'.$item['id'].'\')">';
-
- if($w>120 || $h>120){
- $ratio = $item['meta']->getResizeRatio(120);
- $w = floor($w * $ratio);
- $h = floor($h * $ratio);
- }
-
- $src = ml($item['id'],array('w'=>$w,'h'=>$h));
-
- $p = array();
- $p['width'] = $w;
- $p['height'] = $h;
- $p['alt'] = $item['id'];
- $p['class'] = 'thumb';
- $att = buildAttributes($p);
-
- print '<img src="'.$src.'" '.$att.' />';
- print '</a>';
-
- //read EXIF/IPTC data
- $t = $item['meta']->getField('IPTC.Headline');
- if($t) print '<strong>'.htmlspecialchars($t).'</strong><br />';
-
- $t = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment',
- 'EXIF.TIFFImageDescription',
- 'EXIF.TIFFUserComment'));
- if($t) print htmlspecialchars($t).'<br />';
-
- $t = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category'));
- if($t) print '<em>'.htmlspecialchars($t).'</em><br />';
-
- //add edit button
- if($AUTH >= AUTH_UPLOAD && $item['meta']->getField('File.Mime') == 'image/jpeg'){
- print '<a href="'.DOKU_BASE.'lib/exe/media.php?edit='.rawurlencode($item['id']).'">';
- print '<img src="'.DOKU_BASE.'lib/images/edit.gif" alt="'.$lang['metaedit'].'" title="'.$lang['metaedit'].'" />';
- print '</a>';
- }
-
- ptln('</div>',6);
- }else{
- ptln ('('.filesize_h($item['size']).')',6);
- ptln($del,6);
- }
- ptln('</div></li>',4);
- }
- ptln('</ul>',2);
-}
-
-/**
- * show references to a media file
- * References uses the same visual as search results and share
- * their CSS tags except pagenames won't be links.
- *
- * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
- */
-function tpl_showreferences(&$data){
- global $lang;
-
- $hidden=0; //count of hits without read permission
-
- if(count($data)){
- usort($data,'sort_search_fulltext');
- foreach($data as $row){
- if(auth_quickaclcheck($row['id']) >= AUTH_READ){
- print '<div class="search_result">';
- print '<span class="mediaref_ref">'.$row['id'].'</span>';
- print ': <span class="search_cnt">'.$row['count'].' '.$lang['hits'].'</span><br />';
- print '<div class="search_snippet">'.$row['snippet'].'</div>';
- print '</div>';
- }else
- $hidden++;
- }
- if ($hidden){
- print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>';
- }
- }
-}
-
-/**
- * Print the media upload form if permissions are correct
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function tpl_mediauploadform(){
- global $NS;
- global $UPLOADOK;
- global $AUTH;
- global $lang;
-
- if(!$UPLOADOK) return;
-
- ptln('<form action="'.DOKU_BASE.'lib/exe/media.php" id="dw__upload"'.
- ' method="post" enctype="multipart/form-data">',2);
- ptln($lang['txt_upload'].':<br />',4);
- ptln('<input type="file" name="upload" class="edit" onchange="suggestWikiname();" />',4);
- ptln('<input type="hidden" name="ns" value="'.hsc($NS).'" /><br />',4);
- ptln($lang['txt_filename'].'<br />',4);
- ptln('<input type="text" name="id" class="edit" />',4);
- ptln('<input type="submit" class="button" value="'.$lang['btn_upload'].'" accesskey="s" />',4);
- if($AUTH >= AUTH_DELETE){
- ptln('<label for="dw__ow"><input type="checkbox" name="ow" value="1" id="dw__ow" />'.$lang['txt_overwrt'].'</label>',4);
- }
- ptln('</form>',2);
-}
-
-/**
* Prints or returns the name of the given page (current one if none given).
*
* If useheading is enabled this will use the first headline else
@@ -880,15 +707,18 @@ function tpl_pagetitle($id=null, $ret=false){
* and _iptcTagNames() in inc/jpeg.php (You need to prepend IPTC
* to the names of the latter one)
*
- * Only allowed in: detail.php, mediaedit.php
+ * Only allowed in: detail.php
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function tpl_img_getTag($tags,$alt=''){
+function tpl_img_getTag($tags,$alt='',$src=null){
// Init Exif Reader
global $SRC;
+
+ if(is_null($src)) $src = $SRC;
+
static $meta = null;
- if(is_null($meta)) $meta = new JpegMeta($SRC);
+ if(is_null($meta)) $meta = new JpegMeta($src);
if($meta === false) return $alt;
$info = $meta->getField($tags);
if($info == false) return $alt;
@@ -975,15 +805,15 @@ function tpl_indexerWebBug(){
// configuration methods
/**
* tpl_getConf($id)
- *
+ *
* use this function to access template configuration variables
*/
function tpl_getConf($id){
global $conf;
global $tpl_configloaded;
-
+
$tpl = $conf['template'];
-
+
if (!$tpl_configloaded){
$tconf = tpl_loadConfig();
if ($tconf !== false){
@@ -1004,16 +834,60 @@ function tpl_getConf($id){
* this function is automatically called by tpl_getConf()
*/
function tpl_loadConfig(){
-
+
$file = DOKU_TPLINC.'/conf/default.php';
$conf = array();
-
+
if (!@file_exists($file)) return false;
-
+
// load default config file
include($file);
-
+
return $conf;
}
+/**
+ * prints the "main content" in the mediamanger popup
+ *
+ * Depending on the user's actions this may be a list of
+ * files in a namespace, the meta editing dialog or
+ * a message of referencing pages
+ *
+ * Only allowed in mediamanager.php
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_mediaContent(){
+ global $IMG;
+ global $AUTH;
+ global $INUSE;
+ global $NS;
+ global $JUMPTO;
+
+ ptln('<div id="media__content">');
+ if($_REQUEST['edit']){
+ media_metaform($IMG,$AUTH);
+ }elseif($INUSE){
+ media_filesinuse($INUSE,$IMG);
+ }else{
+ media_filelist($NS,$AUTH,$JUMPTO);
+ }
+ ptln('</div>');
+}
+
+/**
+ * prints the namespace tree in the mediamanger popup
+ *
+ * Only allowed in mediamanager.php
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_mediaTree(){
+ global $NS;
+
+ ptln('<div id="media__tree">');
+ media_nstree($NS);
+ ptln('</div>');
+}
+
//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/toolbar.php b/inc/toolbar.php
index fbe6b3609..072b6f420 100644
--- a/inc/toolbar.php
+++ b/inc/toolbar.php
@@ -145,9 +145,9 @@ function toolbar_JSdefines($varname){
'type' => 'mediapopup',
'title' => $lang['qb_media'],
'icon' => 'image.png',
- 'url' => DOKU_BASE.'lib/exe/media.php?ns=',
+ 'url' => DOKU_BASE.'lib/exe/mediamanager.php?ns=',
'name' => 'mediaselect',
- 'options'=> 'width=600,height=320,left=70,top=50,scrollbars=yes,resizable=yes',
+ 'options'=> 'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes',
),
array(
'type' => 'picker',
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php
index 886e9829d..c9b93a4b8 100644
--- a/lib/exe/ajax.php
+++ b/lib/exe/ajax.php
@@ -97,6 +97,8 @@ function ajax_lock(){
/**
* Delete a draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
*/
function ajax_draftdel(){
$id = cleanID($_POST['id']);
@@ -109,5 +111,39 @@ function ajax_draftdel(){
@unlink($cname);
}
+/**
+ * Return subnamespaces for the Mediamanager
+ */
+function ajax_medians(){
+ global $conf;
+ require_once(DOKU_INC.'inc/search.php');
+ require_once(DOKU_INC.'inc/media.php');
+
+ // wanted namespace
+ $ns = cleanID($_POST['ns']);
+ $dir = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $lvl = count(explode(':',$ns));
+
+ $data = array();
+ search($data,$conf['mediadir'],'search_index',array(),$dir);
+ foreach($data as $item){
+ $item['level'] = $lvl+1;
+ echo media_nstree_li($item);
+ echo media_nstree_item($item);
+ echo '</div></li>';
+ }
+}
+
+/**
+ * Return subnamespaces for the Mediamanager
+ */
+function ajax_medialist(){
+ global $conf;
+ require_once(DOKU_INC.'inc/media.php');
+
+ media_filelist($_POST['ns']);
+}
+
//Setup VIM: ex: et ts=2 enc=utf-8 :
?>
diff --git a/lib/exe/js.php b/lib/exe/js.php
index 05effd31a..583faa5ad 100644
--- a/lib/exe/js.php
+++ b/lib/exe/js.php
@@ -12,6 +12,7 @@ if(!defined('NL')) define('NL',"\n");
require_once(DOKU_INC.'inc/init.php');
require_once(DOKU_INC.'inc/pageutils.php');
require_once(DOKU_INC.'inc/io.php');
+require_once(DOKU_INC.'inc/JSON.php');
// Main (don't run when UNIT test)
if(!defined('SIMPLE_TEST')){
@@ -39,17 +40,21 @@ function js_out(){
// Array of needed files
$files = array(
DOKU_INC.'lib/scripts/events.js',
+ DOKU_INC.'lib/scripts/cookie.js',
DOKU_INC.'lib/scripts/script.js',
DOKU_INC.'lib/scripts/tw-sack.js',
DOKU_INC.'lib/scripts/ajax.js',
DOKU_INC.'lib/scripts/domLib.js',
DOKU_INC.'lib/scripts/domTT.js',
);
- if($edit && $write){
- $files[] = DOKU_INC.'lib/scripts/edit.js';
- if($conf['spellchecker']){
- $files[] = DOKU_INC.'lib/scripts/spellcheck.js';
+ if($edit){
+ if($write){
+ $files[] = DOKU_INC.'lib/scripts/edit.js';
+ if($conf['spellchecker']){
+ $files[] = DOKU_INC.'lib/scripts/spellcheck.js';
+ }
}
+ $files[] = DOKU_INC.'lib/scripts/media.js';
}
$files[] = DOKU_TPLINC.'script.js';
@@ -70,11 +75,17 @@ function js_out(){
// start output buffering and build the script
ob_start();
- // add some translation strings and global variables
+ // add some global variables
+ print "var DOKU_BASE = '".DOKU_BASE."';";
+
+ //FIXME: move thes into LANG
print "var alertText = '".js_escape($lang['qb_alert'])."';";
print "var notSavedYet = '".js_escape($lang['notsavedyet'])."';";
print "var reallyDel = '".js_escape($lang['del_confirm'])."';";
- print "var DOKU_BASE = '".DOKU_BASE."';";
+
+ // load JS specific translations
+ $json = new JSON();
+ echo 'LANG = '.$json->encode($lang['js']).";\n";
// load files
foreach($files as $file){
diff --git a/lib/exe/media.php b/lib/exe/media.php
deleted file mode 100644
index cc78d6b72..000000000
--- a/lib/exe/media.php
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
- if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
- require_once(DOKU_INC.'inc/init.php');
- require_once(DOKU_INC.'inc/common.php');
- require_once(DOKU_INC.'inc/lang/en/lang.php');
- require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
- require_once(DOKU_INC.'inc/html.php');
- require_once(DOKU_INC.'inc/JpegMeta.php');
- require_once(DOKU_INC.'inc/search.php');
- require_once(DOKU_INC.'inc/template.php');
- require_once(DOKU_INC.'inc/auth.php');
- //close sesseion
- session_write_close();
-
- //get namespace to display (either direct or from deletion order)
- if($_REQUEST['delete']){
- $DEL = cleanID($_REQUEST['delete']);
- $NS = getNS($DEL);
- }elseif($_REQUEST['edit']){
- $IMG = cleanID($_REQUEST['edit']);
- $SRC = mediaFN($IMG);
- $NS = getNS($IMG);
- }else{
- $NS = $_REQUEST['ns'];
- $NS = cleanID($NS);
- }
-
- //check upload permissions
- $AUTH = auth_quickaclcheck("$NS:*");
- if($AUTH >= AUTH_UPLOAD){
- $UPLOADOK = true;
- //create the given namespace (just for beautification)
- $mdir = $conf['mediadir'].'/'.utf8_encodeFN(str_replace(':','/',$NS));
- io_makeFileDir("$mdir/xxx");
- }else{
- $UPLOADOK = false;
- }
-
- //handle deletion
- $mediareferences = array();
- if($DEL && $AUTH >= AUTH_DELETE){
- if($conf['refcheck']){
- search($mediareferences,$conf['datadir'],'search_reference',array('query' => $DEL));
- }
- if(!count($mediareferences)){
- media_delete($DEL);
- }elseif(!$conf['refshow']){
- msg(str_replace('%s',noNS($DEL),$lang['mediainuse']),0);
- }
- }
-
- //handle metadatasaving
- if($UPLOADOK && $SRC && $_REQUEST['save']){
- media_metasave($SRC,$_REQUEST['meta']);
- }
-
- //handle upload
- if($_FILES['upload']['tmp_name'] && $UPLOADOK){
- media_upload($NS,$AUTH);
- }
-
- //start output and load template
- header('Content-Type: text/html; charset=utf-8');
- if($conf['refshow'] && count($mediareferences)){
- include(template('mediaref.php'));
- }elseif($IMG){
- include(template('mediaedit.php'));
- }else{
- include(template('media.php'));
- }
-
-/**********************************************/
-
-/**
- * Deletes mediafiles - Auth is not handled here!
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function media_delete($delid){
- global $lang;
-
- $file = mediaFN($delid);
- if(@unlink($file)){
- msg(str_replace('%s',noNS($delid),$lang['deletesucc']),1);
- io_sweepNS($delid,'mediadir');
- return true;
- }
- //something went wrong
- msg(str_replace('%s',$file,$lang['deletefail']),-1);
- return false;
-}
-
-/**
- * Handles Mediafile uploads
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function media_upload($NS,$AUTH){
- require_once(DOKU_INC.'inc/confutils.php');
- global $lang;
- global $conf;
-
- // get file
- $id = $_POST['id'];
- $file = $_FILES['upload'];
- // get id
- if(empty($id)) $id = $file['name'];
- $id = cleanID($NS.':'.$id);
- // get filename
- $fn = mediaFN($id);
-
- // get filetype regexp
- $types = array_keys(getMimeTypes());
- $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types);
- $regex = join('|',$types);
-
- // because a temp file was created already
- if(preg_match('/\.('.$regex.')$/i',$fn)){
- //check for overwrite
- if(@file_exists($fn) && (!$_POST['ow'] || $AUTH < AUTH_DELETE)){
- msg($lang['uploadexist'],0);
- return false;
- }
- // prepare directory
- io_makeFileDir($fn);
- if(move_uploaded_file($file['tmp_name'], $fn)) {
- // set the correct permission here
- if($conf['fperm']) chmod($fn, $conf['fperm']);
- msg($lang['uploadsucc'],1);
- return true;
- }else{
- msg($lang['uploadfail'],-1);
- }
- }else{
- msg($lang['uploadwrong'],-1);
- }
- return false;
-}
-
-/**
- * Userfunction for html_buildlist
- *
- * Prints available media namespaces
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function media_html_list_namespaces($item){
- $ret = '';
- $ret .= '<a href="'.DOKU_BASE.'lib/exe/media.php?ns='.idfilter($item['id']).'" class="idx_dir">';
- $pos = strrpos($item['id'], ':');
- $ret .= substr($item['id'], $pos > 0 ? $pos + 1 : 0);
- $ret .= '</a>';
- return $ret;
-}
-
-/**
- * Saves image meta data
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-function media_metasave($src,$data){
- global $lang;
-
- $meta = new JpegMeta($src);
- $meta->_parseAll();
-
- foreach($data as $key => $val){
- $val=trim($val);
- if(empty($val)){
- $meta->deleteField($key);
- }else{
- $meta->setField($key,$val);
- }
- }
-
- if($meta->save()){
- msg($lang['metasaveok'],1);
- }else{
- msg($lang['metasaveerr'],-1);
- }
-}
-
-?>
diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
new file mode 100644
index 000000000..8b645e434
--- /dev/null
+++ b/lib/exe/mediamanager.php
@@ -0,0 +1,53 @@
+<?
+ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+ define('DOKU_MEDIAMANAGER',1);
+ require_once(DOKU_INC.'inc/init.php');
+ require_once(DOKU_INC.'inc/lang/en/lang.php');
+ require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
+ require_once(DOKU_INC.'inc/media.php');
+ require_once(DOKU_INC.'inc/common.php');
+ require_once(DOKU_INC.'inc/search.php');
+ require_once(DOKU_INC.'inc/template.php');
+ require_once(DOKU_INC.'inc/auth.php');
+ session_write_close(); //close session
+
+
+ // get namespace to display (either direct or from deletion order)
+ if($_REQUEST['delete']){
+ $DEL = cleanID($_REQUEST['delete']);
+ $NS = getNS($DEL);
+ }elseif($_REQUEST['edit']){
+ $IMG = cleanID($_REQUEST['edit']);
+ $NS = getNS($IMG);
+ }elseif($_REQUEST['img']){
+ $IMG = cleanID($_REQUEST['img']);
+ $NS = getNS($IMG);
+ }else{
+ $NS = $_REQUEST['ns'];
+ $NS = cleanID($NS);
+ }
+
+ // check auth
+ $AUTH = auth_quickaclcheck("$NS:*");
+
+ // create the given namespace (just for beautification)
+ if($AUTH >= AUTH_UPLOAD) io_makeFileDir(mediaFN("$NS:xxx"));
+
+ // handle upload
+ if($_FILES['upload']['tmp_name']){
+ $JUMPTO = media_upload($NS,$AUTH);
+ }
+
+ // handle meta saving
+ if($IMG && $_REQUEST['do']['save']){
+ $JUMPTO = media_metasave($IMG,$AUTH,$_REQUEST['meta']);
+ }
+
+ // handle deletion
+ if($DEL) {
+ $INUSE = media_delete($DEL,$AUTH);
+ }
+
+ // finished - start output
+ header('Content-Type: text/html; charset=utf-8');
+ include(template('mediamanager.php'));
diff --git a/lib/images/fileicons/gif.png b/lib/images/fileicons/gif.png
new file mode 100644
index 000000000..3c32f3016
--- /dev/null
+++ b/lib/images/fileicons/gif.png
Binary files differ
diff --git a/lib/images/fileicons/jpeg.png b/lib/images/fileicons/jpeg.png
new file mode 100644
index 000000000..3c32f3016
--- /dev/null
+++ b/lib/images/fileicons/jpeg.png
Binary files differ
diff --git a/lib/images/fileicons/jpg.png b/lib/images/fileicons/jpg.png
new file mode 100644
index 000000000..3c32f3016
--- /dev/null
+++ b/lib/images/fileicons/jpg.png
Binary files differ
diff --git a/lib/images/fileicons/png.png b/lib/images/fileicons/png.png
new file mode 100644
index 000000000..3c32f3016
--- /dev/null
+++ b/lib/images/fileicons/png.png
Binary files differ
diff --git a/lib/images/fileicons/swf.png b/lib/images/fileicons/swf.png
new file mode 100644
index 000000000..03bc8ab48
--- /dev/null
+++ b/lib/images/fileicons/swf.png
Binary files differ
diff --git a/lib/images/fileicons/tar.png b/lib/images/fileicons/tar.png
new file mode 100644
index 000000000..dfa8b586e
--- /dev/null
+++ b/lib/images/fileicons/tar.png
Binary files differ
diff --git a/lib/images/fileicons/txt.png b/lib/images/fileicons/txt.png
index 2bd690434..758950fd2 100644
--- a/lib/images/fileicons/txt.png
+++ b/lib/images/fileicons/txt.png
Binary files differ
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;
}
diff --git a/lib/tpl/default/media.css b/lib/tpl/default/media.css
new file mode 100644
index 000000000..96aac41ce
--- /dev/null
+++ b/lib/tpl/default/media.css
@@ -0,0 +1,115 @@
+/**
+ * The CSS in here cotrols the appearance of the media manager
+ */
+
+#media__left {
+ width: 30%;
+ float: left;
+ border-right: solid 1px __dark__;
+}
+
+#media__right {
+ width: 68%;
+ float: left;
+ border-left: solid 1px __dark__;
+ margin-left: -1px;
+}
+
+#media__tree img {
+ float:left;
+ padding: 0.5em 0.3em 0 0;
+}
+
+#media__tree ul {
+ list-style-type: none;
+ list-style-image: none;
+}
+
+#media__tree li {
+ clear: left;
+ list-style-type: none;
+ list-style-image: none;
+}
+
+/* --- file list --- */
+
+#media__content img.load {
+ margin: 1em auto;
+}
+
+#media__content #scroll__here {
+ border: 1px dashed __dark__;
+}
+
+#media__content .odd {
+ background-color: __lighter__;
+ padding: 0.4em;
+}
+
+#media__content .even {
+ padding: 0.4em;
+}
+
+#media__content a.mediafile {
+ margin-right: 1.5em;
+ font-weight: bold;
+}
+
+#media__content div.detail {
+ padding: 0.3em 0 0.3em 2em;
+}
+
+#media__content div.detail div.thumb {
+ float: left;
+ width: 130px;
+ text-align: center;
+ margin-right: 0.4em;
+}
+
+
+#media__content img.btn {
+ vertical-align: text-bottom;
+}
+
+/* --- upload form --- */
+
+#media__content form.upload {
+ display: block;
+ border-bottom: solid 1px __dark__;
+ padding: 0 0 1em 2em;
+}
+
+/* --- meta edit form --- */
+
+#media__content form.meta {
+ display: block;
+ padding: 0 0 1em 0;
+}
+
+#media__content form.meta label {
+ display: block;
+ width: 20%;
+ float: left;
+ text-align: right;
+ font-weight: bold;
+ padding-right: 1em;
+}
+
+#media__content form.meta .edit {
+ float: left;
+ width: 75%;
+}
+
+#media__content form.meta textarea.edit {
+ height: 6em;
+}
+
+#media__content form.meta div.metafield {
+ clear: left;
+}
+
+#media__content form.meta div.buttons {
+ clear: left;
+ margin-left: 20%;
+ padding-left: 1em;
+}
diff --git a/lib/tpl/default/media.php b/lib/tpl/default/media.php
deleted file mode 100644
index c2c632e46..000000000
--- a/lib/tpl/default/media.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<?php
-/**
- * DokuWiki Default Template
- *
- * This is the template for the media selection popup.
- *
- * You should leave the doctype at the very top - It should
- * always be the very first line of a document.
- *
- * @link http://wiki.splitbrain.org/wiki:tpl:templates
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-?>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title><?php echo hsc($lang['mediaselect'])?> [<?php echo hsc($conf['title'])?>]</title>
-
- <?php tpl_metaheaders()?>
-
- <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
-
-</head>
-
-<body>
-<div class="dokuwiki">
- <?php html_msgarea()?>
-
- <h1><?php echo hsc($lang['mediaselect'])?> <code><?php echo hsc($NS)?></code></h1>
-
- <div class="mediaselect">
-
- <div class="mediaselect-left">
- <strong><a href="<?php echo DOKU_BASE?>lib/exe/media.php?ns="><?php echo hsc($lang['namespaces'])?></a></strong>
-
- <?php tpl_medianamespaces()?>
- </div>
-
- <div class="mediaselect-right">
- <?php tpl_mediafilelist()?>
-
- <div class="uploadform">
- <?php tpl_mediauploadform()?>
- </div>
- </div>
-
- </div>
-
-</div>
-</body>
-</html>
-
diff --git a/lib/tpl/default/mediaedit.php b/lib/tpl/default/mediaedit.php
deleted file mode 100644
index 79175e009..000000000
--- a/lib/tpl/default/mediaedit.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<?php
-/**
- * DokuWiki Default Template
- *
- * This is the template for editing image meta data.
- * It is displayed in the media popup.
- *
- * You should leave the doctype at the very top - It should
- * always be the very first line of a document.
- *
- * @link http://wiki.splitbrain.org/wiki:tpl:templates
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-?>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title><?php echo hsc($lang['mediaselect'])?> [<?php echo hsc($conf['title'])?>]</title>
-
- <?php tpl_metaheaders()?>
-
- <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
-</head>
-
-<body>
-<div class="dokuwiki">
- <?php html_msgarea()?>
-
- <h1><?php echo hsc($lang['metaedit'])?> <code><?php echo hsc(noNS($IMG))?></code></h1>
-
- <div class="mediaedit">
- <?php/* everything in meta array is tried to save and read */?>
-
- <div class="data">
- <form action="<?php echo DOKU_BASE?>lib/exe/media.php" accept-charset="utf-8" method="post">
- <input type="hidden" name="edit" value="<?php echo hsc($IMG)?>" />
- <input type="hidden" name="save" value="1" />
-
- <label class="block" for="img__title"><?php echo $lang['img_title']?></label>
- <input type="text" name="meta[Iptc.Headline]" id="img__title" class="edit"
- value="<?php echo hsc(tpl_img_getTag('IPTC.Headline'))?>" /><br />
-
- <label class="block" for="img__caption"><?php echo $lang['img_caption']?></label>
- <textarea name="meta[Iptc.Caption]" id="img__caption" class="edit" rows="5"><?php
- echo hsc(tpl_img_getTag(array('IPTC.Caption',
- 'EXIF.UserComment',
- 'EXIF.TIFFImageDescription',
- 'EXIF.TIFFUserComment')));
- ?></textarea><br />
-
- <label class="block" for="img__artist"><?php echo $lang['img_artist']?></label>
- <input type="text" name="meta[Iptc.Byline]" id="img__artist" class="edit"
- value="<?php echo hsc(tpl_img_getTag(array('Iptc.Byline',
- 'Exif.TIFFArtist',
- 'Exif.Artist',
- 'Iptc.Credit')))?>" /><br />
-
- <label class="block" for="img__copy"><?php echo $lang['img_copyr']?></label>
- <input type="text" name="meta[Iptc.CopyrightNotice]" id="img__copy" class="edit"
- value="<?php echo hsc(tpl_img_getTag(array('Iptc.CopyrightNotice','Exif.TIFFCopyright','Exif.Copyright')))?>" /><br />
-
-
- <label class="block" for="img__keywords"><?php echo $lang['img_keywords']?></label>
- <textarea name="meta[Iptc.Keywords]" id="img__keywords" class="edit"><?php
- echo hsc(tpl_img_getTag(array('IPTC.Keywords',
- 'EXIF.Category')));
- ?></textarea><br />
-
-
- <input type="submit" value="<?php echo $lang['btn_save']?>" title="ALT+S"
- accesskey="s" class="button" />
-
- </form>
- </div>
-
-
- <div class="footer">
- <hr />
- <?php tpl_button('backtomedia')?>
- </div>
- </div>
-
-</div>
-</body>
-</html>
diff --git a/lib/tpl/default/mediaref.php b/lib/tpl/default/mediamanager.php
index 06af5764c..10b31ba63 100644
--- a/lib/tpl/default/mediaref.php
+++ b/lib/tpl/default/mediamanager.php
@@ -4,8 +4,7 @@
/**
* DokuWiki Default Template
*
- * This is the template for displaying references to a media file.
- * It is displayed in the media popup.
+ * This is the template for the media manager popup
*
* You should leave the doctype at the very top - It should
* always be the very first line of a document.
@@ -18,33 +17,25 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo hsc($lang['mediaselect'])?> [<?php echo hsc($conf['title'])?>]</title>
-
<?php tpl_metaheaders()?>
-
<link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
-
</head>
<body>
-<div class="dokuwiki">
- <?php html_msgarea()?>
+<div id="media__manager" class="dokuwiki">
+ <?html_msgarea()?>
+ <div id="media__left">
+ <h1><?php echo hsc($lang['mediaselect'])?></h1>
- <h1><?php echo hsc($lang['reference'])?> <code><?php echo hsc(noNS($DEL))?></code></h1>
+ <?php tpl_mediaTree() ?>
- <div class="mediaref">
- <div class="mediaref_head">
- <p><?php echo hsc($lang['ref_inuse'])?></p>
+ <?php /* keep the id! additional elements are inserted via JS here */?>
+ <div id="media__opts"></div>
</div>
- <?php tpl_showreferences($mediareferences)?>
-
- <div class="mediaref_footer">
- <hr />
- <?php tpl_button('backtomedia')?>
+ <div id="media__right">
+ <?php tpl_mediaContent() ?>
</div>
- </div>
-
</div>
</body>
</html>
-
diff --git a/lib/tpl/default/style.ini b/lib/tpl/default/style.ini
index e6452ad90..bb4cd2305 100644
--- a/lib/tpl/default/style.ini
+++ b/lib/tpl/default/style.ini
@@ -9,6 +9,9 @@
layout.css = screen
design.css = screen
style.css = screen
+
+media.css = screen
+
rtl.css = rtl
print.css = print