diff --git a/t3lib/core_autoload.php b/t3lib/core_autoload.php index d4c20125a212a6a88fc19f401ffedc9b48263372..7d12a2ef1d531bacc554d136354a5e3fc43dce48 100644 --- a/t3lib/core_autoload.php +++ b/t3lib/core_autoload.php @@ -196,15 +196,16 @@ $t3libClasses = array( 't3lib_tree_abstractdataprovider' => PATH_t3lib . 'tree/class.t3lib_tree_abstractdataprovider.php', 't3lib_tree_abstractstateprovider' => PATH_t3lib . 'tree/class.t3lib_tree_abstractstateprovider.php', 't3lib_tree_node' => PATH_t3lib . 'tree/class.t3lib_tree_node.php', + 't3lib_tree_representationnode' => PATH_t3lib . 'tree/class.t3lib_tree_representationnode.php', 't3lib_tree_nodecollection' => PATH_t3lib . 'tree/class.t3lib_tree_nodecollection.php', 't3lib_tree_sortednodecollection' => PATH_t3lib . 'tree/class.t3lib_tree_sortednodecollection.php', - 't3lib_tree_extjs_abstractextjstree' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php', - 't3lib_tree_extjs_abstractstatefulextjstree' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php', - 't3lib_tree_comparablenode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_comparablenode.php', - 't3lib_tree_renderablenode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_renderablenode.php', - 't3lib_tree_draggableanddropable' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_draggableanddropable.php', - 't3lib_tree_labeleditable' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_labeleditable.php', - 't3lib_tree_recordbasednode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_recordbasednode.php', + 't3lib_tree_extdirect_abstractextjstree' => PATH_t3lib . 'tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php', + 't3lib_tree_comparablenode' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_comparablenode.php', + 't3lib_tree_draggableanddropable' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_draggableanddropable.php', + 't3lib_tree_labeleditable' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_labeleditable.php', + 't3lib_tree_renderer_abstract' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_abstract.php', + 't3lib_tree_renderer_unorderedlist' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_unorderedlist.php', + 't3lib_tree_renderer_extjsjson' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_extjsjson.php', 't3lib_contextmenu_abstractcontextmenu' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_abstractcontextmenu.php', 't3lib_contextmenu_abstractdataprovider' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_abstractdataprovider.php', 't3lib_contextmenu_action' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_action.php', @@ -224,8 +225,7 @@ $t3libClasses = array( 't3lib_contextmenu_pagetree_extdirect_contextmenu' => PATH_t3lib . 'contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php', 't3lib_tree_pagetree_dataprovider' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php', 't3lib_tree_pagetree_node' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_node.php', - 't3lib_tree_extjs_node' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_node.php', - 't3lib_tree_navigationtree_node' => PATH_t3lib . 'tree/navigationtree/class.t3lib_tree_navigationtree_node.php', + 't3lib_tree_extdirect_node' => PATH_t3lib . 'tree/extdirect/class.t3lib_tree_extdirect_node.php', 't3lib_tree_pagetree_nodecollection' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php', 't3lib_tree_pagetree_commands' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_commands.php', 't3lib_contextmenu_pagetree_dataprovider' => PATH_t3lib . 'contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php', diff --git a/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js b/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js index a781831f2d4b3b2ba5b26e5e98e7d9a70a0eb4c9..348d94cb900ae39cf8189e959c2ffba88c761b13 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js +++ b/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js @@ -23,117 +23,126 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.ns('Ext.ux.state'); + +// dummy constructor +Ext.ux.state.TreePanel = function() {}; + /** * State Provider for a tree panel */ -Ext.define('Ext.ux.state.TreePanel', { - extend: 'Ext.state.Stateful', - +Ext.override(Ext.ux.state.TreePanel, { /** - * Mixin constructor - * @param {Object} config - * + * Initializes the plugin + * @param {Ext.tree.TreePanel} tree + * @private */ - constructor: function (config) { - if (config.stateful) { - // Install event handlers on TreePanel - this.on({ - // Add path of expanded node to stateHash - beforeitemexpand: function (node) { - if (this.isRestoringState) { - return; - } - this.stateHash[String(node.getNodeData('id'))] = node.getId(); - }, - // Delete collapsed node from stateHash - beforeitemcollapse: function (node) { - if (this.isRestoringState) { - return; - } - delete this.stateHash[String(node.getNodeData('id'))]; - }, - // Update last selected node in stateHash - selectionchange: function (view, node) { - this.onStateChange(); - if (this.isRestoringState) { - return; - } - if (this.getSelectionModel().getLastSelected()) { - this.stateHash['lastSelectedNode'] = this.getSelectionModel().getLastSelected().getId(); - } - }, - scope: this - }); - // Add/override state properties - Ext.apply(this, { - // Update state on node expand, collapse or selection change - stateEvents: ['itemexpand', 'itemcollapse', 'selectionchange'], - // Avoid updating state while restoring - isRestoringState: false, - // State object - stateHash: {}, - /** - * Restore tree state into the saved state - * - */ - restoreState: function() { - if (this.stateful) { - this.isRestoringState = true; - // Expand paths according to stateHash - for (var pageID in this.stateHash) { - var pageNode = this.getStore().getNodeById(this.stateHash[pageID]); - if (pageNode && !pageNode.isLeaf() && !pageNode.isExpanded()) { - pageNode.on({ - expand: { - single: true, - scope: this, - fn: this.restoreState - } - }); - pageNode.set('expanded', true); - pageNode.commit(); - this.refreshNode(pageNode); - pageNode.fireEvent('expand', pageNode); + init:function(tree) { + tree.lastSelectedNode = null; + tree.isRestoringState = false; + tree.stateHash = {}; + + // install event handlers on TreePanel + tree.on({ + // add path of expanded node to stateHash + beforeexpandnode:function(n) { + if (this.isRestoringState) { + return; + } + var saveID = n.id; + this.stateHash[saveID.substr(1)] = 1; + }, + + // delete path and all subpaths of collapsed node from stateHash + beforecollapsenode:function(n) { + if (this.isRestoringState) { + return; + } + + var deleteID = n.id; + delete this.stateHash[deleteID.substr(1)]; + }, + + beforeclick: function(node) { + if (this.isRestoringState) { + return; + } + this.stateHash['lastSelectedNode'] = node.id; + } + }); + + // update state on node expand or collapse + tree.stateEvents = tree.stateEvents || []; + tree.stateEvents.push('expandnode', 'collapsenode', 'click'); + + // add state related props to the tree + Ext.apply(tree, { + // keeps expanded nodes paths keyed by node.ids + stateHash:{}, + + restoreState: function() { + this.isRestoringState = true; + // get last selected node + for (var pageID in this.stateHash) { + var pageNode = this.getNodeById('p' + pageID); + if (pageNode) { + pageNode.on({ + expand: { + single:true, + scope:this, + fn: this.restoreState } + }); + if (pageNode.expanded === false && pageNode.rendered == true) { + pageNode.expand(); } - // Get last selected node - if (this.stateHash['lastSelectedNode']) { - var node = this.getStore().getNodeById(this.stateHash['lastSelectedNode']); - if (node) { - this.selectPath(node.getPath()); - - var contentId = TYPO3.Backend.ContentContainer.getIdFromUrl() || - String(fsMod.recentIds['web']) || '-1'; - - var isCurrentSelectedNode = ( - String(node.getNodeData('id')) === contentId || - contentId.indexOf('pages' + node.getNodeData('id')) !== -1 - ); - - if (contentId !== '-1' - && !isCurrentSelectedNode - && this == this.app.getTree() - && this.commandProvider - && this.commandProvider.singleClick - ) { - this.commandProvider.singleClick(node, this); - } - } + } + } + if (this.stateHash['lastSelectedNode']) { + var node = this.getNodeById(this.stateHash['lastSelectedNode']); + if (node) { + this.selectPath(node.getPath()); + + var contentId = TYPO3.Backend.ContentContainer.getIdFromUrl() || + String(fsMod.recentIds['web']) || '-1'; + + var isCurrentSelectedNode = ( + String(node.attributes.nodeData.id) === contentId || + contentId.indexOf('pages' + String(node.attributes.nodeData.id)) !== -1 + ); + + if (contentId !== '-1' && !isCurrentSelectedNode && this.app.isVisible() && + this.commandProvider && this.commandProvider.singleClick + ) { + this.commandProvider.singleClick(node, this); } - this.isRestoringState = false; } - }, - /** - * Return stateHash for save by state manager - * - */ - getState: function() { - return { - stateHash: this.stateHash - }; } - }); - this.callParent(arguments); - } + + this.isRestoringState = false; + }, + + // apply state on tree initialization + applyState:function(state) { + if(state) { + Ext.apply(this, state); + + // it is too early to expand paths here + // so do it once on root load + this.root.on({ + load: { + single:true, + scope:this, + fn: this.restoreState + } + }); + } + }, + + // returns stateHash for save by state manager + getState:function() { + return {stateHash:this.stateHash}; + } + }); } }); diff --git a/t3lib/js/extjs/components/pagetree/javascript/actions.js b/t3lib/js/extjs/components/pagetree/javascript/actions.js index 3b4947450931cc03383d79b235882c1ed85e7069..1dbb5b03ea961297f5a5429a5781da9b40952087 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/actions.js +++ b/t3lib/js/extjs/components/pagetree/javascript/actions.js @@ -61,8 +61,8 @@ TYPO3.Components.PageTree.Actions = { tree.t3ContextInfo.inCopyMode = false; if (tree.t3ContextNode) { - tree.t3ContextNode.setNodeData('t3InCutMode', false); - tree.t3ContextNode.setNodeData('t3InCopyMode', false); + tree.t3ContextNode.attributes.nodeData.t3InCutMode = false; + tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false; tree.t3ContextNode = null; } }, @@ -71,55 +71,51 @@ TYPO3.Components.PageTree.Actions = { * Updates an existing node with the given alternative. The new tree node * is returned afterwards. * - * @param {TYPO3.Components.PageTree.Tree} tree - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {Boolean} isExpanded * @param {Object} updatedNode * @param {Function} callback - * @return {Ext.data.NodeInterface} + * @return {Ext.tree.TreeNode} */ - updateNode: function(tree, node, isExpanded, updatedNode, callback) { + updateNode: function(node, isExpanded, updatedNode, callback) { if (!updatedNode) { return null; } - var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model', updatedNode); + updatedNode.uiProvider = node.ownerTree.uiProvider; + var newTreeNode = new Ext.tree.TreeNode(updatedNode); var refreshCallback = this.restoreNodeStateAfterRefresh; if (callback) { - refreshCallback = Ext.Function.createSequence(refreshCallback, callback); + refreshCallback = refreshCallback.createSequence(callback); } node.parentNode.replaceChild(newTreeNode, node); - newTreeNode.set('expanded', isExpanded); - tree.refreshNode(newTreeNode, refreshCallback, tree); + newTreeNode.ownerTree.refreshNode(newTreeNode, refreshCallback); + return newTreeNode; }, /** * Restores the node state * - * @param {TYPO3.Components.PageTree.Tree} tree - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {Boolean} isExpanded * @return {void} */ - restoreNodeStateAfterRefresh: function (records, operation, successful) { - if (successful && operation.node) { - var node = operation.node; - node.parentNode.expand(false); - if (node.isExpanded()) { - node.expand(false); - } else { - node.collapse(false); - } + restoreNodeStateAfterRefresh: function(node, isExpanded) { + node.parentNode.expand(false, false); + if (isExpanded) { + node.expand(false, false); + } else { + node.collapse(false, false); } }, /** * Shows deletion confirmation window * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @param {Function} callback * @param {Boolean} recursiveDelete @@ -134,10 +130,10 @@ TYPO3.Components.PageTree.Actions = { message = TYPO3.Components.PageTree.LLL.recursiveDeleteDialogMessage; } - Ext.MessageBox.show({ + Ext.Msg.show({ title: title, msg: message, - buttons: Ext.MessageBox.YESNO, + buttons: Ext.Msg.YESNO, fn: function (answer) { if (answer === 'yes') { TYPO3.Components.PageTree.Actions.deleteNode(node, tree, callback); @@ -145,21 +141,21 @@ TYPO3.Components.PageTree.Actions = { } return false; }, - animateTarget: tree.getView().getNode(node).id + animEl: 'elId' }); }, /** * Deletes a node directly * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @param {Function} callback * @return {void} */ deleteNode: function(node, tree, callback) { TYPO3.Components.PageTree.Commands.deleteNode( - node.get('nodeData'), + node.attributes.nodeData, function(response) { var succeeded = this.evaluateResponse(response); if (Ext.isFunction(callback)) { @@ -169,7 +165,7 @@ TYPO3.Components.PageTree.Actions = { if (succeeded) { // the node may not be removed in workspace mode if (top.TYPO3.configuration.inWorkspace && response.id) { - this.updateNode(tree, node, node.isExpanded(), response); + this.updateNode(node, node.isExpanded(), response); } else { node.remove(); } @@ -182,13 +178,13 @@ TYPO3.Components.PageTree.Actions = { /** * Removes a node either directly or first shows deletion popup * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ removeNode: function(node, tree) { if (TYPO3.Components.PageTree.Configuration.displayDeleteConfirmation) { - this.confirmDelete(node, tree); + this.confirmDelete(node); } else { this.deleteNode(node, tree); } @@ -198,19 +194,19 @@ TYPO3.Components.PageTree.Actions = { * Restores a given node and moves it to the given destination inside the tree. Use this * method if you want to add it as the first child of the destination. * - * @param {Ext.data.NodeInterface} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree - * @param {Ext.data.NodeInterface} destination + * @param {Ext.tree.TreeNode} destination * @return {void} */ restoreNodeToFirstChildOfDestination: function(node, tree, destination) { TYPO3.Components.PageTree.Commands.restoreNode( - node.get('nodeData'), - destination.get('nodeData').id, - function (updatedNode) { + node.attributes.nodeData, + destination.attributes.nodeData.id, + function(updatedNode) { if (this.evaluateResponse(updatedNode)) { - var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model', - Ext.apply(node.fields, updatedNode) + var newTreeNode = new Ext.tree.TreeNode( + Ext.apply(node.attributes, updatedNode) ); destination.insertBefore(newTreeNode, destination.firstChild); } @@ -223,19 +219,19 @@ TYPO3.Components.PageTree.Actions = { * Restores a given node and moves it to the given destination inside the tree. Use this * method if you want to add the node after the destination node. * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree - * @param {TYPO3.Components.PageTree.Model} destination + * @param {Ext.tree.TreeNode} destination * @return {void} */ restoreNodeAfterDestination: function(node, tree, destination) { TYPO3.Components.PageTree.Commands.restoreNode( - node.get('nodeData'), - -destination.get('nodeData').id, - function (updatedNode) { + node.attributes.nodeData, + -destination.attributes.nodeData.id, + function(updatedNode) { if (this.evaluateResponse(updatedNode)) { - var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model', - Ext.apply(node.fields, updatedNode) + var newTreeNode = new Ext.tree.TreeNode( + Ext.apply(node.attributes, updatedNode) ); destination.parentNode.insertBefore(newTreeNode, destination.nextSibling); } @@ -247,7 +243,7 @@ TYPO3.Components.PageTree.Actions = { /** * Collapses a whole tree branch * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @return {void} */ collapseBranch: function(node) { @@ -257,7 +253,7 @@ TYPO3.Components.PageTree.Actions = { /** * Expands a whole tree branch * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @return {void} */ expandBranch: function(node) { @@ -267,13 +263,13 @@ TYPO3.Components.PageTree.Actions = { /** * Opens a popup windows for previewing the given node/page * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @return {void} */ viewPage: function(node) { var frontendWindow = window.open('', 'newTYPO3frontendWindow'); TYPO3.Components.PageTree.Commands.getViewLink( - node.get('nodeData'), + node.attributes.nodeData, function(result) { frontendWindow.location = result; frontendWindow.focus(); @@ -284,13 +280,13 @@ TYPO3.Components.PageTree.Actions = { /** * Creates a temporary tree mount point * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ mountAsTreeRoot: function(node, tree) { TYPO3.Components.PageTree.Commands.setTemporaryMountPoint( - node.get('nodeData'), + node.attributes.nodeData, function(response) { if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) { TYPO3.Backend.NavigationContainer.PageTree.removeIndicator( @@ -301,18 +297,19 @@ TYPO3.Components.PageTree.Actions = { TYPO3.Components.PageTree.Configuration.temporaryMountPoint = response; TYPO3.Backend.NavigationContainer.PageTree.addTemporaryMountPointIndicator(); - var selectedNode = tree.getSelectionModel().getLastSelected(); + var selectedNode = TYPO3.Backend.NavigationContainer.PageTree.getSelected(); tree.stateId = 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint; - // Refresh tree and restore last selection if under the temporary mount - tree.refreshTree(function () { - var selectionModel = tree.getSelectionModel(); + tree.refreshTree(function() { + var nodeIsSelected = false; if (selectedNode) { - selectionModel.deselect(selectedNode); - selectionModel.select(selectedNode); + nodeIsSelected = TYPO3.Backend.NavigationContainer.PageTree.select( + selectedNode.attributes.nodeData.id + ); } - selectedNode = selectionModel.getLastSelected(); - if (selectedNode) { - this.singleClick(selectedNode, tree); + + var node = (nodeIsSelected ? TYPO3.Backend.NavigationContainer.PageTree.getSelected() : null); + if (node) { + this.singleClick(node, tree); } else { this.singleClick(tree.getRootNode().firstChild, tree); } @@ -325,67 +322,63 @@ TYPO3.Components.PageTree.Actions = { /** * Opens the edit page properties dialog * - * @param {TYPO3.Components.PageTree.Model} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - editPageProperties: function(node, tree) { - tree.getSelectionModel().select(node); + editPageProperties: function(node) { + node.select(); TYPO3.Backend.ContentContainer.setUrl( - 'alt_doc.php?edit[pages][' + node.getNodeData('id') + ']=edit' + 'alt_doc.php?edit[pages][' + node.attributes.nodeData.id + ']=edit' ); }, /** * Opens the new page wizard * - * @param {TYPO3.Components.PageTree.Model} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - newPageWizard: function(node, tree) { - tree.getSelectionModel().select(node); + newPageWizard: function(node) { + node.select(); TYPO3.Backend.ContentContainer.setUrl( - 'db_new.php?id=' + node.getNodeData('id') + '&pagesOnly=1' + 'db_new.php?id=' + node.attributes.nodeData.id + '&pagesOnly=1' ); }, /** * Opens the info popup * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @return {void} */ openInfoPopUp: function(node) { - launchView('pages', node.getNodeData('id')); + launchView('pages', node.attributes.nodeData.id); }, /** * Opens the history popup * - * @param {TYPO3.Components.PageTree.Model} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - openHistoryPopUp: function(node, tree) { - tree.getSelectionModel().select(node); + openHistoryPopUp: function(node) { + node.select(); TYPO3.Backend.ContentContainer.setUrl( - 'show_rechis.php?element=pages:' + node.getNodeData('id') + 'show_rechis.php?element=pages:' + node.attributes.nodeData.id ); }, /** * Opens the export .t3d file dialog * - * @param {TYPO3.Components.PageTree.Model} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - exportT3d: function(node, tree) { - tree.getSelectionModel().select(node); + exportT3d: function(node) { + node.select(); TYPO3.Backend.ContentContainer.setUrl( 'sysext/impexp/app/index.php?tx_impexp[action]=export&' + - 'id=0&tx_impexp[pagetree][id]=' + node.getNodeData('id') + + 'id=0&tx_impexp[pagetree][id]=' + node.attributes.nodeData.id + '&tx_impexp[pagetree][levels]=0' + '&tx_impexp[pagetree][tables][]=_ALL' ); @@ -394,14 +387,13 @@ TYPO3.Components.PageTree.Actions = { /** * Opens the import .t3d file dialog * - * @param {TYPO3.Components.PageTree.Model} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - importT3d: function(node, tree) { - tree.getSelectionModel().select(node); + importT3d: function(node) { + node.select(); TYPO3.Backend.ContentContainer.setUrl( - 'sysext/impexp/app/index.php?id=' + node.getNodeData('id') + + 'sysext/impexp/app/index.php?id=' + node.attributes.nodeData.id + '&table=pages&tx_impexp[action]=import' ); }, @@ -409,13 +401,13 @@ TYPO3.Components.PageTree.Actions = { /** * Enables the cut mode of a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ enableCutMode: function(node, tree) { this.disableCopyMode(node, tree); - node.setNodeData('t3InCutMode', true); + node.attributes.nodeData.t3InCutMode = true; tree.t3ContextInfo.inCutMode = true; tree.t3ContextNode = node; }, @@ -423,25 +415,25 @@ TYPO3.Components.PageTree.Actions = { /** * Disables the cut mode of a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ disableCutMode: function(node, tree) { this.releaseCutAndCopyModes(tree); - node.setNodeData('t3InCutMode', false); + node.attributes.nodeData.t3InCutMode = false; }, /** * Enables the copy mode of a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ enableCopyMode: function(node, tree) { this.disableCutMode(node, tree); - node.setNodeData('t3InCopyMode', true); + node.attributes.nodeData.t3InCopyMode = true; tree.t3ContextInfo.inCopyMode = true; tree.t3ContextNode = node; }, @@ -449,19 +441,19 @@ TYPO3.Components.PageTree.Actions = { /** * Disables the copy mode of a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ disableCopyMode: function(node, tree) { this.releaseCutAndCopyModes(tree); - node.setNodeData('t3InCopyMode', false); + node.attributes.nodeData.t3InCopyMode = false; }, /** * Pastes the cut/copy context node into the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ @@ -471,10 +463,10 @@ TYPO3.Components.PageTree.Actions = { } if (tree.t3ContextInfo.inCopyMode) { - var newNode = tree.t3ContextNode = Ext.create('TYPO3.Components.PageTree.Model', tree.t3ContextNode.fields); + var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes); newNode.id = 'fakeNode'; node.insertBefore(newNode, node.childNodes[0]); - node.setNodeData('t3InCopyMode', false); + node.attributes.nodeData.t3InCopyMode = false; this.copyNodeToFirstChildOfDestination(newNode, tree); } else if (tree.t3ContextInfo.inCutMode) { @@ -483,7 +475,7 @@ TYPO3.Components.PageTree.Actions = { } node.appendChild(tree.t3ContextNode); - node.setNodeData('t3InCutMode', false); + node.attributes.nodeData.t3InCutMode = false; this.moveNodeToFirstChildOfDestination(node, tree); } }, @@ -491,7 +483,7 @@ TYPO3.Components.PageTree.Actions = { /** * Pastes a cut/copy context node after the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ @@ -501,18 +493,19 @@ TYPO3.Components.PageTree.Actions = { } if (tree.t3ContextInfo.inCopyMode) { - var newNode = tree.t3ContextNode = Ext.create('TYPO3.Components.PageTree.Model', tree.t3ContextNode.fields); + var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes); newNode.id = 'fakeNode'; node.parentNode.insertBefore(newNode, node.nextSibling); - node.setNodeData('t3InCopyMode', false); + node.attributes.nodeData.t3InCopyMode = false; this.copyNodeAfterDestination(newNode, tree); } else if (tree.t3ContextInfo.inCutMode) { if (node.getPath().indexOf(tree.t3ContextNode.id) !== -1) { return; } + node.parentNode.insertBefore(tree.t3ContextNode, node.nextSibling); - node.setNodeData('t3InCutMode', false); + node.attributes.nodeData.t3InCutMode = false; this.moveNodeAfterDestination(node, tree); } }, @@ -520,17 +513,17 @@ TYPO3.Components.PageTree.Actions = { /** * Moves the current tree context node after the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ moveNodeAfterDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.moveNodeAfterDestination( - tree.t3ContextNode.get('nodeData'), - node.getNodeData('id'), - function (response) { + tree.t3ContextNode.attributes.nodeData, + node.attributes.nodeData.id, + function(response) { if (this.evaluateResponse(response) && tree.t3ContextNode) { - this.updateNode(tree, tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response); + this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response); } this.releaseCutAndCopyModes(tree); }, @@ -541,17 +534,17 @@ TYPO3.Components.PageTree.Actions = { /** * Moves the current tree context node as the first child of the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ moveNodeToFirstChildOfDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination( - tree.t3ContextNode.get('nodeData'), - node.getNodeData('id'), - function (response) { + tree.t3ContextNode.attributes.nodeData, + node.attributes.nodeData.id, + function(response) { if (this.evaluateResponse(response) && tree.t3ContextNode) { - this.updateNode(tree, tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response); + this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response); } this.releaseCutAndCopyModes(tree); }, @@ -562,21 +555,19 @@ TYPO3.Components.PageTree.Actions = { /** * Inserts a new node after the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ - insertNodeAfterDestination: function (node, tree) { + insertNodeAfterDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.insertNodeAfterDestination( - tree.t3ContextNode.get('nodeData'), - node.previousSibling.getNodeData('id'), + tree.t3ContextNode.attributes.nodeData, + node.previousSibling.attributes.nodeData.id, tree.t3ContextInfo.serverNodeType, - function (response) { + function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, node.isExpanded(), response, function (records, operation, successful) { - if (successful && operation.node) { - tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0)); - } + this.updateNode(node, node.isExpanded(), response, function(node) { + tree.triggerEdit(node); }); } this.releaseCutAndCopyModes(tree); @@ -588,20 +579,18 @@ TYPO3.Components.PageTree.Actions = { /** * Inserts a new node as the first child of the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ insertNodeToFirstChildOfDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination( - tree.t3ContextNode.get('nodeData'), + tree.t3ContextNode.attributes.nodeData, tree.t3ContextInfo.serverNodeType, - function (response) { + function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, true, response, function (records, operation, successful) { - if (successful && operation.node) { - tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0)); - } + this.updateNode(node, true, response, function(node) { + tree.triggerEdit(node); }); } this.releaseCutAndCopyModes(tree); @@ -613,20 +602,18 @@ TYPO3.Components.PageTree.Actions = { /** * Copies the current tree context node after the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ copyNodeAfterDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.copyNodeAfterDestination( - tree.t3ContextNode.get('nodeData'), - node.previousSibling.getNodeData('id'), - function (response) { + tree.t3ContextNode.attributes.nodeData, + node.previousSibling.attributes.nodeData.id, + function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, true, response, function (records, operation, successful) { - if (successful && operation.node) { - tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0)); - } + this.updateNode(node, true, response, function(node) { + tree.triggerEdit(node); }); } this.releaseCutAndCopyModes(tree); @@ -638,20 +625,18 @@ TYPO3.Components.PageTree.Actions = { /** * Copies the current tree context node as the first child of the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ copyNodeToFirstChildOfDestination: function(node, tree) { TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination( - tree.t3ContextNode.get('nodeData'), - node.parentNode.getNodeData('id'), - function (response) { + tree.t3ContextNode.attributes.nodeData, + node.parentNode.attributes.nodeData.id, + function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, true, response, function (records, operation, successful) { - if (successful && operation.node) { - tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0)); - } + this.updateNode(node, true, response, function(node) { + tree.triggerEdit(node); }); } this.releaseCutAndCopyModes(tree); @@ -663,16 +648,15 @@ TYPO3.Components.PageTree.Actions = { /** * Visibilizes a page * - * @param {Ext.data.NodeInterface} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - enablePage: function(node, tree) { + enablePage: function(node) { TYPO3.Components.PageTree.Commands.visiblyNode( - node.get('nodeData'), + node.attributes.nodeData, function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, node.isExpanded(), response); + this.updateNode(node, node.isExpanded(), response); } }, this @@ -682,16 +666,15 @@ TYPO3.Components.PageTree.Actions = { /** * Disables a page * - * @param {Ext.data.NodeInterface} node - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} node * @return {void} */ - disablePage: function(node, tree) { + disablePage: function(node) { TYPO3.Components.PageTree.Commands.disableNode( - node.get('nodeData'), - function (response) { + node.attributes.nodeData, + function(response) { if (this.evaluateResponse(response)) { - this.updateNode(tree, node, node.isExpanded(), response); + this.updateNode(node, node.isExpanded(), response); } }, this @@ -701,11 +684,11 @@ TYPO3.Components.PageTree.Actions = { /** * Reloads the content frame with the current module and node id * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @return {void} */ - singleClick: function (node, tree) { + singleClick: function(node, tree) { tree.currentSelectedNode = node; var separator = '?'; @@ -713,77 +696,68 @@ TYPO3.Components.PageTree.Actions = { separator = '&'; } - tree.getSelectionModel().select(node); + node.select(); + if (tree.stateHash) { + tree.stateHash.lastSelectedNode = node.id; + } - fsMod.recentIds['web'] = node.getNodeData('id'); + fsMod.recentIds['web'] = node.attributes.nodeData.id; TYPO3.Backend.ContentContainer.setUrl( - TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.getNodeData('id') + TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.attributes.nodeData.id ); }, /** * Opens a configured url inside the content frame * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} tree * @param {Object} contextItem * @return {void} */ - openCustomUrlInContentFrame: function (node, tree, contextItem) { + openCustomUrlInContentFrame: function(node, tree, contextItem) { if (!contextItem.customAttributes || !contextItem.customAttributes.contentUrl) { return; } - tree.getSelectionModel().select(node); + node.select(); TYPO3.Backend.ContentContainer.setUrl( - contextItem.customAttributes.contentUrl.replace('###ID###', node.getNodeData('id')) + contextItem.customAttributes.contentUrl.replace('###ID###', node.attributes.nodeData.id) ); }, /** * Updates the title of a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {String} newText * @param {String} oldText * @param {TYPO3.Components.PageTree.TreeEditor} treeEditor - * @param {TYPO3.Components.PageTree.Tree} tree - * @param {String} dataIndex * @return {void} */ - saveTitle: function (node, newText, oldText, treeEditor, tree, dataIndex) { - this.singleClick(node, tree); + saveTitle: function(node, newText, oldText, treeEditor) { + this.singleClick(node.editNode, node.editNode.ownerTree); if (newText === oldText || newText == '') { treeEditor.updateNodeText( node, - node.getNodeData('editableText'), - Ext.util.Format.htmlEncode(oldText), - dataIndex, - tree + node.editNode.attributes.nodeData.editableText, + Ext.util.Format.htmlEncode(oldText) ); return; } TYPO3.Components.PageTree.Commands.updateLabel( - node.get('nodeData'), + node.editNode.attributes.nodeData, newText, function(response) { if (this.evaluateResponse(response)) { - treeEditor.updateNodeText( - node, - response.editableText, - response.updatedText, - dataIndex, - tree - ); + treeEditor.updateNodeText(node, response.editableText, response.updatedText); } else { treeEditor.updateNodeText( node, - node.getNodeData('editableText'), - Ext.util.Format.htmlEncode(oldText), - dataIndex, - tree + node.editNode.attributes.nodeData.editableText, + Ext.util.Format.htmlEncode(oldText) ); } }, diff --git a/t3lib/js/extjs/components/pagetree/javascript/app.js b/t3lib/js/extjs/components/pagetree/javascript/app.js index 2701f93c47a6ed39f31b13bb1ed24f410f2684aa..6a178f5921a17fdeef4d826158e41a9b98d92f71 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/app.js +++ b/t3lib/js/extjs/components/pagetree/javascript/app.js @@ -23,18 +23,18 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.App * * Page tree main application that controls setups the components * * @namespace TYPO3.Components.PageTree - * @extends Ext.panel.Panel + * @extends Ext.Panel * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.App', { - extend: 'Ext.panel.Panel', - +TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, { /** * Panel id * @@ -45,7 +45,7 @@ Ext.define('TYPO3.Components.PageTree.App', { /** * Border * - * @type {String} + * @type {Boolean} */ border: false, @@ -54,38 +54,14 @@ Ext.define('TYPO3.Components.PageTree.App', { * * @type {String} */ - layout: 'border', + layout:'fit', /** - * Components defaults + * Active tree * - * @type {Object} + * @type {TYPO3.Components.PageTree.Tree} */ - defaults: { - border: false, - }, - - /** - * Tree containe - * - * @type {String} - */ - items: [{ - itemId: 'topPanelItems', - height: 49, - region: 'north', - cls: 'typo3-pageTree-topPanelItems' - },{ - itemId: 'treeContainer', - autoScroll: false, - layout: 'card', - region: 'center' - },{ - xtype: 'container', - itemId: 'deletionDropZoneContainer', - cls: 'typo3-pageTree-deletionDropZoneContainer', - region: 'south' - }], + activeTree: null, /** * Initializes the application @@ -96,89 +72,112 @@ Ext.define('TYPO3.Components.PageTree.App', { * @return {void} */ initComponent: function() { - this.addListener('render', function () { - TYPO3.Components.PageTree.DataProvider.loadResources(function(response) { - TYPO3.Components.PageTree.LLL = response['LLL']; - TYPO3.Components.PageTree.Configuration = response['Configuration']; - TYPO3.Components.PageTree.Sprites = response['Sprites']; - - var tree = Ext.create('TYPO3.Components.PageTree.Tree', { - id: this.getId() + '-tree', - deletionDropZoneId: this.getId() + '-deletionDropZone', - ddGroup: this.getId(), - stateful: true, - stateId: 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint, - commandProvider: TYPO3.Components.PageTree.Actions, - contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider, - treeDataProvider: TYPO3.Components.PageTree.DataProvider, - app: this - }); - - var filteringTree = Ext.create('TYPO3.Components.PageTree.FilteringTree', { - id: this.getId() + '-filteringTree', - deletionDropZoneId: this.getId() + '-deletionDropZone', - ddGroup: this.getId(), - commandProvider: TYPO3.Components.PageTree.Actions, - contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider, - stateful: false, - treeDataProvider: TYPO3.Components.PageTree.DataProvider, - app: this - }); - - var topPanelItems = this.getComponent('topPanelItems'); - topPanelItems.add([ - Ext.create('TYPO3.Components.PageTree.TopPanel', { - border: false, - dataProvider: TYPO3.Components.PageTree.DataProvider, - filteringTree: filteringTree, - ddGroup: this.getId(), - height: 49, - itemId: 'topPanel', - tree: tree, - app: this - }), - { - xtype: 'container', - border: false, - defaultType: 'component', - id: this.getId() + '-indicatorBar', - itemId: 'indicatorBar' - } - ]); - - var treeContainer = this.getComponent('treeContainer'); - treeContainer.add([tree, filteringTree]); - treeContainer.addListener( - 'render', - function (panel) { panel.getLayout().setActiveItem(0); } - ); - - var deletionDropZoneContainer = this.getComponent('deletionDropZoneContainer'); - deletionDropZoneContainer.add({ - xtype: 'typo3deletiondropzone', - height: 35, - id: this.getId() + '-deletionDropZone', - commandProvider: TYPO3.Components.PageTree.Actions, - ddGroup: this.getId(), - layout: 'anchor', - app: this - }); - - if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) { - this.addTemporaryMountPointIndicator(); - } - - if (TYPO3.Components.PageTree.Configuration.indicator !== '') { - this.addIndicatorItems(); + TYPO3.Components.PageTree.DataProvider.loadResources(function(response) { + TYPO3.Components.PageTree.LLL = response['LLL']; + TYPO3.Components.PageTree.Configuration = response['Configuration']; + TYPO3.Components.PageTree.Sprites = response['Sprites']; + + var tree = this.activeTree = new TYPO3.Components.PageTree.Tree({ + id: this.id + '-tree', + deletionDropZoneId: this.id + '-deletionDropZone', + ddGroup: this.id, + stateful: true, + stateId: 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint, + stateEvents: [], + autoScroll: true, + autoHeight: false, + plugins: new Ext.ux.state.TreePanel(), + commandProvider: TYPO3.Components.PageTree.Actions, + contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider, + treeDataProvider: TYPO3.Components.PageTree.DataProvider, + app: this, + listeners: { + resize: { + fn: function() { + var treeContainer = Ext.getCmp(this.id + '-treeContainer'); + Ext.getCmp(this.id + '-filteringTree').setSize(treeContainer.getSize()); + treeContainer.doLayout(); + }, + scope: this, + buffer: 250 + } } - this.doLayout(); - - this.ownerCt.on('resize', function() { - this.doLayout(); + }); + + var filteringTree = new TYPO3.Components.PageTree.FilteringTree({ + id: this.id + '-filteringTree', + deletionDropZoneId: this.id + '-deletionDropZone', + ddGroup: this.id, + autoScroll: true, + autoHeight: false, + commandProvider: TYPO3.Components.PageTree.Actions, + contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider, + treeDataProvider: TYPO3.Components.PageTree.DataProvider, + app: this + }).hide(); + + var topPanel = new TYPO3.Components.PageTree.TopPanel({ + dataProvider: TYPO3.Components.PageTree.DataProvider, + filteringTree: filteringTree, + ddGroup: this.id, + tree: tree, + app: this + }); + + var deletionDropZone = new TYPO3.Components.PageTree.DeletionDropZone({ + id: this.id + '-deletionDropZone', + commandProvider: TYPO3.Components.PageTree.Actions, + ddGroup: this.id, + app: this, + region: 'south', + height: 35 + }); + + var topPanelItems = new Ext.Panel({ + id: this.id + '-topPanelItems', + border: false, + region: 'north', + height: 49, + items: [ + topPanel, { + border: false, + id: this.id + '-indicatorBar' + } + ] + }); + + this.add({ + layout: 'border', + items: [ + topPanelItems, + { + border: false, + id: this.id + '-treeContainer', + region: 'center', + layout: 'fit', + items: [tree, filteringTree] + }, + deletionDropZone + ] + }); + + if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) { + topPanelItems.on('afterrender', function() { + this.addTemporaryMountPointIndicator(); }, this); - }, this); + } + + if (TYPO3.Components.PageTree.Configuration.indicator !== '') { + this.addIndicatorItems(); + } + this.doLayout(); + + this.ownerCt.on('resize', function() { + this.doLayout(); + }); }, this); - this.callParent(); + + TYPO3.Components.PageTree.App.superclass.initComponent.apply(this, arguments); }, /** @@ -188,8 +187,9 @@ Ext.define('TYPO3.Components.PageTree.App', { */ addIndicatorItems: function() { this.addIndicator({ - id: this.getId() + '-indicatorBar-indicatorTitle', - cls: this.getId() + '-indicatorBar-item', + border: false, + id: this.id + '-indicatorBar-indicatorTitle', + cls: this.id + '-indicatorBar-item', html: TYPO3.Components.PageTree.Configuration.indicator }); }, @@ -201,13 +201,14 @@ Ext.define('TYPO3.Components.PageTree.App', { */ addTemporaryMountPointIndicator: function() { this.temporaryMountPointInfoIndicator = this.addIndicator({ - id: this.getId() + '-indicatorBar-temporaryMountPoint', - cls: this.getId() + '-indicatorBar-item', + border: false, + id: this.id + '-indicatorBar-temporaryMountPoint', + cls: this.id + '-indicatorBar-item', listeners: { afterrender: { fn: function() { - var element = Ext.get(this.getId() + '-indicatorBar-temporaryMountPoint-clear'); + var element = Ext.fly(this.id + '-indicatorBar-temporaryMountPoint-clear'); element.on('click', function() { TYPO3.BackendUserSettings.ExtDirect.unsetKey( 'pageTree_temporaryMountPoint', @@ -224,21 +225,18 @@ Ext.define('TYPO3.Components.PageTree.App', { scope: this } }, - renderData: { - appId: this.getId(), - spriteIconCls: TYPO3.Components.PageTree.Sprites.Info, - label: TYPO3.Components.PageTree.LLL.temporaryMountPointIndicatorInfo, - mountPoint: TYPO3.Components.PageTree.Configuration.temporaryMountPoint - }, - renderTpl: Ext.create('Ext.XTemplate', - '<p>', - '<span id="{appId}-indicatorBar-temporaryMountPoint-info" class="{appId}-indicatorBar-item-leftIcon {spriteIconCls}"> </span>', - '{label}', - '<span id="{appId}-indicatorBar-temporaryMountPoint-clear" class="{appId}-indicatorBar-item-rightIcon t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-tceforms-input-clearer"> </span>', - '</p>', - '<p>{mountPoint}', + + html: '<p>' + + '<span id="' + this.id + '-indicatorBar-temporaryMountPoint-info' + '" ' + + 'class="' + this.id + '-indicatorBar-item-leftIcon ' + + TYPO3.Components.PageTree.Sprites.Info + '"> ' + + '</span>' + + '<span id="' + this.id + '-indicatorBar-temporaryMountPoint-clear' + '" ' + + 'class="' + this.id + '-indicatorBar-item-rightIcon ' + '">X' + + '</span>' + + TYPO3.Components.PageTree.LLL.temporaryMountPointIndicatorInfo + '<br />' + + TYPO3.Components.PageTree.Configuration.temporaryMountPoint + '</p>' - ) }); }, @@ -250,18 +248,23 @@ Ext.define('TYPO3.Components.PageTree.App', { */ addIndicator: function(component) { if (component.listeners && component.listeners.afterrender) { - component.listeners.afterrender.fn = Ext.Function.createSequence(component.listeners.afterrender.fn, this.afterTopPanelItemAdded, this); + component.listeners.afterrender.fn = component.listeners.afterrender.fn.createSequence( + this.afterTopPanelItemAdded, this + ); } else { - if (!component.listeners) { - component.listeners = {}; + if (component.listeners) { + component.listeners = {} } + component.listeners.afterrender = { scope: this, fn: this.afterTopPanelItemAdded } } - var indicatorBar = this.down('component[itemId=indicatorBar]'); - var indicator = indicatorBar.add(component); + + var indicator = Ext.getCmp(this.id + '-indicatorBar').add(component); + this.doLayout(); + return indicator; }, @@ -272,15 +275,8 @@ Ext.define('TYPO3.Components.PageTree.App', { * @return {void} */ afterTopPanelItemAdded: function(component) { - var topPanel = this.down('component[itemId=topPanel]'); - var indicatorBar = this.down('component[itemId=indicatorBar]'); - var height = 0; - indicatorBar.items.each(function (item) { - height += item.getHeight() + 3; - }); - indicatorBar.setHeight(height); - topPanelItems = this.down('component[itemId=topPanelItems]'); - topPanelItems.setHeight(topPanel.getHeight() + indicatorBar.getHeight()); + var topPanelItems = Ext.getCmp(this.id + '-topPanelItems'); + topPanelItems.setHeight(topPanelItems.getHeight() + component.getHeight() + 3); this.doLayout(); }, @@ -291,9 +287,9 @@ Ext.define('TYPO3.Components.PageTree.App', { * @return {void} */ removeIndicator: function(component) { - var topPanelItems = this.down('component[itemId=topPanelItems]'); + var topPanelItems = Ext.getCmp(this.id + '-topPanelItems'); topPanelItems.setHeight(topPanelItems.getHeight() - component.getHeight() - 3); - Ext.getCmp(this.getId() + '-indicatorBar').remove(component); + Ext.getCmp(this.id + '-indicatorBar').remove(component); this.doLayout(); }, @@ -322,11 +318,11 @@ Ext.define('TYPO3.Components.PageTree.App', { */ refreshTree: function() { if (!isNaN(fsMod.recentIds['web']) && fsMod.recentIds['web'] !== '') { - this.select(fsMod.recentIds['web']); + this.select(fsMod.recentIds['web'], true); } TYPO3.Components.PageTree.DataProvider.getIndicators(function(response) { - var indicators = Ext.getCmp(this.getId() + '-indicatorBar-indicatorTitle'); + var indicators = Ext.getCmp(this.id + '-indicatorBar-indicatorTitle'); if (indicators) { this.removeIndicator(indicators); } @@ -337,7 +333,7 @@ Ext.define('TYPO3.Components.PageTree.App', { } }, this); - this.getTree().refreshTree(); + this.activeTree.refreshTree(); }, /** @@ -346,44 +342,43 @@ Ext.define('TYPO3.Components.PageTree.App', { * @return {TYPO3.Components.PageTree.Tree} */ getTree: function() { - return this.down('component[itemId=treeContainer]').getLayout().getActiveItem(); + return this.activeTree; }, /** - * Sets the current active tree - * @param {TYPO3.Components.PageTree.Tree} tree - * @return {TYPO3.Components.PageTree.Tree} - */ - setTree: function(tree) { - var layout = this.down('component[itemId=treeContainer]').getLayout(); - layout.setActiveItem(tree); - return layout.getActiveItem(tree); - }, - - /** - * Selects a node defined by the page id. + * Selects a node defined by the page id. If the second parameter is set, we + * store the new location into the state hash. * * @param {int} pageId + * @param {Boolean} saveState * @return {Boolean} */ - select: function(pageId) { + select: function(pageId, saveState) { + if (saveState !== false) { + saveState = true; + } + var tree = this.getTree(); var succeeded = false; var node = tree.getRootNode().findChild('realId', pageId, true); if (node) { succeeded = true; tree.selectPath(node.getPath()); + if (!!saveState && tree.stateHash) { + tree.stateHash.lastSelectedNode = node.id; + } } + return succeeded; }, /** * Returns the currently selected node * - * @return {Ext.data.NodeInterface} + * @return {Ext.tree.TreeNode} */ getSelected: function() { - var node = this.getTree().getSelectionModel().getLastSelected(); + var node = this.getTree().getSelectionModel().getSelectedNode(); return node ? node : null; } }); @@ -394,12 +389,15 @@ Ext.define('TYPO3.Components.PageTree.App', { * @return {TYPO3.Components.PageTree.App} */ TYPO3.ModuleMenu.App.registerNavigationComponent('typo3-pagetree', function() { - TYPO3.Backend.NavigationContainer.PageTree = Ext.create('TYPO3.Components.PageTree.App'); + TYPO3.Backend.NavigationContainer.PageTree = new TYPO3.Components.PageTree.App(); // compatibility code - top.nav = TYPO3.Backend.NavigationContainer.PageTree; - top.nav_frame = TYPO3.Backend.NavigationContainer.PageTree; - top.content.nav_frame = TYPO3.Backend.NavigationContainer.PageTree; + top.nav = TYPO3.Backend.NavigationContainer.PageTree; + top.nav_frame = TYPO3.Backend.NavigationContainer.PageTree; + top.content.nav_frame = TYPO3.Backend.NavigationContainer.PageTree; return TYPO3.Backend.NavigationContainer.PageTree; }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.App', TYPO3.Components.PageTree.App); diff --git a/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js b/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js index 5c6ed687aa82b4189688e60b6cd0ac1c8e7b9269..32501b69f334eb1d66e489b917a9bb938ce10d1a 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js +++ b/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js @@ -23,6 +23,8 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.ContextMenu * @@ -32,12 +34,11 @@ * @extends Ext.menu.Menu * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.ContextMenu', { - extend: 'Ext.menu.Menu', +TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, { /** * Context menu node * - * @cfg {TYPO3.Components.PageTree.Model} + * @cfg {Ext.tree.TreeNode} */ node: null, @@ -65,15 +66,15 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { /** * Listeners * - * The click event triggers the configured single click action + * The itemclick event triggers the configured single click action */ listeners: { - click: { - fn: function (menu, item) { - if (item && this.pageTree.commandProvider[item.callbackAction]) { + itemclick: { + fn: function (item) { + if (this.pageTree.commandProvider[item.callbackAction]) { if (item.parentMenu.pageTree.stateHash) { - fsMod.recentIds['web'] = item.parentMenu.node.getNodeData('id'); - item.parentMenu.pageTree.stateHash['lastSelectedNode'] = item.parentMenu.node.getId(); + fsMod.recentIds['web'] = item.parentMenu.node.attributes.nodeData.id; + item.parentMenu.pageTree.stateHash['lastSelectedNode'] = item.parentMenu.node.id; } this.pageTree.commandProvider[item.callbackAction]( @@ -89,12 +90,12 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { /** * Fills the menu with the actions * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {TYPO3.Components.PageTree.Tree} pageTree * @param {Object} contextMenuConfiguration * @return {void} */ - fill: function (node, pageTree, contextMenuConfiguration) { + fill: function(node, pageTree, contextMenuConfiguration) { this.node = node; this.pageTree = pageTree; @@ -102,11 +103,9 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { if (components.length) { for (var component in components) { if (components[component] === '-') { - this.add({ - xtype: 'menuseparator' - }); + this.addSeparator(); } else if (typeof components[component] === 'object') { - this.add(components[component]); + this.addItem(components[component]); } } } @@ -120,7 +119,7 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { * @param {int} level * @return {Object} */ - preProcessContextMenuConfiguration: function (contextMenuConfiguration, level) { + preProcessContextMenuConfiguration: function(contextMenuConfiguration, level) { level = level || 0; if (level > 5) { return []; @@ -139,7 +138,7 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { ); if (subMenuComponents.length) { - var subMenu = Ext.create('TYPO3.Components.PageTree.ContextMenu', { + var subMenu = new TYPO3.Components.PageTree.ContextMenu({ id: this.id + '-sub' + ++subMenus, items: subMenuComponents, node: this.node, @@ -151,8 +150,7 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { cls: 'contextMenu-subMenu', menu: subMenu, icon: contextMenuConfiguration[singleAction]['icon'], - iconCls: contextMenuConfiguration[singleAction]['class'], - xtype: 'menuitem' + iconCls: contextMenuConfiguration[singleAction]['class'] }; } } else if (contextMenuConfiguration[singleAction]['type'] === 'divider') { @@ -165,14 +163,22 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { if (typeof contextMenuConfiguration[singleAction] === 'object') { var component = { - text: contextMenuConfiguration[singleAction]['label'], - icon: contextMenuConfiguration[singleAction]['icon'], - iconCls: contextMenuConfiguration[singleAction]['class'], - callbackAction: contextMenuConfiguration[singleAction]['callbackAction'], - customAttributes: contextMenuConfiguration[singleAction]['customAttributes'], - xtype: 'menuitem' + 'text': contextMenuConfiguration[singleAction]['label'], + 'icon': contextMenuConfiguration[singleAction]['icon'], + 'iconCls': contextMenuConfiguration[singleAction]['class'], + 'callbackAction': contextMenuConfiguration[singleAction]['callbackAction'], + 'customAttributes': contextMenuConfiguration[singleAction]['customAttributes'] }; + component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate( + '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">', + '<span class="{hrefTarget}">', + '<img src="{icon}" class="x-menu-item-icon {iconCls}" unselectable="on" />', + '</span>', + '<span class="x-menu-item-text">{text}</span>', + '</a>' + ); + components[index++] = component; } } @@ -186,3 +192,6 @@ Ext.define('TYPO3.Components.PageTree.ContextMenu', { return components; } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.ContextMenu', TYPO3.Components.PageTree.ContextMenu); diff --git a/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js b/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js index a89afdbff79411f48580e4edf3519f14cf3410e1..443f96fa65880019049a6dbed5ef246c31e75262 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js +++ b/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js @@ -23,19 +23,18 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.DeletionDropZone * * Deletion Drop Zone * * @namespace TYPO3.Components.PageTree - * @extends Ext.panel.Panel + * @extends Ext.Panel * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { - extend: 'Ext.panel.Panel', - alias: 'widget.typo3deletiondropzone', - +TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, { /** * Border * @@ -111,7 +110,10 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { this.getEl().on('mouseout', function(e) { if (!e.within(this.getEl(), true)) { - this.removeCls(this.id + '-activateProxyOver'); + this.removeClass(this.id + '-activateProxyOver'); + if (!this.app.activeTree.shouldCopyNode) { + this.app.activeTree.copyHint.show(); + } } }, this); } @@ -137,7 +139,7 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { '"> </span><span id="' + this.id + '-text">' + TYPO3.Components.PageTree.LLL.dropToRemove + '</span></p>'; - this.callParent(arguments); + TYPO3.Components.PageTree.DeletionDropZone.superclass.initComponent.apply(this, arguments); }, @@ -147,49 +149,44 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { * @return {void} */ createDropZone: function() { - Ext.create('Ext.dd.DropZone', this.getEl(), { + (new Ext.dd.DropZone(this.getEl(), { ddGroup: this.ddGroup, - notifyOver: Ext.Function.bind( - function(ddProxy, e) { - ddProxy.setDragElPos(e.xy[0], e.xy[1] - 60); - return this.id + '-proxyOver'; - }, - this - ), - - notifyEnter: Ext.Function.bind( - function() { - this.addCls(this.id + '-activateProxyOver'); - return this.id + '-proxyOver'; - }, - this - ), - - notifyDrop: Ext.Function.bind( - function (ddProxy, e, dragData) { - var view = dragData.view, - tree = view.panel, - node = view.getRecord(dragData.item); - if (!node) { - return; - } - var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable()); - - var callback = null; - if (!top.TYPO3.configuration.inWorkspace && !nodeHasChildNodes) { - callback = Ext.Function.bind(this.setRecoverState, this); - } - - if (nodeHasChildNodes) { - tree.commandProvider.confirmDelete(node, tree, callback, true); - } else { - tree.commandProvider.deleteNode(node, tree, callback); - } - }, - this - ) - }); + notifyOver: function(ddProxy, e) { + ddProxy.setDragElPos(e.xy[0], e.xy[1] - 60); + return this.id + '-proxyOver'; + }.createDelegate(this), + + notifyEnter: function() { + this.addClass(this.id + '-activateProxyOver'); + if (!this.app.activeTree.shouldCopyNode) { + this.app.activeTree.copyHint.hide(); + } + + return this.id + '-proxyOver'; + }.createDelegate(this), + + notifyDrop: function(ddProxy, e, n) { + var node = n.node; + if (!node) { + return; + } + + var tree = node.ownerTree; + var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable()); + + var callback = null; + if (!top.TYPO3.configuration.inWorkspace && !nodeHasChildNodes) { + callback = this.setRecoverState.createDelegate(this); + } + + if (nodeHasChildNodes) { + node.ownerTree.commandProvider.confirmDelete(node, tree, callback, true); + } else { + node.ownerTree.commandProvider.deleteNode(node, tree, callback); + } + }.createDelegate(this) + })); }, /** @@ -210,7 +207,7 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { this.setHeight(50); this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCanRestore); this.updateText( - node.get('text') + '<br />' + + node.text + '<br />' + '<span class="' + this.id + '-restore">' + '<span class="' + this.id + '-restoreText">' + TYPO3.Components.PageTree.LLL.dropZoneElementRemoved + @@ -221,17 +218,13 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { this.app.doLayout(); ++this.amountOfDrops; - Ext.Function.defer( - function() { - if (!--this.amountOfDrops) { - this.toOriginState(); - } - }, - 10000, - this - ); + (function() { + if (!--this.amountOfDrops) { + this.toOriginState(); + } + }).defer(10000, this); - this.textClickHandler = Ext.Function.bind(this.restoreNode, this, [node, tree]); + this.textClickHandler = this.restoreNode.createDelegate(this, [node, tree]); Ext.get(this.id + '-text').on('click', this.textClickHandler); this.isPreviousSibling = false; @@ -290,7 +283,7 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { this.previousNode = this.textClickHandler = null; this.isPreviousSibling = false; - if (hide && !this.app.getTree().getView().getPlugin('treeViewDragDrop').dragZone.dragging) { + if (hide && !this.app.activeTree.dragZone.dragging) { this.hide(); } @@ -317,14 +310,13 @@ Ext.define('TYPO3.Components.PageTree.DeletionDropZone', { this.updateText(TYPO3.Components.PageTree.LLL.dropZoneElementRestored); this.app.doLayout(); - Ext.Function.defer( - function() { - if (this.textClickHandler) { - this.toOriginState(); - } - }, - 3000, - this - ); + (function() { + if (this.textClickHandler) { + this.toOriginState(); + } + }).defer(3000, this); } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.DeletionDropZone', TYPO3.Components.PageTree.DeletionDropZone); diff --git a/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js b/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js index 5b24822d19bed59cf4281169e3883c513e9f8afa..7ee0d88d312de0316141e51525b4f52b217fcf51 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js +++ b/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js @@ -23,6 +23,8 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.FilteringTree * @@ -32,9 +34,7 @@ * @extends TYPO3.Components.PageTree.Tree * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.FilteringTree', { - extend: 'TYPO3.Components.PageTree.Tree', - +TYPO3.Components.PageTree.FilteringTree = Ext.extend(TYPO3.Components.PageTree.Tree, { /** * Search word * @@ -47,45 +47,29 @@ Ext.define('TYPO3.Components.PageTree.FilteringTree', { * * @return {void} */ - addStore: function (store) { - this.store = Ext.data.StoreManager.lookup(this.getId() + 'FilteredPageTreeStore'); - if (!this.store) { - this.store = Ext.create('Ext.data.TreeStore', { - clearOnLoad: false, - listeners: { - beforeload: { - fn: function (store, operation) { - if (!this.searchWord || this.searchWord === '') { - return false; - } - if (operation.node) { - var node = operation.node; - node.removeAll(); - node.commit(); - operation.params = { - nodeId: node.getNodeData('id'), - nodeData: node.get('nodeData'), - searchWord: this.searchWord - - }; - } - }, - scope: this - } - }, - model: 'TYPO3.Components.PageTree.Model', - nodeParam: 'nodeId', - proxy: { - type: 'direct', - paramOrder: ['nodeId', 'nodeData', 'searchWord'], - directFn: this.treeDataProvider.getFilteredTree, - reader: { - type: 'json' + addTreeLoader: function() { + this.loader = new Ext.tree.TreeLoader({ + directFn: this.treeDataProvider.getFilteredTree, + paramOrder: 'nodeId,attributes,searchWord', + nodeParameter: 'nodeId', + baseAttrs: { + uiProvider: this.uiProvider + }, + + listeners: { + beforeload: function(treeLoader, node) { + if (!node.ownerTree.searchWord || node.ownerTree.searchWord === '') { + return false; } - }, - root: this.rootNodeConfig, - storeId: this.getId() + 'FilteredPageTreeStore' - }); - } + + treeLoader.baseParams.nodeId = node.id; + treeLoader.baseParams.searchWord = node.ownerTree.searchWord; + treeLoader.baseParams.attributes = node.attributes.nodeData; + } + } + }); } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.FilteringTree', TYPO3.Components.PageTree.FilteringTree); diff --git a/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt b/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt index 84566aec2fd71794cf8fc9d2331d9d27d8aefb66..a649b22150ae39b41101fde397cc2c58bcdbd83b 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt +++ b/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt @@ -1,12 +1,10 @@ treeeditor.js -pagetreecolumn.js -contextmenu.js -Ext.ux.state.TreePanel.js -treedropzone.js -treeviewdragdrop.js tree.js filteringtree.js -toppanel.js +nodeui.js deletiondropzone.js +toppanel.js +contextmenu.js actions.js +Ext.ux.state.TreePanel.js app.js diff --git a/t3lib/js/extjs/components/pagetree/javascript/nodeui.js b/t3lib/js/extjs/components/pagetree/javascript/nodeui.js new file mode 100644 index 0000000000000000000000000000000000000000..1a1066063bcecd47c5a5add71a3c12506068feb4 --- /dev/null +++ b/t3lib/js/extjs/components/pagetree/javascript/nodeui.js @@ -0,0 +1,169 @@ +/*************************************************************** +* Copyright notice +* +* (c) 2010-2011 Stefan Galinski <stefan.galinski@gmail.com> +* All rights reserved +* +* This script is part of the TYPO3 project. The TYPO3 project is +* free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* A copy is found in the textfile GPL.txt and important notices to the license +* from the author is found in LICENSE.txt distributed with these scripts. +* +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + +/** + * @class TYPO3.Components.PageTree.DeletionDropZone + * + * Tree Node User Interface that can handle sprite icons and more + * + * @namespace TYPO3.Components.PageTree + * @extends Ext.tree.TreeNodeUI + * @author Stefan Galinski <stefan.galinski@gmail.com> + */ +TYPO3.Components.PageTree.PageTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { + /** + * Adds the sprite icon and adds an event to open the context menu on a single click at the icon node + * + * @param {Ext.tree.TreeNode} n + * @param {Object} a + * @param {Ext.tree.TreeNode} targetNode + * @param {Boolean} bulkRender + * @return {void} + */ + renderElements : function(n, a, targetNode, bulkRender) { + // add some indent caching, this helps performance when rendering a large tree + this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; + + var cb = Ext.isBoolean(a.checked), + nel, + href = this.getHref(a.href), + rootline = ''; + + // TYPO3 modification to show the readable rootline above the user mounts + if (a.readableRootline !== '') { + var rootline = '<li class="x-tree-node-readableRootline">' + a.readableRootline + '</li>'; + } + + var buf = [rootline,'<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">', + '<span class="x-tree-node-indent">',this.indentMarkup,"</span>", + '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />', +// '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />', + a.spriteIconCode, // TYPO3: add sprite icon code + cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '', + '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ', + a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>", + '<ul class="x-tree-node-ct" style="display:none;"></ul>', + "</li>"].join(''); + + if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){ + this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf); + }else{ + this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf); + } + + + this.elNode = this.wrap.childNodes[0]; + this.ctNode = this.wrap.childNodes[1]; + var cs = this.elNode.childNodes; + this.indentNode = cs[0]; + this.ecNode = cs[1]; +// this.iconNode = cs[2]; + this.iconNode = (cs[2].firstChild.tagName === 'SPAN' ? cs[2].firstChild : cs[2]); // TYPO3: get possible overlay icon + var index = 3; // TYPO3: index 4? + if(cb){ + this.checkbox = cs[3]; + // fix for IE6 + this.checkbox.defaultChecked = this.checkbox.checked; + index++; + } + this.anchor = cs[index]; + this.textNode = cs[index].firstChild; + + // TYPO3: call the context menu on a single click (Beware of drag&drop!) + if (!TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu + || TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu === '0' + ) { + Ext.fly(this.iconNode).on('click', function(event) { + this.getOwnerTree().fireEvent('contextmenu', this, event); + event.stopEvent(); + }, n); + } + }, + + /** + * Adds a quick tip to the sprite icon + * + * @param {Ext.tree.TreeNode} node + * @param {Object} tip + * @param {String} title + * @return {void} + */ + onTipChange : function(node, tip, title) { + TYPO3.Components.PageTree.PageTreeNodeUI.superclass.onTipChange.apply(this, arguments); + + if(this.rendered){ + var hasTitle = Ext.isDefined(title); + if(this.iconNode.setAttributeNS){ + this.iconNode.setAttributeNS("ext", "qtip", tip); + if(hasTitle){ + this.iconNode.setAttributeNS("ext", "qtitle", title); + } + }else{ + this.iconNode.setAttribute("ext:qtip", tip); + if(hasTitle){ + this.iconNode.setAttribute("ext:qtitle", title); + } + } + } + }, + + /** + * Returns the drag and drop handles + * + * @return {Object} + */ + getDDHandles: function() { + var ddHandles = [this.iconNode, this.textNode, this.elNode]; + var handlesIndex = ddHandles.length; + + var textNode = Ext.get(this.textNode); + for (var i = 0; i < textNode.dom.childNodes.length; ++i) { + if (textNode.dom.childNodes[i].nodeName === 'SPAN') { + ddHandles[handlesIndex++] = textNode.dom.childNodes[i]; + if (textNode.dom.childNodes[i].childNodes) { + ddHandles[handlesIndex++] = textNode.dom.childNodes[i].childNodes[0]; + } + } + } + + return ddHandles; + }, + + /** + * Only set the onOver class if we are not in dragging mode + * + * @return {void} + */ + onOver: function() { + if (!this.node.ownerTree.dontSetOverClass) { + TYPO3.Components.PageTree.PageTreeNodeUI.superclass.onOver.apply(this, arguments); + } + } +}); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.PageTreeNodeUI', TYPO3.Components.PageTree.PageTreeNodeUI); diff --git a/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js b/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js deleted file mode 100644 index e4941d313a5c622f28928a6e83ed1896c461927c..0000000000000000000000000000000000000000 --- a/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************** -* Copyright notice -* -* (c) 2011 Stanislas Rolland <typo3@sjbr.ca> -* All rights reserved -* -* This script is part of the TYPO3 project. The TYPO3 project is -* free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* The GNU General Public License can be found at -* http://www.gnu.org/copyleft/gpl.html. -* A copy is found in the textfile GPL.txt and important notices to the license -* from the author is found in LICENSE.txt distributed with these scripts. -* -* -* This script is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* This copyright notice MUST APPEAR in all copies of the script! -***************************************************************/ -/** - * @class TYPO3.Components.PageTree.Column - * - * Page tree column - * - * @namespace TYPO3.Components.PageTree - * @extends Ext.grid.column.Column - * @author Stanislas Rolland <typo3@sjbr.ca> - */ -Ext.define('TYPO3.Components.PageTree.Column', { - extend: 'Ext.grid.column.Column', - alias: 'widget.pagetreecolumn', - - /** - * Render a row of the page tree adding relevant icons depending on record depth and record type - * - */ - initComponent: function() { - var origRenderer = this.renderer || this.defaultRenderer, - origScope = this.scope || window; - - this.renderer = function(value, metaData, record, rowIdx, colIdx, store, view) { - var buf = [], - format = Ext.String.format, - depth = record.getDepth(), - treePrefix = Ext.baseCSSPrefix + 'tree-', - elbowPrefix = treePrefix + 'elbow-', - expanderCls = treePrefix + 'expander', - imgText = '<img src="{1}" class="{0}" />', - checkboxText = '<input type="button" role="checkbox" class="{0}" {1} />', - formattedValue = origRenderer.apply(origScope, arguments), - checked = null, - href = record.getNodeData('href'), - target = record.getNodeData('hrefTarget'), - cls = record.getNodeData('cls'), - readableRootline = record.getNodeData('readableRootline'); - - while (record) { - if (!record.isRoot() || (record.isRoot() && view.rootVisible)) { - if (record.getDepth() === depth) { - // Add TYPO3 sprite icon code - buf.unshift(record.getNodeData('spriteIconCode')); - // Check if nodeData['checked'] is boolean - checked = record.getNodeData('checked'); - if (Ext.isBoolean(checked)) { - buf.unshift(format( - checkboxText, - (treePrefix + 'checkbox') + (checked ? ' ' + treePrefix + 'checkbox-checked' : ''), - checked ? 'aria-checked="true"' : '' - )); - if (checked) { - metaData.tdCls += (' ' + treePrefix + 'checked'); - } - } - // Remove +/arrow from the TYPO3 root - if (record.getDepth() === 1) { - buf.unshift(format(imgText, (elbowPrefix + 'empty'), Ext.BLANK_IMAGE_URL)); - } else if (record.isLast()) { - if (record.isExpandable()) { - buf.unshift(format(imgText, (elbowPrefix + 'end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); - } else { - buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL)); - } - } else { - if (record.isExpandable()) { - buf.unshift(format(imgText, (elbowPrefix + 'plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); - } else { - buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL)); - } - } - } else { - // Remove elbow from the TYPO3 root - if (record.isLast() || record.getDepth() === 1) { - buf.unshift(format(imgText, (elbowPrefix + 'empty'), Ext.BLANK_IMAGE_URL)); - } else if (record.getDepth() !== 1) { - buf.unshift(format(imgText, (elbowPrefix + 'line'), Ext.BLANK_IMAGE_URL)); - } - } - } - record = record.parentNode; - } - if (href) { - buf.push('<a href="', href, '" target="', target, '">', formattedValue, '</a>'); - } else { - buf.push(formattedValue); - } - if (cls) { - metaData.tdCls += ' ' + cls; - } - // Show the readable rootline above the user mounts - if (readableRootline !== '') { - buf.unshift('<div class="x-tree-node-readableRootline">' + readableRootline + '</div>'); - } - return buf.join(''); - }; - this.callParent(arguments); - }, - - defaultRenderer: function (value) { - return value; - }, - /** - * Create editing field with correct margin left - * - */ - getEditor: function (record, defaultField) { - var depth = parseInt(record.getDepth()), - marginLeft = 51; - if (depth > 2) { - marginLeft += (depth-2)*16; - } - var field = this.field; - if (!field && this.editor) { - field = this.editor; - delete this.editor; - } - - if (!field && defaultField) { - field = defaultField; - } - - if (field) { - if (Ext.isString(field)) { - field = { xtype: field }; - } - if (field.isFormField) { - field.setFieldStyle({ - marginLeft: marginLeft + 'px' - }); - } - if (Ext.isObject(field) && !field.isFormField) { - field = Ext.ComponentManager.create(field, 'textfield'); - this.field = field; - } - Ext.apply(field, { - name: this.dataIndex - }); - return field; - } - } -}); diff --git a/t3lib/js/extjs/components/pagetree/javascript/toppanel.js b/t3lib/js/extjs/components/pagetree/javascript/toppanel.js index 04d28f9749a4e34dc861e1f61198edfc21e0e74e..f80299d8e9a3ec0c7dede09757fb1b996b71d9b3 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/toppanel.js +++ b/t3lib/js/extjs/components/pagetree/javascript/toppanel.js @@ -23,18 +23,18 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.TopPanel * * Top Panel * * @namespace TYPO3.Components.PageTree - * @extends Ext.panel.Panel + * @extends Ext.Panel * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.TopPanel', { - extend: 'Ext.panel.Panel', - +TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, { /** * Component Id * @@ -43,36 +43,18 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { id: 'typo3-pagetree-topPanel', /** - * Toolbar Object + * Border * - * @type {Ext.Toolbar} + * @type {Boolean} */ - dockedItems: [{ - xtype: 'toolbar', - dock: 'top', - itemId: 'topToolbar' - }], + border: false, /** - * Panel CSS - * - * @type {String} - */ - cls: 'typo3-pagetree-topPanel', - - /** - * Body CSS - * - * @type {String} - */ - bodyCls: 'typo3-pagetree-topPanel-item', - - /** - * Layout + * Toolbar Object * - * @type {String} + * @type {Ext.Toolbar} */ - layout: 'anchor', + tbar: new Ext.Toolbar(), /** * Currently Clicked Toolbar Button @@ -81,10 +63,17 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { */ currentlyClickedButton: null, + /** + * Currently Shown Panel + * + * @type {Ext.Component} + */ + currentlyShownPanel: null, + /** * Filtering Indicator Item * - * @type {Ext.panel.Panel} + * @type {Ext.Panel} */ filteringIndicator: null, @@ -129,20 +118,38 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ initComponent: function() { - this.callParent(); - // Node insertion feature + this.currentlyShownPanel = new Ext.Panel({ + id: this.id + '-defaultPanel', + cls: this.id + '-item' + }); + this.items = [this.currentlyShownPanel]; + + TYPO3.Components.PageTree.TopPanel.superclass.initComponent.apply(this, arguments); + this.addDragDropNodeInsertionFeature(); - // Filter feature + if (!TYPO3.Components.PageTree.Configuration.hideFilter || TYPO3.Components.PageTree.Configuration.hideFilter === '0' ) { this.addFilterFeature(); } - // Refresh feature - this.getDockedComponent('topToolbar').add({xtype: 'tbfill'}); + + this.getTopToolbar().addItem({xtype: 'tbfill'}); this.addRefreshTreeFeature(); }, + /** + * Returns a custom button template to fix some nasty webkit issues + * by removing some useless wrapping html code + * + * @return {void} + */ + getButtonTemplate: function() { + return new Ext.Template( + '<div id="{4}" class="x-btn {3}"><button type="{0}""> </button></div>' + ); + }, + /** * Adds a button to the components toolbar with a related component * @@ -151,6 +158,7 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ addButton: function(button, connectedWidget) { + button.template = this.getButtonTemplate(); if (!button.hasListener('click')) { button.on('click', this.topbarButtonCallback); } @@ -161,7 +169,7 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { this.add(connectedWidget); } - this.getDockedComponent('topToolbar').add(button); + this.getTopToolbar().addItem(button); this.doLayout(); }, @@ -174,45 +182,44 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { topbarButtonCallback: function() { var topPanel = this.ownerCt.ownerCt; + topPanel.currentlyShownPanel.hide(); if (topPanel.currentlyClickedButton) { topPanel.currentlyClickedButton.toggle(false); - if (topPanel.currentlyClickedButton.connectedWidget) { - topPanel.currentlyClickedButton.connectedWidget.hide(); - } } if (topPanel.currentlyClickedButton === this) { topPanel.currentlyClickedButton = null; - if (this.connectedWidget) { - this.connectedWidget.hide(); - } + topPanel.currentlyShownPanel = topPanel.get(topPanel.id + '-defaultPanel'); } else { this.toggle(true); topPanel.currentlyClickedButton = this; - if (this.connectedWidget) { - this.connectedWidget.show(); - } + topPanel.currentlyShownPanel = this.connectedWidget; } + + topPanel.currentlyShownPanel.show(); }, /** * Loads the filtering tree nodes with the given search word * - * @param {Ext.form.field.Trigger} textField + * @param {Ext.form.TextField} textField * @return {void} */ - createFilterTree: function (textField) { + createFilterTree: function(textField) { var searchWord = textField.getValue(); var isNumber = TYPO3.Utility.isNumber(searchWord); var hasMinLength = (searchWord.length > 2 || searchWord.length <= 0); if ((!hasMinLength && !isNumber) || searchWord === this.filteringTree.searchWord) { return; } + this.filteringTree.searchWord = searchWord; if (this.filteringTree.searchWord === '') { + this.app.activeTree = this.tree; + textField.setHideTrigger(true); - this.app.setTree(this.tree); - this.tree.refreshTree(function() { + this.filteringTree.hide(); + this.tree.show().refreshTree(function() { textField.focus(false, 500); }, this); @@ -222,6 +229,7 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { } } else { var selectedNode = this.app.getSelected(); + this.app.activeTree = this.filteringTree; if (!this.filteringIndicator) { this.filteringIndicator = this.app.addIndicator( @@ -229,20 +237,20 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { ); } + textField.setHideTrigger(false); + this.tree.hide(); this.app.ownerCt.getEl().mask('', 'x-mask-loading-message'); - this.app.ownerCt.getEl().addCls('t3-mask-loading'); - this.app.setTree(this.filteringTree); - this.filteringTree.refreshTree(function() { + this.app.ownerCt.getEl().addClass('t3-mask-loading'); + this.filteringTree.show().refreshTree(function() { if (selectedNode) { - this.app.select(selectedNode.getNodeData('id')); + this.app.select(selectedNode.attributes.nodeData.id, false); } - this.app.ownerCt.getEl().unmask(); - textField.setHideTrigger(false); - textField.triggerWrap.setWidth(0); - this.forceComponentLayout(); textField.focus(); + this.app.ownerCt.getEl().unmask(); }, this); } + + this.doLayout(); }, /** @@ -253,27 +261,26 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { */ createIndicatorItem: function(textField) { return { - id: this.app.getId() + '-indicatorBar-filter', - cls: this.app.getId() + '-indicatorBar-item', - renderData: { - appId: this.app.getId(), - spriteIconCls: TYPO3.Components.PageTree.Sprites.Info, - label: TYPO3.Components.PageTree.LLL.activeFilterMode - }, - renderTpl: Ext.create('Ext.XTemplate', - '<p>', - '<span id="{appId}-indicatorBar-filter-info" class="{appId}-indicatorBar-item-leftIcon {spriteIconCls}"> </span>', - ' {label} ', - '<span id="{appId}-indicatorBar-filter-clear" class="{appId}-indicatorBar-item-rightIcon">X</span>', - '</p>' - ), + border: false, + id: this.app.id + '-indicatorBar-filter', + cls: this.app.id + '-indicatorBar-item', + html: '<p>' + + '<span id="' + this.app.id + '-indicatorBar-filter-info' + '" ' + + 'class="' + this.app.id + '-indicatorBar-item-leftIcon ' + + TYPO3.Components.PageTree.Sprites.Info + '"> ' + + '</span>' + + '<span id="' + this.app.id + '-indicatorBar-filter-clear' + '" ' + + 'class="' + this.app.id + '-indicatorBar-item-rightIcon ' + '">X' + + '</span>' + + TYPO3.Components.PageTree.LLL.activeFilterMode + + '</p>', filteringTree: this.filteringTree, listeners: { afterrender: { scope: this, - fn: function(component) { - var element = Ext.get(this.app.getId() + '-indicatorBar-filter-clear'); + fn: function() { + var element = Ext.fly(this.app.id + '-indicatorBar-filter-clear'); element.on('click', function() { textField.setValue(''); this.createFilterTree(textField); @@ -290,65 +297,71 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ addFilterFeature: function() { - var topPanelButton = Ext.create('Ext.button.Button', { - id: this.getId() + '-button-filter', - cls: this.getId() + '-button', + var topPanelButton = new Ext.Button({ + id: this.id + '-button-filter', + cls: this.id + '-button', iconCls: TYPO3.Components.PageTree.Sprites.Filter, tooltip: TYPO3.Components.PageTree.LLL.buttonFilter }); - var textField = Ext.create('Ext.form.field.Trigger', { - id: this.getId() + '-filter', - border: false, + var textField = new Ext.form.TriggerField({ + id: this.id + '-filter', enableKeyEvents: true, - labelWidth: 0, - triggerCls: TYPO3.Components.PageTree.Sprites.InputClear, + triggerClass: TYPO3.Components.PageTree.Sprites.InputClear, value: TYPO3.Components.PageTree.LLL.searchTermInfo, listeners: { blur: { - fn: function (textField) { + scope: this, + fn:function(textField) { if (textField.getValue() === '') { textField.setValue(TYPO3.Components.PageTree.LLL.searchTermInfo); - textField.inputEl.addCls(this.getId() + '-filter-defaultText'); + textField.addClass(this.id + '-filter-defaultText'); } - }, - scope: this + } }, focus: { - fn: function (textField) { + scope: this, + fn: function(textField) { if (textField.getValue() === TYPO3.Components.PageTree.LLL.searchTermInfo) { textField.setValue(''); - textField.inputEl.removeCls(this.getId() + '-filter-defaultText'); + textField.removeClass(this.id + '-filter-defaultText'); } - }, - scope: this + } }, keydown: { fn: this.createFilterTree, scope: this, buffer: 1000 - }, - - show: { - fn: function () { this.focus(); } } } }); textField.setHideTrigger(true); - textField.onTriggerClick = Ext.Function.bind( - function (textField) { - textField.setValue(''); - this.createFilterTree(textField); - }, - this, - [textField] - ); + textField.onTriggerClick = function() { + textField.setValue(''); + this.createFilterTree(textField); + }.createDelegate(this); - this.addButton(topPanelButton, textField); + var topPanelWidget = new Ext.Panel({ + border: false, + id: this.id + '-filterWrap', + cls: this.id + '-item', + items: [textField], + + listeners: { + show: { + scope: this, + fn: function(panel) { + panel.get(this.id + '-filter').focus(); + } + } + } + }); + + this.addButton(topPanelButton, topPanelWidget); }, /** @@ -357,32 +370,28 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ createNewNodeToolbar: function() { - this.dragZone = Ext.create('Ext.dd.DragZone', this.getEl(), { + this.dragZone = new Ext.dd.DragZone(this.getEl(), { ddGroup: this.ownerCt.ddGroup, topPanel: this.ownerCt, endDrag: function() { - this.topPanel.app.getTree().dontSetOverClass = false; + this.topPanel.app.activeTree.dontSetOverClass = false; }, - getDragData: function (event) { + getDragData: function(event) { this.proxyElement = document.createElement('div'); - var clickedButton = event.getTarget('.x-btn'); - if (clickedButton) { - var node = Ext.getCmp(clickedButton.id); - } - if (node) { - node.shouldCreateNewNode = true; - } + + var node = Ext.getCmp(event.getTarget('.x-btn').id); + node.shouldCreateNewNode = true; + return { ddel: this.proxyElement, - item: node, - records: [node] + item: node } }, onInitDrag: function() { - this.topPanel.app.getTree().dontSetOverClass = true; + this.topPanel.app.activeTree.dontSetOverClass = true; var clickedButton = this.dragData.item; var cls = clickedButton.initialConfig.iconCls; @@ -396,18 +405,18 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { } }); - // Listens on the escape key to stop the dragging - Ext.create('Ext.util.KeyMap', document, { + // listens on the escape key to stop the dragging + (new Ext.KeyMap(document, { key: Ext.EventObject.ESC, scope: this, buffer: 250, fn: function(event) { if (this.dragZone.dragging) { - Ext.dd.DragDropManager.stopDrag(event); + Ext.dd.DragDropMgr.stopDrag(event); this.dragZone.onInvalidDrop(event); } } - }, 'keydown'); + }, 'keydown')); }, /** @@ -416,16 +425,11 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ addDragDropNodeInsertionFeature: function() { - var topPanelButton = Ext.create('Ext.button.Button', { - id: this.getId() + '-button-newNode', - cls: this.getId() + '-button', - iconCls: TYPO3.Components.PageTree.Sprites.NewNode, - tooltip: TYPO3.Components.PageTree.LLL.buttonNewNode - }); + var newNodeToolbar = new Ext.Toolbar({ + border: false, + id: this.id + '-item-newNode', + cls: this.id + '-item', - var newNodeToolbar = Ext.create('Ext.toolbar.Toolbar', { - id: this.getId() + '-item-newNode', - cls: this.getId() + '-item', listeners: { render: { fn: this.createNewNodeToolbar @@ -434,10 +438,20 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { }); this.dataProvider.getNodeTypes(function(response) { - newNodeToolbar.add(response); + for (var i = 0; i < response.length; ++i) { + response[i].template = this.getButtonTemplate(); + newNodeToolbar.addItem(response[i]); + } newNodeToolbar.doLayout(); }, this); + var topPanelButton = new Ext.Button({ + id: this.id + '-button-newNode', + cls: this.id + '-button', + iconCls: TYPO3.Components.PageTree.Sprites.NewNode, + tooltip: TYPO3.Components.PageTree.LLL.buttonNewNode + }); + this.addButton(topPanelButton, newNodeToolbar); }, @@ -447,9 +461,9 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { * @return {void} */ addRefreshTreeFeature: function() { - var topPanelButton = Ext.create('Ext.button.Button', { - id: this.getId() + '-button-refresh', - cls: this.getId() + '-button', + var topPanelButton = new Ext.Button({ + id: this.id + '-button-refresh', + cls: this.id + '-button', iconCls: TYPO3.Components.PageTree.Sprites.Refresh, tooltip: TYPO3.Components.PageTree.LLL.buttonRefresh, @@ -457,7 +471,7 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { click: { scope: this, fn: function() { - this.app.getTree().refreshTree(); + this.app.activeTree.refreshTree(); } } } @@ -466,3 +480,6 @@ Ext.define('TYPO3.Components.PageTree.TopPanel', { this.addButton(topPanelButton); } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.TopPanel', TYPO3.Components.PageTree.TopPanel); diff --git a/t3lib/js/extjs/components/pagetree/javascript/tree.js b/t3lib/js/extjs/components/pagetree/javascript/tree.js index fe61c6a8e946c05a169daaacea432fdec7604f6c..7319b02472c735c5b349395d1c92b273e4628d0b 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/tree.js +++ b/t3lib/js/extjs/components/pagetree/javascript/tree.js @@ -23,145 +23,43 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.Tree * * Generic Tree Panel * * @namespace TYPO3.Components.PageTree - * @extends Ext.tree.Panel + * @extends Ext.tree.TreePanel * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.Model', { - extend: 'Ext.data.Model', - fields: [{ - name: 'id', - type: 'string', - defaultValue: 'root' - },{ - name: 'realId', - type: 'string' - },{ - name: 'text', - type: 'string' - },{ - name: 'depth', - type: 'int' - },{ - name: 'root', - type: 'boolean' - },{ - name: 'leaf', - type: 'boolean' - },{ - name: 'parentId', - type: 'string' - },{ - name: 'isFirst', - type: 'boolean' - },{ - name: 'index', - type: 'int' - },{ - name: 'isLast', - type: 'boolean' - },{ - name: 'isExpandable', - type: 'boolean' - },{ - name: 'isInsertedNode', - type: 'boolean' - },{ - name: 'nodeData', - type: 'object' - }], - hasMany: { - name: 'children', - associationKey: 'children', - model: 'TYPO3.Components.PageTree.Model' - }, - // Set method for nodeData fields - setNodeData: function (field, value) { - var nodeData = this.get('nodeData'); - nodeData[field] = value; - this.set('nodeData', Ext.merge(this.get('nodeData'), nodeData)); - }, - // Get method for nodeData fields - getNodeData: function (field) { - return this.get('nodeData')[field]; - } -}); -Ext.define('TYPO3.Components.PageTree.Tree', { - extend: 'Ext.tree.Panel', - /** - * Use extended stateful mixin - * - * @type {Object} - */ - mixins: { - state: 'Ext.ux.state.TreePanel' - }, - - /** - * View configuration - * - * @type {Object} - */ - viewConfig: { - autoScroll: false, - border: false, - toggleOnDblClick: false - }, - - /** - * Columns - * - * @type {TYPO3.Components.PageTree.Column}[] - */ - columns: [{ - xtype: 'pagetreecolumn', - dataIndex: 'text', - flex: 1, - editor: { - xtype: 'textfield', - allowBlank: false - } - }], - - /** - * Header - * - * @type {Boolean} - */ - hideHeaders: true, - preventHeader: true, - +TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, { /** * Border * * @type {Boolean} */ - autoScroll: false, border: false, /** - * Body css + * Indicates if the root node is visible * - * @type {String} + * @type {Boolean} */ - bodyCls: 'typo3-pagetree', + rootVisible: false, /** - * Indicates if the root node is visible + * Tree Editor Instance (Inline Edit) * - * @type {Boolean} + * @type {TYPO3.Components.PageTree.TreeEditor} */ - rootVisible: false, + treeEditor: null, /** * Currently Selected Node * - * @type {TYPO3.Components.PageTree.Model} + * @type {Ext.tree.TreeNode} */ currentSelectedNode: null, @@ -180,18 +78,18 @@ Ext.define('TYPO3.Components.PageTree.Tree', { ddGroup: '', /** - * Id of deletionDropZone + * Indicates if the label should be editable * - * @cfg {String} + * @cfg {Boolean} */ - deletionDropZoneId: '', + labelEdit: true, /** - * Indicates if the label should be editable + * User Interface Provider * - * @cfg {Boolean} + * @cfg {Ext.tree.TreeNodeUI} */ - labelEdit: true, + uiProvider: null, /** * Data Provider @@ -205,7 +103,7 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * * @cfg {Object} */ - commandProvider: null, + commandProvider : null, /** * Context menu provider @@ -215,18 +113,18 @@ Ext.define('TYPO3.Components.PageTree.Tree', { contextMenuProvider: null, /** - * Main applicaton + * Id of the deletion drop zone if any * - * @cfg {TYPO3.Components.PageTree.App} + * @cfg {String} */ - app: null, + deletionDropZoneId: '', /** - * Page Tree Store + * Main applicaton * - * @type {Object} + * @cfg {TYPO3.Components.PageTree.App} */ - store: null, + app: null, /** * Root Node Configuration @@ -241,10 +139,17 @@ Ext.define('TYPO3.Components.PageTree.Tree', { } }, + /** + * Indicator if the control key is pressed + * + * @type {Boolean} + */ + isControlPressed: false, + /** * Context Node * - * @type {TYPO3.Components.PageTree.Model} + * @type {Ext.tree.TreeNode} */ t3ContextNode: null, @@ -253,52 +158,68 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * * @type {Object} */ - t3ContextInfo: { + t3ContextInfo: { inCopyMode: false, inCutMode: false }, /** - * Number of clicks to ignore for the label edit on dblclick feature - * Will be set to 2 by the tree editor + * Registered clicks for the double click feature * * @type {int} */ - inhibitClicks: 0, + clicksRegistered: 0, /** - * Constructor - * Plugins are built by the parent constructor + * Indicator if the control key was pressed * - * @param {Object} config - * @return {void} + * @type {Boolean} */ - constructor: function (config) { - // Inline label editing feature - this.labelEdit = config.labelEdit || this.labelEdit; - if (this.labelEdit ) { - var plugins = config.plugins || []; - config.plugins = plugins.concat( - Ext.create('TYPO3.Components.PageTree.TreeEditor', { - clicksToEdit: 2, - pluginId: 'treeEditor' - }) - ); - } - // Drag & drop feature - if (this.enableDD) { - config.viewConfig = Ext.applyIf(config.viewConfig || {}, this.viewConfig); - var plugins = config.viewConfig.plugins || []; - config.viewConfig.plugins = plugins.concat( - Ext.create('TYPO3.Components.PageTree.plugin.TreeViewDragDrop', { - ddGroup: config.ddGroup, - pluginId: 'treeViewDragDrop' - }) - ); - config.viewConfig.allowCopy = true; + controlKeyPressed: false, + + /** + * Listeners + * + * Event handlers that handle click events and synchronizes the label edit, + * double click and single click events in a useful way. + */ + listeners: { + // single click handler that only triggers after a delay to let the double click event + // a possibility to be executed (needed for label edit) + click: { + fn: function(node, event) { + if (this.clicksRegistered === 2) { + this.clicksRegistered = 0; + event.stopEvent(); + return false; + } + + this.clicksRegistered = 0; + if (this.commandProvider.singleClick) { + this.commandProvider.singleClick(node, this); + } + }, + delay: 400 + }, + + // prevent the expanding / collapsing on double click + beforedblclick: { + fn: function() { + return false; + } + }, + + // prevents label edit on a selected node + beforeclick: { + fn: function(node, event) { + if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) { + node.fireEvent('click', node, event); + ++this.clicksRegistered; + return false; + } + ++this.clicksRegistered; + } } - // Call parent constructor - this.callParent([config]); }, /** @@ -306,74 +227,28 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * * @return {void} */ - initComponent: function () { - // Add the tree store - this.addStore(); - // Add single click handler that only triggers after a delay to let the double click event - // a possibility to be executed (needed for label edit) - this.addListener('itemclick', this.onItemSingleClick, null, { delay: 400 }); - // Init component - this.callParent(); - // Drag & drop feature + initComponent: function() { + if (!this.uiProvider) { + this.uiProvider = TYPO3.Components.PageTree.PageTreeNodeUI; + } + Ext.dd.DragDropMgr.useCache = false; + this.root = new Ext.tree.AsyncTreeNode(this.rootNodeConfig); + this.addTreeLoader(); + + if (this.labelEdit) { + this.enableInlineEditor(); + } + if (this.enableDD) { - this.getView().addListener('afterrender', this.enableDragAndDrop, this); + this.dragConfig = {ddGroup: this.ddGroup}; + this.enableDragAndDrop(); } - // Context menu feature + if (this.contextMenuProvider) { this.enableContextMenu(); } - }, - - /** - * Adds the store to the tree - * - * @return {void} - */ - addStore: function () { - this.store = Ext.data.StoreManager.lookup(this.getId() + 'PageTreeStore'); - if (!this.store) { - this.store = Ext.create('Ext.data.TreeStore', { - clearOnLoad: false, - listeners: { - // Remove nodes and add params to read operation - beforeload: { - fn: function (store, operation, options) { - if (operation.node) { - var node = operation.node; - node.removeAll(); - node.commit(); - operation.params = { - nodeId: node.getNodeData('id'), - nodeData: node.get('nodeData') - - }; - } - } - }, - // Restore state on initial load - load: { - fn: function (store, node, records, successful) { - if (successful) { - this.restoreState(); - } - }, - scope: this - } - }, - model: 'TYPO3.Components.PageTree.Model', - nodeParam: 'nodeId', - proxy: { - type: 'direct', - directFn: this.treeDataProvider.getNextTreeLevel, - paramOrder: ['nodeId', 'nodeData'], - reader: { - type: 'json' - } - }, - root: this.rootNodeConfig, - storeId: this.getId() + 'PageTreeStore' - }); - } + + TYPO3.Components.PageTree.Tree.superclass.initComponent.apply(this, arguments); }, /** @@ -383,9 +258,9 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * @param {Object} scope * return {void} */ - refreshTree: function (callback, scope) { - // Remove readable rootline elements while refreshing - if (!this.store.isLoading()) { + refreshTree: function(callback, scope) { + // remove readable rootline elements while refreshing + if (!this.inRefreshingMode) { var rootlineElements = Ext.select('.x-tree-node-readableRootline'); if (rootlineElements) { rootlineElements.each(function(element) { @@ -393,54 +268,70 @@ Ext.define('TYPO3.Components.PageTree.Tree', { }); } } - this.refreshNode(this.getRootNode(), callback, scope); + + this.refreshNode(this.root, callback, scope); }, /** * Refreshes a given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {Function} callback * @param {Object} scope * return {void} */ - refreshNode: function (node, callback, scope) { - this.store.load({ - node: node, - callback: callback || Ext.emptyFn, - scope: scope || this - }); + refreshNode: function(node, callback, scope) { + if (this.inRefreshingMode) { + return; + } + + scope = scope || node; + this.inRefreshingMode = true; + var loadCallback = function(node) { + node.ownerTree.inRefreshingMode = false; + if (node.ownerTree.restoreState) { + node.ownerTree.restoreState(node.getPath()); + } + }; + + if (callback) { + loadCallback = callback.createSequence(loadCallback); + } + + this.getLoader().load(node, loadCallback, scope); }, /** - * Handles singe click on tree item + * Adds a tree loader implementation that uses the directFn feature * - * return {Boolean} + * return {void} */ - onItemSingleClick: function (view, node, item, index, event) { - var tree = view.panel; - // Check if the tree editor was triggered by dblclick - // If so, stop the next two clicks - if (tree.inhibitClicks) { - --tree.inhibitClicks; - event.stopEvent(); - return false; - } + addTreeLoader: function() { + this.loader = new Ext.tree.TreeLoader({ + directFn: this.treeDataProvider.getNextTreeLevel, + paramOrder: 'nodeId,attributes', + nodeParameter: 'nodeId', + baseAttrs: { + uiProvider: this.uiProvider + }, + + // an id can never be zero in ExtJS, but this is needed + // for the root line feature or it will never be working! + createNode: function(attr) { + if (attr.id == 0) { + attr.id = 'siteRootNode'; + } - if (tree.commandProvider.singleClick) { - tree.commandProvider.singleClick(node, tree); - } - // Fire the context menu on a single click on the node icon (Beware of drag&drop!) - if (!TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu - || TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu === '0' - ) { - var target = event.getTarget('span.t3-icon-apps-pagetree'); - if (target) { - view.fireEvent('itemcontextmenu', view, node, item, index, event); - event.stopEvent(); + return Ext.tree.TreeLoader.prototype.createNode.call(this, attr); + }, + + listeners: { + beforeload: function(treeLoader, node) { + treeLoader.baseParams.nodeId = node.id; + treeLoader.baseParams.attributes = node.attributes.nodeData; + } } - } - return true; + }); }, /** @@ -449,33 +340,58 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * return {void} */ enableContextMenu: function() { - this.contextMenu = Ext.create('TYPO3.Components.PageTree.ContextMenu', { pageTree: this }); - this.getView().on('itemcontextmenu', function (view, node, item, index, event) { - view.panel.openContextMenu(view, node, item, index, event); + this.contextMenu = new TYPO3.Components.PageTree.ContextMenu(); + + this.on('contextmenu', function(node, event) { + this.openContextMenu(node, event); }); }, /** * Open a context menu for the given node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {Ext.EventObject} event * return {void} */ - openContextMenu: function(view, node, item, index, event) { - var tree = view.panel; - node.setNodeData('t3ContextInfo', tree.t3ContextInfo); - tree.contextMenuProvider.getActionsForNodeArray( - node.get('nodeData'), - function (configuration) { - tree.contextMenu.removeAll(); - tree.contextMenu.fill(node, tree, configuration); - if (tree.contextMenu.items.length) { - tree.contextMenu.showAt(event.getXY()); + openContextMenu: function(node, event) { + var attributes = Ext.apply(node.attributes.nodeData, { + t3ContextInfo: node.ownerTree.t3ContextInfo + }); + + this.contextMenuProvider.getActionsForNodeArray( + attributes, + function(configuration) { + this.contextMenu.removeAll(); + this.contextMenu.fill(node, this, configuration); + if (this.contextMenu.items.length) { + this.contextMenu.showAt(event.getXY()); + } - } + }, + this ); - event.stopEvent(); + }, + + /** + * Initialize the inline editor for the given tree. + * + * @return {void} + */ + enableInlineEditor: function() { + this.treeEditor = new TYPO3.Components.PageTree.TreeEditor(this); + }, + + /** + * Triggers the editing of the node if the tree editor is available + * + * @param {Ext.tree.TreeNode} node + * @return {void} + */ + triggerEdit: function(node) { + if (this.treeEditor) { + this.treeEditor.triggerEdit(node); + } }, /** @@ -484,144 +400,208 @@ Ext.define('TYPO3.Components.PageTree.Tree', { * return {void} */ enableDragAndDrop: function() { - var view = this.getView(); - var dragZone = view.getPlugin('treeViewDragDrop').dragZone; - - // Show drop zone before drag, otherwise the proxy is never notified - dragZone.onBeforeDrag = Ext.Function.bind(this.startDeletionDropZone, view); - // Hide the drop zone after the drag completes - dragZone.onMouseUp = Ext.Function.bind(this.stopDeletionDropZone, view); - dragZone.endDrag = Ext.Function.bind(this.stopDeletionDropZone, view); - dragZone.afterInvalidDrop = Ext.Function.bind(this.stopDeletionDropZone, view, [true]); - - // Node is moved - this.on('itemmove', this.moveNode, this); - - // New node is created/copied - view.on('beforedrop', this.beforeDropNode, this); - view.on('drop', this.dropNode, this); + // init proxy element + this.on('startdrag', this.initDd, this); + this.on('enddrag', this.stopDd, this); + + // node is moved + this.on('movenode', this.moveNode, this); + + // new node is created/copied + this.on('beforenodedrop', this.beforeDropNode, this); + this.on('nodedrop', this.dropNode, this); + + // listens on the ctrl key to toggle the copy mode + (new Ext.KeyMap(document, { + key: Ext.EventObject.CONTROL, + scope: this, + buffer: 250, + fn: function() { + if (!this.controlKeyPressed && this.dragZone.dragging && this.copyHint) { + if (this.shouldCopyNode) { + this.copyHint.show(); + } else { + this.copyHint.hide(); + } + + this.shouldCopyNode = !this.shouldCopyNode; + this.dragZone.proxy.el.toggleClass('typo3-pagetree-copy'); + } + this.controlKeyPressed = true; + } + }, 'keydown')); + + (new Ext.KeyMap(document, { + key: Ext.EventObject.CONTROL, + scope: this, + fn: function() { + this.controlKeyPressed = false; + } + }, 'keyup')); + + // listens on the escape key to stop the dragging + (new Ext.KeyMap(document, { + key: Ext.EventObject.ESC, + scope: this, + buffer: 250, + fn: function(event) { + if (this.dragZone.dragging) { + Ext.dd.DragDropMgr.stopDrag(event); + this.dragZone.onInvalidDrop(event); + } + } + }, 'keydown')); }, /** - * Enables the deletion drop zone if configured + * Disables the deletion drop zone if configured * * @return {void} */ - startDeletionDropZone: function (dragData, event) { - var view = dragData.view, - tree = view.panel, - node = view.getRecord(dragData.item), - nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable()); - var tree = this.panel; - if (tree.deletionDropZoneId && + stopDd: function() { + if (this.deletionDropZoneId) { + Ext.getCmp(this.deletionDropZoneId).hide(); + this.app.doLayout(); + } + }, + + /** + * Enables the deletion drop zone if configured. Also it creates the + * shown dd proxy element. + * + * @param {TYPO3.Components.PageTree.Tree} treePanel + * @param {Ext.tree.TreeNode} node + * @return {void} + */ + initDd: function(treePanel, node) { + var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable()); + if (this.deletionDropZoneId && (!nodeHasChildNodes || (nodeHasChildNodes && TYPO3.Components.PageTree.Configuration.canDeleteRecursivly) )) { - Ext.getCmp(tree.deletionDropZoneId).show(); + Ext.getCmp(this.deletionDropZoneId).show(); + this.app.doLayout(); } + this.initDDProxyElement(); }, /** - * Disables the deletion drop zone if configured + * Adds the copy hint to the proxy element * * @return {void} */ - stopDeletionDropZone: function (forceStop) { - var tree = this.panel; - if (tree.deletionDropZoneId && (!this.getPlugin('treeViewDragDrop').dragZone.dragging || forceStop)) { - Ext.getCmp(tree.deletionDropZoneId).hide(); - } + initDDProxyElement: function() { + this.shouldCopyNode = false; + this.copyHint = new Ext.Element(document.createElement('div')).addClass(this.id + '-copy'); + this.copyHint.dom.appendChild(document.createTextNode(TYPO3.Components.PageTree.LLL.copyHint)); + this.copyHint.setVisibilityMode(Ext.Element.DISPLAY); + this.dragZone.proxy.el.shadow = false; + this.dragZone.proxy.ghost.dom.appendChild(this.copyHint.dom); }, /** - * Creates a place holder node when a new node is about to be dropped + * Creates a Fake Node * - * @param {HTMLElement node} node - * @param {object} dragData - * @param {TYPO3.Components.PageTree.Model} overNode - * @param {string} dropPosition - * @return {boolean} + * This must be done to prevent the calling of the moveNode event. + * + * @param {object} dragElement */ - beforeDropNode: function (node, dragData, overNode, dropPosition) { - if (dragData && dragData.item && dragData.item.shouldCreateNewNode) { - // Inserting a new node of the type that was selected in the top panel - this.t3ContextInfo.serverNodeType = dragData.item.nodeType; - dragData.dropNode = Ext.create('TYPO3.Components.PageTree.Model', { + beforeDropNode: function(dragElement) { + if (dragElement.data && dragElement.data.item && dragElement.data.item.shouldCreateNewNode) { + this.t3ContextInfo.serverNodeType = dragElement.data.item.nodeType; + dragElement.dropNode = new Ext.tree.TreeNode({ text: TYPO3.Components.PageTree.LLL.fakeNodeHint, leaf: true, isInsertedNode: true }); - dragData.records = [dragData.dropNode]; + + // fix incorrect cancel value + dragElement.cancel = false; + + } else if (this.shouldCopyNode) { + dragElement.dropNode.ui.onOut(); + var attributes = dragElement.dropNode.attributes; + attributes.isCopiedNode = true; + attributes.id = 'fakeNode'; + dragElement.dropNode = new Ext.tree.TreeNode(attributes); } + return true; }, /** - * Handle the copy and insert events + * Differentiate between the copy and insert event * - * @param {HTMLElement node} node - * @param {object} dragData - * @param {TYPO3.Components.PageTree.Model} overNode - * @param {string} dropPosition + * @param {Ext.tree.TreeDropZone} dragElement * return {void} */ - dropNode: function (node, dragData, overNode, dropPosition) { - if (dragData.dropNode) { - if (dragData.dropNode.get('isInsertedNode')) { - dragData.dropNode.set('isInsertedNode', false); - this.insertNode(dragData.dropNode); - } - } else if (dragData.copy) { - this.copyNode(dragData.records[0]); + dropNode: function(dragElement) { + this.controlKeyPressed = false; + if (dragElement.dropNode.attributes.isInsertedNode) { + dragElement.dropNode.attributes.isInsertedNode = false; + this.insertNode(dragElement.dropNode); + } else if (dragElement.dropNode.attributes.isCopiedNode) { + dragElement.dropNode.attributes.isCopiedNode = false; + this.copyNode(dragElement.dropNode) } }, /** * Moves a node * - * @param {TYPO3.Components.PageTree.Model} movedNode - * @param {TYPO3.Components.PageTree.Model} oldParent - * @param {TYPO3.Components.PageTree.Model} newParent + * @param {TYPO3.Components.PageTree.Tree} tree + * @param {Ext.tree.TreeNode} movedNode + * @param {Ext.tree.TreeNode} oldParent + * @param {Ext.tree.TreeNode} newParent * @param {int} position * return {void} */ - moveNode: function (movedNode, oldParent, newParent, position) { - this.t3ContextNode = movedNode; + moveNode: function(tree, movedNode, oldParent, newParent, position) { + this.controlKeyPressed = false; + tree.t3ContextNode = movedNode; + if (position === 0) { - this.commandProvider.moveNodeToFirstChildOfDestination(newParent, this); + this.commandProvider.moveNodeToFirstChildOfDestination(newParent, tree); } else { var previousSiblingNode = newParent.childNodes[position - 1]; - this.commandProvider.moveNodeAfterDestination(previousSiblingNode, this); + this.commandProvider.moveNodeAfterDestination(previousSiblingNode, tree); } }, /** * Inserts a node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} movedNode * return {void} */ - insertNode: function (node) { - this.t3ContextNode = node.parentNode; - if (node.previousSibling) { - this.commandProvider.insertNodeAfterDestination(node, this); + insertNode: function(movedNode) { + this.t3ContextNode = movedNode.parentNode; + + movedNode.disable(); + if (movedNode.previousSibling) { + this.commandProvider.insertNodeAfterDestination(movedNode, this); } else { - this.commandProvider.insertNodeToFirstChildOfDestination(node, this); + this.commandProvider.insertNodeToFirstChildOfDestination(movedNode, this); } }, /** * Copies a node * - * @param {TYPO3.Components.PageTree.Model} movedNode + * @param {Ext.tree.TreeNode} movedNode * return {void} */ - copyNode: function (node) { - this.t3ContextNode = node; - if (node.previousSibling) { - this.commandProvider.copyNodeAfterDestination(node, this); + copyNode: function(movedNode) { + this.t3ContextNode = movedNode; + + movedNode.disable(); + if (movedNode.previousSibling) { + this.commandProvider.copyNodeAfterDestination(movedNode, this); } else { - this.commandProvider.copyNodeToFirstChildOfDestination(node, this); + this.commandProvider.copyNodeToFirstChildOfDestination(movedNode, this); } } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.Tree', TYPO3.Components.PageTree.Tree); diff --git a/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js b/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js deleted file mode 100644 index 2f4888ca9ffc77976915ab8180120f1bd2ac925f..0000000000000000000000000000000000000000 --- a/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************** -* Copyright notice -* -* (c) 2011 Stanislas Rolland <typo3@sjbr.ca> -* All rights reserved -* -* This script is part of the TYPO3 project. The TYPO3 project is -* free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* The GNU General Public License can be found at -* http://www.gnu.org/copyleft/gpl.html. -* A copy is found in the textfile GPL.txt and important notices to the license -* from the author is found in LICENSE.txt distributed with these scripts. -* -* -* This script is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* This copyright notice MUST APPEAR in all copies of the script! -***************************************************************/ -/** - * @class TYPO3.Components.PageTree.ViewDropZone - * - * handleNodeDrop method is modified in order to process copied nodes - * - * Based on ExtJS 4.0.7. - * Should be reviewed on ExtJS upgrade - * - * @namespace TYPO3.Components.PageTree - * @extends Ext.tree.ViewDropZone - * @author Stanislas Rolland <typo3@sjbr.ca> - */ -Ext.define('TYPO3.Components.PageTree.ViewDropZone', { - extend: 'Ext.tree.ViewDropZone', - - handleNodeDrop: function(data, targetNode, position) { - var me = this, - view = me.view, - parentNode = targetNode.parentNode, - store = view.getStore(), - recordDomNodes = [], - records, i, len, - insertionMethod, argList, - needTargetExpand, - transferData, - processDrop; - - if (data.copy) { - records = data.records; - data.records = []; - for (i = 0, len = records.length; i < len; i++) { - data.records.push(Ext.apply({}, records[i].data)); - } - } - - me.cancelExpand(); - - if (position == 'before') { - insertionMethod = parentNode.insertBefore; - argList = [null, targetNode]; - targetNode = parentNode; - } else if (position == 'after') { - if (targetNode.nextSibling) { - insertionMethod = parentNode.insertBefore; - argList = [null, targetNode.nextSibling]; - } else { - insertionMethod = parentNode.appendChild; - argList = [null]; - } - targetNode = parentNode; - } else { - if (!targetNode.isExpanded()) { - needTargetExpand = true; - } - insertionMethod = targetNode.appendChild; - argList = [null]; - } - - transferData = function() { - var node; - for (i = 0, len = data.records.length; i < len; i++) { - argList[0] = data.records[i]; - node = insertionMethod.apply(targetNode, argList); - // We need to update the records array in order to process the copied nodes in the drop event handler - data.records[i] = node; - - if (Ext.enableFx && me.dropHighlight) { - recordDomNodes.push(view.getNode(node)); - } - } - - if (Ext.enableFx && me.dropHighlight) { - Ext.Array.forEach(recordDomNodes, function(n) { - if (n) { - Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor); - } - }); - } - }; - - if (needTargetExpand) { - targetNode.expand(false, transferData); - } else { - transferData(); - } - } -}); \ No newline at end of file diff --git a/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js b/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js index 5daa34e2d79ec015ad0316cc427fe8cce03d1b52..0d12e7d526678b227e3039e4a31f56e3f38e3910 100644 --- a/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js +++ b/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js @@ -23,6 +23,8 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +Ext.namespace('TYPO3.Components.PageTree'); + /** * @class TYPO3.Components.PageTree.TreeEditor * @@ -30,46 +32,30 @@ * editable label. * * @namespace TYPO3.Components.PageTree - * @extends Ext.ux.tree.TreeEditing + * @extends Ext.tree.TreeEditor * @author Stefan Galinski <stefan.galinski@gmail.com> */ -Ext.define('TYPO3.Components.PageTree.TreeEditor', { - extend: 'Ext.grid.plugin.CellEditing', - alias: 'plugin.pagetreeeditor', - +TYPO3.Components.PageTree.TreeEditor = Ext.extend(Ext.tree.TreeEditor, { /** - * @override - * @private Collects all information necessary for any subclasses to perform their editing functions. - * @param record - * @param columnHeader - * @returns {Object} The editing context based upon the passed record and column + * Don't send any save events if the value wasn't changed + * + * @type {Boolean} */ - getEditingContext: function (record, columnHeader) { - var me = this, - grid = me.grid, - store = grid.store, - colIdx, - editor, - originalValue, - value; + ignoreNoChange: false, - if (Ext.isNumber(columnHeader)) { - colIdx = columnHeader; - columnHeader = grid.headerCt.getHeaderAtIndex(colIdx); - } else { - colIdx = columnHeader.getIndex(); - } + /** + * Edit delay + * + * @type {int} + */ + editDelay: 250, - return { - column: columnHeader, - colIdx: colIdx, - field: columnHeader.dataIndex, - grid: grid, - originalValue: record.getNodeData('editableText'), - record: record, - tree: grid - }; - }, + /** + * Indicates if an underlying shadow should be shown + * + * @type {Boolean} + */ + shadow: false, /** * Listeners @@ -77,66 +63,80 @@ Ext.define('TYPO3.Components.PageTree.TreeEditor', { * Handles the synchronization between the edited label and the shown label. */ listeners: { - beforeedit: { - fn: function (editEvent) { - var tree = editEvent.tree; - // Prevent editing the currently selected node - // Prevent editing if the node is not editable - if (editEvent.record == tree.currentSelectedNode || !editEvent.record.getNodeData('editable')) { - if (tree.currentSelectedNode) { - tree.getView().select(tree.currentSelectedNode); - } - return false; - } - // Inhibit clicks on the tree while editing - tree.inhibitClicks = 2; + beforecomplete: function(node) { + this.updatedValue = this.getValue(); + if (this.updatedValue === '') { + this.cancelEdit(); + return false; } + this.setValue(this.editNode.attributes.prefix + Ext.util.Format.htmlEncode(this.updatedValue) + this.editNode.attributes.suffix); }, - validateedit: { - fn: function (treeEditor, editEvent) { - var editorField = treeEditor.getEditor(editEvent.record, editEvent.column); - this.newValue = editorField.getValue(); - if (this.newValue === '' || this.newValue === editEvent.originalValue) { - var tree = editEvent.tree; - if (tree.currentSelectedNode) { - tree.getView().select(tree.currentSelectedNode); - } + + complete: { + fn: function(node, newValue, oldValue) { + if (newValue === oldValue) { + this.fireEvent('canceledit', this); return false; - } else { - editorField.setValue(editEvent.record.getNodeData('prefix') + Ext.util.Format.htmlEncode(this.newValue) + editEvent.record.getNodeData('suffix')); } - + + this.editNode.getOwnerTree().commandProvider.saveTitle(node, this.updatedValue, oldValue, this); } }, - edit: { - fn: function (treeEditor, editEvent) { - var tree = editEvent.tree; - tree.commandProvider.saveTitle(editEvent.record, this.newValue, editEvent.originalValue, treeEditor, tree, editEvent.field); + + startEdit: { + fn: function(element, value) { + this.field.selectText(); + } + }, + + canceledit: function() { + var tree = this.editNode.getOwnerTree(); + if (tree.currentSelectedNode) { + tree.currentSelectedNode.select(); } } }, - cancelEdit: function () { - var tree = this.grid; - if (tree.currentSelectedNode) { - tree.getView().select(tree.currentSelectedNode); - } - this.callParent(arguments); - }, /** - * Updates the text field + * Updates the edit node * - * @param {TYPO3.Components.PageTree.Model} node + * @param {Ext.tree.TreeNode} node * @param {String} editableText - * @param {String} updatedText - * @param {String} dataIndex - * @param {TYPO3.Components.PageTree.Tree} tree + * @param {String} updatedNode * @return {void} */ - updateNodeText: function (record, editableText, updatedText, dataIndex, tree) { - record.set(dataIndex, record.getNodeData('prefix') + updatedText + record.getNodeData('suffix')); - record.setNodeData('editableText', editableText); - record.commit(); - tree.getView().refresh(record.getId()); + updateNodeText: function(node, editableText, updatedNode) { + this.editNode.setText(this.editNode.attributes.prefix + updatedNode + this.editNode.attributes.suffix); + this.editNode.attributes.editableText = editableText; + }, + + /** + * Overridden method to set another editable text than the node text attribute + * + * @param {Ext.tree.TreeNode} node + * @return {Boolean} + */ + triggerEdit: function(node) { + this.completeEdit(); + if (node.attributes.editable !== false) { + this.editNode = node; + if (this.tree.autoScroll) { + Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body); + } + + var value = node.text || ''; + if (!Ext.isGecko && Ext.isEmpty(node.text)) { + node.setText(' '); + } + + // TYPO3 MODIFICATION to use another attribute + value = node.attributes.editableText; + + this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]); + return false; + } } }); + +// XTYPE Registration +Ext.reg('TYPO3.Components.PageTree.TreeEditor', TYPO3.Components.PageTree.TreeEditor); diff --git a/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js b/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js deleted file mode 100644 index b0c5bee20c5fd2d65579c48756e0d8d9ca9e1987..0000000000000000000000000000000000000000 --- a/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************** -* Copyright notice -* -* (c) 2011 Stanislas Rolland <typo3@sjbr.ca> -* All rights reserved -* -* This script is part of the TYPO3 project. The TYPO3 project is -* free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* The GNU General Public License can be found at -* http://www.gnu.org/copyleft/gpl.html. -* A copy is found in the textfile GPL.txt and important notices to the license -* from the author is found in LICENSE.txt distributed with these scripts. -* -* -* This script is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* This copyright notice MUST APPEAR in all copies of the script! -***************************************************************/ -/** - * @class TYPO3.Components.PageTree.plugin.TreeViewDragDrop - * - * onViewRender method is modified in order to use TYPO3.Components.PageTree.ViewDropZone - * - * @namespace TYPO3.Components.PageTree - * @extends Ext.tree.plugin.TreeViewDragDrop - * @author Stanislas Rolland <typo3@sjbr.ca> - */ -Ext.define('TYPO3.Components.PageTree.plugin.TreeViewDragDrop', { - extend: 'Ext.tree.plugin.TreeViewDragDrop', - alias: 'plugin.pagetreeviewdragdrop', - - onViewRender: function(view) { - var me = this; - - if (me.enableDrag) { - me.dragZone = Ext.create('Ext.tree.ViewDragZone', { - view: view, - ddGroup: me.dragGroup || me.ddGroup, - dragText: me.dragText, - repairHighlightColor: me.nodeHighlightColor, - repairHighlight: me.nodeHighlightOnRepair - }); - } - - if (me.enableDrop) { - me.dropZone = Ext.create('TYPO3.Components.PageTree.ViewDropZone', { - view: view, - ddGroup: me.dropGroup || me.ddGroup, - allowContainerDrops: me.allowContainerDrops, - appendOnly: me.appendOnly, - allowParentInserts: me.allowParentInserts, - expandDelay: me.expandDelay, - dropHighlightColor: me.nodeHighlightColor, - dropHighlight: me.nodeHighlightOnDrop - }); - } - } -}); \ No newline at end of file diff --git a/t3lib/js/extjs/tree/tree.js b/t3lib/js/extjs/tree/tree.js index bbd262485b33cf8b8a1eb74c06bb3f87a23ecf1e..f0cad3962071883b4f1ad80753c0d669723cca24 100644 --- a/t3lib/js/extjs/tree/tree.js +++ b/t3lib/js/extjs/tree/tree.js @@ -23,64 +23,60 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ + +Ext.ns('TYPO3.Components', 'TYPO3.Components.Tree'); + /** * TYPO3window - General TYPO3 tree component */ -Ext.ns('TYPO3.Components.Tree'); TYPO3.Components.Tree = {}; TYPO3.Components.Tree.StandardTreeItemData = []; -Ext.define('TYPO3.Components.Tree.StandardTree', { - extend: 'Ext.tree.Panel', - - constructor: function(config) { - var conf = Ext.apply({ - header: false, - width: 280, - rootVisible: false, - useArrows: false, - lines: true, - autoScroll: true, - containerScroll: true, - exclusiveSelectedKey: null, - stateful: true, - filterOptionStartsWith: true, - countSelectedNodes: 0, - // Needs to be migrated to ExtJS 4 - loader: new Ext.tree.TreeLoader({ - preloadChildren: true, - clearOnLoad: false - }), - root: new Ext.tree.AsyncTreeNode({ - text: TYPO3.l10n.localize('tcatree'), - id: 'root', - expanded: true, - children: TYPO3.Components.Tree.StandardTreeItemData[config.id] - }), - collapseFirst: false, - listeners: { - 'checkchange': function(checkedNode, checked) { - if (Ext.isFunction(this.checkChangeHandler)) { - this.checkChangeHandler.call(this, checkedNode, checked); - } - }, - scope: this - } - }, config); - this.callParent([conf]); - }, - initComponent: function() { - if (this.initialConfig.showHeader) { - Ext.apply(this, { - dockedItems: [{ - xtype: 'toolbar', - dock: 'top', - items: TYPO3.Components.Tree.Toolbar([], this) - }] - }); +TYPO3.Components.Tree.StandardTree = function(config) { + var conf = Ext.apply({ + header: false, + width: 280, + rootVisible: false, + useArrows: false, + lines: true, + autoScroll: true, + containerScroll: true, + exclusiveSelectedKey: null, + stateful: true, + filterOptionStartsWith: true, + countSelectedNodes: 0, + loader: new Ext.tree.TreeLoader({ + preloadChildren: true, + clearOnLoad: false + }), + root: new Ext.tree.AsyncTreeNode({ + text: TYPO3.l10n.localize('tcatree'), + id: 'root', + expanded: true, + children: TYPO3.Components.Tree.StandardTreeItemData[config.id] + }), + collapseFirst: false, + listeners: { + 'checkchange': function(checkedNode, checked) { + if (Ext.isFunction(this.checkChangeHandler)) { + this.checkChangeHandler.call(this, checkedNode, checked); + } + }, + scope: this } - this.callParent(arguments); + }, config); + TYPO3.Components.Tree.StandardTree.superclass.constructor.call(this, conf); +}; + + +Ext.extend(TYPO3.Components.Tree.StandardTree, Ext.tree.TreePanel, { + + initComponent: function() { + Ext.apply(this, { + tbar: this.initialConfig.showHeader ? TYPO3.Components.Tree.Toolbar([], this) : null + }); + TYPO3.Components.Tree.StandardTree.superclass.initComponent.call(this); }, filterTree: function(filterText) { var text = filterText.getValue(); @@ -143,7 +139,7 @@ TYPO3.Components.Tree.Toolbar = function(items, scope) { ] } }, - Ext.create('Ext.form.field.Text', { + new Ext.form.TextField({ width: 150, emptyText: TYPO3.l10n.localize('tcatree.findItem'), enableKeyEvents: true, diff --git a/t3lib/tree/class.t3lib_tree_abstracttree.php b/t3lib/tree/class.t3lib_tree_abstracttree.php index 5ba1ae315e535bf86c182c76f46b4cc768644d70..cda092584e1993f431ccdf0eb20bccfde018190e 100644 --- a/t3lib/tree/class.t3lib_tree_abstracttree.php +++ b/t3lib/tree/class.t3lib_tree_abstracttree.php @@ -63,7 +63,7 @@ abstract class t3lib_tree_AbstractTree { } /** - * @param t3lib_tree_renderer_Abstract $nodeRenderer + * @param t3lib_tree_renderer_Abstract $dataProvider * @return void */ public function setNodeRenderer(t3lib_tree_renderer_Abstract $nodeRenderer) { @@ -83,15 +83,6 @@ abstract class t3lib_tree_AbstractTree { * @return t3lib_tree_Node */ abstract public function getRoot(); - - /** - * @param mixed $search - * @return t3lib_tree_Node - */ - public function find($search) { - return $this->getRoot()->find($search); - } - } ?> \ No newline at end of file diff --git a/t3lib/tree/class.t3lib_tree_node.php b/t3lib/tree/class.t3lib_tree_node.php index 319307ccba22baec40ff4c221d11cc392f07e206..dd098882ecb3121dd4783326f2abe88349bc45d7 100644 --- a/t3lib/tree/class.t3lib_tree_node.php +++ b/t3lib/tree/class.t3lib_tree_node.php @@ -62,6 +62,7 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable { * This is useful for the deserialization. * * @param array $data + * @return void */ public function __construct(array $data = array()) { if (count($data)) { @@ -106,7 +107,7 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable { * @return boolean */ public function hasChildNodes() { - if ($this->childNodes != NULL && $this->childNodes->count() > 0) { + if ($this->childNodes !== NULL) { return TRUE; } @@ -213,7 +214,7 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable { * @param array $data * @return void */ - public function dataFromArray(array $data) { + public function dataFromArray($data) { $this->setId($data['id']); if (isset($data['parentNode']) && $data['parentNode'] !== '') { @@ -254,43 +255,6 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable { } $this->dataFromArray($arrayRepresentation); } - - /** - * searches the tree to find an node - * - * @param mixed $search - * @return t3lib_tree_Node - */ - public function find($search) { - $result = NULL; - - if($this->getId() == $search) { - $result = $this; - } elseif($this->hasChildNodes() && $this->getChildNodes() != NULL) { - foreach ($this->getChildNodes() AS $childNode) { - $result = $childNode->find($search); - if ($result != NULL) { - break; - } - } - } - - return $result; - } - - public function getLevel() { - if ($this->getParentNode() == NULL) { - return 0; - } else { - $i = 1; - $node = $this->getParentNode(); - while ($node != NULL) { - $node = $node->getParentNode(); - $i++; - } - return $i; - } - } } ?> \ No newline at end of file diff --git a/t3lib/tree/class.t3lib_tree_nodecollection.php b/t3lib/tree/class.t3lib_tree_nodecollection.php index e1a9293a452fa15d733f6777ccdfe3f57d0e7013..266f11ee98d30b19ac98933992077fe686390f04 100644 --- a/t3lib/tree/class.t3lib_tree_nodecollection.php +++ b/t3lib/tree/class.t3lib_tree_nodecollection.php @@ -62,9 +62,7 @@ class t3lib_tree_NodeCollection extends ArrayObject { * * @noapi * @see t3lib_tree_Node::compareTo - * @param t3lib_tree_Node $node - * @param t3lib_tree_Node $otherNode - * @return int + * @return void */ public function nodeCompare(t3lib_tree_Node $node, t3lib_tree_Node $otherNode) { return $node->compareTo($otherNode); diff --git a/t3lib/tree/class.t3lib_tree_representationnode.php b/t3lib/tree/class.t3lib_tree_representationnode.php index 4c64a733ad1ead5fd1439334e51aa08ba6c604ef..8a9482a393547d87ed54adfa248c535a64c815dd 100644 --- a/t3lib/tree/class.t3lib_tree_representationnode.php +++ b/t3lib/tree/class.t3lib_tree_representationnode.php @@ -32,7 +32,6 @@ * @author Steffen Ritter <info@steffen-ritter.net> * @package TYPO3 * @subpackage t3lib - * @deprecated Not needed anymore as of 4.7, will be removed on 4.9 */ class t3lib_tree_RepresentationNode extends t3lib_tree_Node { /** @@ -70,10 +69,6 @@ class t3lib_tree_RepresentationNode extends t3lib_tree_Node { */ protected $callbackAction = ''; - public function __construct() { - t3lib_div::deprecationLog("The Class t3lib_tree_RepresentationNode is deprecated as of TYPO3 4.7, will be removed in 4.9"); - } - /** * @param string $class * @return void diff --git a/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php b/t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php similarity index 83% rename from t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php rename to t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php index 6ac45d21d8bb46daad4847abc2fcf459d3c22e9f..8dcfe320b41001893cf2089b6cbc5e67657f49e3 100644 --- a/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php +++ b/t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php @@ -27,13 +27,12 @@ /** * Abstract ExtJS tree based on ExtDirect - * extends with StateProvider * - * @author Steffen Ritter + * @author Stefan Galinski <stefan.galinski@gmail.com> * @package TYPO3 * @subpackage t3lib */ -abstract class t3lib_tree_ExtJs_AbstractStatefulExtJsTree extends t3lib_tree_ExtJs_AbstractExtJsTree { +abstract class t3lib_tree_ExtDirect_AbstractExtJsTree extends t3lib_tree_AbstractTree { /** * State Provider @@ -57,6 +56,15 @@ abstract class t3lib_tree_ExtJs_AbstractStatefulExtJsTree extends t3lib_tree_Ext return $this->stateProvider; } + /** + * Fetches the next tree level + * + * @abstract + * @param int $nodeId + * @param stdClass $nodeData + * @return array + */ + abstract public function getNextTreeLevel($nodeId, $nodeData); } ?> \ No newline at end of file diff --git a/t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php b/t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php similarity index 65% rename from t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php rename to t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php index 678aaa62493c6bd7517d3971bba5c35f183b34f1..625ad0028aac54243f09c9bbc9c5f66cd012d169 100644 --- a/t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php +++ b/t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php @@ -26,37 +26,68 @@ ***************************************************************/ /** - * Extends the ExtJS-Tree Nodes with custom features implemented for the TYPO3 Navigation Panel + * Node for the usage with ExtDirect and ExtJS * - * @author Steffen Ritter <info@steffen-ritter.net> + * @author Stefan Galinski <stefan.galinski@gmail.com> * @package TYPO3 * @subpackage t3lib */ -class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { +class t3lib_tree_extdirect_Node extends t3lib_tree_Node { + /** + * Node type + * + * @var string + */ + protected $type = ''; + /** + * Leaf Node Indicator + * + * @var bool + */ + protected $leaf = TRUE; /** - * Database record (not serialized or merged into the result array!) + * Indicator if the node is expanded * - * @var array + * @var bool */ - protected $record = array(); + protected $expanded = FALSE; + /** + * Indicator if the node can be expanded + * + * @var bool + */ + protected $expandable = FALSE; /** - * Indicator if the node can have children's + * Indicator if the node is draggable * * @var bool */ - protected $allowChildren = TRUE; + protected $draggable = TRUE; /** - * Node type + * Indicator if the node is allowed as a drop target + * + * @var bool + */ + protected $isDropTarget = TRUE; + + /** + * Label * * @var string */ - protected $type = ''; + protected $text = ''; + /** + * Editable Label text + * + * @var string + */ + protected $editableText = ''; /** * Prefix text of the label @@ -73,19 +104,60 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { protected $suffix = ''; /** - * Context Info + * CSS Class * - * @var array + * @var string */ - protected $contextInfo = array(); + protected $cls = ''; /** - * Editable Label text + * Quick Tip * * @var string */ - protected $editableText = ''; + protected $qtip = ''; + /** + * Sprite Icon HTML + * + * @var string + */ + protected $spriteIconCode = ''; + + /** + * Text source field (title, nav_title, ...) + * + * @var string + */ + protected $t3TextSourceField = ''; + + /** + * Indicator if the copy mode is activated + * + * @var bool + */ + protected $t3InCopyMode = FALSE; + + /** + * Indicator if the cut mode is activated + * + * @var bool + */ + protected $t3InCutMode = FALSE; + + /** + * Database record (not serialized or merged into the result array!) + * + * @var array + */ + protected $record = array(); + + /** + * Context Info + * + * @var array + */ + protected $contextInfo = array(); /** * Indicator if the label is editable @@ -94,92 +166,173 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { */ protected $labelIsEditable = TRUE; + /** + * Indicator if the node can have children's + * + * @var bool + */ + protected $allowChildren = TRUE; /** - * Sets the context info + * Set's the node type * - * @param array $contextInfo + * @param string $type * @return void */ - public function setContextInfo($contextInfo) { - $this->contextInfo = (array) $contextInfo; + public function setType($type) { + $this->type = $type; } /** - * Returns the context info + * Returns the node type * - * @return array + * @return string */ - public function getContextInfo() { - return (array) $this->contextInfo; + public function getType() { + return $this->type; } + /** + * Sets the leaf node indicator + * + * @param bool $isLeaf + * @return void + */ + public function setLeaf($isLeaf) { + $this->leaf = ($isLeaf == TRUE); + } /** - * Sets the indicator if the node can have child nodes + * Returns if the node is a leaf node * - * @param boolean $allowChildren + * @return bool + */ + public function isLeafNode() { + return $this->leaf; + } + + /** + * Sets the expandable indicator + * + * @param bool $expandable * @return void */ - public function setAllowChildren($allowChildren) { - $this->allowChildren = ($allowChildren == TRUE); + public function setExpandable($expandable) { + $this->expandable = ($expandable == TRUE); } /** - * Checks if the node can have child nodes + * Returns the expandable indicator * * @return bool */ - public function canHaveChildren() { - return $this->allowChildren; + public function isExpandable() { + return $this->expandable; + } + + /** + * Sets the expanded indicator + * + * @param bool $expanded + * @return void + */ + public function setExpanded($expanded) { + $this->expanded = ($expanded == TRUE); } + /** + * Returns the expanded indicator + * + * @return bool + */ + public function isExpanded() { + if ($this->isLeafNode()) { + return TRUE; + } + + return $this->expanded; + } /** - * Sprite Icon HTML + * Sets the draggable indicator * - * @var string + * @param bool $draggable + * @return void */ - protected $spriteIconCode = ''; + public function setDraggable($draggable) { + $this->draggable = ($draggable == TRUE); + } /** - * Text source field (title, nav_title, ...) + * Returns the draggable indicator * - * @var string + * @return bool */ - protected $t3TextSourceField = ''; + public function isDraggable() { + return $this->draggable; + } /** - * Indicator if the copy mode is activated + * Sets the indicator if the node can be a drop target * - * @var bool + * @param bool $isDropTarget + * @return void */ - protected $t3InCopyMode = FALSE; + public function setIsDropTarget($isDropTarget) { + $this->isDropTarget = ($isDropTarget == TRUE); + } /** - * Indicator if the cut mode is activated + * Returns the indicator if the node is a drop target * - * @var bool + * @return bool */ - protected $t3InCutMode = FALSE; + public function isDropTarget() { + return $this->isDropTarget; + } - /** - * Sets the sprite icon code + /** + * Sets the label of the node with the source field and the prefix * - * @param string $spriteIcon + * @param string $text + * @param string $textSourceField + * @param string $prefix + * @param string $suffix * @return void */ - public function setSpriteIconCode($spriteIcon) { - $this->spriteIconCode = $spriteIcon; + public function setText($text, $textSourceField = 'title', $prefix = '', $suffix = '') { + $this->text = $text; + $this->t3TextSourceField = $textSourceField; + $this->prefix = $prefix; + $this->suffix = $suffix; } /** - * Returns the sprite icon code + * Returns the label * * @return string */ - public function getSpriteIconCode() { - return $this->spriteIconCode; + public function getText() { + return $this->text; + } + + /** + * Sets the editable text + * + * @param string $editableText + * @return void + */ + public function setEditableText($editableText) { + $this->editableText = $editableText; + } + + /** + * Returns the editable text + * + * @return string + */ + public function getEditableText() { + return $this->editableText; } /** @@ -246,45 +399,63 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { public function getSuffix() { return $this->suffix; } - + /** - * Set's the node type + * Sets the css class(es) * - * @param string $type + * @param string $class * @return void */ - public function setType($type) { - $this->type = $type; + public function setCls($class) { + $this->cls = $class; } /** - * Returns the node type + * Returns the css class(es) * * @return string */ - public function getType() { - return $this->type; + public function getCls() { + return $this->cls; } /** - * Sets the editable text + * Sets the quick tip * - * @param string $editableText + * @param string $qtip * @return void */ - public function setEditableText($editableText) { - $this->editableText = $editableText; + public function setQTip($qtip) { + $this->qtip = $qtip; } /** - * Returns the editable text + * Returns the quick tip * * @return string */ - public function getEditableText() { - return $this->editableText; + public function getQTip() { + return $this->qtip; } + /** + * Sets the sprite icon code + * + * @param string $spriteIcon + * @return void + */ + public function setSpriteIconCode($spriteIcon) { + $this->spriteIconCode = $spriteIcon; + } + + /** + * Returns the sprite icon code + * + * @return string + */ + public function getSpriteIconCode() { + return $this->spriteIconCode; + } /** * Sets the indicator if the label is editable @@ -306,39 +477,74 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { } /** - * Sets the label of the node with the source field and the prefix + * Sets the database record array * - * @param string $text - * @param string $textSourceField - * @param string $prefix - * @param string $suffix + * @param array $record * @return void */ - public function setText($text, $textSourceField = 'title', $prefix = '', $suffix = '') { - $this->text = $text; - $this->t3TextSourceField = $textSourceField; - $this->prefix = $prefix; - $this->suffix = $suffix; + public function setRecord($record) { + $this->record = (array) $record; } /** - * Sets data of the node by a given data array + * Returns the database record array * - * @param array $data + * @return array + */ + public function getRecord() { + return $this->record; + } + + /** + * Sets the context info + * + * @param array $contextInfo * @return void */ - public function dataFromArray($data) { - parent::dataFromArray($data); + public function setContextInfo($contextInfo) { + $this->contextInfo = (array) $contextInfo; + } - $this->setText($data['label'], $data['t3TextSourceField'], $data['prefix'], $data['suffix']); - $this->setType($data['type']); - $this->setEditableText($data['editableText']); - $this->setSpriteIconCode($data['spriteIconCode']); - $this->setInCopyMode($data['t3InCopyMode']); - $this->setInCutMode($data['t3InCutMode']); - $this->setContextInfo($data['t3ContextInfo']); - $this->setLabelIsEditable($data['editable']); - $this->setAllowChildren($data['allowChildren']); + /** + * Returns the context info + * + * @return array + */ + public function getContextInfo() { + return (array) $this->contextInfo; + } + + /** + * Sets the child nodes collection + * + * @param t3lib_tree_NodeCollection $childNodes + * @return void + */ + public function setChildNodes(t3lib_tree_NodeCollection $childNodes) { + parent::setChildNodes($childNodes); + + if ($childNodes->count()) { + $this->setLeaf(FALSE); + } + } + + /** + * Sets the indicator if the node can have child nodes + * + * @param boolean $allowChildren + * @return void + */ + public function setAllowChildren($allowChildren) { + $this->allowChildren = ($allowChildren == TRUE); + } + + /** + * Checks if the node can have child nodes + * + * @return bool + */ + public function canHaveChildren() { + return $this->allowChildren; } /** @@ -348,14 +554,20 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { * @return array */ public function toArray($addChildNodes = TRUE) { - $arrayRepresentation = parent::toArray($addChildNodes); - - $arrayRepresentation2 = array( + $arrayRepresentation = array( + 'serializeClassName' => get_class($this), + 'id' => $this->getId(), 'type' => $this->getType(), 'editableText' => $this->getEditableText(), 'text' => $this->getPrefix() . $this->getText() . $this->getSuffix(), + 'cls' => $this->getCls(), 'prefix' => $this->getPrefix(), 'suffix' => $this->getSuffix(), + 'qtip' => $this->getQTip(), + 'expanded' => $this->isExpanded(), + 'expandable' => $this->isExpandable(), + 'draggable' => $this->isDraggable(), + 'isTarget' => $this->isDropTarget(), 'spriteIconCode' => $this->getSpriteIconCode(), 't3TextSourceField' => $this->getTextSourceField(), 't3InCopyMode' => $this->isInCopyMode(), @@ -368,51 +580,56 @@ class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node { // only set the leaf attribute if the node has children's, // otherwise you cannot add child's to real leaf nodes if (!$this->isLeafNode()) { - $arrayRepresentation2['leaf'] = FALSE; + $arrayRepresentation['leaf'] = FALSE; } - // Do not nest nodeData and children arrays - unset($arrayRepresentation['nodeData']); - unset($arrayRepresentation['children']); - $arrayRepresentation = array_merge($arrayRepresentation, $arrayRepresentation2); - // Suhosin(?) or some other strange environment thingy prevents // the direct copy of an array into an index of the same array $copy = $arrayRepresentation; $arrayRepresentation['nodeData'] = $copy; - if ($this->hasChildNodes() && $addChildNodes) { + if ($this->hasChildNodes()) { $arrayRepresentation['children'] = $this->childNodes->toArray(); } return $arrayRepresentation; } - /** - * Sets the database record array + * Sets data of the node by a given data array * - * @param array $record + * @param array $data * @return void */ - public function setRecord($record) { - $this->record = (array) $record; - } - - /** - * Returns the database record array - * - * @return array - */ - public function getRecord() { - return $this->record; - } + public function dataFromArray($data) { + parent::dataFromArray($data); + $this->setType($data['type']); + $this->setText($data['label'], $data['t3TextSourceField'], $data['prefix'], $data['suffix']); + $this->setEditableText($data['editableText']); + $this->setCls($data['cls']); + $this->setQTip($data['qtip']); + $this->setExpanded($data['expanded']); + $this->setExpandable($data['expandable']); + $this->setDraggable($data['draggable']); + $this->setIsDropTarget($data['isTarget']); + $this->setSpriteIconCode($data['spriteIconCode']); + $this->setInCopyMode($data['t3InCopyMode']); + $this->setInCutMode($data['t3InCutMode']); + $this->setContextInfo($data['t3ContextInfo']); + $this->setLabelIsEditable($data['editable']); + $this->setAllowChildren($data['allowChildren']); + // only set the leaf attribute if it's applied + // otherwise you cannot insert nodes into this one + if (isset($data['leaf'])) { + $this->setLeaf(FALSE); + } + } } -if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php'])) { - include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php']); +if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php'])) { + include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php']); } ?> \ No newline at end of file diff --git a/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php b/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php deleted file mode 100644 index b7762907bc2372b586ac38a30c6ad60ffdb5e6a0..0000000000000000000000000000000000000000 --- a/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Abstract ExtJS tree based on ExtDirect - * - * @author Stefan Galinski <stefan.galinski@gmail.com> - * @package TYPO3 - * @subpackage t3lib - */ -abstract class t3lib_tree_ExtJs_AbstractExtJsTree extends t3lib_tree_AbstractTree { - - /** - * Fetches the next tree level - * - * @abstract - * @param int $nodeId - * @param stdClass $nodeData - * @return array - */ - abstract public function getNextTreeLevel($nodeId, $nodeData); -} - -?> \ No newline at end of file diff --git a/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php b/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php deleted file mode 100644 index 517f306611cb2164196bdfae0f07b59e0c608155..0000000000000000000000000000000000000000 --- a/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php +++ /dev/null @@ -1,590 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Node for the usage with ExtDirect and ExtJS - * - * @author Stefan Galinski <stefan.galinski@gmail.com> - * @package TYPO3 - * @subpackage t3lib - */ -class t3lib_tree_ExtJs_Node extends t3lib_tree_Node implements t3lib_tree_RenderableNode { - - /** - * Indicator if the node is allowDrag - * - * @var bool - */ - protected $allowDrag = TRUE; - - /** - * Indicator if the node is allowed as a drop target - * - * @var bool - */ - protected $allowDrop = TRUE; - - /** - * Indicator if the noded is checked - * three-state: TRUE|FALSE|NULL - * NULL won't show a checkbox - * - * @var boolean|NULL - */ - protected $checked = NULL; - - /** - * CSS Class - * - * @var string - */ - protected $cls = ''; - - /** - * The number of parents this node has. ... - * - * @var int - */ - protected $depth; - - /** - * Indicator if the node can be expanded - * - * @var bool - */ - protected $expandable = TRUE; - - /** - * Indicator if the node is expanded - * - * @var bool - */ - protected $expanded = FALSE; - - /** - * An URL for a link that's created when this config is specified. - * - * @var string|NULL - */ - protected $href = NULL; - - /** - * Target for link in $href - * - * @var string - */ - protected $hrefTarget = ''; - - /** - * URL for this node's icon file - * - * @var string - */ - protected $icon; - - /** - * URL for this node's icon css class - * - * @var string - */ - protected $iconCls; - - - /** - * The position of the node inside its parents - * starting from 0 - * - * @var int - */ - protected $index; - - - /** - * True if this is the first node. - * - * @var boolean - */ - protected $isFirst; - - /** - * True if this is the last node - */ - protected $isLast; - - /** - * Leaf Node Indicator - * - * @var bool - */ - protected $leaf = TRUE; - - /** - * Quick Tip - * - * @var string - */ - protected $qtip = ''; - - /** - * Quick Tip title - * - * @var string - */ - protected $qtitle = ''; - - /** - * is root node? - * - * @var boolean - */ - protected $root = FALSE; - - /** - * Label - * - * @var string - */ - protected $text = ''; - - /** - * Sets the leaf node indicator - * - * @param bool $isLeaf - * @return void - */ - public function setLeaf($isLeaf) { - $this->leaf = ($isLeaf == TRUE); - } - - /** - * Returns if the node is a leaf node - * - * @return bool - */ - public function isLeafNode() { - return $this->leaf; - } - - /** - * Sets the expandable indicator - * - * @param bool $expandable - * @return void - */ - public function setExpandable($expandable) { - $this->expandable = ($expandable == TRUE); - } - - /** - * Returns the expandable indicator - * - * @return bool - */ - public function isExpandable() { - return $this->expandable; - } - - /** - * Sets the expanded indicator - * - * @param bool $expanded - * @return void - */ - public function setExpanded($expanded) { - $this->expanded = ($expanded == TRUE); - } - - /** - * Returns the expanded indicator - * - * @return bool - */ - public function isExpanded() { - if ($this->isLeafNode()) { - return TRUE; - } - - return $this->expanded; - } - - /** - * Sets the allowDrag indicator - * - * @param bool $draggable - * @return void - */ - public function setAllowDrag($draggable) { - $this->allowDrag = ($draggable == TRUE); - } - - /** - * Returns the allowDrag indicator - * - * @return bool - */ - public function isDraggable() { - return $this->allowDrag; - } - - /** - * Sets the indicator if the node can be a drop target - * - * @param bool $isDropTarget - * @return void - */ - public function setAllowDrop($isDropTarget) { - $this->allowDrop = ($isDropTarget == TRUE); - } - - /** - * Returns the indicator if the node is a drop target - * - * @return bool - */ - public function allowDrop() { - return $this->allowDrop; - } - - /** - * Sets the label of the node with the source field and the prefix - * - * @param string $text - * @return void - */ - public function setText($text) { - $this->text = $text; - } - - /** - * Returns the label - * - * @return string - */ - public function getText() { - return $this->text; - } - - /** - * Sets the css class(es) - * - * @param string $class - * @return void - */ - public function setCls($class) { - $this->cls = $class; - } - - /** - * Returns the css class(es) - * - * @return string - */ - public function getCls() { - return $this->cls; - } - - /** - * Sets the quick tip - * - * @param string $qtip - * @return void - */ - public function setQTip($qtip) { - $this->qtip = $qtip; - } - - /** - * Returns the quick tip - * - * @return string - */ - public function getQTip() { - return $this->qtip; - } - - /** - * Sets the child nodes collection - * - * @param t3lib_tree_NodeCollection $childNodes - * @return void - */ - public function setChildNodes(t3lib_tree_NodeCollection $childNodes) { - parent::setChildNodes($childNodes); - - if ($childNodes->count()) { - $this->setLeaf(FALSE); - } - } - - /** - * Returns the node in an array representation that can be used for serialization - * - * @param bool $addChildNodes - * @return array - */ - public function toArray($addChildNodes = TRUE) { - $arrayRepresentation = array( - 'serializeClassName' => get_class($this), - 'allowDrag' => $this->isDraggable(), - 'allowDrop' => $this->allowDrop(), - 'checked' => $this->getChecked(), - 'cls' => $this->getCls(), - 'depth' => $this->getDepth(), - 'expandable' => $this->isExpandable(), - 'expanded' => $this->isExpanded(), - 'href' => $this->getHref(), - 'hrefTarget' => $this->getHrefTarget(), - 'id' => $this->getId(), - 'icon' => $this->getIcon(), - 'iconCls' => $this->getIconCls(), - 'index' => $this->getIndex(), - 'isFirst' => $this->getIsFirst(), - 'isLast' => $this->getIsLast(), - 'parentId' => (!$this->getRoot() && $this->getParentNode() ? $this->getParentNode()->getId() : ''), - 'qtip' => $this->getQTip(), - 'qtitle' => $this->getQtitle(), - 'root' => $this->getRoot(), - 'text' => $this->getText(), - ); - - // do not provide config if empty - if (trim($this->href) == '') { - unset($arrayRepresentation['href']); - unset($arrayRepresentation['hrefTarget']); - } - - // only added check option if checkbox should be shown - if($this->getChecked() == NULL) { - unset($arrayRepresentation['checked']); - } - // only set the leaf attribute if the node has children's, - // otherwise you cannot add child's to real leaf nodes - if (!$this->isLeafNode()) { - $arrayRepresentation['leaf'] = FALSE; - } - - // Suhosin(?) or some other strange environment thingy prevents - // the direct copy of an array into an index of the same array - $copy = $arrayRepresentation; - $arrayRepresentation['nodeData'] = $copy; - - if ($this->hasChildNodes() && $addChildNodes) { - $arrayRepresentation['children'] = $this->childNodes->toArray(); - } - - return $arrayRepresentation; - } - - /** - * Sets data of the node by a given data array - * - * @param array $data - * @return void - */ - public function dataFromArray($data) { - parent::dataFromArray($data); - - $this->setText($data['label']); - $this->setCls($data['cls']); - $this->setQTip($data['qtip']); - $this->setExpanded($data['expanded']); - $this->setExpandable($data['expandable']); - $this->setAllowDrag($data['allowDrag']); - $this->setAllowDrop($data['isTarget']); - $this->setChecked(isset($data['checked']) ? (bool)$data['checked'] : NULL); - - // only set the leaf attribute if it's applied - // otherwise you cannot insert nodes into this one - if (isset($data['leaf'])) { - $this->setLeaf(FALSE); - } - } - - /** - * @param bool|NULL $checked - */ - public function setChecked($checked) { - $this->checked = $checked; - } - - /** - * @return bool|NULL - */ - public function getChecked() { - return $this->checked; - } - - /** - * @param int $depth - */ - public function setDepth($depth) { - $this->depth = $depth; - } - - /** - * @return int - */ - public function getDepth() { - return $this->depth; - } - - /** - * @param NULL|string $href - */ - public function setHref($href) { - $this->href = $href; - } - - /** - * @return NULL|string - */ - public function getHref() { - return $this->href; - } - - /** - * @param string $hrefTarget - */ - public function setHrefTarget($hrefTarget) { - $this->hrefTarget = $hrefTarget; - } - - /** - * @return string - */ - public function getHrefTarget() { - return $this->hrefTarget; - } - - /** - * @param string $icon - */ - public function setIcon($icon) { - $this->icon = $icon; - } - - /** - * @return string - */ - public function getIcon() { - return $this->icon; - } - - /** - * @param string $iconCls - */ - public function setIconCls($iconCls) { - $this->iconCls = $iconCls; - } - - /** - * @return string - */ - public function getIconCls() { - return $this->iconCls; - } - - /** - * @param int $index - */ - public function setIndex($index) { - $this->index = $index; - } - - /** - * @return int - */ - public function getIndex() { - return $this->index; - } - - /** - * @param boolean $isFirst - */ - public function setIsFirst($isFirst) { - $this->isFirst = $isFirst; - } - - /** - * @return boolean - */ - public function getIsFirst() { - return $this->isFirst; - } - - public function setIsLast($isLast) { - $this->isLast = $isLast; - } - - public function getIsLast() { - return $this->isLast; - } - - - /** - * @param string $qtitle - */ - public function setQtitle($qtitle) { - $this->qtitle = $qtitle; - } - - /** - * @return string - */ - public function getQtitle() { - return $this->qtitle; - } - - /** - * @param boolean $root - */ - public function setRoot($root) { - $this->root = $root; - } - - /** - * @return boolean - */ - public function getRoot() { - return $this->root; - } - - /** - * returns a string representation - * - * @return string - */ - public function toString() { - return $this->getText(); - } -} - -if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extjs/class.t3lib_tree_extjs_node.php'])) { - include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extjs/class.t3lib_tree_extjs_node.php']); -} - -?> \ No newline at end of file diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php b/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php deleted file mode 100644 index ed7c0932dc50dc3ccad4babc58fd7c1e15403a54..0000000000000000000000000000000000000000 --- a/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Interface that defines the comparison of nodes - * - * @author Stefan Galinski <stefan.galinski@gmail.com> - * @package TYPO3 - * @subpackage t3lib - */ -interface t3lib_tree_ComparableNode { - /** - * Compare Node against another one - * - * Returns: - * 1 if the current node is greater than the $other, - * -1 if $other is greater than the current node and - * 0 if the nodes are equal - * - * <strong>Example</strong> - * <pre> - * if ($this->sortValue > $other->sortValue) { - * return 1; - * } elseif ($this->sortValue < $other->sortValue) { - * return -1; - * } else { - * return 0; - * } - * </pre> - * - * @param t3lib_tree_Node $other - * @return integer see description - */ - public function compareTo($other); - - /** - * Compares a node if it's identical to another node by the id property. - * - * @param t3lib_tree_Node $other - * @return boolean - */ - public function equals(t3lib_tree_Node $other); - -} -?> \ No newline at end of file diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php b/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php deleted file mode 100644 index 2bdf9cdd4af88778e25059d519f0bf85b79ad4a7..0000000000000000000000000000000000000000 --- a/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Describes necessary methods if the nodes are allowDrag and dropable - * within the tree. - * - * @author Stefan Galinski <stefan.galinski@gmail.com> - * @author Steffen Ritter <info@steffen-ritter.net> - * @package TYPO3 - * @subpackage t3lib - */ -interface t3lib_tree_DraggableAndDropable { - /** - * Moves given node inside a destination node - * - * @param t3lib_tree_Node $node - * @param t3lib_tree_Node $destination - * @return void - */ - public function moveNodeInDestinationNode($node, $destination); - - /** - * Moves given node after a destination node - * - * @param t3lib_tree_Node $node - * @param t3lib_tree_Node $destination - * @return void - */ - public function moveNodeAfterDestinationNode($node, $destination); - - /** - * Copies given node inside a destination node - * - * @param t3lib_tree_Node $node - * @param t3lib_tree_Node $destination - * @return void - */ - public function copyNodeInDestinationNode($node, $destination); - - /** - * Copies given node after a destination node - * - * @param t3lib_tree_Node $node - * @param t3lib_tree_Node $destination - * @return void - */ - public function copyNodeAfterDestinationNode($node, $destination); - -} -?> \ No newline at end of file diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php b/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php deleted file mode 100644 index 52f7ce8382c15204ff0fcde1b773289fdfdd7d42..0000000000000000000000000000000000000000 --- a/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Describes necessary methods if the node label should be editable - * within the tree. - * - * @author Stefan Galinski <stefan.galinski@gmail.com> - * @author Steffen Ritter <info@steffen-ritter.net> - * @package TYPO3 - * @subpackage t3lib - */ -interface t3lib_tree_LabelEditable { - /** - * Sets the new label - * - * @param string $label - * @return void - */ - public function setLabel($label); -} -?> \ No newline at end of file diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php b/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php deleted file mode 100644 index d4268b78598b9b88b96d9072a888248d403328d4..0000000000000000000000000000000000000000 --- a/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Interface that defines the nodes based on records - * - * @author Steffen Ritter <info@steffen-ritter.net> - * @package TYPO3 - * @subpackage t3lib - */ -interface t3lib_tree_RecordBasedNode { - - /** - * Returns the source field of the label - * - * @return string - */ - public function getTextSourceField(); - - /** - * set the source field of the label - * - * @param string $field - * @return void - */ - public function setTextSourceField($field); - - /** - * Sets the database record array - * - * @param array $record - * @return void - */ - public function setRecord($record); - - /** - * Returns the database record array - * - * @return array - */ - public function getRecord(); - - /** - * Returns the table of the record data - * - * @return string - */ - public function getSourceTable(); - - /** - * sets the Table of record source data - * - * @param string $table - * @return void - */ - public function setSourceTable($table); - -} -?> diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php b/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php deleted file mode 100644 index 1c7ba3e166705371d277aea8ab2969d5fc9a3004..0000000000000000000000000000000000000000 --- a/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/*************************************************************** - * Copyright notice - * - * (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees> - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * A copy is found in the textfile GPL.txt and important notices to the license - * from the author is found in LICENSE.txt distributed with these scripts. - * - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -/** - * Interface that defines the to be rendered - * - * @author Steffen Ritter <info@steffen-ritter.net> - * @package TYPO3 - * @subpackage t3lib - */ -interface t3lib_tree_RenderableNode { - /** - * returns a string representation - * - * @return string - */ - public function toString(); - - /** - * returns an array representation of an node - * - * @return array - */ - public function toArray(); -} -?> diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php index 782c7b5609c51db8a8bf417f75213f2026b98774..532761ede0fca3788b6455f6c8db3b23749af1f8 100644 --- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php +++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php @@ -36,7 +36,7 @@ final class t3lib_tree_pagetree_Commands { /** * Visibly the page * - * @param t3lib_tree_pagetree_Node $node + * @param t3lib_tree_pagetree_Node $nodeData * @return void */ public static function visiblyNode(t3lib_tree_pagetree_Node $node) { @@ -47,7 +47,7 @@ final class t3lib_tree_pagetree_Commands { /** * Hide the page * - * @param t3lib_tree_pagetree_Node $node + * @param t3lib_tree_pagetree_Node $nodeData * @return void */ public static function disableNode(t3lib_tree_pagetree_Node $node) { @@ -58,7 +58,7 @@ final class t3lib_tree_pagetree_Commands { /** * Delete the page * - * @param t3lib_tree_pagetree_Node $node + * @param t3lib_tree_pagetree_Node $nodeData * @return void */ public static function deleteNode(t3lib_tree_pagetree_Node $node) { @@ -69,7 +69,7 @@ final class t3lib_tree_pagetree_Commands { /** * Restore the page * - * @param t3lib_tree_pagetree_Node $node + * @param t3lib_tree_pagetree_Node $nodeData * @param int $targetId * @return void */ @@ -85,7 +85,7 @@ final class t3lib_tree_pagetree_Commands { /** * Updates the node label * - * @param t3lib_tree_pagetree_Node $node + * @param t3lib_tree_pagetree_Node $nodeData * @param string $updatedLabel * @return void */ @@ -276,7 +276,6 @@ final class t3lib_tree_pagetree_Commands { * Creates a node with the given record information's * * @param array $record - * @param int $mountPoint * @return t3lib_tree_pagetree_Node */ public static function getNewNode($record, $mountPoint = 0) { @@ -336,7 +335,7 @@ final class t3lib_tree_pagetree_Commands { if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) { $_params = array('pages', $record['uid']); foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) { - $stat .= t3lib_div::callUserFunction($_funcRef, $_params, NULL); + $stat .= t3lib_div::callUserFunction($_funcRef, $_params, $this); } } @@ -359,11 +358,11 @@ final class t3lib_tree_pagetree_Commands { $subNode->setSpriteIconCode($spriteIconCode); if (!$subNode->canCreateNewPages() || intval($record['t3ver_state']) === 2) { - $subNode->setAllowDrop(FALSE); + $subNode->setIsDropTarget(FALSE); } if (!$subNode->canBeEdited() || !$subNode->canBeRemoved() || intval($record['t3ver_state']) === 2) { - $subNode->setAllowDrag(FALSE); + $subNode->setDraggable(FALSE); } return $subNode; diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php index 78b010ddd7be109b1b721badd48da3e1663c7167..4cd6f238992702ad32f5b53cf9b7d04c2394728c 100644 --- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php +++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php @@ -123,7 +123,7 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { if (!is_array($subpages) || !count($subpages)) { return $nodeCollection; } - $index = -1; + foreach ($subpages as $subpage) { if (in_array($subpage['uid'], $this->hiddenRecords)) { continue; @@ -135,20 +135,14 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { } $subNode = t3lib_tree_pagetree_Commands::getNewNode($subpage, $mountPoint); - $subNode->setParentNode($node); - $subNode->setDepth($node->getDepth() + 1); - $subNode->setIndex(++$index); - $subNode->setIsFirst($index === 0); - $subNode->setIsLast($index === (count($subpages)-1)); if ($this->nodeCounter < $this->nodeLimit) { $childNodes = $this->getNodes($subNode, $mountPoint, $level + 1); $subNode->setChildNodes($childNodes); - $subNode->setLeaf(!$subNode->hasChildNodes()); $this->nodeCounter += $childNodes->count(); } else { $subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId())); } - $subNode->setExpandable(!$subNode->isLeafNode()); + $nodeCollection->append($subNode); } @@ -166,7 +160,7 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { * @param t3lib_tree_Node $node * @param string $searchFilter * @param int $mountPoint - * @return t3lib_tree_pagetree_NodeCollection + * @return void */ public function getFilteredNodes(t3lib_tree_Node $node, $searchFilter, $mountPoint = 0) { /** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */ @@ -211,10 +205,13 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { if ($reference && $reference->offsetExists($ident)) { /** @var $refNode t3lib_tree_pagetree_Node */ $refNode = $reference->offsetGet($ident); - if ($refNode->hasChildNodes()) { - $refNode->setExpanded(TRUE); - $refNode->setLeaf(FALSE); - $reference = $refNode->getChildNodes(); + $refNode->setExpanded(TRUE); + $refNode->setLeaf(FALSE); + + $reference = $refNode->getChildNodes(); + if ($reference == NULL) { + $reference = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection'); + $refNode->setChildNodes($reference); } } else { $refNode = t3lib_tree_pagetree_Commands::getNewNode($rootlineElement, $mountPoint); @@ -290,7 +287,6 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { } $showRootlineAboveMounts = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPathAboveMounts'); - $index = -1; foreach ($mountPoints as $mountPoint) { if ($mountPoint === 0) { $sitename = 'TYPO3'; @@ -326,13 +322,10 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { $subNode->setExpanded(TRUE); $subNode->setCls('typo3-pagetree-node-notExpandable'); } - $subNode->setDepth(1); - $subNode->setIndex(++$index); - $subNode->setIsFirst($index === 0); - $subNode->setIsLast($index === (count($mountPoints)-1)); + $subNode->setIsMountPoint(TRUE); - $subNode->setAllowDrag(FALSE); - $subNode->setAllowDrop(FALSE); + $subNode->setDraggable(FALSE); + $subNode->setIsDropTarget(FALSE); if ($searchFilter === '') { $childNodes = $this->getNodes($subNode, $mountPoint); @@ -370,22 +363,21 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider { } if ($searchFilter !== '') { - $searchWhere = ''; if (is_numeric($searchFilter) && $searchFilter > 0) { - $searchWhere .= 'uid = ' . intval($searchFilter) . ' OR '; + $seachWhere .= 'uid = ' . intval($searchFilter) . ' OR '; } $searchFilter = $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages'); $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle'); if ($useNavTitle) { - $searchWhere .= '(nav_title LIKE ' . $searchFilter . + $seachWhere .= '(nav_title LIKE ' . $searchFilter . ' OR (nav_title = "" && title LIKE ' . $searchFilter . '))'; } else { - $searchWhere .= 'title LIKE ' . $searchFilter; + $seachWhere .= 'title LIKE ' . $searchFilter; } - $where .= ' AND (' . $searchWhere . ')'; + $where .= ' AND (' . $seachWhere . ')'; } return $where; diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php index 619273a2b9185ef3e2473cfebceb54a245400db4..a97f7ac826996a4b8ece8f81fbc4072c1b889e6a 100644 --- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php +++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php @@ -53,7 +53,7 @@ class t3lib_tree_pagetree_Indicator { */ protected function getIndicatorProviders() { $providers = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['pagetree']['t3lib_tree_pagetree']['indicator']['providers']; - if (!is_array($providers) || count($this->indicatorProviders) > 0) { + if (!is_array($providers)) { return; } @@ -69,13 +69,13 @@ class t3lib_tree_pagetree_Indicator { /** * Runs through all indicator providers and returns all indicators collected. * - * @return array An array of indicator objects + * @return array An array of */ public function getAllIndicators() { $indicators = array(); foreach ($this->indicatorProviders as $indicatorProvider) { $indicator = $indicatorProvider->getIndicator(); - if ($indicator) { + if($indicator) { $indicators[] = $indicator; } } diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php index 4c5145933a583b76d453a47d2018ebe170a7eb4c..91af17c4d33001ee575bf57ad57be14f6554b160 100644 --- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php +++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php @@ -32,7 +32,7 @@ * @package TYPO3 * @subpackage t3lib */ -class t3lib_tree_pagetree_Node extends t3lib_tree_NavigationTree_Node implements t3lib_tree_RecordBasedNode { +class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node { /** * Cached access rights to save some performance * @@ -297,19 +297,6 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_NavigationTree_Node implements public function canBeTemporaryMountPoint() { return TRUE; } - - /** - * Returns a special id for a page tree node - * - * @return string - */ - public function getPageTreeNodeId() { - if ($this->getId() === 'root') { - return 'root'; - } else { - return 'p' . dechex($this->getId()) . ($this->getMountPoint() ? '-' . dechex($this->getMountPoint()) : ''); - } - } /** * Returns the node in an array representation that can be used for serialization @@ -320,34 +307,17 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_NavigationTree_Node implements public function toArray($addChildNodes = TRUE) { $arrayRepresentation = parent::toArray(); - $arrayRepresentation2['id'] = $this->getPageTreeNodeId(); - $arrayRepresentation2['realId'] = $this->getId(); - $arrayRepresentation2['serializeClassName'] = get_class($this); - $arrayRepresentation2['parentId'] = (!$this->getRoot() && $this->getParentNode()) ? $this->getParentNode()->getPageTreeNodeId() : 'root'; - $arrayRepresentation2['readableRootline'] = $this->getReadableRootline(); - $arrayRepresentation2['mountPoint'] = $this->getMountPoint(); - $arrayRepresentation2['workspaceId'] = $this->getWorkspaceId(); - $arrayRepresentation2['isMountPoint'] = $this->isMountPoint(); - - // only set the leaf attribute if the node has children's, - // otherwise you cannot add child's to real leaf nodes - if (!$this->isLeafNode()) { - $arrayRepresentation2['leaf'] = FALSE; - } - // Do not nest nodeData and children arrays - unset($arrayRepresentation['nodeData']); - unset($arrayRepresentation['children']); - $arrayRepresentation = array_merge($arrayRepresentation, $arrayRepresentation2); - - // Suhosin(?) or some other strange environment thingy prevents - // the direct copy of an array into an index of the same array - $copy = $arrayRepresentation; - $arrayRepresentation['nodeData'] = $copy; - $arrayRepresentation['nodeData']['id'] = $arrayRepresentation['realId']; - - if ($this->hasChildNodes() && $addChildNodes) { - $arrayRepresentation['children'] = $this->childNodes->toArray(); - } + $arrayRepresentation['id'] = 'p' . dechex($this->getId()) . ($this->getMountPoint() ? '-' . dechex($this->getMountPoint()) : ''); + $arrayRepresentation['realId'] = $this->getId(); + $arrayRepresentation['nodeData']['id'] = $this->getId(); + + $arrayRepresentation['readableRootline'] = $this->getReadableRootline(); + $arrayRepresentation['nodeData']['readableRootline'] = $this->getReadableRootline(); + + $arrayRepresentation['nodeData']['mountPoint'] = $this->getMountPoint(); + $arrayRepresentation['nodeData']['workspaceId'] = $this->getWorkspaceId(); + $arrayRepresentation['nodeData']['isMountPoint'] = $this->isMountPoint(); + $arrayRepresentation['nodeData']['serializeClassName'] = get_class($this); return $arrayRepresentation; } @@ -365,35 +335,6 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_NavigationTree_Node implements $this->setReadableRootline($data['readableRootline']); $this->setIsMountPoint($data['isMountPoint']); } - - /** - * set the source field of the label - * - * @param string $field - * @return void - */ - public function setTextSourceField($field) { - $this->t3TextSourceField = $field; - } - - /** - * Returns the table of the record data - * - * @return string - */ - public function getSourceTable() { - return 'pages'; - } - - /** - * sets the Table of record source data - * - * @param string $table - * @return void - */ - public function setSourceTable($table) { - // not needed, pagetree always is 'pages' - } } if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php'])) { diff --git a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php index 12ccaeb8ed014d648c3b63670e664ea81d20f6f4..a3a33dac362ca8b8d76c4abedbb55fe3840f83cc 100644 --- a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php +++ b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php @@ -225,7 +225,7 @@ class t3lib_tree_pagetree_extdirect_Commands { * * @param stdClass $nodeData * @param int $destination - * @return array + * @return void */ public function moveNodeAfterDestination($nodeData, $destination) { /** @var $node t3lib_tree_pagetree_Node */ diff --git a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php index 466195f9c6763f6794e0a5555c744b2fda98729f..e8df3f8f2ab2711fd799603347925d0aa5cb6c9f 100644 --- a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php +++ b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php @@ -32,7 +32,7 @@ * @package TYPO3 * @subpackage t3lib */ -class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtJs_AbstractStatefulExtJsTree { +class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree { /** * Data Provider * @@ -180,7 +180,7 @@ class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtJs_AbstractStatef /** * Returns the language labels, sprites and configuration options for the pagetree * - * @return array + * @return void */ public function loadResources() { $file = 'LLL:EXT:lang/locallang_core.xml:'; diff --git a/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css b/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css index aed04b76ab3eca17b7f9cf0be8a42968c2c8e6fb..8ae4e364b21ce822b27a23892984d893099f3695 100644 --- a/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css +++ b/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css @@ -6,32 +6,50 @@ Pagetree #typo3-pagetree, #typo3-pagetree .x-panel-bwrap, #typo3-pagetree .x-panel-body { - border: none; height: 100%; } -.typo3-pagetree .x-grid-table { - padding-left: 5px; +#typo3-pagetree .x-panel-tbar { + padding: 0; + margin: 0; +} + +.x-tree-node .x-tree-node-el { + margin-right: 0; } .x-tree-node-readableRootline { padding: 10px 0 3px 10px; } -.typo3-pagetree span.t3-icon { +.x-tree-lines .typo3-pagetree-node-notExpandable .x-tree-ec-icon { + visibility: hidden; +} + +.x-tree-lines .typo3-pagetree-node-notExpandable ul .x-tree-ec-icon { + visibility: visible; +} + +#typo3-pagetree span.t3-icon { margin-bottom: 2px; } -.typo3-pagetree .x-grid-row .x-grid-cell a .typo3-pagetree-status, +#typo3-pagetree .x-toolbar, +.typo3-pagetree-topPanel-item .x-toolbar { + padding-bottom: 0; +} + +#typo3-pagetree ul.x-tree-root-ct { + padding-left: 5px; + padding-top: 15px; +} + +.x-tree-node a .typo3-pagetree-status, .x-dd-drag-ghost a .typo3-pagetree-status { padding: 0; margin: 0 3px 0 0; } -.typo3-pagetree .x-form-field { - height: 19px; -} - /** * * section drag and drop @@ -68,62 +86,62 @@ Pagetree * @section Top Panel * */ -#typo3-pagetree .x-docked-top { - padding: 0; +#typo3-pagetree-topPanel .x-toolbar-left { + height: 20px; } -.typo3-pagetree-topPanel { - height: 49px; +.typo3-pagetree-topPanel-button { + margin: 0 5px 0 0; + padding: 1px 2px; + height: 18px; } -#typo3-pagetree-topPanel .x-docked-top .x-box-inner { - height: 22px; - margin: 0; -} - -#typo3-pagetree .typo3-pagetree-topPanel-button { - height: 21px; - margin-right: 1px; - margin-top: 0px !important; - padding: 1px 3px 0 3px; +.typo3-pagetree-topPanel-button button { + height: 16px; + width: 16px; } .typo3-pagetree-topPanel-item { - padding: 2px 0 0 0; + padding: 5px 3px 0 3px; height: 22px; } -#typo3-pagetree-topPanel-item-newNode { - padding: 0; +#typo3-pagetree-topPanel-filterWrap { + padding-top: 3px; + height: 24px; } -.typo3-pagetree-topPanel-item .x-form-item { - border: none !important; - margin: 3px; - width: 100%; +#typo3-pagetree-topPanel-filter { + height: 16px; + width: 98% !important; + padding: 1px 0 1px 2px; } -.typo3-pagetree-topPanel-item .x-form-field { - height: 18px; - line-height: 16px; +#typo3-pagetree-topPanel-filterWrap .t3-icon-input-clear { + right: 2%; } -.typo3-pagetree-topPanel-filter .t3-icon-input-clear { +#typo3-pagetree .typo3-pagetree-topPanel-button { + margin-right: 1px; + margin-top: -2px; + padding: 2px 3px; } -.typo3-pagetree-topPanel-item .x-form-trigger-wrap { - margin: 0; +#typo3-pagetree-topPanel-defaultPanel { + padding-left: 6px; +} + +#typo3-pagetree-topPanel-filterWrap .x-form-field-trigger-wrap { + width: 100% !important; + margin: 0 20px 0 0; } .typo3-pagetree-topPanel-item .x-form-trigger { - background-image: none; - border-bottom: none !important; + margin: 4px 0 0; display: none; - margin-right: 0; - margin-top: 1px; } -.typo3-pagetree-topPanel-item .x-form-trigger-wrap-focus:hover .x-form-trigger { +.typo3-pagetree-topPanel-item .x-form-field-trigger-wrap:hover .x-form-trigger { display: block; } @@ -136,31 +154,25 @@ Pagetree * @section Indicator Bar * */ -#typo3-pagetree-indicatorBar { - width: 100%; -} - -#typo3-pagetree-indicatorBar-filter, -#typo3-pagetree-indicatorBar-temporaryMountPoint { - padding: 10px 20px; +.typo3-pagetree-indicatorBar-item p { + padding: 5px 10px; } #typo3-pagetree-indicatorBar-filter p, #typo3-pagetree-indicatorBar-temporaryMountPoint p { - padding-left: 5px; - width: 100%; + padding: 10px 35px; } .typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-leftIcon { - position: relative; - left: -10px; - top: 0px; + left: 10px; + top: 9px; + position: absolute; } .typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-rightIcon { - position: relative; - right: -10px; - vertical-align: top; + right: 10px; + top: 5px; + position: absolute; } #typo3-pagetree-indicatorBar-indicatorTitle span { diff --git a/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css b/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css index 2337e495ae04da2a9b9fc2dc3391f5834dc192d1..67dd10fc473fcaff1b3a890a46bde53e7a8828ab 100644 --- a/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css +++ b/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css @@ -3,29 +3,28 @@ Pagetree - - - - - - - - - - - - - - - - - - - - - */ #typo3-pagetree-treeContainer, -.typo3-pageTree-topPanelItems { +#typo3-pagetree-topPanelItems { background-color: #ebebeb; } -.typo3-pagetree .x-panel-body { +#typo3-pagetree .x-tree .x-panel-body { background: none; } -.typo3-pagetree .x-grid-row .x-grid-cell { +#typo3-pagetree .x-tree-node .x-tree-node-el { border-top: 1px solid transparent; border-bottom: 1px solid transparent; border-left: 1px solid transparent; - font-size: 12px; } -.typo3-pagetree .x-grid-row.x-grid-row-over .x-grid-cell, -.typo3-pagetree .x-grid-row.x-grid-row-selected .x-grid-cell { +#typo3-pagetree .x-tree-node .x-tree-node-over, +#typo3-pagetree .x-tree-node .x-tree-selected { border-bottom: 1px solid #d7d7d7; border-top: 1px solid #d7d7d7; border-left: 1px solid #d7d7d7; } -.typo3-pagetree .x-grid-row.x-grid-row-over .x-grid-cell { +#typo3-pagetree .x-tree-node .x-tree-node-over { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAABCAYAAAAb4BS0AAAAGElEQVR42gENAPL/AMjIyEzIyMizyMjI/zhvCQelaHPPAAAAAElFTkSuQmCC"); /* star-hack targets IE7 */ *background-image: url("../../images/shadows/navigation-container.png"); @@ -40,34 +39,20 @@ Pagetree border-bottom-right-radius: 3px; } -.typo3-pagetree .x-grid-row-selected .x-grid-cell { +#typo3-pagetree .x-tree-node .x-tree-selected { background-color: #f8f8f8; } -.typo3-pagetree .x-grid-row-selected.x-grid-row-over .x-grid-cell { +#typo3-pagetree .x-tree-node .x-tree-selected.x-tree-node-over { background-image: none; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } -.typo3-pagetree .x-tree-elbow-plus, -.typo3-pagetree .x-tree-elbow-end-plus { - background-image:url('../../images/icons/apps/pagetree-collapse.png'); -} - -.typo3-pagetree .x-tree-elbow-minus, -.typo3-pagetree .x-tree-elbow-end-minus, -.typo3-pagetree .x-grid-tree-node-expanded .x-tree-elbow-plus, -.typo3-pagetree .x-grid-tree-node-expanded .x-tree-elbow-end-plus { - background-image:url('../../images/icons/apps/pagetree-expand.png'); -} - -.typo3-pagetree .x-form-field { - color: black; - font-family: Verdana,Arial,Helvetica,sans-serif; - font-size: 11px; - line-height: 14px; +#typo3-pagetree .x-panel-tbar { + background-color: #585858; + border: none; } /** @@ -77,8 +62,6 @@ Pagetree */ .typo3-pagetree-tree-copy { color: #666; - font-size: 11px; - text-align: center; } .x-dd-drag-ghost { @@ -166,13 +149,7 @@ Pagetree * @section Top Panel * */ -#typo3-pagetree-topPanel .x-docked-top, -#typo3-pagetree-topPanel .x-docked-top .x-box-inner { - background-color: #585858; - border: none; -} - -#typo3-pagetree .x-panel-body .x-toolbar { +#typo3-pagetree .x-toolbar { background: none; border: none; } @@ -182,10 +159,6 @@ Pagetree border: none; } -#typo3-pagetree-topPanel-body { - background-color: #dadada; -} - #typo3-pagetree-topPanel .x-btn-click, #typo3-pagetree-topPanel .x-btn-over { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAWCAIAAACKUbHAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD9JREFUCB19wdERAUAARDEv23+FmsGZG38Sz0sfKoXEppDKyldyxBzzM1eObWYMM5Zr/ipEWRm9UXnr0OVxvQAaNAkk1SzJpgAAAABJRU5ErkJggg=="); @@ -220,6 +193,19 @@ Pagetree #typo3-pagetree .typo3-pagetree-topPanel-item { background-color: #dadada; + line-height: normal; +} + +#typo3-pagetree-topPanel-filter { + border: 1px solid #aeaeae; + -moz-box-shadow: inset 0 1px 1px #aeaeae; + -ms-box-shadow: inset 0 1px 1px #aeaeae; + -webkit-box-shadow: inset 0 1px 1px #aeaeae; + box-shadow: inset 0 2px 1px #aeaeae; +} + +.typo3-pagetree-topPanel-filter-defaultText { + color: gray; } #typo3-pagetree .typo3-pagetree-topPanel-button { @@ -233,10 +219,7 @@ Pagetree #typo3-pagetree-topPanel-defaultPanel { color: #a2aab8; -} - -.typo3-pagetree-topPanel-filter-defaultText { - color: gray; + line-height: 18px; } #typo3-pagetree-topPanel-item-newNode .x-btn-over { @@ -288,8 +271,7 @@ Pagetree * */ -#typo3-pagetree-indicatorBar-temporaryMountPoint p, -#typo3-pagetree-indicatorBar-filter p { +#typo3-pagetree-indicatorBar-temporaryMountPoint p { line-height: 13px; } @@ -314,7 +296,8 @@ Pagetree * @section Deletion Drop Zone * */ -#typo3-pagetree-deletionDropZone .x-panel-body { + +#typo3-pagetree-deletionDropZone { color: #FFF; background-color: #585858; -moz-box-shadow: inset 0 2px 5px #414141;