MDL-13766
authordongsheng <dongsheng>
Thu, 31 Jul 2008 02:51:28 +0000 (02:51 +0000)
committerdongsheng <dongsheng>
Thu, 31 Jul 2008 02:51:28 +0000 (02:51 +0000)
1. Filepicker component for moodleform
2. Integrate TinyMCE and FilePicker
3. Fix show/hide bug in filepicker
4. Rewrite print_login function for ajax

lang/en_utf8/repository.php
lib/editor/tinymce.js.php
lib/form/filepicker.php [new file with mode: 0644]
lib/formslib.php
lib/weblib.php
repository/ajax.php
repository/boxnet/lang/en_utf8/repository_boxnet.php
repository/boxnet/repository.class.php
repository/flickr/lang/en_utf8/repository_flickr.php
repository/lib.php

index 0593262..edecbd4 100644 (file)
@@ -4,3 +4,16 @@ $string['repositories'] = 'Repositories';
 $string['manageuserrepository'] = 'Manage individual repository';
 $string['plugin'] = 'Repository Plug-ins';
 $string['settings'] = 'Settings';
+$string['openpicker'] = 'Open file picker';
+$string['submit'] = 'Submit';
+$string['listview'] = 'List View';
+$string['thumbview'] = 'Thumbnail View';
+$string['search'] = 'Search ';
+$string['logout'] = 'Logout';
+$string['loading'] = 'Loading...';
+$string['title'] = 'Repository File Picker';
+$string['filename'] = 'Filename';
+$string['sync'] = 'Sync';
+$string['download'] = 'Download';
+$string['back'] = '&lt; Back';
+$string['close'] = 'Close';
index 486edaa..986da2f 100644 (file)
@@ -205,18 +205,7 @@ echo <<<EOF
         tinyMCE.execCommand('mceToggleEditor',false,id);
     }
     function mce_moodlefilemanager(field_name, url, type, win) {
-        tinyMCE.activeEditor.windowManager.open({
-            file: "{$CFG->httpswwwroot}/lib/editor/tinymce/jscripts/tiny_mce/plugins/moodlelink/link.php?id={$courseid}",
-            width: 480,  
-            height: 380,
-            resizable: "yes",
-            inline: "yes",  
-            close_previous: "no"
-        }, {
-            window: win,
-            input: field_name
-        });
-        return false;
+         openpicker();
     }
     function mce_saveOnSubmit(id) {
         var prevOnSubmit = document.getElementById(id).form.onsubmit;
diff --git a/lib/form/filepicker.php b/lib/form/filepicker.php
new file mode 100644 (file)
index 0000000..249dc19
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+// $Id$
+
+require_once("HTML/QuickForm/button.php");
+require_once(dirname(dirname(dirname(__FILE__))) . '/repository/lib.php');
+
+/**
+ * HTML class for a button type element
+ *
+ * @author       Dongsheng Cai <dongsheng@cvs.moodle.org>
+ * @version      1.0
+ * @since        Moodle 2.0
+ * @access       public
+ */
+class MoodleQuickForm_filepicker extends HTML_QuickForm_button
+{
+    var $_helpbutton='';
+    function setHelpButton($helpbuttonargs, $function='helpbutton'){
+        if (!is_array($helpbuttonargs)){
+            $helpbuttonargs=array($helpbuttonargs);
+        }else{
+            $helpbuttonargs=$helpbuttonargs;
+        }
+        //we do this to to return html instead of printing it
+        //without having to specify it in every call to make a button.
+        if ('helpbutton' == $function){
+            $defaultargs=array('', '', 'moodle', true, false, '', true);
+            $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+        }
+        $this->_helpbutton=call_user_func_array($function, $helpbuttonargs);
+    }
+    function getHelpButton(){
+        return $this->_helpbutton;
+    }
+    function getElementTemplateType(){
+        if ($this->_flagFrozen){
+            return 'nodisplay';
+        } else {
+            return 'default';
+        }
+    }
+    function toHtml() {
+        global $CFG;
+        if ($this->_flagFrozen) {
+            return $this->getFrozenHtml();
+        } else {
+            $ret = get_repository_client();
+            return $this->_getTabs() . '<input' . $this->_getAttrString($this->_attributes) . ' onclick=\'openpicker()\' />'.$ret['html'].$ret['js'];
+        }
+    }
+}
index e8cd578..bc00cf0 100644 (file)
@@ -1850,6 +1850,7 @@ $GLOBALS['_HTML_QuickForm_default_renderer'] =& new MoodleQuickForm_Renderer();
 
 MoodleQuickForm::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'MoodleQuickForm_checkbox');
 MoodleQuickForm::registerElementType('file', "$CFG->libdir/form/file.php", 'MoodleQuickForm_file');
+MoodleQuickForm::registerElementType('filepicker', "$CFG->libdir/form/filepicker.php", 'MoodleQuickForm_filepicker');
 MoodleQuickForm::registerElementType('group', "$CFG->libdir/form/group.php", 'MoodleQuickForm_group');
 MoodleQuickForm::registerElementType('password', "$CFG->libdir/form/password.php", 'MoodleQuickForm_password');
 MoodleQuickForm::registerElementType('passwordunmask', "$CFG->libdir/form/passwordunmask.php", 'MoodleQuickForm_passwordunmask');
index e95102e..83174aa 100644 (file)
@@ -43,6 +43,8 @@ require_once("$CFG->libdir/filterlib.php");
 
 require_once("$CFG->libdir/ajax/ajaxlib.php");
 
+require_once("$CFG->dirroot/repository/lib.php");
+
 /// Constants
 
 /// Define text formatting types ... eventually we can add Wiki, BBcode etc
@@ -4871,6 +4873,8 @@ function print_textarea($usehtmleditor, $rows, $cols, $width, $height, $name, $v
     if ($usehtmleditor) {
         $str_toggle = '<span class="helplink"><a href="javascript:mce_toggleEditor(\''. $id .'\');"><img width="50" height="17" src="'. $CFG->httpswwwroot .'/lib/editor/tinymce/images/toggle.gif" alt="'. get_string('editortoggle') .'" title="'. get_string('editortoggle') .'" class="icontoggle" /></a></span>';
         // Show shortcuts button if HTML editor is in use, but only if JavaScript is enabled (MDL-9556)
+        $ret = get_repository_client();
+        $str .= $ret['html'].$ret['js'];
         $str .= '<div class="textareaicons">';
         $str .= '<script type="text/javascript">
 //<![CDATA[
index e139a95..bc433bb 100644 (file)
@@ -35,48 +35,7 @@ if(!empty($_GET['create'])) {
   picker.
 
 \*******************************************************/
-$meta = <<<EOD
-<link rel="stylesheet" type="text/css" href="../lib/yui/reset-fonts-grids/reset-fonts-grids.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/reset/reset-min.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/resize/assets/skins/sam/resize.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/container/assets/skins/sam/container.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/layout/assets/skins/sam/layout.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/button/assets/skins/sam/button.css" />
-<link rel="stylesheet" type="text/css" href="../lib/yui/menu/assets/skins/sam/menu.css" />
-<style type="text/css">
-body {margin:0; padding:0; background: #FFF7C6;}
-img{margin:0;padding:0;border:0}
-h1{font-size: 36px}
-#list{line-height: 1.5em}
-#list a{ padding: 3px }
-#list li a:hover{ background: gray; color:white; }
-#paging{margin:10px 5px; clear:both}
-#paging a{padding: 4px; border: 1px solid gray}
-#panel{padding:0;margin:0; text-align:left;}
-.file_name{color:green;}
-.file_date{color:blue}
-.file_size{color:gray}
-.grid{width:80px; float:left;text-align:center;}
-.grid div{width: 80px; height: 36px; overflow: hidden}
-.repo-opt{font-size: 10px;color:red}
-</style>
-<script type="text/javascript" src="../lib/yui/yahoo/yahoo.js"></script>
-<script type="text/javascript" src="../lib/yui/event/event.js"></script>
-<script type="text/javascript" src="../lib/yui/dom/dom.js"></script>
-<script type="text/javascript" src="../lib/yui/element/element-beta.js"></script>
-<script type="text/javascript" src="../lib/yui/dragdrop/dragdrop.js"></script>
-<script type="text/javascript" src="../lib/yui/container/container.js"></script>
-<script type="text/javascript" src="../lib/yui/resize/resize-beta.js"></script>
-<script type="text/javascript" src="../lib/yui/animation/animation.js"></script>
-<script type="text/javascript" src="../lib/yui/layout/layout-beta.js"></script>
-<script type="text/javascript" src="../lib/yui/connection/connection.js"></script>
-<script type="text/javascript" src="../lib/yui/json/json.js"></script>
-<script type="text/javascript" src="../lib/yui/menu/menu.js"></script>
-<script type="text/javascript" src="../lib/yui/button/button-debug.js"></script>
-<script type="text/javascript" src="../lib/yui/selector/selector-beta.js"></script>
-<script type="text/javascript" src="../lib/yui/logger/logger.js"></script>
-EOD;
-echo $meta;
+$ret = get_repository_client();
 ?>
 </head>
 <body class=" yui-skin-sam">
@@ -122,314 +81,8 @@ if(btn){
 }
 </script>
 </div>
-<script type="text/javascript">
-var repository_client = (function() {
-    // private static field
-    var dver = '1.0';
-    // private static methods
-    function alert_version(){
-        alert(dver);
-    }
-    function _client(){
-        // public varible
-        this.name = 'repository_client';
-        // private varible
-        var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, layout = null, resize = null;
-        var IE_QUIRKS = (YAHOO.env.ua.ie && document.compatMode == "BackCompat");
-        var IE_SYNC = (YAHOO.env.ua.ie == 6 || (YAHOO.env.ua.ie == 7 && IE_QUIRKS));
-        var PANEL_BODY_PADDING = (10*2);
-        var btn_list = {label: 'List', value: 'l', checked: true, onclick: {fn: _client.viewlist}};
-        var btn_thumb = {label: 'Thumbnail', value: 't', onclick: {fn: _client.viewthumb}};
-        var select = new YAHOO.util.Element('select');
-        var list = null;
-        var resize = null;
-        var panel = new YAHOO.widget.Panel('file-picker', {
-            draggable: true,
-            close: false,
-            underlay: 'none',
-            width: '510px',
-            xy: [100, 100]
-        });
-        // construct code section
-        {
-            panel.setHeader('Moodle Repository Picker');
-            panel.setBody('<div id="layout"></div>');
-            panel.beforeRenderEvent.subscribe(function() {
-                Event.onAvailable('layout', function() {
-                    layout = new YAHOO.widget.Layout('layout', {
-                        height: 400, width: 490,
-                        units: [
-                            {position: 'top', height: 32, resize: false, 
-                            body:'<div class="yui-buttongroup" id="repo-viewbar"></div>', gutter: '2'},
-                            {position: 'left', width: 150, resize: true, 
-                            body:'<ul id="repo-list"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
-                            {position: 'center', body: '<div id="panel"></div>', 
-                            scroll: true, gutter: '0 2 0 0' }
-                        ]
-                    });
-                    layout.render();
-                });
-            });
-            resize = new YAHOO.util.Resize('file-picker', {
-                handles: ['br'],
-                autoRatio: true,
-                status: true,
-                minWidth: 380,
-                minHeight: 400
-            });
-            resize.on('resize', function(args) {
-                var panelHeight = args.height;
-                var headerHeight = this.header.offsetHeight; // Content + Padding + Border
-                var bodyHeight = (panelHeight - headerHeight);
-                var bodyContentHeight = (IE_QUIRKS) ? bodyHeight : bodyHeight - PANEL_BODY_PADDING;
-                YAHOO.util.Dom.setStyle(this.body, 'height', bodyContentHeight + 'px');
-                if (IE_SYNC) {
-                    this.sizeUnderlay();
-                    this.syncIframe();
-                }
-                layout.set('height', bodyContentHeight);
-                layout.set('width', (args.width - PANEL_BODY_PADDING));
-                layout.resize();
-
-            }, panel, true);
-            _client.viewbar = new YAHOO.widget.ButtonGroup({
-                id: 'btngroup',
-                name: 'buttons',
-                disabled: true,
-                container: 'repo-viewbar'
-                });
-        }
-        // public method
-        this.create_picker = function(){
-            // display UI
-            panel.render();
-            _client.viewbar.addButtons([btn_list, btn_thumb]);
-            // init repository list
-            list = new YAHOO.util.Element('repo-list');
-            list.on('contentReady', function(e){
-                for(var i=0; i<_client.repos.length; i++) {
-                    var repo = _client.repos[i];
-                    li = document.createElement('ul');
-                    li.innerHTML = '<a href="###" id="repo-call-'+repo.id+'">'+
-                        repo.repositoryname+'</a><br/>';
-                    li.innerHTML += '<a href="###" class="repo-opt" onclick="repository_client.search('+repo.id+')">Search</a>';
-                    li.innerHTML += '<a href="###" class="repo-opt" id="repo-logout-'+repo.id+'">Logout</a>';
-                    li.id = 'repo-'+repo.id;
-                    this.appendChild(li);
-                    var e = new YAHOO.util.Element('repo-call-'+repo.id);
-                    e.on('click', function(e){
-                        var re = /repo-call-(\d+)/i;
-                        var id = this.get('id').match(re);
-                        repository_client.req(id[1], 1, 0);
-                        });
-                    e = new YAHOO.util.Element('repo-logout-'+repo.id);
-                    e.on('click', function(e){
-                        var re = /repo-logout-(\d+)/i;
-                        var id = this.get('id').match(re);
-                        repository_client.req(id[1], 1, 1);
-                        });
-                    repo = null;
-                }
-                });
-        }
-    }
-    // public static varible
-    _client.repos = [];
-    _client.repositoryid = 0;
-    _client.datasource, 
-    _client.viewmode = 0;
-    _client.viewbar =null;
-    // public static mehtod
-    _client.postdata = function(obj) {
-        var str = '';
-        for(k in obj) {
-            if(obj[k] instanceof Array) {
-                for(i in obj[k]) {
-                    str += (encodeURIComponent(k) +'[]='+encodeURIComponent(obj[k][i]));
-                    str += '&';
-                }
-            } else {
-                str += encodeURIComponent(k) +'='+encodeURIComponent(obj[k]);
-                str += '&';
-            }
-        }
-        return str;
-    }
-    _client.loading = function(){
-        var panel = new YAHOO.util.Element('panel');
-        panel.get('element').innerHTML = '<img src="<?php echo $CFG->pixpath.'/i/loading.gif'?>" alt="loading..." />';
-    }
-    _client.rename = function(oldname, url){
-        var panel = new YAHOO.util.Element('panel');
-        var html = '<div>';
-        html += '<label for="newname">Name:</label>';
-        html += '<input type="text" id="newname" value="'+oldname+'" /><br/>';
-        html += '<label for="syncfile">Sync?</label>';
-        html += '<input type="checkbox" id="syncfile" /><br/>';
-        html += '<input type="hidden" id="fileurl" value="'+url+'" />';
-        html += '<input type="button" onclick="repository_client.download()" value="Download" />';
-        html += '<a href="###" onclick="repository_client.viewfiles()">Back</a>';
-        html += '</div>';
-        panel.get('element').innerHTML = html;
-    }
-    _client.print_login = function(){
-        var panel = new YAHOO.util.Element('panel');
-        var data = _client.datasource.l;
-        panel.get('element').innerHTML = data;
-    }
-
-    _client.viewfiles = function(){
-        if(_client.viewmode) {
-            _client.viewthumb();
-        } else {
-            _client.viewlist();
-        }
-    }
-
-    _client.viewthumb = function(){
-        var panel = new YAHOO.util.Element('panel');
-        _client.viewbar.check(1);
-        obj = _client.datasource.list;
-        var str = '';
-        str += _client.makepage();
-        for(k in obj){
-            str += '<div class="grid">';
-            str += '<img title="'+obj[k].title+'" src="'+obj[k].thumbnail+'" />';
-            str += '<div style="text-align:center">';
-            str += ('<input type="radio" title="'+obj[k].title
-                    +'" name="selected-files" value="'+obj[k].source
-                    +'" onclick=\'repository_client.rename("'+obj[k].title+'", "'
-                    +obj[k].source+'")\' />');
-            str += obj[k].title+'</div>';
-            str += '</div>';
-        }
-        panel.get('element').innerHTML = str;
-        _client.viewmode = 1;
-        return str;
-    }
-
-    _client.viewlist = function(){
-        var panel = new YAHOO.util.Element('panel');
-        var str = '';
-        _client.viewbar.check(0);
-        obj = _client.datasource.list;
-        str += _client.makepage();
-        var re = new RegExp();
-        re.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
-        for(k in obj){
-            str += ('<input type="radio" title="'+obj[k].title+'" name="selected-files" value="'+obj[k].source+'" onclick=\'repository_client.rename("'+obj[k].title+'", "'+obj[k].source+'")\' /> ');
-            if(re.test(obj[k].source)) {
-                str += '<a class="file_name" href="'+obj[k].source+'">'+obj[k].title+'</a>';
-            } else {
-                str += '<span class="file_name" >'+obj[k].title+'</span>';
-            }
-            str += '<br/>';
-            str += '<label>Date: </label><span class="file_date">'+obj[k].date+'</span><br/>';
-            str += '<label>Size: </label><span class="file_size">'+obj[k].size+'</span>';
-            str += '<br/>';
-        }
-        panel.get('element').innerHTML = str;
-        _client.viewmode = 0;
-        return str;
-    }
-    // XXX: A ugly hack to show paging for flickr
-    _client.makepage = function(){
-        var str = '';
-        if(_client.datasource.pages){
-            str += '<div id="paging">';
-            for(var i = 1; i <= _client.datasource.pages; i++) {
-                str += '<a onclick="repository_client.req('+_client.repositoryid+', '+i+', 0)" href="###">';
-                str += String(i);
-                str += '</a> ';
-            }
-            str += '</div>';
-        }
-        return str;
-    }
-    _client.download = function(){
-        var title = document.getElementById('newname').value;
-        var file = document.getElementById('fileurl').value;
-        _client.loading();
-        var trans = YAHOO.util.Connect.asyncRequest('POST', 
-            'ws.php?id='+_client.repositoryid+'&action=download', _client.dlfile, 
-            _client.postdata({'file':file, 'title':title}));
-    }
-    _client.login = function(){
-        YAHOO.util.Connect.setForm('moodle-repo-login');
-        _client.loading();
-        var trans = YAHOO.util.Connect.asyncRequest('POST', 'ws.php', _client.callback);
-    }
-    _client.callback = {
-    success: function(o) {
-        var panel = new YAHOO.util.Element('panel');
-        try {
-            var ret = YAHOO.lang.JSON.parse(o.responseText);
-        } catch(e) {
-            alert('Callback: Invalid JSON String\n'+o.responseText);
-        }
-        if(ret.e){
-            panel.get('element').innerHTML = ret.e;
-            return;
-        }
-        _client.datasource = ret;
-        if(_client.datasource.l){
-            _client.print_login();
-        } else if(_client.datasource.list) {
-            if(_client.viewmode) {
-                _client.viewthumb();
-            } else {
-                _client.viewlist();
-            }
-        }
-      }
-    }
-    _client.dlfile = {
-    success: function(o) {
-        var panel = new YAHOO.util.Element('panel');
-        try {
-            var ret = YAHOO.lang.JSON.parse(o.responseText);
-        } catch(e) {
-            alert('Invalid JSON String\n'+o.responseText);
-        }
-        if(ret.e){
-            panel.get('element').innerHTML = ret.e;
-            return;
-        }
-        var html = '<h1>Download Successfully!</h1>';
-        html += '<a href="###" onclick="repository_client.viewfiles()">Back</a>';
-        panel.get('element').innerHTML = html;
-      }
-    }
-    // request file list or login
-    _client.req = function(id, path, reset) {
-        _client.viewbar.set('disabled', false);
-        _client.loading();
-        _client.repositoryid = id;
-        var trans = YAHOO.util.Connect.asyncRequest('GET', 'ws.php?id='+id+'&p='+path+'&reset='+reset, _client.callback);
-    }
-    _client.search = function(id){
-        var data = window.prompt("What are you searching for?");
-        if(data == null || data == '') {
-            alert('nothing entered');
-            return;
-        }
-        _client.viewbar.set('disabled', false);
-        _client.loading();
-        var trans = YAHOO.util.Connect.asyncRequest('GET', 'ws.php?id='+id+'&s='+data, _client.callback);
-    }
-    return _client;
-})();
 <?php
-$repos = repository_instances();
-foreach($repos as $repo) {
-    echo 'repository_client.repos.push('.json_encode($repo).');'."\n";
-    echo "\n";
-}
+echo $ret['js'];
 ?>
-function openpicker(){
-    var r = new repository_client();
-    r.create_picker();
-}
-</script>
 </body>
 </html>
index 013c198..184380b 100644 (file)
@@ -8,3 +8,5 @@ $string['saved'] = 'Box.net data saved.';
 $string['invalidpassword'] = 'Invalid password';
 $stirng['invalidtoken'] = 'Invalid auth-token';
 $string['nullfilelist'] = 'There are no files in this repository';
+$string['username'] = 'Box.net Account:';
+$string['password'] = 'Your Password:';
index 1374cee..7cd4b06 100755 (executable)
@@ -61,6 +61,9 @@ class repository_boxnet extends repository{
         if ($entry = $DB->get_record('repository', array('id'=>$this->repositoryid))) {
             $ret->username = $entry->username;
             $ret->password = $entry->password;
+        } else {
+            $ret->username = '';
+            $ret->password = '';
         }
         return $ret;
     }
@@ -126,9 +129,28 @@ class repository_boxnet extends repository{
                 $str .= '<input type="password" value="'.$ret->password.'" id="box_password" name="password" /><br/>';
                 $str .= '<input type="button" onclick="repository_client.login()" value="Go" />';
                 $str .= '</form>';
-                if($this->options['ajax']){
+                if ($this->options['ajax']) {
+                    $e1->type = 'hidden';
+                    $e1->name = 'ticket';
+                    $e1->value = $t['ticket'];
+
+                    $e2->type = 'hidden';
+                    $e2->name = 'id';
+                    $e2->value = $this->repositoryid;
+
+                    $e3->label = get_string('username', 'repository_boxnet');
+                    $e3->id    = 'box_username';
+                    $e3->type  = 'text';
+                    $e3->name  = 'username';
+                    $e3->value = $ret->username;
+                    
+                    $e4->label = get_string('password', 'repository_boxnet');
+                    $e4->id    = 'box_password';
+                    $e4->type  = 'password';
+                    $e4->name  = 'password';
+
                     $ret = array();
-                    $ret['l'] = $str;
+                    $ret['l'] = array($e1, $e2, $e3, $e4);
                     return $ret;
                 } else {
                     echo $str;
index ce54de8..43135b8 100644 (file)
@@ -2,3 +2,5 @@
 $string['repositoryname'] = 'Flickr';
 $string['repositorydesc'] = 'Repository for flickr.com';
 $string['notitle'] = 'notitle';
+$string['username'] = 'Flickr Account:';
+$string['remember'] = 'Remember me';
index 2844121..431c1f2 100644 (file)
@@ -51,7 +51,7 @@
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  */
 require_once(dirname(dirname(__FILE__)) . '/config.php');
-require_once($CFG->libdir.'/filelib.php');
+require_once(dirname(dirname(__FILE__)).'/lib/filelib.php');
 
 abstract class repository {
     protected $options;
@@ -331,3 +331,416 @@ function repository_get_plugins(){
     }
     return $ret;
 }
+function get_repository_client(){
+    global $CFG;
+    $strsubmit    = get_string('submit', 'repository');
+    $strlistview  = get_string('listview', 'repository');
+    $strthumbview = get_string('thumbview', 'repository');
+    $strsearch    = get_string('search', 'repository');
+    $strlogout    = get_string('logout', 'repository');
+    $strloading   = get_string('loading', 'repository');
+    $strtitle     = get_string('title', 'repository');
+    $filename     = get_string('filename', 'repository');
+    $strsync      = get_string('sync', 'repository');
+    $strdownload  = get_string('download', 'repository');
+    $strback      = get_string('back', 'repository');
+    $strclose     = get_string('close', 'repository');
+
+    $js = <<<EOD
+    <style type="text/css">
+    #list{line-height: 1.5em}
+    #list a{ padding: 3px }
+    #list li a:hover{ background: gray; color:white; }
+    #paging{margin:10px 5px; clear:both}
+    #paging a{padding: 4px; border: 1px solid gray}
+    #panel{padding:0;margin:0; text-align:left;}
+    .file_name{color:green;}
+    .file_date{color:blue}
+    .file_size{color:gray}
+    .grid{width:80px; float:left;text-align:center;}
+    .grid div{width: 80px; height: 36px; overflow: hidden}
+    .repo-opt{font-size: 10px;color:red}
+    </style>
+    <style type="text/css">
+    @import "$CFG->wwwroot/lib/yui/reset-fonts-grids/reset-fonts-grids.css";
+    @import "$CFG->wwwroot/lib/yui/reset/reset-min.css";
+    @import "$CFG->wwwroot/lib/yui/resize/assets/skins/sam/resize.css";
+    @import "$CFG->wwwroot/lib/yui/container/assets/skins/sam/container.css";
+    @import "$CFG->wwwroot/lib/yui/layout/assets/skins/sam/layout.css";
+    @import "$CFG->wwwroot/lib/yui/button/assets/skins/sam/button.css";
+    @import "$CFG->wwwroot/lib/yui/menu/assets/skins/sam/menu.css";
+    </style>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/yahoo/yahoo.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/event/event.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/dom/dom.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/element/element-beta.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/dragdrop/dragdrop.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/container/container.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/resize/resize-beta.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/animation/animation.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/layout/layout-beta.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/connection/connection.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/json/json.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/menu/menu.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/button/button-debug.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/selector/selector-beta.js"></script>
+    <script type="text/javascript" src="$CFG->wwwroot/lib/yui/logger/logger.js"></script>
+    <script>
+    var repository_client = (function() {
+        // private static field
+        var dver = '1.0';
+        // private static methods
+        function alert_version(){
+            alert(dver);
+        }
+        function _client(){
+            // public varible
+            this.name = 'repository_client';
+            // private varible
+            var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, layout = null, resize = null;
+            var IE_QUIRKS = (YAHOO.env.ua.ie && document.compatMode == "BackCompat");
+            var IE_SYNC = (YAHOO.env.ua.ie == 6 || (YAHOO.env.ua.ie == 7 && IE_QUIRKS));
+            var PANEL_BODY_PADDING = (10*2);
+            var btn_list = {label: '$strlistview', value: 'l', checked: true, onclick: {fn: _client.viewlist}};
+            var btn_thumb = {label: '$strthumbview', value: 't', onclick: {fn: _client.viewthumb}};
+            var select = new YAHOO.util.Element('select');
+            var list = null;
+            var resize = null;
+            var panel = new YAHOO.widget.Panel('file-picker', {
+                draggable: true,
+                close: true,
+                underlay: 'none',
+                width: '510px',
+                zindex: 300006,
+                xy: [100, 100]
+            });
+            // construct code section
+            {
+                panel.setHeader('$strtitle');
+                panel.setBody('<div id="layout"></div>');
+                panel.beforeRenderEvent.subscribe(function() {
+                    Event.onAvailable('layout', function() {
+                        layout = new YAHOO.widget.Layout('layout', {
+                            height: 400, width: 490,
+                            units: [
+                                {position: 'top', height: 32, resize: false, 
+                                body:'<div class="yui-buttongroup" id="repo-viewbar"></div>', gutter: '2'},
+                                {position: 'left', width: 150, resize: true, 
+                                body:'<ul id="repo-list"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
+                                {position: 'center', body: '<div id="panel"></div>', 
+                                scroll: true, gutter: '0 2 0 0' }
+                            ]
+                        });
+                        layout.render();
+                    });
+                });
+                resize = new YAHOO.util.Resize('file-picker', {
+                    handles: ['br'],
+                    autoRatio: true,
+                    status: true,
+                    minWidth: 380,
+                    minHeight: 400
+                });
+                resize.on('resize', function(args) {
+                    var panelHeight = args.height;
+                    var headerHeight = this.header.offsetHeight; // Content + Padding + Border
+                    var bodyHeight = (panelHeight - headerHeight);
+                    var bodyContentHeight = (IE_QUIRKS) ? bodyHeight : bodyHeight - PANEL_BODY_PADDING;
+                    YAHOO.util.Dom.setStyle(this.body, 'height', bodyContentHeight + 'px');
+                    if (IE_SYNC) {
+                        this.sizeUnderlay();
+                        this.syncIframe();
+                    }
+                    layout.set('height', bodyContentHeight);
+                    layout.set('width', (args.width - PANEL_BODY_PADDING));
+                    layout.resize();
+
+                }, panel, true);
+                _client.viewbar = new YAHOO.widget.ButtonGroup({
+                    id: 'btngroup',
+                    name: 'buttons',
+                    disabled: true,
+                    container: 'repo-viewbar'
+                    });
+            }
+            // public method
+            this.show = function(){
+                panel.show();
+            }
+            this.create_picker = function(){
+                // display UI
+                panel.render();
+                _client.viewbar.addButtons([btn_list, btn_thumb]);
+                // init repository list
+                list = new YAHOO.util.Element('repo-list');
+                list.on('contentReady', function(e){
+                    for(var i=0; i<_client.repos.length; i++) {
+                        var repo = _client.repos[i];
+                        li = document.createElement('ul');
+                        li.innerHTML = '<a href="###" id="repo-call-'+repo.id+'">'+
+                            repo.repositoryname+'</a><br/>';
+                        li.innerHTML += '<a href="###" class="repo-opt" onclick="repository_client.search('+repo.id+')">$strsearch</a>';
+                        li.innerHTML += '<a href="###" class="repo-opt" id="repo-logout-'+repo.id+'">$strlogout</a>';
+                        li.id = 'repo-'+repo.id;
+                        this.appendChild(li);
+                        var e = new YAHOO.util.Element('repo-call-'+repo.id);
+                        e.on('click', function(e){
+                            var re = /repo-call-(\d+)/i;
+                            var id = this.get('id').match(re);
+                            repository_client.req(id[1], 1, 0);
+                            });
+                        e = new YAHOO.util.Element('repo-logout-'+repo.id);
+                        e.on('click', function(e){
+                            var re = /repo-logout-(\d+)/i;
+                            var id = this.get('id').match(re);
+                            repository_client.req(id[1], 1, 1);
+                            });
+                        repo = null;
+                    }
+                    });
+            }
+        }
+        // public static varible
+        _client.repos = [];
+        _client.repositoryid = 0;
+        _client.datasource, 
+        _client.viewmode = 0;
+        _client.viewbar =null;
+        // public static mehtod
+        _client.postdata = function(obj) {
+            var str = '';
+            for(k in obj) {
+                if(obj[k] instanceof Array) {
+                    for(i in obj[k]) {
+                        str += (encodeURIComponent(k) +'[]='+encodeURIComponent(obj[k][i]));
+                        str += '&';
+                    }
+                } else {
+                    str += encodeURIComponent(k) +'='+encodeURIComponent(obj[k]);
+                    str += '&';
+                }
+            }
+            return str;
+        }
+        _client.loading = function(){
+            var panel = new YAHOO.util.Element('panel');
+            panel.get('element').innerHTML = '<span>$strloading</span>';
+        }
+        _client.rename = function(oldname, url){
+            var panel = new YAHOO.util.Element('panel');
+            var html = '<div>';
+            html += '<label for="newname">$filename</label>';
+            html += '<input type="text" id="newname" value="'+oldname+'" /><br/>';
+            html += '<label for="syncfile">$strsync</label>';
+            html += '<input type="checkbox" id="syncfile" /><br/>';
+            html += '<input type="hidden" id="fileurl" value="'+url+'" />';
+            html += '<input type="button" onclick="repository_client.download()" value="$strdownload" />';
+            html += '<a href="###" onclick="repository_client.viewfiles()">$strback</a>';
+            html += '</div>';
+            panel.get('element').innerHTML = html;
+        }
+        _client.print_login = function(){
+            var panel = new YAHOO.util.Element('panel');
+            var data = _client.datasource.l;
+            var str = '';
+            for(var k in data){
+                str += '<p>';
+                var lable_id = '';
+                var field_id = '';
+                var field_value = '';
+                if(data[k].id){
+                    lable_id = ' for="'+data[k].id+'"';
+                    field_id = ' id="'+data[k].id+'"';
+                }
+                if (data[k].label) {
+                    str += '<label'+lable_id+'>'+data[k].label+'</label>';
+                }
+                if(data[k].value){
+                    field_value = ' value="'+data[k].value+'"';
+                }
+                str += '<input type="'+data[k].type+'"'+' name="'+data[k].name+'"'+field_id+field_value+' />';
+                str += '</p>';
+            }
+            str += '<p><input type="button" onclick="repository_client.login()" value="$strsubmit" /></p>';
+            panel.get('element').innerHTML = str;
+        }
+
+        _client.viewfiles = function(){
+            if(_client.viewmode) {
+                _client.viewthumb();
+            } else {
+                _client.viewlist();
+            }
+        }
+
+        _client.viewthumb = function(){
+            var panel = new YAHOO.util.Element('panel');
+            _client.viewbar.check(1);
+            obj = _client.datasource.list;
+            var str = '';
+            str += _client.makepage();
+            for(k in obj){
+                str += '<div class="grid">';
+                str += '<img title="'+obj[k].title+'" src="'+obj[k].thumbnail+'" />';
+                str += '<div style="text-align:center">';
+                str += ('<input type="radio" title="'+obj[k].title
+                        +'" name="selected-files" value="'+obj[k].source
+                        +'" onclick=\'repository_client.rename("'+obj[k].title+'", "'
+                        +obj[k].source+'")\' />');
+                str += obj[k].title+'</div>';
+                str += '</div>';
+            }
+            panel.get('element').innerHTML = str;
+            _client.viewmode = 1;
+            return str;
+        }
+
+        _client.viewlist = function(){
+            var panel = new YAHOO.util.Element('panel');
+            var str = '';
+            _client.viewbar.check(0);
+            obj = _client.datasource.list;
+            str += _client.makepage();
+            var re = new RegExp();
+            re.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
+            for(k in obj){
+                str += ('<input type="radio" title="'+obj[k].title+'" name="selected-files" value="'+obj[k].source+'" onclick=\'repository_client.rename("'+obj[k].title+'", "'+obj[k].source+'")\' /> ');
+                if(re.test(obj[k].source)) {
+                    str += '<a class="file_name" href="'+obj[k].source+'">'+obj[k].title+'</a>';
+                } else {
+                    str += '<span class="file_name" >'+obj[k].title+'</span>';
+                }
+                str += '<br/>';
+                str += '<label>Date: </label><span class="file_date">'+obj[k].date+'</span><br/>';
+                str += '<label>Size: </label><span class="file_size">'+obj[k].size+'</span>';
+                str += '<br/>';
+            }
+            panel.get('element').innerHTML = str;
+            _client.viewmode = 0;
+            return str;
+        }
+        // XXX: An ugly hack to show paging for flickr
+        _client.makepage = function(){
+            var str = '';
+            if(_client.datasource.pages){
+                str += '<div id="paging">';
+                for(var i = 1; i <= _client.datasource.pages; i++) {
+                    str += '<a onclick="repository_client.req('+_client.repositoryid+', '+i+', 0)" href="###">';
+                    str += String(i);
+                    str += '</a> ';
+                }
+                str += '</div>';
+            }
+            return str;
+        }
+        _client.download = function(){
+            var title = document.getElementById('newname').value;
+            var file = document.getElementById('fileurl').value;
+            _client.loading();
+            var trans = YAHOO.util.Connect.asyncRequest('POST', 
+                '$CFG->wwwroot/repository/ws.php?id='+_client.repositoryid+'&action=download', 
+                _client.dlfile, _client.postdata({'file':file, 'title':title}));
+        }
+        _client.login = function(){
+            var obj = {};
+            var data = _client.datasource.l;
+            for (var k in data) {
+                var el = document.getElementsByName(data[k].name)[0];
+                obj[data[k].name] = '';
+                if(el.type == 'checkbox') {
+                    obj[data[k].name] = el.checked;
+                } else {
+                    obj[data[k].name] = el.value;
+                }
+            }
+            _client.loading();
+            var trans = YAHOO.util.Connect.asyncRequest('POST', 
+                '$CFG->wwwroot/repository/ws.php', _client.callback,
+                _client.postdata(obj));
+        }
+        _client.callback = {
+            success: function(o) {
+                var panel = new YAHOO.util.Element('panel');
+                try {
+                    var ret = YAHOO.lang.JSON.parse(o.responseText);
+                } catch(e) {
+                    alert('Callback: Invalid JSON String'+o.responseText);
+                };
+                if(ret.e){
+                    panel.get('element').innerHTML = ret.e;
+                    return;
+                }
+                _client.datasource = ret;
+                if(_client.datasource.l){
+                    _client.print_login();
+                } else if(_client.datasource.list) {
+                    if(_client.viewmode) {
+                        _client.viewthumb();
+                    } else {
+                        _client.viewlist();
+                    }
+                }
+            }
+        }
+        _client.dlfile = {
+            success: function(o) {
+                var panel = new YAHOO.util.Element('panel');
+                try {
+                    var ret = YAHOO.lang.JSON.parse(o.responseText);
+                } catch(e) {
+                    alert('Invalid JSON String'+o.responseText);
+                }
+                if(ret.e){
+                    panel.get('element').innerHTML = ret.e;
+                    return;
+                }
+                var html = '<h1>Download Successfully!</h1>';
+                html += '<a href="###" onclick="repository_client.viewfiles()">Back</a>';
+                panel.get('element').innerHTML = html;
+            }
+        }
+        // request file list or login
+        _client.req = function(id, path, reset) {
+            _client.viewbar.set('disabled', false);
+            _client.loading();
+            _client.repositoryid = id;
+            var trans = YAHOO.util.Connect.asyncRequest('GET', '$CFG->wwwroot/repository/ws.php?id='+id+'&p='+path+'&reset='+reset, _client.callback);
+        }
+        _client.search = function(id){
+            var data = window.prompt("What are you searching for?");
+            if(data == null || data == '') {
+                alert('nothing entered');
+                return;
+            }
+            _client.viewbar.set('disabled', false);
+            _client.loading();
+            var trans = YAHOO.util.Connect.asyncRequest('GET', '$CFG->wwwroot/repository/ws.php?id='+id+'&s='+data, _client.callback);
+        }
+        return _client;
+    })();
+EOD;
+
+    $repos = repository_instances();
+    foreach($repos as $repo) {
+        $js .= 'repository_client.repos.push('.json_encode($repo).');'."\n";
+        $js .= "\n";
+    }
+
+    $js .= <<<EOD
+    function openpicker() {
+        if(!repository_client.instance) {
+            repository_client.instance = new repository_client();
+            repository_client.instance.create_picker();
+        } else {
+            repository_client.instance.show();
+        }
+    }
+    </script>
+EOD;
+    $html = <<<EOD
+    <div class='yui-skin-sam'>
+        <div id="file-picker"></div>
+    </div>
+EOD;
+    return array('html'=>$html, 'js'=>$js);
+}