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..feed55806 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,66 @@ 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->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'); + $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' => array('type' => 'ajax', 'url' => '/Library/delete'.$params, 'callback' => 'window["deleteAudioClip"]'), + 'title' => 'Delete'); + + if(isset($pl_sess->id)) { + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/add-item'.$params, 'callback' => 'window["setSPLContent"]'), + 'title' => 'Add to Playlist'); + } + + } + else if($type === "pl") { + + if(!isset($pl_sess->id) || $pl_sess->id !== $id) { + $menu[] = array('action' => + array('type' => 'ajax', + 'url' => '/Playlist/edit/view/spl'.$params, + 'callback' => 'window["openDiffSPL"]'), + 'title' => 'Edit'); + } + else if(isset($pl_sess->id) && $pl_sess->id === $id) { + $menu[] = array('action' => + array('type' => 'ajax', + 'url' => '/Playlist/close/view/spl'.$params, + 'callback' => 'window["noOpenPL"]'), + 'title' => 'Close'); + } + + $menu[] = array('action' => array('type' => 'gourl', 'url' => '/Playlist/metadata'.$params), + 'title' => 'Description'); + + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/delete'.$params, 'callback' => 'window["deletePlaylist"]'), + 'title' => 'Delete'); + + } + + //returns format jjmenu is looking for. + die(json_encode($menu)); - $this->view->menu = $contextMenu; } public function deleteAction() @@ -69,7 +102,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; } @@ -80,9 +113,8 @@ class LibraryController extends Zend_Controller_Action return; } } - - $this->view->message = "file doesn\'t exist"; + $this->view->id = $id; } public function contentsAction() diff --git a/application/controllers/PlaylistController.php b/application/controllers/PlaylistController.php index bb9792296..06dffaac2 100644 --- a/application/controllers/PlaylistController.php +++ b/application/controllers/PlaylistController.php @@ -19,7 +19,9 @@ class PlaylistController extends Zend_Controller_Action ->addActionContext('set-cue', 'json') ->addActionContext('move-item', 'json') ->addActionContext('close', 'json') + ->addActionContext('edit', 'json') ->addActionContext('delete-active', 'json') + ->addActionContext('delete', 'json') ->initContext(); $this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME); @@ -43,6 +45,28 @@ class PlaylistController extends Zend_Controller_Action $this->_helper->redirector('index'); } + private function changePlaylist($pl_id){ + + $pl_sess = $this->pl_sess; + + if(isset($pl_sess->id)) { + + $pl = Playlist::Recall($pl_sess->id); + if($pl !== FALSE) { + $this->closePlaylist($pl); + } + } + + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); + + $pl = Playlist::Recall($pl_id); + if($pl === FALSE) { + return FALSE; + } + $pl->lock($userInfo->id); + $pl_sess->id = $pl_id; + } + private function closePlaylist($pl) { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); @@ -67,10 +91,9 @@ class PlaylistController extends Zend_Controller_Action $pl = new Playlist(); $pl_id = $pl->create("Test Zend Auth"); $pl->setPLMetaData('dc:creator', $userInfo->login); - $pl->lock($userInfo->id); //set this playlist as active id. - $pl_sess->id = $pl_id; + $this->changePlaylist($pl_id); $this->_helper->redirector('metadata'); } @@ -80,6 +103,19 @@ class PlaylistController extends Zend_Controller_Action $request = $this->getRequest(); $form = new Application_Form_PlaylistMetadata(); + + $pl_id = $this->_getParam('id', null); + //not a new playlist + if(!is_null($pl_id)) { + $this->changePlaylist($pl_id); + + $pl = $this->getPlaylist(); + $title = $pl->getPLMetaData(UI_MDATA_KEY_TITLE); + $desc = $pl->getPLMetaData(UI_MDATA_KEY_DESCRIPTION); + + $data = array( 'title' => $title, 'description' => $desc); + $form->populate($data); + } if ($request->isPost()) { if ($form->isValid($request->getPost())) { @@ -89,8 +125,9 @@ class PlaylistController extends Zend_Controller_Action $pl = $this->getPlaylist(); $pl->setPLMetaData(UI_MDATA_KEY_TITLE, $formdata["title"]); - if(isset($formdata["description"])) + if(isset($formdata["description"])) { $pl->setPLMetaData(UI_MDATA_KEY_DESCRIPTION, $formdata["description"]); + } $this->_helper->redirector('edit'); } @@ -101,12 +138,22 @@ class PlaylistController extends Zend_Controller_Action public function editAction() { - $this->view->headScript()->appendFile('/js/campcaster/playlist/playlist.js','text/javascript'); + $this->view->headScript()->appendFile('/js/campcaster/playlist/playlist.js','text/javascript'); + $pl_id = $this->_getParam('id', null); + $display = $this->_getParam('view', null); + if(!is_null($pl_id)) { + $this->changePlaylist($pl_id); + } + $pl = $this->getPlaylist(); $this->view->pl = $pl; - $this->view->playlistcontents = $pl->getContents(); + + if($display === 'spl') { + $this->view->html = $this->view->render('sideplaylist/index.phtml'); + unset($this->view->pl); + } } public function addItemAction() @@ -137,6 +184,7 @@ class PlaylistController extends Zend_Controller_Action { $oldPos = $this->_getParam('oldPos'); $newPos = $this->_getParam('newPos'); + $display = $this->_getParam('view'); $pl = $this->getPlaylist(); @@ -216,12 +264,20 @@ 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); + } } + + $this->view->id = $id; } public function deleteActiveAction() diff --git a/application/controllers/SearchController.php b/application/controllers/SearchController.php index c4554f8f7..a96248964 100644 --- a/application/controllers/SearchController.php +++ b/application/controllers/SearchController.php @@ -27,8 +27,9 @@ class SearchController extends Zend_Controller_Action $this->_helper->layout->setLayout('search'); $this->view->headScript()->appendFile('/js/campcaster/onready/search.js','text/javascript'); + $this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript'); + $this->view->headLink()->appendStylesheet('/css/contextmenu.css'); - $this->_helper->actionStack('context-menu', 'library'); $this->_helper->actionStack('display', 'search'); $this->_helper->actionStack('contents', 'library'); $this->_helper->actionStack('index', 'sideplaylist'); @@ -74,7 +75,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/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 index 243c4b08d..5b2dd9069 100644 --- a/public/css/jquery.contextMenu.css +++ b/public/css/jquery.contextMenu.css @@ -1,7 +1,7 @@ /* Generic context menu styles */ .contextMenu { position: absolute; - width: 200px; + width: 120px; z-index: 99999; border: solid 1px #CCC; background: #EEE; 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/advancedsearch.js b/public/js/campcaster/library/advancedsearch.js index 2daf34390..07b9ea9cb 100644 --- a/public/js/campcaster/library/advancedsearch.js +++ b/public/js/campcaster/library/advancedsearch.js @@ -47,11 +47,8 @@ function searchLibrary() { $("#library_display tr:not(:first-child)").remove(); $("#library_display tbody").append(json.results); - $("#library_display tr:not(:first-child)") - .contextMenu({menu: 'myMenu'}, contextMenu) - .draggable({ - helper: 'clone' - }); + //in campcaster/library.js + addLibraryItemEvents(); } }); 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..258278022 100644 --- a/public/js/campcaster/library/library.js +++ b/public/js/campcaster/library/library.js @@ -1,24 +1,62 @@ -function deleteItem(json){ - var id; +function getId() { + var tr_id = $(this.triggerElement).attr("id"); + tr_id = tr_id.split("_"); + return tr_id[1]; +} + +function getType() { + var tr_id = $(this.triggerElement).attr("id"); + tr_id = tr_id.split("_"); + + return tr_id[0]; +} + +function deleteItem(type, id) { + var tr_id; + + tr_id = type+"_"+id; + + $("#library_display tr#" +tr_id).remove(); +} + +function deleteAudioClip(json) { if(json.message) { - alert(j.message); - return; + alert(json.message); + return; } - id = this.url.split('/').pop(); - $("#library_display tr#" +id).remove(); + deleteItem("au", json.id); +} + +function deletePlaylist(json) { + if(json.message) { + alert(json.message); + return; + } + + deleteItem("pl", json.id); +} + +function addLibraryItemEvents() { + $('#library_display tr[id ^= "au"]') + .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"}); + } function setLibraryContents(data){ $("#library_display tr:not(:first-child)").remove(); $("#library_display").append(data); - $("#library_display tr:not(:first-child)") - .contextMenu({menu: 'myMenu'}, contextMenu) - .draggable({ - helper: 'clone' - }); + addLibraryItemEvents() } function setUpLibrary() { @@ -45,9 +83,5 @@ function setUpLibrary() { $.post(url, {ob: ob, order: order}, setLibraryContents); }); - $("#library_display tr:not(:first-child)") - .contextMenu({menu: 'myMenu'}, contextMenu) - .draggable({ - helper: 'clone' - }); + addLibraryItemEvents() } diff --git a/public/js/campcaster/library/spl.js b/public/js/campcaster/library/spl.js index f57da75db..e307afc63 100644 --- a/public/js/campcaster/library/spl.js +++ b/public/js/campcaster/library/spl.js @@ -28,7 +28,7 @@ function addSPLItem(event, ui){ if(tr.get(0).tagName === 'LI') return; - id = tr.attr('id'); + id = tr.attr('id').split("_").pop(); url = '/Playlist/add-item/format/json'; url = url + '/id/'+id; @@ -90,6 +90,15 @@ function deleteSPL() { $.post(url, noOpenPL); } +function openDiffSPL(json) { + + $("#side_playlist") + .empty() + .append(json.html); + + setUpSPL(); +} + function setUpSPL() { $("#spl_sortable").sortable(); diff --git a/public/js/contextmenu/jjmenu.js b/public/js/contextmenu/jjmenu.js new file mode 100644 index 000000000..48f75ea4b --- /dev/null +++ b/public/js/contextmenu/jjmenu.js @@ -0,0 +1,367 @@ +/* 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) { + + $("#jjmenu_main").hide(); + + 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);