MDL-31901: FileManager, added image for accessing right-click action
authorMarina Glancy <marina@moodle.com>
Thu, 3 May 2012 07:14:59 +0000 (15:14 +0800)
committerMarina Glancy <marina@moodle.com>
Mon, 21 May 2012 03:57:52 +0000 (11:57 +0800)
files/renderer.php
lib/form/filemanager.js
repository/filepicker.js
theme/base/style/filemanager.css

index 1d2ac26..73009a2 100644 (file)
@@ -227,21 +227,42 @@ class core_files_renderer extends plugin_renderer_base {
     /**
      * FileManager JS template for displaying one file in 'icon view' mode.
      *
+     * Except for elements described in fp_js_template_iconfilename, this template may also
+     * contain element with class 'fp-contextmenu'. If context menu is available for this
+     * file, the top element will receive the additional class 'fp-hascontextmenu' and
+     * the element with class 'fp-contextmenu' will hold onclick event for displaying
+     * the context menu.
+     *
      * @see fp_js_template_iconfilename()
      * @return string
      */
     private function fm_js_template_iconfilename() {
-        return $this->fp_js_template_iconfilename();
+        $rv = '<div class="fp-file" style="position:relative">
+        <a href="#">
+    <div class="{!}fp-thumbnail"></div>
+    <div class="{!}fp-filename"></div></a>
+    <a class="{!}fp-contextmenu" href="#">'.$this->pix_icon('i/menu', '▶').'</a>
+</div>';
+        return preg_replace('/\{\!\}/', '', $rv);
     }
 
     /**
      * FileManager JS template for displaying file name in 'table view' and 'tree view' modes.
      *
+     * Except for elements described in fp_js_template_listfilename, this template may also
+     * contain element with class 'fp-contextmenu'. If context menu is available for this
+     * file, the top element will receive the additional class 'fp-hascontextmenu' and
+     * the element with class 'fp-contextmenu' will hold onclick event for displaying
+     * the context menu.
+     *
+     * @todo MDL-32736 remove onclick="return false;"
      * @see fp_js_template_listfilename()
      * @return string
      */
     private function fm_js_template_listfilename() {
-        return $this->fp_js_template_listfilename();
+        $rv = '<span><span class="{!}fp-icon"></span> <span class="{!}fp-filename"></span>
+            <a class="{!}fp-contextmenu" href="#" onclick="return false;">'.$this->pix_icon('i/menu', '▶').'</a></span>';
+        return preg_replace('/\{\!\}/', '', $rv);
     }
 
     /**
@@ -444,7 +465,7 @@ class core_files_renderer extends plugin_renderer_base {
      * @return string
      */
     private function fp_js_template_iconfilename() {
-        $rv = '<a class="{!}fp-file" href="#" >
+        $rv = '<a class="fp-file" href="#" >
     <div class="{!}fp-thumbnail"></div>
     <div class="{!}fp-filename"></div>
 </a>';
index aa0b2ec..5624f92 100644 (file)
@@ -420,7 +420,7 @@ M.form_filemanager.init = function(Y, options) {
                 filenode : element_template,
                 callbackcontext : this,
                 callback : function(e, node) {
-                    e.preventDefault();
+                    if (e.preventDefault) { e.preventDefault(); }
                     if (node.type == 'folder') {
                         this.refresh(node.filepath);
                     } else {
@@ -428,15 +428,18 @@ M.form_filemanager.init = function(Y, options) {
                     }
                 },
                 rightclickcallback : function(e, node) {
+                    if (e.preventDefault) { e.preventDefault(); }
                     this.select_file(node);
-                    e.preventDefault();
                 }
             };
             if (this.viewmode == 2) {
                 options.dynload = true;
                 options.filepath = this.options.path;
                 options.treeview_dynload = this.treeview_dynload;
+                options.norootrightclick = true;
                 options.callback = function(e, node) {
+                    // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node'
+                    if (!node.fullname) {return;}
                     if (node.type != 'folder') {
                         if (e.node.parent && e.node.parent.origpath) {
                             // set the current path
index 97f81f2..b1b0c3c 100644 (file)
@@ -82,6 +82,7 @@ YUI.add('moodle-core_filepicker', function(Y) {
      *   filenode : Node element that contains template for displaying one file
      *   callback : On click callback. The element of the fileslist array will be passed as argument
      *   rightclickcallback : On right click callback (optional).
+     *   norootrightclick : No right click for top element in the tree
      *   callbackcontext : context where callbacks are executed
      *   sortable : whether content may be sortable (in table mode)
      *   dynload : allow dynamic load for tree view
@@ -128,8 +129,13 @@ YUI.add('moodle-core_filepicker', function(Y) {
 
             el.one('.fp-filename').setContent(file_get_displayname(node));
             // TODO add tooltip with node.title or node.thumbnail_title
+            var tmpnodedata = {className:''};
             if (file_is_folder(node)) {
                 el.get('children').addClass('fp-folder');
+                tmpnodedata.className = tmpnodedata.className + ' fp-folder';
+            }
+            if (options.rightclickcallback && !node.nocontextmenu) {
+                tmpnodedata.className = tmpnodedata.className + ' fp-hascontextmenu';
             }
             if (node.icon) {
                 el.one('.fp-icon').appendChild(Y.Node.create('<img/>').set('src', node.icon));
@@ -138,7 +144,8 @@ YUI.add('moodle-core_filepicker', function(Y) {
                 }
             }
             // create node
-            var tmpNode = new YAHOO.widget.HTMLNode(el.getContent(), level, false);
+            tmpnodedata.html = el.getContent();
+            var tmpNode = new YAHOO.widget.HTMLNode(tmpnodedata, level, false);
             if (node.dynamicLoadComplete) {
                 tmpNode.dynamicLoadComplete = true;
             }
@@ -157,6 +164,7 @@ YUI.add('moodle-core_filepicker', function(Y) {
         /** initialize tree view */
         var initialize_tree_view = function() {
             var parentid = scope.one('.'+classname).get('id');
+            // TODO MDL-32736 use YUI3 gallery TreeView
             scope.treeview = new YAHOO.widget.TreeView(parentid);
             if (options.dynload) {
                 scope.treeview.setDynamicLoad(Y.bind(options.treeview_dynload, options.callbackcontext), 1);
@@ -171,6 +179,9 @@ YUI.add('moodle-core_filepicker', function(Y) {
                 for (var i in options.filepath) {
                     if (mytreeel == null) {
                         mytreeel = mytree;
+                        if (options.norootrightclick) {
+                            mytreeel.nocontextmenu = true;
+                        }
                     } else {
                         mytreeel.children = [{}];
                         mytreeel = mytreeel.children[0];
@@ -204,16 +215,21 @@ YUI.add('moodle-core_filepicker', function(Y) {
             }
             scope.treeview.subscribe('clickEvent', function(e){
                 e.node.highlight(false);
-                Y.bind(options.callback, options.callbackcontext)(e, e.node.fileinfo);
+                var callback = options.callback;
+                if (options.rightclickcallback && e.event.target &&
+                        Y.Node(e.event.target).ancestor('.fp-treeview .fp-contextmenu', true)) {
+                    callback = options.rightclickcallback;
+                }
+                Y.bind(callback, options.callbackcontext)(e, e.node.fileinfo);
+                YAHOO.util.Event.stopEvent(e.event)
             });
-            if (options.rightclickcallback) {
-                scope.treeview.subscribe('dblClickEvent', function(e){ // TODO right click!
+            // TODO MDL-32736 support right click
+            /*if (options.rightclickcallback) {
+                scope.treeview.subscribe('dblClickEvent', function(e){
                     e.node.highlight(false);
-                    if (e.node.path != '/') {
-                        Y.bind(options.rightclickcallback, options.callbackcontext)(e, e.node.fileinfo);
-                    }
+                    Y.bind(options.rightclickcallback, options.callbackcontext)(e, e.node.fileinfo);
                 });
-            }
+            }*/
             scope.treeview.draw();
         };
         /** formatting function for table view */
@@ -237,6 +253,9 @@ YUI.add('moodle-core_filepicker', function(Y) {
                     lazyloading[el.one('.fp-icon img').generateID()] = o.data['realicon'];
                 }
             }
+            if (options.rightclickcallback) {
+                el.get('children').addClass('fp-hascontextmenu');
+            }
             // TODO add tooltip with o.data['title'] (o.value) or o.data['thumbnail_title']
             return el.getContent();
         }
@@ -264,7 +283,13 @@ YUI.add('moodle-core_filepicker', function(Y) {
             scope.tableview.render('#'+parentid);
             scope.tableview.delegate('click', function (e, tableview) {
                 var record = tableview.getRecord(e.currentTarget.get('id'));
-                if (record) { Y.bind(options.callback, this)(e, record.getAttrs()); }
+                if (record) {
+                    var callback = options.callback;
+                    if (options.rightclickcallback && e.target.ancestor('.fp-tableview .fp-contextmenu', true)) {
+                        callback = options.rightclickcallback;
+                    }
+                    Y.bind(callback, this)(e, record.getAttrs());
+                }
             }, 'tr', options.callbackcontext, scope.tableview);
             if (options.rightclickcallback) {
                 scope.tableview.delegate('contextmenu', function (e, tableview) {
@@ -309,6 +334,9 @@ YUI.add('moodle-core_filepicker', function(Y) {
                 if (file_is_folder(node)) {
                     element.addClass('fp-folder');
                 }
+                if (options.rightclickcallback) {
+                    element.addClass('fp-hascontextmenu');
+                }
                 var filenamediv = element.one('.fp-filename');
                 filenamediv.setContent(file_get_displayname(node));
                 var imgdiv = element.one('.fp-thumbnail'), width, height, src;
@@ -333,7 +361,13 @@ YUI.add('moodle-core_filepicker', function(Y) {
                     lazyloading[img.generateID()] = node.realthumbnail;
                 }
                 imgdiv.appendChild(img);
-                element.on('click', options.callback, options.callbackcontext, node);
+                element.on('click', function(e, nd) {
+                    if (options.rightclickcallback && e.target.ancestor('.fp-iconview .fp-contextmenu', true)) {
+                        Y.bind(options.rightclickcallback, this)(e, nd);
+                    } else {
+                        Y.bind(options.callback, this)(e, nd);
+                    }
+                }, options.callbackcontext, node);
                 if (options.rightclickcallback) {
                     element.on('contextmenu', options.rightclickcallback, options.callbackcontext, node);
                 }
@@ -807,6 +841,7 @@ M.core_filepicker.init = function(Y, options) {
                 filenode : element_template,
                 callbackcontext : this,
                 callback : function(e, node) {
+                    // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node'
                     if (!node.children) {
                         if (e.node.parent && e.node.parent.origpath) {
                             // set the current path
@@ -846,7 +881,7 @@ M.core_filepicker.init = function(Y, options) {
                 filenode : element_template,
                 callbackcontext : this,
                 callback : function(e, node) {
-                    e.preventDefault();
+                    if (e.preventDefault) {e.preventDefault();}
                     if(node.children) {
                         if (this.active_repo.dynload) {
                             this.list({'path':node.path});
@@ -880,7 +915,7 @@ M.core_filepicker.init = function(Y, options) {
                 callbackcontext : this,
                 sortable : !this.active_repo.hasmorepages,
                 callback : function(e, node) {
-                    e.preventDefault();
+                    if (e.preventDefault) {e.preventDefault();}
                     if (node.children) {
                         if (this.active_repo.dynload) {
                             this.list({'path':node.path});
index 7de8d93..d85963e 100644 (file)
@@ -238,6 +238,11 @@ background: #CCC!important;filter: progid:DXImageTransform.Microsoft.gradient(st
 .filemanager .fp-iconview .fp-file div {overflow: hidden;}
 .filemanager .fp-iconview .fp-file .fp-filename {height:48px;text-align:center;min-width:50px;}
 
+.filemanager .fp-contextmenu {display:none;}
+.filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu {display:block;position:absolute;right:0px;top:0px;}
+.filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,
+.filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu {display:inline;}
+
 .filemanager .fp-select .fp-select-loading {display:none;}
 .filemanager .fp-select.loading .fp-select-loading {display:block;}
 .filemanager .fp-select.loading form {display:none;}