diff --git a/application/Bootstrap.php b/application/Bootstrap.php index 63dd10b33..43d6f69a0 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -1,7 +1,5 @@ setFetchMode(DB_FETCHMODE_ASSOC); +Zend_Session::start(); + class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initDoctype() diff --git a/application/controllers/LibraryController.php b/application/controllers/LibraryController.php index df805861d..1d8755f1e 100644 --- a/application/controllers/LibraryController.php +++ b/application/controllers/LibraryController.php @@ -18,6 +18,7 @@ class LibraryController extends Zend_Controller_Action ->addActionContext('plupload', 'html') ->addActionContext('upload', 'json') ->addActionContext('delete', 'json') + ->addActionContext('context-menu', 'json') ->initContext(); $this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME); @@ -27,34 +28,46 @@ class LibraryController extends Zend_Controller_Action public function indexAction() { $this->view->headScript()->appendFile('/js/campcaster/onready/library.js','text/javascript'); + $this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript'); + $this->view->headScript()->appendFile('/js/campcaster/library/context-menu.js','text/javascript'); + $this->view->headLink()->appendStylesheet('/css/contextmenu.css'); $this->_helper->layout->setLayout('library'); unset($this->search_sess->md); unset($this->search_sess->order); - $this->_helper->actionStack('context-menu', 'library'); $this->_helper->actionStack('contents', 'library'); $this->_helper->actionStack('index', 'sideplaylist'); } public function contextMenuAction() { - $this->_helper->viewRenderer->setResponseSegment('library'); + $id = $this->_getParam('id'); + $type = $this->_getParam('type'); - $this->view->headScript()->appendFile('/js/campcaster/library/context-menu.js','text/javascript'); - $this->view->headScript()->appendFile('/js/contextmenu/jquery.contextMenu.js','text/javascript'); - $this->view->headLink()->appendStylesheet('/css/jquery.contextMenu.css'); + $callback = 'window["contextMenu"]'; + $params = '/format/json/id/#id#/type/#type#'; $pl_sess = $this->pl_sess; - $contextMenu; - $contextMenu[] = array('action' => '/Library/delete', 'text' => 'Delete'); - - if(isset($pl_sess->id)) - $contextMenu[] = array('action' => '/Playlist/add-item', 'text' => 'Add To Playlist'); + if($type === "au") { + + $menu[] = array('action' => '/Library/delete'.$params, 'title' => 'Delete'); + + if(isset($pl_sess->id)) + $menu[] = array('action' => '/Playlist/add-item'.$params, 'title' => 'Add To Playlist'); + + } + else if($type === "pl") { + + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/delete'.$params, 'callback' => $callback), 'title' => 'Delete'); + + } + + //returns format jjmenu is looking for. + die(json_encode($menu)); - $this->view->menu = $contextMenu; } public function deleteAction() @@ -69,7 +82,7 @@ class LibraryController extends Zend_Controller_Action return; } else if(is_null($file)) { - $this->view->message = "file doesn\'t exist"; + $this->view->message = "file doesn't exist"; return; } @@ -81,8 +94,6 @@ class LibraryController extends Zend_Controller_Action } } - $this->view->message = "file doesn\'t exist"; - } public function contentsAction() diff --git a/application/controllers/PlaylistController.php b/application/controllers/PlaylistController.php index bb9792296..2fca21295 100644 --- a/application/controllers/PlaylistController.php +++ b/application/controllers/PlaylistController.php @@ -20,6 +20,7 @@ class PlaylistController extends Zend_Controller_Action ->addActionContext('move-item', 'json') ->addActionContext('close', 'json') ->addActionContext('delete-active', 'json') + ->addActionContext('delete', 'json') ->initContext(); $this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME); @@ -216,11 +217,17 @@ class PlaylistController extends Zend_Controller_Action public function deleteAction() { $id = $this->_getParam('id', null); + $pl = Playlist::Recall($id); - if (!is_null($id)) { + if ($pl !== FALSE) { - $this->closePlaylist(); Playlist::Delete($id); + + $pl_sess = $this->pl_sess; + + if($pl_sess->id === $id){ + unset($pl_sess->id); + } } } diff --git a/application/controllers/SearchController.php b/application/controllers/SearchController.php index c4554f8f7..79ae0ea62 100644 --- a/application/controllers/SearchController.php +++ b/application/controllers/SearchController.php @@ -28,7 +28,6 @@ class SearchController extends Zend_Controller_Action $this->view->headScript()->appendFile('/js/campcaster/onready/search.js','text/javascript'); - $this->_helper->actionStack('context-menu', 'library'); $this->_helper->actionStack('display', 'search'); $this->_helper->actionStack('contents', 'library'); $this->_helper->actionStack('index', 'sideplaylist'); @@ -74,7 +73,13 @@ class SearchController extends Zend_Controller_Action $order = isset($this->search_sess->order) ? $this->search_sess->order : NULL; $this->view->files = StoredFile::searchFiles($info, $order); - $this->view->results = $this->view->render('library/update.phtml'); + + if (count($this->view->files) > 0) { + $this->view->results = $this->view->render('library/update.phtml'); + } + else { + $this->view->results = "No Results"; + } unset($this->view->files); } diff --git a/application/models/StoredFile.php b/application/models/StoredFile.php index 31e47aa59..1931f5900 100644 --- a/application/models/StoredFile.php +++ b/application/models/StoredFile.php @@ -1740,7 +1740,43 @@ class StoredFile { "6" => "!=", ); - $sql = "SELECT * FROM ".$CC_CONFIG['filesTable']; + //$sql = "SELECT * FROM ".$CC_CONFIG['filesTable']; + + + $plSelect = "SELECT "; + $fileSelect = "SELECT "; + $_SESSION["br"] = ""; + foreach ($g_metadata_xml_to_db_mapping as $key => $val){ + $_SESSION["br"] .= "key: ".$key." value:".$val.", "; + if($key === "dc:title"){ + $plSelect .= "name AS ".$val.", "; + $fileSelect .= $val.", "; + } + else if ($key === "dc:creator"){ + $plSelect .= "creator AS ".$val.", "; + $fileSelect .= $val.", "; + } + else if ($key === "dcterms:extent"){ + $plSelect .= "length, "; + $fileSelect .= "length, "; + } + else if ($key === "dc:description"){ + $plSelect .= "text(description) AS ".$val.", "; + $fileSelect .= $val.", "; + } + else { + $plSelect .= "NULL AS ".$val.", "; + $fileSelect .= $val.", "; + } + } + + $sql = "SELECT * FROM ((".$plSelect."PL.id, 'playlist' AS ftype + FROM ".$CC_CONFIG["playListTable"]." AS PL + LEFT JOIN ".$CC_CONFIG['playListTimeView']." PLT ON PL.id = PLT.id) + + UNION + + (".$fileSelect."id, ftype FROM ".$CC_CONFIG["filesTable"]." AS FILES)) AS RESULTS "; $cond = array(); foreach(array_keys($md) as $key) { diff --git a/application/views/scripts/library/context-menu.phtml b/application/views/scripts/library/context-menu.phtml index 260fb3b3d..e69de29bb 100644 --- a/application/views/scripts/library/context-menu.phtml +++ b/application/views/scripts/library/context-menu.phtml @@ -1,3 +0,0 @@ - diff --git a/application/views/scripts/library/contextMenuPartial.phtml b/application/views/scripts/library/contextMenuPartial.phtml deleted file mode 100644 index 31b484496..000000000 --- a/application/views/scripts/library/contextMenuPartial.phtml +++ /dev/null @@ -1 +0,0 @@ -
  • text ?>
  • diff --git a/application/views/scripts/library/libraryTablePartial.phtml b/application/views/scripts/library/libraryTablePartial.phtml index 8cb982cf5..52074462d 100644 --- a/application/views/scripts/library/libraryTablePartial.phtml +++ b/application/views/scripts/library/libraryTablePartial.phtml @@ -1,5 +1,5 @@ - + track_title ?> artist_name ?> album_title ?> diff --git a/build/build.properties b/build/build.properties index 1647a215d..3e7d17c6b 100644 --- a/build/build.properties +++ b/build/build.properties @@ -1,4 +1,4 @@ -project.home = /home/naomi/dev-campcaster/campcaster +project.home = /home/naomiaro/dev-campcaster/campcaster project.build = ${project.home}/build #Database driver diff --git a/public/css/contextmenu.css b/public/css/contextmenu.css new file mode 100644 index 000000000..1d5d4fe57 --- /dev/null +++ b/public/css/contextmenu.css @@ -0,0 +1,33 @@ +div.jjmenu { + + position:absolute; + background:#fffef0; + border-bottom:2px solid gray; + border-right:1px solid gray; + padding:0px; +} + +div.jj_menu_item { + color:black; + border:1px solid gray; + border-bottom:none; + background:url(menuitem.gif) no-repeat black; + cursor:pointer; +} + +div.jj_menu_item span { + display:block; + padding:4px; +} + +div.jj_menu_item_more span { + background:url(more.gif) right no-repeat; +} +div.jj_menu_item_more span { + padding-right:20px; +} + +div.jj_menu_item_hover { + background:#e4e4e4; + +} diff --git a/public/css/jquery.contextMenu.css b/public/css/jquery.contextMenu.css deleted file mode 100644 index 243c4b08d..000000000 --- a/public/css/jquery.contextMenu.css +++ /dev/null @@ -1,62 +0,0 @@ -/* Generic context menu styles */ -.contextMenu { - position: absolute; - width: 200px; - z-index: 99999; - border: solid 1px #CCC; - background: #EEE; - padding: 0px; - margin: 0px; - display: none; -} - -.contextMenu LI { - list-style: none; - padding: 0px; - margin: 0px; -} - -.contextMenu A { - color: #333; - text-decoration: none; - display: block; - line-height: 20px; - height: 20px; - background-position: 6px center; - background-repeat: no-repeat; - outline: none; - padding: 1px 5px; - padding-left: 28px; -} - -.contextMenu LI.hover A { - color: #FFF; - background-color: #3399FF; -} - -.contextMenu LI.disabled A { - color: #AAA; - cursor: default; -} - -.contextMenu LI.hover.disabled A { - background-color: transparent; -} - -.contextMenu LI.separator { - border-top: solid 1px #CCC; -} - -/* - Adding Icons - - You can add icons to the context menu by adding - classes to the respective LI element(s) -*/ - -.contextMenu LI.edit A { background-image: url(images/page_white_edit.png); } -.contextMenu LI.cut A { background-image: url(images/cut.png); } -.contextMenu LI.copy A { background-image: url(images/page_white_copy.png); } -.contextMenu LI.paste A { background-image: url(images/page_white_paste.png); } -.contextMenu LI.delete A { background-image: url(images/page_white_delete.png); } -.contextMenu LI.quit A { background-image: url(images/door.png); } diff --git a/public/css/menuitem.gif b/public/css/menuitem.gif new file mode 100644 index 000000000..a612ffbcc Binary files /dev/null and b/public/css/menuitem.gif differ diff --git a/public/css/more.gif b/public/css/more.gif new file mode 100644 index 000000000..1d15d69e1 Binary files /dev/null and b/public/css/more.gif differ diff --git a/public/js/campcaster/library/context-menu.js b/public/js/campcaster/library/context-menu.js index 6a27470a0..23e0341dd 100644 --- a/public/js/campcaster/library/context-menu.js +++ b/public/js/campcaster/library/context-menu.js @@ -1,15 +1,33 @@ +/* function contextMenu(action, el, pos) { var method = action.split('/').pop(), - url; + url, tr_id, id; + + tr_id = $(el).attr('id'); + id = tr_id.split("_").pop(); + url = '/'+action; if (method === 'delete') { - url = action + '/format/json'; - url = url + '/id/' + $(el).attr('id'); - $.post(url, deleteItem); + url = url + '/format/json'; + url = url + '/id/' + id; + $.post(url, function(json) { + + if(json.message) { + alert(json.message); + return; + } + + $("#library_display tr#" +tr_id).remove(); + }); } else if (method === 'add-item') { - url = action + '/format/json'; - url = url + '/id/' + $(el).attr('id'); + url = url + '/format/json'; + url = url + '/id/' + id; $.post(url, setSPLContent); } } +*/ + +function contextMenu() { + alert("callback"); +} diff --git a/public/js/campcaster/library/library.js b/public/js/campcaster/library/library.js index c1dad5e53..773a29641 100644 --- a/public/js/campcaster/library/library.js +++ b/public/js/campcaster/library/library.js @@ -1,24 +1,34 @@ -function deleteItem(json){ - var id; +function getId() { + var tr_id = $(this.triggerElement).attr("id"); + tr_id = tr_id.split("_"); - if(json.message) { - alert(j.message); - return; - } + return tr_id[1]; +} - id = this.url.split('/').pop(); - $("#library_display tr#" +id).remove(); +function getType() { + var tr_id = $(this.triggerElement).attr("id"); + tr_id = tr_id.split("_"); + + return tr_id[0]; } function setLibraryContents(data){ $("#library_display tr:not(:first-child)").remove(); $("#library_display").append(data); - $("#library_display tr:not(:first-child)") - .contextMenu({menu: 'myMenu'}, contextMenu) + /* + $('#library_display tr[id ^= "au"]') + .contextMenu({menu: 'audioMenu'}, contextMenu) .draggable({ helper: 'clone' }); + + $('#library_display tr[id ^= "pl"]') + .contextMenu({menu: 'plMenu'}, contextMenu) + .draggable({ + helper: 'clone' + }); + */ } function setUpLibrary() { @@ -45,9 +55,27 @@ function setUpLibrary() { $.post(url, {ob: ob, order: order}, setLibraryContents); }); - $("#library_display tr:not(:first-child)") - .contextMenu({menu: 'myMenu'}, contextMenu) + /* + $('#library_display tr[id ^= "au"]') + .contextMenu({menu: 'audioMenu'}, contextMenu) .draggable({ helper: 'clone' }); + + $('#library_display tr[id ^= "pl"]') + .contextMenu({menu: 'plMenu'}, contextMenu) + + */ + + $('#library_display tr:not(:first-child)') + .draggable({ + helper: 'clone' + }); + + $('#library_display tr:not(:first-child)') + .jjmenu("rightClick", + [{get:"/Library/context-menu/format/json/id/#id#/type/#type#"}], + {id: getId, type: getType}, + {xposition: "mouse", yposition: "mouse"}); + } diff --git a/public/js/contextmenu/jjmenu.js b/public/js/contextmenu/jjmenu.js new file mode 100644 index 000000000..41dd33534 --- /dev/null +++ b/public/js/contextmenu/jjmenu.js @@ -0,0 +1,366 @@ +/* jjmenu - context menu jquery plugin + * http://jursza.net/dev/jjmenu/ + * + * @author Jacek Jursza (okhan.pl@gmail.com) + * @version 1.1.2 + * @date 2010-08-28 + * @category jQuery plugin + * @copyright (c) 2009 Jacek Jursza (http://jursza.net/) + * @licence MIT [http://www.opensource.org/licenses/mit-license.php] + */ + +(function($){ + + $.fn.jjmenu = function (clickEvent, param, myReplaces, effect) { + + var global = this; + var acceptEvent = false; + + + if ( clickEvent == "rightClick" || clickEvent == "both" ) + { + global.mousedown(function(event) { + if (event.button == 2 && (clickEvent == "rightClick" || clickEvent == "both")) { // right click + global.pageX = event.pageX; + global.pageY = event.pageY; + event.preventDefault(); + event.stopPropagation(); + var mmain = new menu("main", param, myReplaces, this, effect); + $(this)[0].oncontextmenu = function() { + return false; + } + $(this).unbind('mouseup'); + $(this).blur(); + return false; + } + }); + + document.body.oncontextmenu = function() { + if ($("div[id^=jjmenu_main]").length) return false; + } + } + + if ( clickEvent == "click" || clickEvent == "both" ) + { + global.click( + function(event) { + if (this == event.target) { + global.pageX = event.pageX; + global.pageY = event.pageY; + event.preventDefault(); + event.stopPropagation(); + var mmain = new menu("main", param, myReplaces, this, effect); + $(this).blur(); + return false; + } + }); + } + + $(document).click(function(event) { if (event.button!=2) $("div[id^=jjmenu]").remove(); }); + + /* Menu obeject */ + function menu(id,param,myReplaces,el,effect) { + + var effect = getEffect(id, effect); + + if (id == "main") window.triggerElement = el; + $("div[id^=jjmenu_"+id+"]").remove(); + + var m = document.createElement('div'); + var ms = document.createElement('span'); + $(m).append(ms); + + m.className = "jjmenu"; m.id = "jjmenu_"+id; + $(m).css({display:'none'}); + $(document.body).append(m); + + positionMenu(); + + var dynamicItems = false; + + for (var i in param) { + + if (param[i].get) { + + dynamicItems = true; + $.getJSON(uReplace(param[i].get), function(data) { + for (var ii in data) { + putItem(data[ii]); + } + checkPosition(); + }) + $(this).ajaxError( function() { + checkPosition(); + }); + } + else if (param[i].getByFunction) { + + if (typeof(param[i].getByFunction) == "function") { + var uF = param[i].getByFunction; + } + else { + var uF = eval(param[i].getByFunction); + } + var uItems = uF(myReplaces); + for (var ii in uItems) { + putItem(uItems[ii]); + } + checkPosition(); + } + else { + putItem(param[i]); + } + } + + if (!dynamicItems) checkPosition(); + showMenu(); + + /* first position menu */ + function positionMenu() { + + var pos = $(el).offset(); + + var t = pos.top; + + if (effect.xposition == "left") { + var l = pos.left; + } + else { + var l = pos.left+$(el).width()+10; + } + + if (effect.xposition == "mouse") { + l = global.pageX; + } + if (effect.yposition == "mouse") { + t = global.pageY; + } + + $(m).css({position:"absolute",top:t+"px",left:l+"px"}); + } + + /* correct menu position */ + function checkPosition() { + + var isHidden = $(m).css("display") == "none" ? true : false; + var noAuto = false; + + if (effect.orientation == "top" || effect.orientation == "bottom") { + noAuto = true; + } + + if (isHidden) $(m).show(); + var positionTop = $(m).offset().top; + var positionLeft = $(m).offset().left; + if (isHidden) $(m).hide(); + + var xPos = positionTop - $(window).scrollTop(); + + $(m).css({left:"0px"}); + var menuHeight = $(m).outerHeight(); + var menuWidth = $(m).outerWidth(); + $(m).css({left:positionLeft+"px"}); + + var nleft = positionLeft; + if ( positionLeft + menuWidth > $(window).width() ) { + nleft = $(window).width() - menuWidth; + } + + var spaceBottom = true; + if (effect.yposition == "auto" && effect.xposition == "left") { + + if ( xPos + menuHeight + $(el).outerHeight() > $(window).height()) { + spaceBottom = false; + } + } + else { + + if ( xPos + menuHeight > $(window).height()) { + spaceBottom = false; + } + } + + var spaceTop = true; + if (positionTop - menuHeight < 0) { + spaceTop = false; + } + + if (effect.yposition == "bottom") { + positionTop = positionTop + $(el).outerHeight(); + } + + if ( (effect.orientation == "auto" && spaceBottom == false && spaceTop == true) || effect.orientation == "top") { + // top orientation + var ntop = parseInt(positionTop,10) - parseInt(menuHeight,10); + $(m).addClass("topOriented"); + + } else { + // bottom orientation + $(m).addClass("bottomOriented"); + if (effect.yposition == "auto" && effect.xposition == "left") { + positionTop = positionTop + $(el).outerHeight(); + } + var ntop = parseInt(positionTop,10); + } + + $(m).css({"top":ntop+"px", "left":nleft+"px"}); + } + + /* show menu depends to effect.show */ + function showMenu() { + + if (!effect || effect.show == "default") { + $(m).show(); + return false; + } + + var speed = parseInt(effect.speed); + speed = isNaN(speed) ? 500 : speed; + + switch (effect.show) + { + case "fadeIn": + $(m).fadeIn(speed); + break; + + case "slideDown": + $(m).slideDown(speed); + break; + + default: + $(m).show(); + break; + } + } + + /* put item to menu */ + function putItem(n) { + + var item = document.createElement('div'); + $(item).hover(function(){ + $(this).addClass("jj_menu_item_hover") + }, + function(){ + $(this).removeClass("jj_menu_item_hover") + }); + + $(item).click( function(event) { + event.stopPropagation(); + doAction(n.action); + }); + + var span = document.createElement('span'); + $(item).append(span); + + + switch (n.type) + { + case "sub": + item.className = "jj_menu_item jj_menu_item_more"; + $(item).click(function() { + if ($("#jjmenu_"+id+"_sub").length > 0) { + $("div[id^=jjmenu_"+id+"_sub]").remove(); + } + else { + var sub = new menu(id+"_sub", n.src, myReplaces, this, effect); + } + }); + break; + + default: + $(item).hover(function() { $("div[id^=jjmenu_"+id+"_sub]").remove(); }); + item.className = "jj_menu_item"; + break; + } + + + if (n.customClass && n.customClass.length>0) { + jQuery(span).addClass(n.customClass); + } + + $(span).html(uReplace(n.title)); + $(ms).append(item); + } + + /* do action on menu item */ + function doAction(act) { + + if (act) { + + switch (act.type) { + + case "gourl": + if (act.target) { + var newWindow = window.open(uReplace(act.url), act.target); + newWindow.focus(); + return false; + } + else { + document.location.href=uReplace(act.url); + } + break; + + case "ajax": + $.getJSON(uReplace(act.url), function(data) { + + + var cb = eval(act.callback); + if (typeof(cb) == "function") { + cb(data); + } + + }); + break; + + case "fn": + var callfn = 'var cb = '+act.callback; + jQuery.globalEval(callfn); + if (typeof(cb) == "function") { + cb(myReplaces); + } + break; + } + } + } + + /* replace string with user parameters */ + function uReplace(str) { + if (myReplaces) { + for (var u in myReplaces) { + str = str.replace("#"+u+"#", eval("myReplaces."+u)); + } + } + return str; + } + + /* get effect opbject */ + function getEffect(id, effect) { + + var defEffect = { + show:"default", + xposition:"right", + yposition:"auto", + orientation:"auto" + }; + + if (!effect) { return defEffect; } + + if (!effect.show) effect.show = "default"; + + var show = effect.show; + + if (!effect.xposition) effect.xposition = "right"; + if (!effect.yposition) effect.yposition = "auto"; + if (!effect.orientation) effect.orientation = "auto"; + + if (id != "main") { + var subeffect = defEffect; + subeffect.show = show; + } + + return ( id == "main" ) ? effect : subeffect; + } + } // !menu + }; + + })(jQuery); diff --git a/public/js/contextmenu/jquery.contextMenu.js b/public/js/contextmenu/jquery.contextMenu.js deleted file mode 100644 index a06f0bbdf..000000000 --- a/public/js/contextmenu/jquery.contextMenu.js +++ /dev/null @@ -1,211 +0,0 @@ -// jQuery Context Menu Plugin -// -// Version 1.01 -// -// Cory S.N. LaViska -// A Beautiful Site (http://abeautifulsite.net/) -// -// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/ -// -// Terms of Use -// -// This plugin is dual-licensed under the GNU General Public License -// and the MIT License and is copyright A Beautiful Site, LLC. -// -if(jQuery)( function() { - $.extend($.fn, { - - contextMenu: function(o, callback) { - // Defaults - if( o.menu == undefined ) return false; - if( o.inSpeed == undefined ) o.inSpeed = 150; - if( o.outSpeed == undefined ) o.outSpeed = 75; - // 0 needs to be -1 for expected results (no fade) - if( o.inSpeed == 0 ) o.inSpeed = -1; - if( o.outSpeed == 0 ) o.outSpeed = -1; - // Loop each context menu - $(this).each( function() { - var el = $(this); - var offset = $(el).offset(); - // Add contextMenu class - $('#' + o.menu).addClass('contextMenu'); - // Simulate a true right click - $(this).mousedown( function(e) { - var evt = e; - evt.stopPropagation(); - $(this).mouseup( function(e) { - e.stopPropagation(); - var srcElement = $(this); - $(this).unbind('mouseup'); - if( evt.button == 2 ) { - // Hide context menus that may be showing - $(".contextMenu").hide(); - // Get this context menu - var menu = $('#' + o.menu); - - if( $(el).hasClass('disabled') ) return false; - - // Detect mouse position - var d = {}, x, y; - if( self.innerHeight ) { - d.pageYOffset = self.pageYOffset; - d.pageXOffset = self.pageXOffset; - d.innerHeight = self.innerHeight; - d.innerWidth = self.innerWidth; - } else if( document.documentElement && - document.documentElement.clientHeight ) { - d.pageYOffset = document.documentElement.scrollTop; - d.pageXOffset = document.documentElement.scrollLeft; - d.innerHeight = document.documentElement.clientHeight; - d.innerWidth = document.documentElement.clientWidth; - } else if( document.body ) { - d.pageYOffset = document.body.scrollTop; - d.pageXOffset = document.body.scrollLeft; - d.innerHeight = document.body.clientHeight; - d.innerWidth = document.body.clientWidth; - } - (e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft; - (e.pageY) ? y = e.pageY : y = e.clientY + d.scrollTop; - - // Show the menu - $(document).unbind('click'); - $(menu).css({ top: y, left: x }).fadeIn(o.inSpeed); - // Hover events - $(menu).find('A').mouseover( function() { - $(menu).find('LI.hover').removeClass('hover'); - $(this).parent().addClass('hover'); - }).mouseout( function() { - $(menu).find('LI.hover').removeClass('hover'); - }); - - // Keyboard - $(document).keypress( function(e) { - switch( e.keyCode ) { - case 38: // up - if( $(menu).find('LI.hover').size() == 0 ) { - $(menu).find('LI:last').addClass('hover'); - } else { - $(menu).find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover'); - if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:last').addClass('hover'); - } - break; - case 40: // down - if( $(menu).find('LI.hover').size() == 0 ) { - $(menu).find('LI:first').addClass('hover'); - } else { - $(menu).find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover'); - if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:first').addClass('hover'); - } - break; - case 13: // enter - $(menu).find('LI.hover A').trigger('click'); - break; - case 27: // esc - $(document).trigger('click'); - break - } - }); - - // When items are selected - $('#' + o.menu).find('A').unbind('click'); - $('#' + o.menu).find('LI:not(.disabled) A').click( function() { - $(document).unbind('click').unbind('keypress'); - $(".contextMenu").hide(); - // Callback - if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} ); - return false; - }); - - // Hide bindings - setTimeout( function() { // Delay for Mozilla - $(document).click( function() { - $(document).unbind('click').unbind('keypress'); - $(menu).fadeOut(o.outSpeed); - return false; - }); - }, 0); - } - }); - }); - - // Disable text selection - if( $.browser.mozilla ) { - $('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); }); - } else if( $.browser.msie ) { - $('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); }); - } else { - $('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); }); - } - // Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome) - $(el).add($('UL.contextMenu')).bind('contextmenu', function() { return false; }); - - }); - return $(this); - }, - - // Disable context menu items on the fly - disableContextMenuItems: function(o) { - if( o == undefined ) { - // Disable all - $(this).find('LI').addClass('disabled'); - return( $(this) ); - } - $(this).each( function() { - if( o != undefined ) { - var d = o.split(','); - for( var i = 0; i < d.length; i++ ) { - $(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled'); - - } - } - }); - return( $(this) ); - }, - - // Enable context menu items on the fly - enableContextMenuItems: function(o) { - if( o == undefined ) { - // Enable all - $(this).find('LI.disabled').removeClass('disabled'); - return( $(this) ); - } - $(this).each( function() { - if( o != undefined ) { - var d = o.split(','); - for( var i = 0; i < d.length; i++ ) { - $(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled'); - - } - } - }); - return( $(this) ); - }, - - // Disable context menu(s) - disableContextMenu: function() { - $(this).each( function() { - $(this).addClass('disabled'); - }); - return( $(this) ); - }, - - // Enable context menu(s) - enableContextMenu: function() { - $(this).each( function() { - $(this).removeClass('disabled'); - }); - return( $(this) ); - }, - - // Destroy context menu(s) - destroyContextMenu: function() { - // Destroy specified context menus - $(this).each( function() { - // Disable action - $(this).unbind('mousedown').unbind('mouseup'); - }); - return( $(this) ); - } - - }); -})(jQuery);