Issue #7307: Bugfixes for "Open Documents" extension - Part 1
authorBenni Mack <benni.mack@typo3.org>
Fri, 22 Feb 2008 20:30:28 +0000 (20:30 +0000)
committerBenni Mack <benni.mack@typo3.org>
Fri, 22 Feb 2008 20:30:28 +0000 (20:30 +0000)
 - Changed getSetUpdateSignal() function in t3lib_BEfunc and added hook possibility
 - Used hook for tx_opendocs to be updated when opening & closing a document
 - Several bugfixes and new features for tx_opendocs

git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@3263 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_befunc.php
typo3/alt_doc.php
typo3/sysext/opendocs/class.tx_opendocs.php
typo3/sysext/opendocs/ext_tables.php
typo3/sysext/opendocs/locallang_opendocs.xml
typo3/sysext/opendocs/opendocs.css
typo3/sysext/opendocs/opendocs.js
typo3/template.php

index 79759ef..62bb869 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-22  Benjamin Mack  <mack@xnos.org>
+
+       * Issue #7307: Bugfixes for "Open Documents" extension - Part 1
+         - Changed getSetUpdateSignal() function in t3lib_BEfunc and added hook possibility
+         - Used hook for tx_opendocs to be updated when opening & closing a document
+         - Several bugfixes and new features for tx_opendocs
+
 2008-02-22  Jeff Segars  <jeff@webempoweredchurch.org>
 
        * Added feature #7247: Add hook for warning messages within Help->About modules and improve existing warning messages
index 17e829d..5d94ccb 100755 (executable)
@@ -2680,44 +2680,91 @@ class t3lib_BEfunc      {
         * Call to update the page tree frame (or something else..?) after
         * t3lib_BEfunc::getSetUpdateSignal('updatePageTree') -> will set the page tree to be updated.
         * t3lib_BEfunc::getSetUpdateSignal() -> will return some JavaScript that does the update (called in the typo3/template.php file, end() function)
+        * please use the setUpdateSignal function instead now, as it allows you to add more parameters
         * Usage: 11
         *
         * @param       string          Whether to set or clear the update signal. When setting, this value contains strings telling WHAT to set. At this point it seems that the value "updatePageTree" is the only one it makes sense to set.
         * @return      string          HTML code (<script> section)
+        * @see t3lib_BEfunc::getUpdateSignalCode()
+        * @see t3lib_BEfunc::setUpdateSignal()
+        * @deprecated  since TYPO3 4.2, please use the setUpdateSignal function instead, as it allows you to add more parameters
+        */
+       function getSetUpdateSignal($set = '')  {
+                       // kept for backwards compatibility if $set is empty, use "getUpdateSignalCode()" instead
+               if ($set) {
+                       return t3lib_BEfunc::setUpdateSignal($set);
+               } else {
+                       return t3lib_BEfunc::getUpdateSignalCode();
+               }
+       }
+
+
+       /**
+        * Call to update the page tree frame (or something else..?) after
+        * use 'updatePageTree' as a first parameter will set the page tree to be updated.
+        * Usage: 10
+        *
+        * @param       string          Key to set the update signal. When setting, this value contains strings telling WHAT to set. At this point it seems that the value "updatePageTree" is the only one it makes sense to set. If empty, all update signals will be removed.
+        * @param       mixed           Additional information for the update signal, used to only refresh a branch of the tree
+        * @return      void
+        * @see t3lib_BEfunc::getUpdateSignalCode()
         */
-       function getSetUpdateSignal($set='')    {
+       public function setUpdateSignal($set = '', $params = '') {
                global $BE_USER;
-               $key = 't3lib_BEfunc::getSetUpdateSignal';
-               $out='';
-               if ($set)       {
-                       $modData=array();
-                       $modData['set']=$set;
-                       $BE_USER->pushModuleData($key,$modData);
+               $modData = $BE_USER->getModuleData('t3lib_BEfunc::getUpdateSignal', 'ses');
+
+               if ($set) {
+                       $modData[$set] = array(
+                               'set' => $set,
+                               'parameter' => $params);
+               } else {        // clear the module data
+                       $modData = array();
+               }
+               $BE_USER->pushModuleData('t3lib_BEfunc::getUpdateSignal', $modData);
+       }
+
+
+       /**
+        * Call to update the page tree frame (or something else..?) if this is set by the function
+        * setUpdateSignal(). It will return some JavaScript that does the update (called in the typo3/template.php file, end() function)
+        * Usage: 1
+        *
+        * @return      string          HTML javascript code
+        * @see t3lib_BEfunc::setUpdateSignal()
+        */
+       public function getUpdateSignalCode() {
+               $signals = array();
+               $modData = $GLOBALS['BE_USER']->getModuleData('t3lib_BEfunc::getUpdateSignal', 'ses');
+               if (!count($modData)) {
+                       return '';
+               }
+
+                       // Hook: Allows to let TYPO3 execute your JS code 
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['updateSignalHook'])) {
+                       $updateSignals = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['updateSignalHook'];
                } else {
-                       $modData = $BE_USER->getModuleData($key,'ses');
-                       if (trim($modData['set']))      {
-                               $l=explode(',',$modData['set']);
-                               while(list(,$v)=each($l))       {
-                                       switch($v)      {
-                                               case 'updatePageTree':
-                                               case 'updateFolderTree':
-                                                       $out.='
-                                       <script type="text/javascript">
-                                       /*<![CDATA[*/
-                                                       if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav)  {
-                                                               top.content.nav_frame.refresh_nav();
-                                                       }
-                                       /*]]>*/
-                                       </script>';
-                                               break;
-                                       }
-                               }
-                               $modData=array();
-                               $modData['set']='';
-                               $BE_USER->pushModuleData($key,$modData);
+                       $updateSignals = array();
+               }
+
+                       // loop through all setUpdateSignals and get the JS code
+               foreach ($modData as $set => $val) {
+                       if (isset($updateSignals[$set])) {
+                               $params = array('set' => $set, 'parameter' => $val['parameter'], 'JScode' => '');
+                               $ref = NULL;
+                               t3lib_div::callUserFunction($updateSignals[$set], $params, $ref);
+                               $signals[] = $params['JScode'];
+                       } else if ($set == 'updatePageTree' || $set == 'updateFolderTree') {
+                               $signals[] = '
+                                       if (top && top.content && top.content.nav_frame && top.content.nav_frame.Tree) {
+                                               top.content.nav_frame.Tree.refresh();
+                                       }';
                        }
                }
-               return $out;
+
+               $content = implode(chr(10), $signals);
+
+               t3lib_BEfunc::setUpdateSignal();        // for backwards compatibility, should be replaced
+               return $content;
        }
 
 
index d2a7704..56a945a 100755 (executable)
@@ -304,7 +304,7 @@ class SC_alt_doc {
 
                        // If pages are being edited, we set an instruction about updating the page tree after this operation.
                if (isset($this->data['pages']))        {
-                       t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
+                       t3lib_BEfunc::setUpdateSignal('updatePageTree');
                }
 
 
@@ -533,14 +533,21 @@ class SC_alt_doc {
                                $this->editRegularContentFromId();
                        }
 
+
                                // Creating the editing form, wrap it with buttons, document selector etc.
                        $editForm = $this->makeEditForm();
 
-
-
                        if ($editForm)  {
                                $this->firstEl = reset($this->elementsData);
 
+                                       // Checking if the currently open document is stored in the list of "open documents" - if not, then add it:
+                               if ((strcmp($this->docDat[1], $this->storeUrlMd5) || !isset($this->docHandler[$this->storeUrlMd5])) && !$this->dontStoreDocumentRef) {
+                                               $this->docHandler[$this->storeUrlMd5] = array($this->storeTitle, $this->storeArray, $this->storeUrl, $this->firstEl);
+                                               $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler, $this->storeUrlMd5));
+                                               t3lib_BEfunc::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler));
+                               }
+
+
                                        // Module configuration
                                $this->modTSconfig = ($this->viewId ? t3lib_BEfunc::getModTSconfig($this->viewId,'mod.xMOD_alt_doc') : array());
 
@@ -884,20 +891,29 @@ class SC_alt_doc {
                $buttons['open_in_new_window'] = $this->openInNewWindowLink();
                return $buttons;
        }
-       
+
+       /**
+        * Returns the language switch/selector for editing,
+        * show only when a single record is edited
+        * - multiple records are too confusing
+        * @return      string          the HTML
+        */
        function langSelector() {
                $langSelector = '';
-               
-                       // language switch/selector for editing, show only when a single record is edited
-                       // - multiple records are too confusing
                if (count($this->elementsData) == 1) {
                        $langSelector = $this->languageSwitch($this->firstEl['table'], $this->firstEl['uid'], $this->firstEl['pid']);
                }
                return $langSelector;
        }
-       
+
+
+       /**
+        * Compiles the extra form headers if the tceforms
+        *
+        * @return      string          the HTML
+        */
        function extraFormHeaders() {
-               $extraHeader = '';
+               $extraTemplate = '';
                
                if (is_array($this->tceforms->extraFormHeaders)) {
                        $extraTemplate = t3lib_parsehtml::getSubpart($this->doc->moduleTemplate, '###DOCHEADER_EXTRAHEADER###');
@@ -906,6 +922,7 @@ class SC_alt_doc {
                return $extraTemplate;
        }
 
+
        /**
         * Put together the various elements (buttons, selectors, form) into a table
         *
@@ -1382,6 +1399,7 @@ class SC_alt_doc {
                        }
                        $BE_USER->pushModuleData('opendocs::recent', $recentDocs);
                        $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler, $this->docDat[1]));
+                       t3lib_BEfunc::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler));
                }
 
 
index fc149a6..7f009af 100644 (file)
@@ -58,21 +58,32 @@ class tx_opendocs implements backend_toolbarItem {
         */
        public function __construct(TYPO3backend &$backendReference = null) {
                $this->backendReference = $backendReference;
-
-               list($this->openDocs,)  = $GLOBALS['BE_USER']->getModuleData('alt_doc.php','ses');
-               $this->recentDocs       = $GLOBALS['BE_USER']->getModuleData('opendocs::recent');
+               $this->loadDocsFromUserSession();
        }
 
+
        /**
         * checks whether the user has access to this toolbar item
         *
         * @return  boolean  true if user has access, false if not
         */
        public function checkAccess() {
-                       // FIXME - needs proper access check
-               return true;
+               $conf = $GLOBALS['BE_USER']->getTSConfig('backendToolbarItem.tx_opendocs.disabled');
+               return ($conf['value'] == 1 ? false : true);
+       }
+
+
+       /**
+        * loads the opened and recently opened documents from the user 
+        *
+        * @return  void
+        */
+       public function loadDocsFromUserSession() {
+               list($this->openDocs,)  = $GLOBALS['BE_USER']->getModuleData('alt_doc.php','ses');
+               $this->recentDocs       = $GLOBALS['BE_USER']->getModuleData('opendocs::recent');
        }
 
+
        /**
         * renders the toolbar item and the empty menu
         *
@@ -81,52 +92,48 @@ class tx_opendocs implements backend_toolbarItem {
        public function render() {
                $this->addJavascriptToBackend();
                $this->addCssToBackend();
+               $numDocs = count($this->openDocs);
 
                        // return the toolbar item and an empty UL
                $output  = '<a href="#" class="toolbar-item">';
+               $output .= '<span id="tx-opendocs-num">'.($numDocs > 0 ? $numDocs : '').'</span>';
                $output .= '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], t3lib_extMgm::extRelPath($this->EXTKEY).'opendocs.png', 'width="23" height="14"').' title="'.$GLOBALS['LANG']->getLL('toolbaritem',1).'" alt="" />';
                $output .= '</a>';
-               $output .= '<ul class="toolbar-item-menu" style="display: none;"></ul>';
+               $output .= '<div class="toolbar-item-menu" style="display: none;"></div>';
 
                return $output;
        }
 
 
        /**
-        * returns the opened documents list as an array
-        *
-        * @return      array   all open documents as list-items
-        */
-       public function getOpenDocuments() {
-               $docs = array();
-
-                       // Traverse the list of open documents:
-               if (is_array($this->openDocs)) {
-                       foreach($this->openDocs as $md5k => $lnk) {
-                               $docs[] = '<li><a target="content" href="'.htmlspecialchars('alt_doc.php?'.$lnk[2]).'">'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($lnk[0]))).'</a></li>';
-                       }
-               }
-               return $docs;
-       }
-
-
-       /**
         * returns the recent documents list as an array
         *
         * @return      array   all recent documents as list-items
         */
-       public function getRecentDocuments() {
-               $docs = array();
-
-               if (is_array($this->recentDocs)) {
-                       $docs[] = '<li class="menu-item-div">'.$GLOBALS['LANG']->getLL('recent_docs',1).'</li>';
-
-                               // Traverse the list of open documents:
-                       foreach($this->recentDocs as $md5k => $lnk) {
-                               $docs[] = '<li><a target="content" href="'.htmlspecialchars('alt_doc.php?'.$lnk[2]).'">'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($lnk[0]))).'</a></li>';
-                       }
+       public function renderMenuEntry($itm, $md5sum, $isRecentDoc = false) {
+               $table = $itm[3]['table'];
+               $uid   = $itm[3]['uid'];
+               $rec   = t3lib_BEfunc::getRecordWSOL($table, $uid);
+               $label = htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($itm[0])));
+               $icon  = '<img src="'.t3lib_iconWorks::getIcon($table, $rec).'" alt="'.$label.'" />';
+               $link  = $GLOBALS['BACK_PATH'].'alt_doc.php?'.$itm[2];
+
+               if ($isRecentDoc) {
+                       $entry = '
+                               <tr id="opendocs-'.$table.'-'.$uid.'" class="recentdoc">
+                                       <td class="opendocs-icon">'.$icon.'</td>
+                                       <td class="opendocs-label" colspan="2" id="opendocs-label-'.$table.'-'.$uid.'"><a href="'.$link.'" target="content" onclick="TYPO3BackendOpenDocs.hideMenu();">'.$label.'</a></td>
+                               </tr>';
+               } else {
+                       $closeIcon = '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/closedok.gif', 'width="16" height="16"').' title="Close Document" alt="" />';
+                       $entry = '
+                               <tr id="opendocs-'.$table.'-'.$uid.'" class="opendoc">
+                                       <td class="opendocs-icon">'.$icon.'</td>
+                                       <td class="opendocs-label" id="opendocs-label-'.$table.'-'.$uid.'"><a href="'.$link.'" target="content" onclick="TYPO3BackendOpenDocs.hideMenu();">'.$label.'</a></td>
+                                       <td class="opendocs-close" onclick="return TYPO3BackendOpenDocs.closeDocument(\''.$md5sum.'\');">'.$closeIcon.'</td>
+                               </tr>';
                }
-               return $docs;
+               return $entry;
        }
 
 
@@ -161,30 +168,96 @@ class tx_opendocs implements backend_toolbarItem {
        }
 
 
+       /*******************
+        ***    HOOKS    ***
+        *******************/
 
+       /**
+        * called as a hook in t3lib_BEfunc::setUpdateSignal, calls a JS function to change
+        * the number of opened documents
+        *
+        * @return      string          list item HTML attibutes
+        */
+       public function updateNumberOfOpenDocsHook(&$params, &$ref) {
+               $params['JScode'] = '
+                       if (top && top.TYPO3BackendOpenDocs) {
+                               top.TYPO3BackendOpenDocs.updateNumberOfDocs('.count($this->openDocs).', false);
+                       }
+               ';
+       }
+
+
+
+       /******************
+        *** AJAX CALLS ***
+        ******************/
 
        /**
         * returns the opened documents list for the AJAX call formatted as HTML list
         *
+        * @param       array           array full of additional params, not used yet
+        * @param       TYPO3AJAX       Ajax request object
         * @return      string          list item HTML attibutes
         */
        public function renderBackendMenuContents($params, &$ajaxObj) {
-               $itms = $this->getOpenDocuments();
-               $itmsRecent = $this->getRecentDocuments();
+               $itms = $this->openDocs;
+               $itmsRecent = $this->recentDocs;
+               $entries = array();
+
+               if (count($itms)) {
+                       $entries[] = '<tr class="menu-item-div"><td colspan="3">'.$GLOBALS['LANG']->getLL('open_docs',1).'</td></tr>';
+                       foreach ($itms as $md5sum => $itm) {
+                               $entries[] = $this->renderMenuEntry($itm, $md5sum);
+                       }
+               }
+
 
 
                        // if there are "recent documents" in the list, add them
                if (count($itmsRecent)) {
-                       $itms = array_merge($itms, $itmsRecent);
+                       $entries[] = '<tr class="menu-item-div"><td colspan="3">'.$GLOBALS['LANG']->getLL('recent_docs',1).'</td></tr>';
+                       foreach ($itmsRecent as $md5sum => $itm) {
+                               $entries[] = $this->renderMenuEntry($itm, $md5sum, true);
+                       }
                }
 
-
-               if (count($itms)) {
-                       $ajaxObj->addContent('opendocs', implode('', $itms));
+               if (count($entries)) {
+                       $content = '<table class="opendocs-list">'.implode('', $entries).'</table>';
+                       $ajaxObj->addContent('opendocs', $content);
                } else {
-                       $ajaxObj->addContent('opendocs', '<li>'.$GLOBALS['LANG']->getLL('no_docs',1).'</li>');
+                       $ajaxObj->addContent('opendocs', '<div id="opendocs-nodocs">'.$GLOBALS['LANG']->getLL('no_docs',1).'</div>');
                }
        }
+
+
+
+       /**
+        * closes a document in the session and 
+        * @param       array           array full of additional params, not used yet
+        * @param       TYPO3AJAX       Ajax request object
+        * @return      string          list item HTML attibutes
+        */
+       public function closeDocument($params, &$ajaxObj) {
+               $md5sum = t3lib_div::_GP('md5sum');
+               if ($md5sum && isset($this->openDocs[$md5sum])) {
+
+                               // add the closing document to the recent documents
+                       $this->recentDocs = array_merge(array($md5sum => $this->openDocs[$md5sum]), $this->recentDocs);
+                       if (count($this->recentDocs) > 8) {
+                               $this->recentDocs = array_slice($this->recentDocs, 0, 8);
+                       }
+
+                               // remove it from the list of the open documents
+                       unset($this->openDocs[$md5sum]);
+
+                               // store it again
+                       list(,$docDat) = $GLOBALS['BE_USER']->getModuleData('alt_doc.php','ses');
+                       $GLOBALS['BE_USER']->pushModuleData('alt_doc.php', array($this->openDocs, $docDat));
+                       $GLOBALS['BE_USER']->pushModuleData('opendocs::recent', $this->recentDocs);
+               }
+               $this->renderBackendMenuContents($params, $ajaxObj);
+       }
+
 }
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['EXT:opendocs/class.tx_opendocs.php']) {
index 350d645..18d12f2 100644 (file)
@@ -8,8 +8,12 @@ if (TYPO3_MODE == 'BE') {
        $GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'][] = t3lib_extMgm::extPath('opendocs').'registerToolbarItem.php';
 
 
-               // register AJAX call
-       $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX']['tx_opendocs::backendmenu'] = t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php:tx_opendocs->renderBackendMenuContents';
+               // register AJAX calls
+       $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX']['tx_opendocs::backendMenu']   = t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php:tx_opendocs->renderBackendMenuContents';
+       $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX']['tx_opendocs::closeDocument'] = t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php:tx_opendocs->closeDocument';
+
+               // register update signal to update the number of open documents
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['updateSignalHook']['tx_opendocs::updateNumber'] = t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php:tx_opendocs->updateNumberOfOpenDocsHook';
 
 
                // register menu module if option is wanted
@@ -19,4 +23,4 @@ if (TYPO3_MODE == 'BE') {
        }
 }
 
-?>
\ No newline at end of file
+?>
index 5fcb1b0..4874ffa 100755 (executable)
@@ -12,7 +12,7 @@
                        <label index="toolbaritem">Open and Recently Edited Documents</label>
                        <label index="open_docs">Opened Documents</label>
                        <label index="recent_docs">Recently Edited Documents</label>
-                       <label index="no_docs">There are no open documents</label>
+                       <label index="no_docs">There are no open documents at this time.</label>
                </languageKey>
        </data>
 </T3locallang>
index f21bffe..0797803 100644 (file)
@@ -1,49 +1,53 @@
 #open-documents-menu {
-       width: 30px;
+       width: 40px;
 }
 
-#open-documents-menu img {
-       margin: 1px 0 0;
+span#tx-opendocs-num {
+       padding: 0 2px;
+       line-height: 14px;
 }
 
-#open-documents-menu ul {
-       width: 185px;
+#open-documents-menu div {
        position: absolute;
        list-style: none;
-       padding: 2px 0px 0px;
-       margin: 0px;
+       margin: 0;
+       padding: 2px 0 0;
        background-color: #f9f9f9;
        border: 1px solid #abb2bc;
        border-top: none;
 }
 
-#open-documents-menu li {
+#open-documents-menu table,
+#open-documents-menu tr {
+       width: 100%;
+       border-collapse: collapse;
+       padding: 0;
+       border: 0;
+       margin: 0;
+}
+
+#open-documents-menu td {
        text-align: left;
-       float: none;
-       vertical-align: middle;
+       vertical-align: top;
        line-height: 14px;
        font-size: 11px;
+       margin: 0;
        padding: 1px 1px 1px 0;
 }
 
-#open-documents-menu li img {
-       float: left;
-       padding-right: 3px;
+#open-documents-menu td.opendocs-close {
+       text-align: right;
 }
 
-#open-documents-menu li a {
+#open-documents-menu tr.menu-item-div td {
+       border-top: 1px solid #abb2bc;
+       font-weight: bold;
+       padding: 2px 3px;
+}
+
+#open-documents-menu td a {
        text-decoration: none;
-       vertical-align: middle;
-       display: block;
-       padding: 1px 1px 1px 4px;
+       padding: 1px;
        font-size: 11px;
 }
 
-#open-documents-menu li a:hover {
-       background: #f0f0f0;
-}
-#open-documents-menu li.menu-item-div {
-       border-top: 1px solid #abb2bc;
-       font-weight: bold;
-       padding: 2px 0 2px 3px;
-}
index faf7bfe..b3505f0 100644 (file)
  */
 var OpenDocs = Class.create({
        ajaxScript: 'ajax.php',
-       ajaxID: 'tx_opendocs::backendmenu',
+       ajaxIDloadMenu: 'tx_opendocs::backendMenu',
+       ajaxIDcloseDoc: 'tx_opendocs::closeDocument',
        menuItem: 'open-documents-menu',
-       menu: null,             // the <ul> tag
+       menu: null,             // the <div> tag
        toolbarItem: null,      // the <a> tag
 
 
@@ -39,16 +40,17 @@ var OpenDocs = Class.create({
         */
        initialize: function() {
                Event.observe(window, 'load', function() {
+                       this.ajaxScript = top.TS.PATH_typo3 + this.ajaxScript; // can't be initialized earlier
                        this.getMenu();
-                       Event.observe(window,        'resize', this.positionMenu.bindAsEventListener(this));
-                       Event.observe(this.menuItem, 'click',    this.toggleMenu.bindAsEventListener(this));
+                       Event.observe(window,          'resize', this.positionMenu.bindAsEventListener(this));
+                       Event.observe(this.toolbarItem, 'click',   this.toggleMenu.bindAsEventListener(this));
                }.bindAsEventListener(this));
        },
 
 
        getMenu: function() {
-               this.menu = $$('#' + this.menuItem + ' ul')[0];
-               this.toolbarItem = $$('#'+this.menuItem+' a')[0];
+               this.toolbarItem = $(this.menuItem).firstChild;
+               this.menu = this.toolbarItem.nextSibling;
        },
 
 
@@ -72,7 +74,8 @@ var OpenDocs = Class.create({
        /**
         * toggles the visibility of the menu and places it under the toolbar icon
         */
-       toggleMenu: function() {
+       toggleMenu: function(event) {
+               Event.stop(event);
                this.toolbarItem.blur();
                if(!this.toolbarItem.hasClassName('toolbar-item-active')) {
                        this.showMenu();
@@ -82,20 +85,26 @@ var OpenDocs = Class.create({
        },
 
 
+
        /**
         * displays the menu and does the AJAX call to the TYPO3 backend
         */
        showMenu: function() {
-               new Ajax.Request(this.ajaxScript, {
-                       parameters: 'ajaxID=' + this.ajaxID,
+               new Ajax.Updater(this.menu, this.ajaxScript, {
+                       parameters: { ajaxID: this.ajaxIDloadMenu },
                        onSuccess: function(xhr) {
-                               this.menu.innerHTML = xhr.responseText;
-                               Effect.Appear(this.menu, {duration: 0.2});
+                               if (!this.menu.visible()) {
+                                       Effect.Appear(this.menu, {
+                                               duration: 0.2,
+                                               afterFinish: function() { this.positionMenu(); }.bind(this)
+                                       });
+                               }
                        }.bind(this)
                });
-               this.positionMenu();
-               this.toolbarItem.addClassName('toolbar-item-active');
-               TYPO3BackendToolbarManager.hideOthers(this.toolbarItem);
+               if (!this.toolbarItem.hasClassName('toolbar-item-active')) {
+                       this.toolbarItem.addClassName('toolbar-item-active');
+                       TYPO3BackendToolbarManager.hideOthers(this.toolbarItem);
+               }
        },
 
 
@@ -103,9 +112,39 @@ var OpenDocs = Class.create({
         * hides the menu
         */
        hideMenu: function() {
-               Effect.Fade(this.menu, {duration: 0.1});
+               Effect.Fade(this.menu, {duration: 0.1} );
                this.toolbarItem.removeClassName('toolbar-item-active');
+       },
+
+
+       /**
+        * updates the number of open documents in the toolbar
+        */
+       updateNumberOfDocs: function(num, doNotUpdateMenu) {
+               if (num < 0) {
+                       num = $$('tr.opendoc').length;
+               }
+               if (num == 0) {
+                       num = '';
+               }
+               $('tx-opendocs-num').innerHTML = num;
+               if (this.menu.visible() && !doNotUpdateMenu) {
+                       this.showMenu();
+               }
+       },
+
+       /**
+        * this function calls the backend to close an open documentshould let the 
+        */
+       closeDocument: function(md5sum) {
+               new Ajax.Updater(this.menu, this.ajaxScript, {
+                       parameters: { ajaxID: this.ajaxIDcloseDoc, md5sum: md5sum },
+                       onSuccess: function() { this.updateNumberOfDocs(-1, true); }.bind(this)
+               });
+               return false;
        }
+
 });
 
 var TYPO3BackendOpenDocs = new OpenDocs();
+
index 1ec2553..b50b98d 100755 (executable)
@@ -695,7 +695,7 @@ $str.=$this->docBodyTagBegin().
                $str = $this->sectionEnd().
                                $this->postCode.
                                $this->endPageJS().
-                               t3lib_BEfunc::getSetUpdateSignal().
+                               $this->wrapScriptTags(t3lib_BEfunc::getUpdateSignalCode()).
                                $this->parseTime().
                                ($this->form?'
 </form>':'');