--- TYPO3core_orig/t3lib/class.t3lib_ajax.php 1970-01-01 01:00:00.000000000 +0100 +++ TYPO3core/t3lib/class.t3lib_ajax.php 2005-10-23 21:38:39.000000000 +0200 + + */ + +/** + * TYPO3 XMLHTTP class (new in TYPO3 4.0.0) + * This class contains two main parts: + * (1) generation of JavaScript code which creates an XMLHTTP object in a cross-browser manner + * (2) generation of XML data as a reply + * + * @author Sebastian Kurfuerst + * @package TYPO3 + * @subpackage t3lib + */ +class t3lib_ajax { + /** + * gets javascript code needed to handle an XMLHTTP request in the frontend. + * all JS functions have to call ajax_doRequest(url) to make a request to the server. + * USE: + * see examples of using this function in template.php -> getContextMenuCode and alt_clickmenu.php -> printContent + * + * @param string $handlerFunction JS function handling the XML data from the server. That function gets the returned XML data as parameter. + * @param string $fallback JS fallback function which is called with the URL of the request in case ajax is not available. + * @param boolean $debug If set to 1, the returned XML data is outputted as text in an alert window - useful for debugging, PHP errors are shown there, ... + * @return string JavaScript code needed to make and handle an XMLHTTP request + */ + function getJScode($handlerFunction, $fallback = '', $debug=0) { + // init xmlhttp request object + $code = ' + function ajax_initObject() { + var A; + try { + A=new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + A=new ActiveXObject("Microsoft.XMLHTTP"); + } catch (oc) { + A=null; + } + } + if(!A && typeof XMLHttpRequest != "undefined") { + A = new XMLHttpRequest(); + } + return A; + }'; + // in case ajax is not available, fallback function + if($fallback) { + $fallback .= '(url)'; + } else { + $fallback = 'return'; + } + $code .= ' + function ajax_doRequest(url) { + var x; + + x = ajax_initObject(); + if(!x) { + '.$fallback.'; + } + x.open("GET", url, true); + + x.onreadystatechange = function() { + if (x.readyState != 4) { + return; + } + '.($debug?'alert(x.responseText)':'').' + var xmldoc = x.responseXML; + var t3ajax = xmldoc.getElementsByTagName("t3ajax")[0]; + '.$handlerFunction.'(t3ajax); + } + x.send(""); + + delete x; + }'; + + return $code; + } + + /** + * Function outputting XML data for TYPO3 ajax. The function directly outputs headers and content to the browser. + * + * @param string $innerXML XML data which will be sent to the browser + * @return void + */ + function outputXMLreply($innerXML) { + // ajax needs xml data + header('Content-Type: text/xml'); + $xml = ' +'.$innerXML.''; + echo $xml; + } + +} + + +if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_ajax.php']) { + include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_ajax.php']); +} +?> --- TYPO3core_orig/typo3/alt_clickmenu.php 2005-10-21 10:06:59.000000000 +0200 +++ TYPO3core/typo3/alt_clickmenu.php 2005-10-23 22:11:27.000000000 +0200 @@ -112,6 +112,7 @@ require ('init.php'); require ('template.php'); require_once (PATH_t3lib.'class.t3lib_clipboard.php'); +require_once(PATH_t3lib.'class.t3lib_ajax.php'); $LANG->includeLLFile('EXT:lang/locallang_misc.xml'); @@ -142,6 +143,7 @@ var $dontDisplayTopFrameCM=0; // If true, the context sensitive menu will not appear in the top frame, only as a layer. var $leftIcons=0; // If true, Show icons on the left. var $extClassArray=array(); // Array of classes to be used for user processing of the menu content. This is for the API of adding items to the menu from outside. + var $ajax=0; // enable/disable ajax behavior // Internal, dynamic: var $elCount=0; // Counter for elements in the menu. Used to number the name / id of the mouse-over icon. @@ -154,19 +156,23 @@ /** * Initialize click menu * - * @param string Input "item" GET var. * @return string The clickmenu HTML content */ - function init($item) { - + function init() { // Setting GPvars: $this->cmLevel = intval(t3lib_div::_GP('cmLevel')); $this->CB = t3lib_div::_GP('CB'); + if(t3lib_div::_GP('ajax')) { + $this->ajax = 1; + ini_set('display_errors',0); // XML has to be parsed, no parse errors allowed + } - - // Explode the incoming command: - $this->iParts = explode('|',$item); - + // can be set differently as well + $this->iParts[0] = t3lib_div::_GP('table'); + $this->iParts[1] = t3lib_div::_GP('uid'); + $this->iParts[2] = t3lib_div::_GP('listFr'); + $this->iParts[3] = t3lib_div::_GP('enDisItems'); + // Setting flags: if ($this->iParts[2]) $this->listFrame=1; if ($GLOBALS['BE_USER']->uc['condensedMode'] || $this->iParts[2]==2) $this->alwaysContentFrame=1; @@ -191,7 +197,7 @@ } } - // Return clickmenu conten: + // Return clickmenu content: return $CMcontent; } @@ -201,7 +207,11 @@ * @return boolean */ function doDisplayTopFrameCM() { - return !$GLOBALS['SOBE']->doc->isCMlayers() || !$this->dontDisplayTopFrameCM; + if($this->ajax) { + return false; + } else { + return !$GLOBALS['SOBE']->doc->isCMlayers() || !$this->dontDisplayTopFrameCM; + } } @@ -1028,18 +1038,21 @@ // Set back path place holder to real back path $CMtable = str_replace($this->PH_backPath,$this->backPath,$CMtable); - + if($this->ajax) { + $innerXML = ''.$this->cmLevel.''; + return $innerXML; + } else { // Create JavaScript section: $script=$GLOBALS['TBE_TEMPLATE']->wrapScriptTags(' -if (top.content && top.content'.$frameName.' && top.content'.$frameName.'.setLayerObj) { - top.content'.$frameName.'.setLayerObj(unescape("'.t3lib_div::rawurlencodeJS($CMtable).'"),'.$this->cmLevel.'); -} -'.(!$this->doDisplayTopFrameCM()?'hideCM();':'') -); + if (top.content && top.content'.$frameName.' && top.content'.$frameName.'.setLayerObj) { + top.content'.$frameName.'.setLayerObj(unescape("'.t3lib_div::rawurlencodeJS($CMtable).'"),'.$this->cmLevel.'); + } + '.(!$this->doDisplayTopFrameCM()?'hideCM();':'') + ); + return $script; + } } - - return $script; } /** @@ -1205,7 +1218,10 @@ */ function linkItem($str,$icon,$onClick,$onlyCM=0,$dontHide=0) { $this->elCount++; - + if($this->ajax) { + $onClick = str_replace('top.loadTopMenu', 'showClickmenu_raw', $onClick); + } + $WHattribs = t3lib_iconWorks::skinImg($BACK_PATH,'gfx/content_client.gif','width="7" height="10"',2); return array( @@ -1327,7 +1343,11 @@ * @return boolean */ function isCMlayers() { - return $GLOBALS['SOBE']->doc->isCMlayers() && !$this->CB; + if($this->ajax) { + return !$this->CB; + } else { + return $GLOBALS['SOBE']->doc->isCMlayers() && !$this->CB; + } } /** @@ -1410,9 +1430,11 @@ } // Initialize template object - $this->doc = t3lib_div::makeInstance('template'); - $this->doc->docType='xhtml_trans'; - $this->doc->backPath = $BACK_PATH; + if(!$this->ajax) { + $this->doc = t3lib_div::makeInstance('template'); + $this->doc->docType='xhtml_trans'; + $this->doc->backPath = $BACK_PATH; + } // Setting mode for display and background image in the top frame $this->dontDisplayTopFrameCM= $this->doc->isCMlayers() && !$BE_USER->getTSConfigVal('options.contextMenu.options.alwaysShowClickMenuInTopFrame'); @@ -1480,6 +1502,8 @@ */ function main() { + $this->ajax = t3lib_div::_GP('ajax')?TRUE:FALSE; + // Initialize Clipboard object: $clipObj = t3lib_div::makeInstance('t3lib_clipboard'); $clipObj->initializeClipboard(); @@ -1501,10 +1525,11 @@ $clickMenu->backPath = $this->backPath; // Start page - $this->content.=$this->doc->startPage('Context Sensitive Menu'); - + if(!$this->ajax) { + $this->content.=$this->doc->startPage('Context Sensitive Menu'); + } // Set content of the clickmenu with the incoming var, "item" - $this->content.= $clickMenu->init($this->item); + $this->content.= $clickMenu->init(); } /** @@ -1513,8 +1538,12 @@ * @return void */ function printContent() { - $this->content.= $this->doc->endPage(); - echo $this->content; + if(!$this->ajax) { + $this->content.= $this->doc->endPage(); + echo $this->content; + } else { + t3lib_ajax::outputXMLreply($this->content); + } } } --- TYPO3core_orig/typo3/template.php 2005-10-21 10:06:59.000000000 +0200 +++ TYPO3core/typo3/template.php 2005-10-23 21:54:48.000000000 +0200 @@ -116,7 +116,7 @@ if (!defined('TYPO3_MODE')) die("Can't include this file directly."); - +require_once(PATH_t3lib.'class.t3lib_ajax.php'); @@ -288,8 +288,8 @@ * @return string The link-wrapped input string. */ function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE) { - $backPath = '&backPath='.rawurlencode($this->backPath).'|'.t3lib_div::shortMD5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']); - $onClick = 'top.loadTopMenu(\''.$this->backPath.'alt_clickmenu.php?item='.rawurlencode($table.'|'.$uid.'|'.$listFr.'|'.$enDisItems).$backPath.$addParams.'\');'.$this->thisBlur().'return false;'; + $backPath = rawurlencode($this->backPath).'|'.t3lib_div::shortMD5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']); + $onClick = 'showClickmenu("'.$table.'","'.$uid.'","'.$listFr.'","'.$enDisItems.'","'.str_replace('&','&',addcslashes($backPath,'"')).'","'.str_replace('&','&',addcslashes($addParams,'"')).'");return false;'; return $returnOnClick ? $onClick : ''.$str.''; } @@ -1231,10 +1231,46 @@ * @return array If values are present: [0] = A - '; + }'; + $content.=' /*]]>*/ + '; return array( $content, ' onmousemove="GL_getMouse(event);" onload="initLayer();"', '' ); - } else return array('','',''); + } else { + $content.=' /*]]>*/ + '; + return array($content,'',''); + } } /**