[TASK] Rewrite clickmenu JS with jQuery 05/33805/7
authorBenjamin Mack <benni@typo3.org>
Tue, 4 Nov 2014 22:19:07 +0000 (23:19 +0100)
committerFrank Nägler <typo3@naegler.net>
Wed, 12 Nov 2014 14:31:51 +0000 (15:31 +0100)
The JS functionality of the ClickMenu
was previously based on PrototypeJS
which is now replaced by a jQuery
RequireJS module.

Certain options and parameters
are not needed anymore and are removed.

Releases: master
Resolves: #62709
Change-Id: I2096ef589590bdffc54693b49cdc92627e982e3d
Reviewed-on: http://review.typo3.org/33805
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Frank Nägler <typo3@naegler.net>
Tested-by: Frank Nägler <typo3@naegler.net>
16 files changed:
typo3/js/tree.js
typo3/sysext/backend/Classes/ClickMenu/ClickMenu.php
typo3/sysext/backend/Classes/Controller/ClickMenuController.php
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Classes/Template/DocumentTemplate.php
typo3/sysext/backend/Resources/Public/JavaScript/ClickMenu.js [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/clickmenu.js [deleted file]
typo3/sysext/beuser/Resources/Private/Partials/BackendUser/IndexListRow.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html
typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Index.html
typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php
typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-33805-ClickMenuRewrite.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php
typo3/sysext/sys_note/Resources/Private/Templates/Note/List.html
typo3/sysext/tstemplate/Classes/Controller/TypoScriptTemplateInformationModuleFunctionController.php

index d64d0c6..35282f8 100644 (file)
@@ -25,7 +25,6 @@ var DragDrop = {
 
        // options needed for doing the changes when dropping
        table: null,    // can be "pages" or "folders"
-       changeURL: null,
        backPath: null,
 
 
@@ -54,12 +53,11 @@ var DragDrop = {
        dropElement: function(event) {
                var dropID = this.getIdFromEvent(event);
                if ((this.dragID) && (this.dragID !== dropID)) {
-                       var urlParams = 'dragDrop=' + this.table +
+                       var parameters = 'dragDrop=' + this.table +
                                        '&srcId=' + this.dragID +
                                        '&dstId=' + dropID +
                                        '&backPath=' + this.backPath;
-                       Clickmenu.clickURL = this.changeURL;
-                       Clickmenu.callURL(urlParams);
+                       TYPO3.ClickMenu.fetch(parameters);
                }
                this.cancelDragEvent();
                return false;
index 1095657..bbb2e03 100644 (file)
@@ -484,7 +484,7 @@ class ClickMenu {
                return ($overrideLoc ? 'var docRef=' . $overrideLoc : 'var docRef=(top.content.list_frame)?top.content.list_frame:' . $loc)
                        . '; docRef.location.href=top.TS.PATH_typo3+\'' . $url . '\'' . ($retUrl ? '+\'&' . $retUrl . '=\'+top.rawurlencode('
                        . $this->frameLocation('docRef.document') . '.pathname+' . $this->frameLocation('docRef.document') . '.search)' : '')
-                       . ';' . ($hideCM ? 'return hideCM();' : '');
+                       . ';';
        }
 
        /**
@@ -527,7 +527,7 @@ class ClickMenu {
                } else {
                        $conf = $loc;
                }
-               $editOnClick = 'if(' . $conf . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'' . $this->clipObj->pasteUrl($table, $uid, 0) . '&redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search); hideCM();}';
+               $editOnClick = 'if(' . $conf . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'' . $this->clipObj->pasteUrl($table, $uid, 0) . '&redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search);}';
                return $this->linkItem($this->label('paste' . $type), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-paste-' . $type)), $editOnClick . 'return false;');
        }
 
@@ -540,7 +540,7 @@ class ClickMenu {
         * @internal
         */
        public function DB_info($table, $uid) {
-               return $this->linkItem($this->label('info'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-info')), 'top.launchView(\'' . $table . '\', \'' . $uid . '\'); return hideCM();');
+               return $this->linkItem($this->label('info'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-info')), 'top.launchView(\'' . $table . '\', \'' . $uid . '\');');
        }
 
        /**
@@ -687,7 +687,7 @@ class ClickMenu {
                if (!$editOnClick) {
                        $editOnClick = 'if(' . $loc . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'alt_doc.php?returnUrl=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'&edit[' . $table . '][' . $uid . ']=edit' . $addParam . '\';}';
                }
-               return $this->linkItem($this->label('edit'), $this->excludeIcon(IconUtility::getSpriteIcon($theIcon)), $editOnClick . 'return hideCM();');
+               return $this->linkItem($this->label('edit'), $this->excludeIcon(IconUtility::getSpriteIcon($theIcon)), $editOnClick . ';');
        }
 
        /**
@@ -702,7 +702,7 @@ class ClickMenu {
                $editOnClick = '';
                $loc = 'top.content.list_frame';
                $editOnClick = 'if(' . $loc . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'' . ($this->listFrame ? 'alt_doc.php?returnUrl=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'&edit[' . $table . '][-' . $uid . ']=new\'' : 'db_new.php?id=' . (int)$uid . '\'') . ';}';
-               return $this->linkItem($this->label('new'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-' . ($table === 'pages' ? 'page' : 'document') . '-new')), $editOnClick . 'return hideCM();');
+               return $this->linkItem($this->label('new'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-' . ($table === 'pages' ? 'page' : 'document') . '-new')), $editOnClick . ';');
        }
 
        /**
@@ -721,7 +721,7 @@ class ClickMenu {
                } else {
                        $conf = '1==1';
                }
-               $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_db.php?redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&cmd[' . $table . '][' . $uid . '][delete]=1&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';}hideCM();';
+               $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_db.php?redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&cmd[' . $table . '][' . $uid . '][delete]=1&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';};';
                if ($table === 'pages') {
                        $editOnClick .= 'top.nav.refresh.defer(500, top.nav);';
                }
@@ -737,7 +737,7 @@ class ClickMenu {
         * @internal
         */
        public function DB_view($id, $anchor = '') {
-               return $this->linkItem($this->label('view'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-view')), BackendUtility::viewOnClick($id, $this->PH_backPath, BackendUtility::BEgetRootLine($id), $anchor) . 'return hideCM();');
+               return $this->linkItem($this->label('view'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-view')), BackendUtility::viewOnClick($id, $this->PH_backPath, BackendUtility::BEgetRootLine($id), $anchor) . ';');
        }
 
        /**
@@ -764,7 +764,6 @@ class ClickMenu {
 
                                node.ownerTree.commandProvider.mountAsTreeRoot(useNode, node.ownerTree);
                        }
-                       return hideCM();
                        ');
        }
 
@@ -795,7 +794,7 @@ class ClickMenu {
        public function DB_changeFlag($table, $rec, $flagField, $title, $name, $iconRelPath = 'gfx/') {
                $uid = $rec['_ORIG_uid'] ?: $rec['uid'];
                $loc = 'top.content.list_frame';
-               $editOnClick = 'if(' . $loc . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_db.php?redirect=\'' . '+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&data[' . $table . '][' . $uid . '][' . $flagField . ']=' . ($rec[$flagField] ? 0 : 1) . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';}hideCM();';
+               $editOnClick = 'if(' . $loc . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_db.php?redirect=\'' . '+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&data[' . $table . '][' . $uid . '][' . $flagField . ']=' . ($rec[$flagField] ? 0 : 1) . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';};';
                if ($table === 'pages') {
                        $editOnClick .= 'top.nav.refresh.defer(500, top.nav);';
                }
@@ -969,7 +968,7 @@ class ClickMenu {
                }
 
                $editOnClick = 'if(' . $loc . '){' . $loc . '.location.href=top.TS.PATH_typo3+' . GeneralUtility::quoteJSvalue($scriptUrl . '&target=' . rawurlencode($path)) . ($noReturnUrl ? '' : '+\'&returnUrl=\'+top.rawurlencode(' . $this->frameLocation($loc . '.document') . '.pathname+' . $this->frameLocation($loc . '.document') . '.search)') . ';}';
-               return $this->linkItem($this->label($type), $this->excludeIcon('<img' . IconUtility::skinImg($this->PH_backPath, ('gfx/' . $image), 'width="12" height="12"') . ' alt="" />'), $editOnClick . 'top.nav.refresh();return hideCM();');
+               return $this->linkItem($this->label($type), $this->excludeIcon('<img' . IconUtility::skinImg($this->PH_backPath, ('gfx/' . $image), 'width="12" height="12"') . ' alt="" />'), $editOnClick . 'top.nav.refresh();');
        }
 
        /**
@@ -1023,7 +1022,7 @@ class ClickMenu {
                } else {
                        $conf = '1==1';
                }
-               $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_file.php?redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&file[delete][0][data]=' . rawurlencode($path) . '&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';}hideCM();';
+               $editOnClick = 'if(' . $loc . ' && ' . $conf . ' ){' . $loc . '.location.href=top.TS.PATH_typo3+\'tce_file.php?redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+\'' . '&file[delete][0][data]=' . rawurlencode($path) . '&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '\';};';
                return $this->linkItem($this->label('delete'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-edit-delete')), $editOnClick . 'return false;');
        }
 
@@ -1044,7 +1043,7 @@ class ClickMenu {
                } else {
                        $conf = $loc;
                }
-               $editOnClick = 'if(' . $conf . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'' . $this->clipObj->pasteUrl('_FILE', $path, 0) . '&redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search);  }hideCM();top.nav.refresh();';
+               $editOnClick = 'if(' . $conf . '){' . $loc . '.location.href=top.TS.PATH_typo3+\'' . $this->clipObj->pasteUrl('_FILE', $path, 0) . '&redirect=\'+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search);  };top.nav.refresh();';
                return $this->linkItem($this->label('pasteinto'), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-paste-into')), $editOnClick . 'return false;');
        }
 
@@ -1124,7 +1123,7 @@ class ClickMenu {
                $negativeSign = $into === 'into' ? '' : '-';
                $editOnClick = '';
                $loc = 'top.content.list_frame';
-               $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_db.php?redirect="+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+"' . '&cmd[pages][' . $srcUid . '][' . $action . ']=' . $negativeSign . $dstUid . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '";}hideCM();top.nav.refresh();';
+               $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_db.php?redirect="+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+"' . '&cmd[pages][' . $srcUid . '][' . $action . ']=' . $negativeSign . $dstUid . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '";};top.nav.refresh();';
                return $this->linkItem($this->label($action . 'Page_' . $into), $this->excludeIcon(IconUtility::getSpriteIcon('actions-document-paste-' . $into)), $editOnClick . 'return false;', 0);
        }
 
@@ -1140,7 +1139,7 @@ class ClickMenu {
        public function dragDrop_copymovefolder($srcPath, $dstPath, $action) {
                $editOnClick = '';
                $loc = 'top.content.list_frame';
-               $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_file.php?redirect="+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+"' . '&file[' . $action . '][0][data]=' . $srcPath . '&file[' . $action . '][0][target]=' . $dstPath . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '";}hideCM();top.nav.refresh();';
+               $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_file.php?redirect="+top.rawurlencode(' . $this->frameLocation(($loc . '.document')) . '.pathname+' . $this->frameLocation(($loc . '.document')) . '.search)+"' . '&file[' . $action . '][0][data]=' . $srcPath . '&file[' . $action . '][0][target]=' . $dstPath . '&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode() . BackendUtility::getUrlToken('tceAction') . '";};top.nav.refresh();';
                return $this->linkItem($this->label($action . 'Folder_into'), $this->excludeIcon(IconUtility::getSpriteIcon('apps-pagetree-drag-move-into')), $editOnClick . 'return false;', 0);
        }
 
@@ -1198,10 +1197,10 @@ class ClickMenu {
                                // Create JavaScript section:
                                $script = $GLOBALS['TBE_TEMPLATE']->wrapScriptTags('
 
-                               if (top.content && top.content' . $frameName . ' && top.content' . $frameName . '.Clickmenu) {
-                                       top.content' . $frameName . '.Clickmenu.populateData(unescape("' . GeneralUtility::rawurlencodeJS($CMtable) . '"),' . $this->cmLevel . ');
+                               if (top.content && top.content' . $frameName . ' && top.content' . $frameName . '.TYPO3.ClickMenu) {
+                                       top.content' . $frameName . '.TYPO3.ClickMenu.populateData(unescape("' . GeneralUtility::rawurlencodeJS($CMtable) . '"),' . $this->cmLevel . ');
                                }
-                               hideCM();
+                               TYPO3.ClickMenu.hideAll();
                                ');
                                return $script;
                        }
@@ -1243,7 +1242,7 @@ class ClickMenu {
                                $onClick = preg_replace('/return[[:space:]]+false[[:space:]]*;/i', '', $onClick);
                                $onClick = preg_replace('/hideCM\\(\\);/i', '', $onClick);
                                if (!$i[5]) {
-                                       $onClick .= 'Clickmenu.hideAll();';
+                                       $onClick .= 'TYPO3.ClickMenu.hideAll();';
                                }
                                $CSM = ' oncontextmenu="this.click();return false;"';
                                $out[] = '
index e2ba443..559afb1 100644 (file)
@@ -200,6 +200,7 @@ class ClickMenuController {
                $clipObj->endClipboard();
                // Create clickmenu object
                $clickMenu = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\ClickMenu\\ClickMenu');
+               $clickMenu->ajax = TRUE;
                // Set internal vars in clickmenu object:
                $clickMenu->clipObj = $clipObj;
                $clickMenu->extClassArray = $this->extClassArray;
index daa7129..05d54db 100644 (file)
@@ -2515,8 +2515,7 @@ class FormEngine {
         */
        public function getClickMenu($str, $table, $uid = 0) {
                if ($this->enableClickMenu) {
-                       $onClick = $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($str, $table, $uid, 1, '', '+copy,info,edit,view', TRUE);
-                       return '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' . $str . '</a>';
+                       return $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($str, $table, $uid, 1, '', '+copy,info,edit,view');
                }
                return '';
        }
index 558d9aa..fe18347 100644 (file)
@@ -490,15 +490,26 @@ function jumpToUrl(URL) {
         * @param string $table Table name/File path. If the icon is for a database record, enter the tablename from $GLOBALS['TCA']. If a file then enter the absolute filepath
         * @param int $uid If icon is for database record this is the UID for the record from $table
         * @param bool $listFr Tells the top frame script that the link is coming from a "list" frame which means a frame from within the backend content frame.
-        * @param string $addParams Additional GET parameters for the link to alt_clickmenu.php
+        * @param string $addParams Additional GET parameters for the link to the ClickMenu AJAX request
         * @param string $enDisItems Enable / Disable click menu items. Example: "+new,view" will display ONLY these two items (and any spacers in between), "new,view" will display all BUT these two items.
-        * @param bool $returnOnClick If set, will return only the onclick JavaScript, not the whole link.
+        * @param bool $returnTagParameters If set, will return only the onclick JavaScript, not the whole link.
         * @return string The link-wrapped input string.
         */
-       public function wrapClickMenuOnIcon($str, $table, $uid = 0, $listFr = TRUE, $addParams = '', $enDisItems = '', $returnOnClick = FALSE) {
-               $backPath = rawurlencode($this->backPath) . '|' . GeneralUtility::shortMD5(($this->backPath . '|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']));
-               $onClick = 'Clickmenu.show("' . $table . '","' . ($uid !== 0 ? $uid : '') . '","' . strval($listFr) . '","' . str_replace('+', '%2B', $enDisItems) . '","' . str_replace('&', '&amp;', addcslashes($backPath, '"')) . '","' . str_replace('&', '&amp;', addcslashes($addParams, '"')) . '");return false;';
-               return $returnOnClick ? $onClick : '<a href="#" onclick="' . htmlspecialchars($onClick) . '" oncontextmenu="this.click();return false;">' . $str . '</a>';
+       public function wrapClickMenuOnIcon($content, $table, $uid = 0, $listFr = TRUE, $addParams = '', $enDisItems = '', $returnTagParameters = FALSE) {
+               $tagParameters = array(
+                       'class'           => 't3-js-clickmenutrigger',
+                       'data-table'      => $table,
+                       'data-uid'        => (int)$uid !== 0 ? (int)$uid : '',
+                       'data-listframe'  => $listFr,
+                       'data-iteminfo'   => str_replace('+', '%2B', $enDisItems),
+                       'data-parameters' => $addParams,
+               );
+
+               if ($returnTagParameters) {
+                       return $tagParameters;
+               } else {
+                       return '<a href="#"' . GeneralUtility::implodeAttributes($tagParameters) . '>' . $content . '</a>';
+               }
        }
 
        /**
@@ -1461,9 +1472,8 @@ function jumpToUrl(URL) {
         * @return void
         */
        public function getContextMenuCode() {
-               $this->pageRenderer->loadPrototype();
-               $this->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/clickmenu.js');
-               $this->pageRenderer->addInlineSetting('ClickMenu', 'ajaxURL', BackendUtility::getAjaxUrl('ContextMenu::load', array(), $this->backPath));
+               $this->pageRenderer->loadJquery();
+               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ClickMenu');
        }
 
        /**
@@ -1474,13 +1484,13 @@ function jumpToUrl(URL) {
         * @return void
         */
        public function getDragDropCode($table) {
+               $this->getContextMenuCode();
                $this->pageRenderer->loadPrototype();
                $this->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/common.js');
                $this->loadJavascriptLib('js/tree.js');
                // Setting prefs for drag & drop
                $this->JScodeArray['dragdrop'] = '
-                       DragDrop.changeURL = "' . $this->backPath . 'alt_clickmenu.php";
-                       DragDrop.backPath  = "' . GeneralUtility::shortMD5(('' . '|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) . '";
+                       DragDrop.backPath  = "' . GeneralUtility::shortMD5('|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) . '";
                        DragDrop.table     = "' . $table . '";
                ';
        }
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/ClickMenu.js b/typo3/sysext/backend/Resources/Public/JavaScript/ClickMenu.js
new file mode 100644 (file)
index 0000000..bc92419
--- /dev/null
@@ -0,0 +1,272 @@
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Javascript container used to load the clickmenu via AJAX
+ * to render the result in a layer next to the mouse cursor
+ */
+define('TYPO3/CMS/Backend/ClickMenu', ['jquery'], function($) {
+
+       var ClickMenu = {
+               mousePos: {
+                       X: null,
+                       Y: null
+               },
+               delayClickMenuHide: false
+       };
+
+       ClickMenu.initializeEvents = function() {
+               $(document).on('click contextmenu', '.t3-js-clickmenutrigger', function(event) {
+                       event.preventDefault();
+                       ClickMenu.show(
+                               $(this).data('table'),
+                               $(this).data('uid'),
+                               $(this).data('listframe'),
+                               $(this).data('iteminfo'),
+                               $(this).data('parameters')
+                       );
+               });
+
+               // register mouse movement inside the document
+               $(document).on('mousemove', ClickMenu.storeMousePositionEvent);
+       };
+
+       /**
+        * main function, called from most clickmenu links
+        *
+        * @param table Table from where info should be fetched
+        * @param uid The UID of the item
+        * @param listFr list Frame?
+        * @param enDisItems Items to disable / enable
+        * @param addParams Additional params
+        * @return void
+        */
+       ClickMenu.show = function(table, uid, listFr, enDisItems, addParams) {
+               var parameters = '';
+
+               if (typeof table !== 'undefined') {
+                       parameters += 'table=' + encodeURIComponent(table);
+               }
+               if (typeof uid !== 'undefined') {
+                       parameters += (parameters.length > 0 ? '&' : '') + 'uid=' + uid;
+               }
+               if (typeof listFr !== 'undefined') {
+                       parameters += (parameters.length > 0 ? '&' : '') + 'listFr=' + listFr;
+               }
+               if (typeof enDisItems !== 'undefined') {
+                       parameters += (parameters.length > 0 ? '&' : '') + 'enDisItems=' + enDisItems;
+               }
+               if (typeof addParams !== 'undefined') {
+                       parameters += (parameters.length > 0 ? '&' : '') + 'addParams=' + addParams;
+               }
+               this.fetch(parameters);
+       };
+
+       /**
+        * make the AJAX request
+        *
+        * @param array parameters Parameters sent to the server
+        * @return void
+        */
+       ClickMenu.fetch = function(parameters) {
+               var url = TYPO3.settings.ajaxUrls['ContextMenu::load'];
+               if (parameters) {
+                       url += ((url.indexOf('?') == -1) ? '?' : '&') + parameters;
+               }
+               $.ajax(url).done(function(response) {
+                       if (!response.getElementsByTagName('data')[0]) {
+                               var res = parameters.match(/&reloadListFrame=(0|1|2)(&|$)/);
+                               var reloadListFrame = parseInt(res[1], 0);
+                               if (reloadListFrame) {
+                                       var doc = reloadListFrame != 2 ? top.content.list_frame : top.content;
+                                       doc.location.reload(true);
+                               }
+                               return;
+                       }
+                       var menu = response.getElementsByTagName('data')[0].getElementsByTagName('clickmenu')[0];
+                       var data = menu.getElementsByTagName('htmltable')[0].firstChild.data;
+                       var level = menu.getElementsByTagName('cmlevel')[0].firstChild.data;
+                       ClickMenu.populateData(data, level);
+               });
+       };
+
+       /**
+        * fills the clickmenu with content and displays it correctly
+        * depending on the mouse position
+        * @param data The data that will be put in the menu
+        * @param level The depth of the clickmenu
+        */
+       ClickMenu.populateData = function(data, level) {
+               this.initializeClickMenuContainer();
+
+               level = parseInt(level, 10) || 0;
+               var $obj = $('#contentMenu' + level);
+
+               if ($obj.length && (level === 0 || $('#contentMenu' + (level-1)).is(':visible'))) {
+                       $obj.html(data);
+                       var x = this.mousePos.X;
+                       var y = this.mousePos.Y;
+                       var dimsWindow = {
+                               width: $(document).width()-20, // saving margin for scrollbars
+                               height: $(document).height()
+                       };
+
+                       // dimensions for the clickmenu
+                       var dims = {
+                               width: $obj.width(),
+                               height: $obj.height()
+                       };
+
+                       var relative = {
+                               X: this.mousePos.X - $(document).scrollLeft(),
+                               Y: this.mousePos.Y - $(document).scrollTop()
+                       };
+
+                       // adjusting the Y position of the layer to fit it into the window frame
+                       // if there is enough space above then put it upwards,
+                       // otherwise adjust it to the bottom of the window
+                       if (dimsWindow.height - dims.height < relative.Y) {
+                               if (relative.Y > dims.height) {
+                                       y -= (dims.height - 10);
+                               } else {
+                                       y += (dimsWindow.height - dims.height - relative.Y);
+                               }
+                       }
+                       // adjusting the X position like Y above, but align it to the left side of the viewport if it does not fit completely
+                       if (dimsWindow.width - dims.width < relative.X) {
+                               if (relative.X > dims.width) {
+                                       x -= (dims.width - 10);
+                               } else if ((dimsWindow.width - dims.width - relative.X) < $(document).scrollLeft()) {
+                                       x = $(document).scrollLeft();
+                               } else {
+                                       x += (dimsWindow.width - dims.width - relative.X);
+                               }
+                       }
+
+                       $obj.css({left: x + 'px', top: y + 'px'}).show();
+               }
+       };
+
+       /**
+        * event handler function that saves the
+        * actual position of the mouse
+        * in the Clickmenu object
+        * @param event The event object
+        */
+       ClickMenu.storeMousePositionEvent = function(event) {
+               ClickMenu.mousePos.X = event.pageX;
+               ClickMenu.mousePos.Y = event.pageY;
+               ClickMenu.mouseOutFromMenu('#contentMenu0');
+               ClickMenu.mouseOutFromMenu('#contentMenu1');
+       };
+
+       /**
+        * hides a visible menu if the mouse has moved outside
+        * of the object
+        * @param obj The object to hide
+        * @result void
+        */
+       ClickMenu.mouseOutFromMenu = function(obj) {
+               var $element = $(obj);
+
+               if ($element.length > 0 && $element.is(':visible') && !this.within($element, this.mousePos.X, this.mousePos.Y)) {
+                       this.hide($element);
+               } else if ($element.length > 0 && $element.is(':visible')) {
+                       this.delayClickMenuHide = true;
+               }
+       };
+
+       ClickMenu.within = function($element, x, y) {
+               var offset = $element.offset();
+           return (y >= offset.top &&
+                               y <  offset.top + $element.height() &&
+                               x >= offset.left &&
+                               x <  offset.left + $element.width());
+       };
+
+       /**
+        * hides a clickmenu
+        *
+        * @param obj The clickmenu object to hide
+        * @result void
+        */
+       ClickMenu.hide = function(obj) {
+               this.delayClickMenuHide = false;
+               window.setTimeout(function() {
+                       if (!ClickMenu.delayClickMenuHide) {
+                               $(obj).hide();
+                       }
+               }, 500);
+       };
+
+       /**
+        * hides all clickmenus
+        */
+       ClickMenu.hideAll = function() {
+               this.hide('#contentMenu0');
+               this.hide('#contentMenu1');
+       };
+
+       /**
+        * manipulates the DOM to add the divs needed for clickmenu at the bottom of the <body>-tag
+        *
+        * @return void
+        */
+       ClickMenu.initializeClickMenuContainer = function() {
+               if ($('#contentMenu0').length === 0) {
+                       var code = '<div id="contentMenu0" style="display: block;"></div><div id="contentMenu1" style="display: block;"></div>';
+                       $('body').append(code);
+               }
+       };
+
+       ClickMenu.initializeEvents();
+
+       // make it globally available
+       TYPO3.ClickMenu = ClickMenu;
+       return ClickMenu;
+});
+
+
+/**
+ * available calls to the old API
+ */
+Clickmenu = {
+       show: function(table, uid, listFr, enDisItems, addParams) {
+               if (console !== undefined) {
+                       console.log('Clickmenu.show is deprecated and will be removed with CMS 8, please use TYPO3.ClickMenu.');
+               }
+               TYPO3.ClickMenu.show(table, uid, listFr, enDisItems, addParams);
+       },
+       populateData: function(data, level) {
+               if (console !== undefined) {
+                       console.log('Clickmenu.popuplateData is deprecated and will be removed with CMS 8, please use TYPO3.ClickMenu.');
+               }
+               TYPO3.ClickMenu.populateData(data, level);
+       }
+};
+
+/**
+ * @param url
+ * @deprecated since 4.2, Used in Core: \TYPO3\CMS\Backend\ClickMenu\ClickMenu::linkItem()
+ */
+function showClickmenu_raw(url) {
+       if (console !== undefined) {
+               console.log('showClickmenu_raw is deprecated and will be removed with CMS 8, please use TYPO3.ClickMenu.');
+       }
+       var parts = url.split('?');
+       if (parts.length === 2) {
+               TYPO3.ClickMenu.fetch(parts[1]);
+       } else {
+               TYPO3.ClickMenu.fetch(url);
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/clickmenu.js b/typo3/sysext/backend/Resources/Public/JavaScript/clickmenu.js
deleted file mode 100644 (file)
index 0dc0984..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Javascript functions regarding the clickmenu
- * relies on the javascript library "prototype"
- */
-
-/**
- * new clickmenu code to make an AJAX call and render the
- * AJAX result in a layer next to the mouse cursor
- */
-var Clickmenu = {
-       clickURL: TYPO3.settings.ClickMenu.ajaxURL,
-       mousePos: { X: null, Y: null },
-       delayClickMenuHide: false,
-
-       /**
-        * main function, called from most clickmenu links
-        * @param       table           table from where info should be fetched
-        * @param       uid             the UID of the item
-        * @param       listFr          list Frame?
-        * @param       enDisItems      Items to disable / enable
-        * @param       backPath        TYPO3 backPath
-        * @param       addParams       additional params
-        * @return      nothing
-        */
-       show: function(table, uid, listFr, enDisItems, backPath, addParams) {
-               var params = 'table=' + encodeURIComponent(table) +
-                       '&uid=' + uid +
-                       '&listFr=' + listFr +
-                       '&enDisItems=' + enDisItems +
-                       '&backPath=' + backPath +
-                       '&addParams=' + addParams;
-               this.callURL(params);
-       },
-
-
-       /**
-        * switch function that either makes an AJAX call
-        * or loads the request in the top frame
-        *
-        * @param       params  parameters added to the URL
-        * @return      nothing
-        */
-       callURL: function(params) {
-               params += '&ajax=1';
-               var call = new Ajax.Request(this.clickURL, {
-                       method: 'get',
-                       parameters: params,
-                       onComplete: function(xhr) {
-                               var response = xhr.responseXML;
-
-                               if (!response.getElementsByTagName('data')[0]) {
-                                       var res = params.match(/&reloadListFrame=(0|1|2)(&|$)/);
-                                       var reloadListFrame = parseInt(res[1], 0);
-                                       if (reloadListFrame) {
-                                               var doc = reloadListFrame != 2 ? top.content.list_frame : top.content;
-                                               doc.location.reload(true);
-                                       }
-                                       return;
-                               }
-                               var menu  = response.getElementsByTagName('data')[0].getElementsByTagName('clickmenu')[0];
-                               var data  = menu.getElementsByTagName('htmltable')[0].firstChild.data;
-                               var level = menu.getElementsByTagName('cmlevel')[0].firstChild.data;
-                               this.populateData(data, level);
-
-                       }.bind(this)
-               });
-       },
-
-
-       /**
-        * fills the clickmenu with content and displays it correctly
-        * depending on the mouse position
-        * @param       data    the data that will be put in the menu
-        * @param       level   the depth of the clickmenu
-        */
-       populateData: function(data, level) {
-               if (!$('contentMenu0')) {
-                       this.addClickmenuItem();
-               }
-               level = parseInt(level, 10) || 0;
-               var obj = $('contentMenu' + level);
-
-               if (obj && (level === 0 || Element.visible('contentMenu' + (level-1)))) {
-                       obj.innerHTML = data;
-                       var x = this.mousePos.X;
-                       var y = this.mousePos.Y;
-                       var dimsWindow = document.viewport.getDimensions();
-                       dimsWindow.width = dimsWindow.width-20; // saving margin for scrollbars
-
-                       var dims = Element.getDimensions(obj); // dimensions for the clickmenu
-                       var offset = document.viewport.getScrollOffsets();
-                       var relative = { X: this.mousePos.X - offset.left, Y: this.mousePos.Y - offset.top };
-
-                       // adjusting the Y position of the layer to fit it into the window frame
-                       // if there is enough space above then put it upwards,
-                       // otherwise adjust it to the bottom of the window
-                       if (dimsWindow.height - dims.height < relative.Y) {
-                               if (relative.Y > dims.height) {
-                                       y -= (dims.height - 10);
-                               } else {
-                                       y += (dimsWindow.height - dims.height - relative.Y);
-                               }
-                       }
-                       // adjusting the X position like Y above, but align it to the left side of the viewport if it does not fit completely
-                       if (dimsWindow.width - dims.width < relative.X) {
-                               if (relative.X > dims.width) {
-                                       x -= (dims.width - 10);
-                               } else if ((dimsWindow.width - dims.width - relative.X) < offset.left) {
-                                       x = offset.left;
-                               } else {
-                                       x += (dimsWindow.width - dims.width - relative.X);
-                               }
-                       }
-
-                       obj.style.left = x + 'px';
-                       obj.style.top  = y + 'px';
-                       Element.show(obj);
-               }
-       },
-
-
-       /**
-        * event handler function that saves the actual position of the mouse
-        * in the Clickmenu object
-        * @param       event   the event object
-        */
-       calcMousePosEvent: function(event) {
-               if (!event) {
-                       event = window.event;
-               }
-               this.mousePos.X = Event.pointerX(event);
-               this.mousePos.Y = Event.pointerY(event);
-               this.mouseOutFromMenu('contentMenu0');
-               this.mouseOutFromMenu('contentMenu1');
-       },
-
-
-       /**
-        * hides a visible menu if the mouse has moved outside
-        * of the object
-        * @param       obj     the object to hide
-        * @result      nothing
-        */
-       mouseOutFromMenu: function(obj) {
-               obj = $(obj);
-               if (obj && Element.visible(obj) && !Position.within(obj, this.mousePos.X, this.mousePos.Y)) {
-                       this.hide(obj);
-               } else if (obj && Element.visible(obj)) {
-                       this.delayClickMenuHide = true;
-               }
-       },
-
-       /**
-        * hides a clickmenu
-        *
-        * @param       obj     the clickmenu object to hide
-        * @result      nothing
-        */
-       hide: function(obj) {
-               this.delayClickMenuHide = false;
-               window.setTimeout(function() {
-                       if (!Clickmenu.delayClickMenuHide) {
-                               Element.hide(obj);
-                       }
-               }, 500);
-       },
-
-       /**
-        * hides all clickmenus
-        */
-       hideAll: function() {
-               this.hide('contentMenu0');
-               this.hide('contentMenu1');
-       },
-
-
-       /**
-        * hides / displays all selector boxes in a page, fixes an IE 5 selector problem
-        * originally by Michiel van Leening
-        *
-        * @param       action  hide (= "hidden") or show (= "visible")
-        * @result      nothing
-        */
-       _toggleSelectorBoxes: function(action) {
-               for (var i = 0; i < document.forms.length; i++) {
-                       for (var j = 0; j < document.forms[i].elements.length; j++) {
-                               if (document.forms[i].elements[j].type == 'select-one') {
-                                       document.forms[i].elements[j].style.visibility = action;
-                               }
-                       }
-               }
-       },
-
-
-       /**
-        * manipulates the DOM to add the divs needed for clickmenu at the bottom of the <body>-tag
-        *
-        * @return      nothing
-        */
-       addClickmenuItem: function() {
-               var code = '<div id="contentMenu0" style="display: block;"></div><div id="contentMenu1" style="display: block;"></div>';
-               var insert = new Insertion.Bottom(document.getElementsByTagName('body')[0], code);
-       }
-};
-
-// register mouse movement inside the document
-Event.observe(document, 'mousemove', Clickmenu.calcMousePosEvent.bindAsEventListener(Clickmenu), true);
-
-
-/**
- * @param url
- * @deprecated since 4.2, Used in Core: \TYPO3\CMS\Backend\ClickMenu\ClickMenu::linkItem()
- */
-function showClickmenu_raw(url) {
-       var parts = url.split('?');
-       if (parts.length === 2) {
-               Clickmenu.clickURL = parts[0];
-               Clickmenu.callURL(parts[1]);
-       } else {
-               Clickmenu.callURL(url);
-       }
-}
-// ## END ##
index a14bb99..c2e4f1a 100644 (file)
@@ -2,7 +2,7 @@
 
 <tr class="db_list_normal">
        <td class="col-icon">
-               <a href="#" onClick="Clickmenu.show('be_users', '{backendUser.uid}', '1', '', '', ''); return false;" title="id={backendUser.uid}">
+               <a href="#" class="t3-js-clickmenutrigger" data-table="be_users" data-uid="{backendUser.uid}" data-listframe="1" title="id={backendUser.uid}">
                        <bu:spriteIconForRecord table="be_users" object="{backendUser}" />
                </a>
        </td>
index 27157cc..33129c2 100644 (file)
@@ -17,7 +17,7 @@
                                <th class="label"></th>
                                <f:for each="{compareUserList}" as="compareUser">
                                        <th>
-                                               <a href="#" onClick="Clickmenu.show('be_users', '{compareUser.uid}', '1', '', '', ''); return false;" title="id={compareUser.uid}">
+                                               <a href="#" class="t3-js-clickmenutrigger" data-table="be_users" data-uid="{compareUser.uid}" data-listframe="1" title="id={compareUser.uid}">
                                                        <bu:spriteIconForRecord table="be_users" object="{compareUser}" /></a>
                                                {compareUser.userName}
                                        </th>
                                <f:for each="{compareUserList}" as="compareUser">
                                        <td>
                                                <f:for each="{compareUser.BackendUserGroups}" as="backendUserGroup">
-                                                       <a href="#" onClick="Clickmenu.show('be_groups', '{backendUserGroup.uid}', '1', '', '', ''); return false;" title="id={backendUserGroup.uid}">
+                                                       <a href="#" class="t3-js-clickmenutrigger" data-table="be_groups" data-uid="{backendUserGroup.uid}" data-listframe="1" title="id={backendUserGroup.uid}">
                                                                <bu:spriteIconForRecord table="be_users" object="{backendUserGroup}" />
                                                        </a>
                                                        {backendUserGroup.title}<br />
index af0963d..d8853ab 100644 (file)
@@ -25,7 +25,7 @@
                                                        arguments="{uid: compareUser.uid}"
                                                ><bu:SpriteManagerIcon iconName="actions-selection-delete" /></f:link.action>
 
-                                               <a href="#" onClick="Clickmenu.show('be_users', '{compareUser.uid}', '1', '', '', ''); return false;" title="id={compareUser.uid}">
+                                               <a href="#" class="t3-js-clickmenutrigger" data-table="be_users" data-uid="{compareUser.uid}" data-listframe="1" title="id={compareUser.uid}">
                                                        <bu:spriteIconForRecord table="be_users" object="{compareUser}" />
                                                </a>
 
index 608988c..c0069c1 100644 (file)
@@ -837,7 +837,7 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
         * @param string $tableName Is the tablename to check: If "pages" table then edit,new,delete and editcontent permissions can be checked. Other tables will be checked for "editcontent" only (and $type will be ignored)
         * @param string $actionType For $tableName='pages' this can be 'edit' (2), 'new' (8 or 16), 'delete' (4), 'editcontent' (16). For all other tables this is ignored. (16 is used)
         * @return bool
-        * @access public (used by typo3/alt_clickmenu.php)
+        * @access public (used by ClickMenuController)
         */
        public function isPSet($compiledPermissions, $tableName, $actionType = '') {
                if ($this->isAdmin()) {
index 704451d..e77613e 100644 (file)
@@ -351,8 +351,8 @@ class ExtendedFileUtility extends BasicFileUtility {
                                        }
                                        $shortcutRecord = BackendUtility::getRecord($row['tablename'], $row['recuid']);
                                        $icon = IconUtility::getSpriteIconForRecord($row['tablename'], $shortcutRecord);
-                                       $onClick = 'Clickmenu.show("' . $row['tablename'] . '", "' . $row['recuid'] . '", "1", "+info,history,edit", "|", "");return false;';
-                                       $shortcutContent[] = '<a href="#" oncontextmenu="this.click();return false;" onclick="' . htmlspecialchars($onClick) . '">' . $icon . '</a>' . htmlspecialchars((BackendUtility::getRecordTitle($row['tablename'], $shortcutRecord) . '  [' . BackendUtility::getRecordPath($shortcutRecord['pid'], '', 80) . ']'));
+                                       $icon = '<a href="#" class="t3-js-clickmenutrigger" data-table="' . $row['tablename'] . '" data-uid="' . $row['recuid'] . '" data-listframe="1" data-iteminfo="%2Binfo,history,edit">' . $icon . '</a>';
+                                       $shortcutContent[] = $icon . htmlspecialchars((BackendUtility::getRecordTitle($row['tablename'], $shortcutRecord) . '  [' . BackendUtility::getRecordPath($shortcutRecord['pid'], '', 80) . ']'));
                                }
 
                                // render a message that the file could not be deleted
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-33805-ClickMenuRewrite.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-33805-ClickMenuRewrite.rst
new file mode 100644 (file)
index 0000000..1e92196
--- /dev/null
@@ -0,0 +1,43 @@
+====================================
+Breaking: #33805 - ClickMenu Rewrite
+====================================
+
+Description
+===========
+
+The ClickMenu has seen some major changes under the hood. This implies some refactoring within JavaScript where existing
+functionality is replaced by a AMD Module based on jQuery. The following JS methods are now replaced by respective
+methods.
+
+       showClickmenu_raw()
+       Clickmenu.show()
+       Clickmenu.populateData()
+
+The new functionality is available via a global JavaScript object called TYPO3.ClickMenu which has equal
+functions.
+
+Additionally the ClickMenu is now used via AJAX completely, all non-AJAX calls are not supported anymore.
+
+Impact
+======
+
+A third-party extension using alt_clickmenu.php directly in the backend, or using the above JavaScript calls directly.
+
+Affected installations
+======================
+
+Any installation using extensions having Backend modules using JavaScript functions for the ClickMenu inline
+and installations using extensions using alt_clickmenu.php directly.
+
+Migration
+=========
+
+Any use of "Clickmenu.show()" etc should be avoided and channelled through the according DocumentTemplate methods.
+
+       DocumentTemplate->wrapClickMenuOnIcon()
+       DocumentTemplate->getContextMenuCode()
+
+If a backend module without a DocumentTemplate (with e.g. Extbase/Fluid) is used, this is done with a separate class
+and according data attribute:
+
+       <a href="#" class="t3-js-clickmenutrigger" data-table="be_users" data-uid="{record.uid}" data-listframe="1">
index b1485fe..aae5dc7 100644 (file)
@@ -79,7 +79,7 @@ class ContainerViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBacken
 
                // Load various standard libraries
                if ($enableClickMenu) {
-                       $doc->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/clickmenu.js');
+                       $doc->getContextMenuCode();
                }
                if ($loadPrototype) {
                        $pageRenderer->loadPrototype();
index 9a36e06..414fe2e 100644 (file)
@@ -10,7 +10,7 @@
                        <f:for each="{notes}" as="note">
                                <div class="single-note category-{note.category}">
                                        <div class="header">
-                                               <span class="typeicon" oncontextmenu="this.click();return false;" onclick="Clickmenu.show('sys_note', '{note.uid}', '1', '','', ''); return false;"></span>
+                                               <span class="typeicon t3-js-clickmenutrigger" data-table="sys_note" data-uid="{note.uid}" data-listframe="1"></span>
                                                <span><f:translate key="author" /></span>
                                                <f:if condition="{note.author.realName}">
                                                        <f:then>{note.author.realName}</f:then>
index 2c7be8f..462bfa7 100644 (file)
@@ -221,8 +221,7 @@ class TypoScriptTemplateInformationModuleFunctionController extends AbstractFunc
                                                GeneralUtility::callUserFunction($hookFunction, $hookParameters, $this);
                                        }
                                }
-                       }
-                       $content = IconUtility::getSpriteIconForRecord('sys_template', $tplRow, array('oncontextmenu' => "this.click();return false;", 'onclick' => "Clickmenu.show('sys_template', '" . $tplRow['uid'] . "', '1', '','', ''); return false;")) . '<strong>' . htmlspecialchars($tplRow['title']) . '</strong>' . htmlspecialchars((trim($tplRow['sitetitle']) ? ' (' . $tplRow['sitetitle'] . ')' : ''));
+                       $content = IconUtility::getSpriteIconForRecord('sys_template', $tplRow, array('class' => 't3-js-clickmenutrigger', 'data-table' => 'sys_template', 'data-uid' => $tplRow['uid'], 'data-listframe' => 1)) . '<strong>' . htmlspecialchars($tplRow['title']) . '</strong>' . htmlspecialchars((trim($tplRow['sitetitle']) ? ' (' . $tplRow['sitetitle'] . ')' : ''));
                        $theOutput .= $this->pObj->doc->section($lang->getLL('templateInformation'), $content, 0, 1);
                        if ($manyTemplatesMenu) {
                                $theOutput .= $this->pObj->doc->section('', $manyTemplatesMenu);