From dd143eaa322710c40dc0d6b69c0b685b58c9f277 Mon Sep 17 00:00:00 2001
From: Tymoteusz Motylewski <t.motylewski@gmail.com>
Date: Mon, 28 May 2018 18:55:29 +0200
Subject: [PATCH] [BUGFIX] Remember selected page in fsMod and refactor page
 selection

Currently selected page is remembered in the fsMod js object.
The JS code responsible for handling click on the node text and node
background is refactored. Now both uses node.checked property.

Resolves: #85100
Resolves: #85106
Releases: master
Change-Id: I08768e82a62e942c247d968df707bf64426e1dab
Reviewed-on: https://review.typo3.org/57076
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
---
 .../Controller/PageLayoutController.php       |  2 +-
 .../Public/JavaScript/PageTree/PageTree.js    | 48 ++++++++++++++++++-
 .../Resources/Public/JavaScript/SvgTree.js    | 23 +--------
 .../Resources/Public/JavaScript/backend.js    |  2 +-
 .../Controller/RecordListController.php       | 14 +++---
 .../sysext/sys_action/Classes/ActionTask.php  |  4 +-
 6 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php
index c5495b85983a..ffdefd316e5a 100644
--- a/typo3/sysext/backend/Classes/Controller/PageLayoutController.php
+++ b/typo3/sysext/backend/Classes/Controller/PageLayoutController.php
@@ -729,7 +729,7 @@ class PageLayoutController
             $this->moduleTemplate->addJavaScriptCode('mainJsFunctions', '
                 if (top.fsMod) {
                     top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
-                    top.fsMod.navFrameHighlightedID["web"] = "pages' . (int)$this->id . '_"+top.fsMod.currentBank;
+                    top.fsMod.navFrameHighlightedID["web"] = top.fsMod.currentBank + "_" + ' . (int)$this->id . ';
                 }
                 ' . ($this->popView ? BackendUtility::viewOnClick($this->id, '', BackendUtility::BEgetRootLine($this->id)) : '') . '
                 function deleteRecord(table,id,url) {   //
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTree.js
index c53d3b99ecac..fcfbac760390 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTree.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTree.js
@@ -55,6 +55,7 @@ define(['jquery',
       _this.dispatch.on('nodeRightClick.pageTree', _this.nodeRightClick);
       _this.dispatch.on('contextmenu.pageTree', _this.contextmenu);
       _this.dispatch.on('updateSvg.pageTree', _this.updateSvg);
+      _this.dispatch.on('prepareLoadedNode.pageTree', _this.prepareLoadedNode);
       _this.dragDrop = PageTreeDragDrop;
       _this.dragDrop.init(_this);
 
@@ -186,12 +187,16 @@ define(['jquery',
      * @param {Node} node
      */
     PageTree.prototype.nodeSelectedAfter = function(node) {
+      //remember the selected page in the global state
+      fsMod.recentIds.web = node.identifier;
+      fsMod.currentBank = node.stateIdentifier.split('_')[0];
+      fsMod.navFrameHighlightedID.web = node.stateIdentifier;
+
       var separator = '?';
       if (currentSubScript.indexOf('?') !== -1) {
         separator = '&';
       }
 
-      fsMod.recentIds.web = node.identifier;
       TYPO3.Backend.ContentContainer.setUrl(
         currentSubScript + separator + 'id=' + node.identifier
       );
@@ -233,6 +238,18 @@ define(['jquery',
         .attr('data-context', 'tree');
     };
 
+    /**
+     * Event listener called for each loaded node,
+     * here used to mark node remembered in fsMode as selected
+     *
+     * @param node
+     */
+    PageTree.prototype.prepareLoadedNode = function(node) {
+      if (node.stateIdentifier === fsMod.navFrameHighlightedID.web) {
+        node.checked = true;
+      }
+    };
+
     PageTree.prototype.hideChildren = function(node) {
       _super_.hideChildren(node);
       Persistent.set('BackendComponents.States.Pagetree.stateHash.' + node.stateIdentifier, 0);
@@ -274,6 +291,35 @@ define(['jquery',
       return nodes;
     };
 
+    /**
+     * Node selection logic (triggered by different events)
+     * Page tree supports only one node to be selected at a time
+     * so the default function from SvgTree needs to be overriden
+     *
+     * @param {Node} node
+     */
+    PageTree.prototype.selectNode = function (node) {
+      if (!this.isNodeSelectable(node)) {
+        return;
+      }
+
+      var _this = this;
+      var checked = node.checked;
+
+      var selectedNodes = this.getSelectedNodes();
+      selectedNodes.forEach(function (node) {
+        if (node.checked === true) {
+          node.checked = false;
+          _this.dispatch.call('nodeSelectedAfter', _this, node);
+        }
+      });
+
+      node.checked = true;
+
+      this.dispatch.call('nodeSelectedAfter', this, node);
+      this.update();
+    };
+
     /**
      * Event handler for double click on a node's label
      * Changed text position if there is 'stop page tree' option
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js
index dff70fc55381..f468927d626b 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js
@@ -568,7 +568,6 @@ define(
             _this.nodeBgEvents().mouseOut(node, this);
           })
           .on('click', function(node) {
-            _this.nodeBgEvents().click(node, this);
             _this.selectNode(node);
           })
           .on('contextmenu', function(node) {
@@ -612,25 +611,6 @@ define(
           }
         };
 
-        self.click = function(node, element) {
-          var $nodeBg = $(element).closest('svg').find('.nodes-bg .node-bg[data-state-id=' + node.stateIdentifier + ']');
-
-          _this.nodes.forEach(function(node) {
-            if (node.selected === true) {
-              node.selected = false;
-            }
-          });
-
-          node.selected = true;
-          if ($nodeBg.length) {
-            $nodeBg.addClass('node-selected')
-              .parents('svg')
-              .find('.node-selected')
-              .not($nodeBg)
-              .removeClass('node-selected');
-          }
-        };
-
         return self;
       },
 
@@ -882,7 +862,7 @@ define(
           nextNode = nodeBgClass.data()[i + 1];
         }
 
-        if (node.selected) {
+        if (node.checked) {
           bgClass += ' node-selected';
         }
 
@@ -1113,7 +1093,6 @@ define(
        */
       clickOnLabel: function(node, element) {
         this.selectNode(node);
-        this.nodeBgEvents().click(node, element);
       },
 
       /**
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/backend.js b/typo3/sysext/backend/Resources/Public/JavaScript/backend.js
index db65a90f79b6..64e214d9d73a 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/backend.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/backend.js
@@ -97,7 +97,7 @@ function openUrlInWindow(url, windowName) {	//
  */
 function loadEditId(id, addGetVars) {	//
   top.fsMod.recentIds.web = id;
-  top.fsMod.navFrameHighlightedID.web = "pages" + id + "_0";		// For highlighting
+  top.fsMod.navFrameHighlightedID.web = '0_' + id; // For highlighting
 
   if (top.nav_frame && top.nav_frame.refresh_nav) {
     top.nav_frame.refresh_nav();
diff --git a/typo3/sysext/recordlist/Classes/Controller/RecordListController.php b/typo3/sysext/recordlist/Classes/Controller/RecordListController.php
index 42c519902f7e..84617ae8db53 100644
--- a/typo3/sysext/recordlist/Classes/Controller/RecordListController.php
+++ b/typo3/sysext/recordlist/Classes/Controller/RecordListController.php
@@ -390,12 +390,12 @@ class RecordListController
             $this->moduleTemplate->addJavaScriptCode(
                 'RecordListInlineJS',
                 '
-				function jumpExt(URL,anchor) {	//
+				function jumpExt(URL,anchor) {
 					var anc = anchor?anchor:"";
 					window.location.href = URL+(T3_THIS_LOCATION?"&returnUrl="+T3_THIS_LOCATION:"")+anc;
 					return false;
 				}
-				function jumpSelf(URL) {	//
+				function jumpSelf(URL) {
 					window.location.href = URL+(T3_RETURN_URL?"&returnUrl="+T3_RETURN_URL:"");
 					return false;
 				}
@@ -404,9 +404,9 @@ class RecordListController
 					return false;
 				}
 
-				function setHighlight(id) {	//
-					top.fsMod.recentIds["web"]=id;
-					top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_"+top.fsMod.currentBank;	// For highlighting
+				function setHighlight(id) {
+					top.fsMod.recentIds["web"] = id;
+					top.fsMod.navFrameHighlightedID["web"] = top.fsMod.currentBank + "_" + id; // For highlighting
 
 					if (top.nav_frame && top.nav_frame.refresh_nav) {
 						top.nav_frame.refresh_nav();
@@ -414,10 +414,10 @@ class RecordListController
 				}
 				' . $this->moduleTemplate->redirectUrls($listUrl) . '
 				' . $dblist->CBfunctions() . '
-				function editRecords(table,idList,addParams,CBflag) {	//
+				function editRecords(table,idList,addParams,CBflag) {
 					window.location.href="' . (string)$uriBuilder->buildUriFromRoute('record_edit', ['returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]) . '&edit["+table+"]["+idList+"]=edit"+addParams;
 				}
-				function editList(table,idList) {	//
+				function editList(table,idList) {
 					var list="";
 
 						// Checking how many is checked, how many is not
diff --git a/typo3/sysext/sys_action/Classes/ActionTask.php b/typo3/sysext/sys_action/Classes/ActionTask.php
index 3d6ffee474b8..883b15836005 100644
--- a/typo3/sysext/sys_action/Classes/ActionTask.php
+++ b/typo3/sysext/sys_action/Classes/ActionTask.php
@@ -940,8 +940,8 @@ class ActionTask implements \TYPO3\CMS\Taskcenter\TaskInterface
 				}
 
 				function setHighlight(id) {
-					top.fsMod.recentIds["web"]=id;
-					top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_"+top.fsMod.currentBank;	// For highlighting
+					top.fsMod.recentIds["web"] = id;
+					top.fsMod.navFrameHighlightedID["web"] = top.fsMod.currentBank + "_" + id; // For highlighting
 
 					if (top.nav_frame && top.nav_frame.refresh_nav) {
 						top.nav_frame.refresh_nav();
-- 
GitLab