Commit 2affe491 authored by Thomas Schlumberger's avatar Thomas Schlumberger Committed by Anja Leichsenring
Browse files

[TASK] Rework folder trees based on CSS only

Renders all folder and page trees in the same HTML
manner.

These are located in:
- Link Wizards
- RTE popups
- Select / Group Field Selector Popups (e.g. Insert Record)

Next steps:
- Rework the impexp tree
- Rework the Move Tree and the New Element Position Maps
- Add highlighting
- Simplify the calls to each method and remove
"old" parameters to methods, rename the methods
to make them speaking.

Releases: master
Resolves: #68018
Change-Id: I675368039f2065dcd9e4bb2555da4495f84eb87b
Reviewed-on: http://review.typo3.org/41001


Reviewed-by: Benni Mack's avatarBenjamin Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenjamin Mack <benni@typo3.org>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent 74cfa98c
......@@ -381,9 +381,8 @@ abstract class AbstractTreeView {
$this->ids = $curIds;
// Set PM icon for root of mount:
$cmd = $this->bank . '_' . ($isOpen ? '0_' : '1_') . $uid . '_' . $this->treeName;
$icon = IconUtility::getSpriteIcon('treeline-' . ($isOpen ? 'minus' : 'plus') . 'only');
$firstHtml = $this->PM_ATagWrap($icon, $cmd);
$firstHtml = $this->PM_ATagWrap('', $cmd, '', $isOpen);
// Preparing rootRec for the mount
if ($uid) {
$rootRec = $this->getRecord($uid);
......@@ -397,15 +396,13 @@ abstract class AbstractTreeView {
// In case it was swapped inside getRecord due to workspaces.
$uid = $rootRec['uid'];
// Add the root of the mount to ->tree
$this->tree[] = array('HTML' => $firstHtml, 'row' => $rootRec, 'bank' => $this->bank);
$this->tree[] = array('HTML' => $firstHtml, 'row' => $rootRec, 'hasSub' => $isOpen, 'bank' => $this->bank);
// If the mount is expanded, go down:
if ($isOpen) {
// Set depth:
$depthD = IconUtility::getSpriteIcon('treeline-blank');
if ($this->addSelfId) {
$this->ids[] = $uid;
}
$this->getTree($uid, 999, $depthD, '', $rootRec['_SUBCSSCLASS']);
$this->getTree($uid, 999, '', '', $rootRec['_SUBCSSCLASS']);
}
// Add tree:
$treeArr = array_merge($treeArr, $this->tree);
......@@ -426,27 +423,40 @@ abstract class AbstractTreeView {
$treeArr = $this->tree;
}
$out = '';
// put a table around it with IDs to access the rows from JS
// not a problem if you don't need it
// In XHTML there is no "name" attribute of <td> elements -
// but Mozilla will not be able to highlight rows if the name
// attribute is NOT there.
$out .= '
<!--
TYPO3 tree structure.
-->
<table cellpadding="0" cellspacing="0" border="0" id="typo3-tree">';
foreach ($treeArr as $k => $v) {
$idAttr = htmlspecialchars($this->domIdPrefix . $this->getId($v['row']) . '_' . $v['bank']);
$out .= '
<tr>
<td id="' . $idAttr . '"' . ($v['row']['_CSSCLASS'] ? ' class="' . $v['row']['_CSSCLASS'] . '"' : '') . '>' . $v['HTML'] . $this->wrapTitle($this->getTitleStr($v['row'], $titleLen), $v['row'], $v['bank']) . '</td>
</tr>
';
$closeDepth = array();
foreach ($treeArr as $treeItem) {
$classAttr = $treeItem['row']['_CSSCLASS'];
if ($treeItem['isFirst']) {
$out .= '<ul class="list-tree">';
}
// Add CSS classes to the list item
if ($treeItem['hasSub']) {
$classAttr .= ' list-tree-control-open';
}
$idAttr = htmlspecialchars($this->domIdPrefix . $this->getId($treeItem['row']) . '_' . $treeItem['bank']);
$out .= '<li id="' . $idAttr . '"' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '') . '><span class="list-tree-group">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLen), $treeItem['row'], $treeItem['bank']) . '</span>';
if (!$treeItem['hasSub']) {
$out .= '</li>';
}
// We have to remember if this is the last one
// on level X so the last child on level X+1 closes the <ul>-tag
if ($treeItem['isLast']) {
$closeDepth[$treeItem['invertedDepth']] = 1;
}
// If this is the last one and does not have subitems, we need to close
// the tree as long as the upper levels have last items too
if ($treeItem['isLast'] && !$treeItem['hasSub']) {
for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++) {
$closeDepth[$i] = 0;
$out .= '</ul></li>';
}
}
}
$out .= '
</table>';
$out = '<ul class="list-tree" id="treeRoot">' . $out . '</ul>';
return $out;
}
......@@ -462,21 +472,19 @@ abstract class AbstractTreeView {
* @param int $a The current entry number
* @param int $c The total number of entries. If equal to $a, a "bottom" element is returned.
* @param int $nextCount The number of sub-elements to the current element.
* @param bool $exp The element was expanded to render subelements if this flag is set.
* @param bool $isOpen The element was expanded to render subelements if this flag is set.
* @return string Image tag with the plus/minus icon.
* @access private
* @see \TYPO3\CMS\Backend\Tree\View\PageTreeView::PMicon()
*/
public function PMicon($row, $a, $c, $nextCount, $exp) {
$PM = $nextCount ? ($exp ? 'minus' : 'plus') : 'join';
$BTM = $a == $c ? 'bottom' : '';
$icon = IconUtility::getSpriteIcon('treeline-' . $PM . $BTM);
public function PMicon($row, $a, $c, $nextCount, $isOpen) {
if ($nextCount) {
$cmd = $this->bank . '_' . ($exp ? '0_' : '1_') . $row['uid'] . '_' . $this->treeName;
$cmd = $this->bank . '_' . ($isOpen ? '0_' : '1_') . $row['uid'] . '_' . $this->treeName;
$bMark = $this->bank . '_' . $row['uid'];
$icon = $this->PM_ATagWrap($icon, $cmd, $bMark);
return $this->PM_ATagWrap('', $cmd, $bMark, $isOpen);
} else {
return '';
}
return $icon;
}
/**
......@@ -485,17 +493,18 @@ abstract class AbstractTreeView {
* @param string $icon HTML string to wrap, probably an image tag.
* @param string $cmd Command for 'PM' get var
* @param bool $bMark If set, the link will have a anchor point (=$bMark) and a name attribute (=$bMark)
* @param bool $isOpen
* @return string Link-wrapped input string
* @access private
*/
public function PM_ATagWrap($icon, $cmd, $bMark = '') {
public function PM_ATagWrap($icon, $cmd, $bMark = '', $isOpen = FALSE) {
if ($this->thisScript) {
if ($bMark) {
$anchor = '#' . $bMark;
$name = ' name="' . $bMark . '"';
}
$aUrl = $this->getThisScript() . 'PM=' . $cmd . $anchor;
return '<a href="' . htmlspecialchars($aUrl) . '"' . $name . '>' . $icon . '</a>';
return '<a class="list-tree-control ' . ($isOpen ? 'list-tree-control-open' : 'list-tree-control-closed') . ' href="' . htmlspecialchars($aUrl) . '"' . $name . '><i class="fa"></i></a>';
} else {
return $icon;
}
......@@ -731,7 +740,6 @@ abstract class AbstractTreeView {
end($this->tree);
// Get the key for this space
$treeKey = key($this->tree);
$LN = $a == $c ? 'blank' : 'line';
// If records should be accumulated, do so
if ($this->setRecs) {
$this->recs[$row['uid']] = $row;
......@@ -742,34 +750,35 @@ abstract class AbstractTreeView {
$this->orig_ids_hierarchy[$depth][] = $row['_ORIG_uid'] ?: $row['uid'];
// Make a recursive call to the next level
$HTML_depthData = $depthData . IconUtility::getSpriteIcon('treeline-' . $LN);
if ($depth > 1 && $this->expandNext($newID) && !$row['php_tree_stop']) {
$nextCount = $this->getTree($newID, $depth - 1, $this->makeHTML ? $HTML_depthData : '', $blankLineCode . ',' . $LN, $row['_SUBCSSCLASS']);
$hasSub = $this->expandNext($newID) && !$row['php_tree_stop'];
if ($depth > 1 && $hasSub) {
$nextCount = $this->getTree($newID, $depth - 1, '', '', $row['_SUBCSSCLASS']);
if (!empty($this->buffer_idH)) {
$idH[$row['uid']]['subrow'] = $this->buffer_idH;
}
// Set "did expand" flag
$exp = 1;
$isOpen = 1;
} else {
$nextCount = $this->getCount($newID);
// Clear "did expand" flag
$exp = 0;
$isOpen = 0;
}
// Set HTML-icons, if any:
if ($this->makeHTML) {
$HTML = $depthData . $this->PMicon($row, $a, $c, $nextCount, $exp);
$HTML .= $this->wrapStop($this->getIcon($row), $row);
$HTML = $this->PMicon($row, $a, $c, $nextCount, $isOpen) . $this->wrapStop($this->getIcon($row), $row);
}
// Finally, add the row/HTML content to the ->tree array in the reserved key.
$this->tree[$treeKey] = array(
'row' => $row,
'HTML' => $HTML,
'HTML_depthData' => $this->makeHTML == 2 ? $HTML_depthData : '',
'invertedDepth' => $depth,
'blankLineCode' => $blankLineCode,
'bank' => $this->bank
'bank' => $this->bank,
'hasSub' => $nextCount && $hasSub,
'isFirst' => $a === 1,
'isLast' => $a === $c,
);
}
$this->getDataFree($res);
$this->buffer_idH = $idH;
return $c;
......@@ -842,8 +851,7 @@ abstract class AbstractTreeView {
}
return $parentId;
} else {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',', $this->fieldArray), $this->table, $this->parentField . '=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($parentId, $this->table) . BackendUtility::deleteClause($this->table) . BackendUtility::versioningPlaceholderClause($this->table) . $this->clause, '', $this->orderByFields);
return $res;
return $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',', $this->fieldArray), $this->table, $this->parentField . '=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($parentId, $this->table) . BackendUtility::deleteClause($this->table) . BackendUtility::versioningPlaceholderClause($this->table) . $this->clause, '', $this->orderByFields);
}
}
......@@ -859,8 +867,7 @@ abstract class AbstractTreeView {
if (is_array($this->data)) {
return count($this->dataLookup[$res][$this->subLevelID]);
} else {
$c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
return $c;
return $GLOBALS['TYPO3_DB']->sql_num_rows($res);
}
}
......
......@@ -83,7 +83,7 @@ class ElementBrowserFolderTreeView extends FolderTreeView {
* @return string Link-wrapped input string
* @access private
*/
public function PM_ATagWrap($icon, $cmd, $bMark = '') {
public function PM_ATagWrap($icon, $cmd, $bMark = '', $isOpen = FALSE) {
$name = $anchor = '';
if ($bMark) {
$anchor = '#' . $bMark;
......
......@@ -68,32 +68,49 @@ class ElementBrowserPageTreeView extends BrowseTreeView {
$treeArr = $this->tree;
}
$out = '';
$c = 0;
foreach ($treeArr as $k => $v) {
$c++;
$bgColorClass = ($c + 1) % 2 ? 'bgColor' : 'bgColor-10';
if ($GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid'] == $v['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']) {
$arrCol = '<td><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR" alt="" /></td>';
$bgColorClass = 'bgColor4';
// We need to count the opened <ul>'s every time we dig into another level,
// so we know how many we have to close when all children are done rendering
$closeDepth = array();
foreach ($treeArr as $treeItem) {
$classAttr = $treeItem['row']['_CSSCLASS'];
if ($treeItem['isFirst']) {
$out .= '<ul class="list-tree">';
}
// Add CSS classes to the list item
if ($treeItem['hasSub']) {
$classAttr .= ' list-tree-control-open';
}
if ($GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid'] == $treeItem['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']) {
$arrCol = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR pull-right" alt="" />';
} else {
$arrCol = '<td></td>';
$arrCol = '';
}
$aOnClick = 'return jumpToUrl(' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=' . $GLOBALS['SOBE']->browser->act . '&mode=' . $GLOBALS['SOBE']->browser->mode . '&expandPage=' . $v['row']['uid']) . ');';
$cEbullet = $this->ext_isLinkable($v['row']['doktype'], $v['row']['uid']) ? '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/ol/arrowbullet.gif', 'width="18" height="16"') . ' alt="" /></a>' : '';
$out .= '
<tr class="' . $bgColorClass . '">
<td nowrap="nowrap"' . ($v['row']['_CSSCLASS'] ? ' class="' . $v['row']['_CSSCLASS'] . '"' : '') . '>' . $v['HTML'] . $this->wrapTitle($this->getTitleStr($v['row'], $titleLen), $v['row'], $this->ext_pArrPages) . '</td>' . $arrCol . '<td>' . $cEbullet . '</td>
</tr>';
}
$out = '
$aOnClick = 'return jumpToUrl(' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=' . $GLOBALS['SOBE']->browser->act . '&mode=' . $GLOBALS['SOBE']->browser->mode . '&expandPage=' . $treeItem['row']['uid']) . ');';
$cEbullet = $this->ext_isLinkable($treeItem['row']['doktype'], $treeItem['row']['uid']) ? '<a href="#" class="pull-right" onclick="' . htmlspecialchars($aOnClick) . '"><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/ol/arrowbullet.gif', 'width="18" height="16"') . ' alt="" /></a>' : '';
$out .= '<li' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '') . '><span class="list-tree-group">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLen), $treeItem['row'], $this->ext_pArrPages) . $cEbullet . $arrCol . '</span>';
if (!$treeItem['hasSub']) {
$out .= '</li>';
}
<!--
Navigation Page Tree:
-->
<table border="0" cellpadding="0" cellspacing="0" id="typo3-tree">
' . $out . '
</table>';
// We have to remember if this is the last one
// on level X so the last child on level X+1 closes the <ul>-tag
if ($treeItem['isLast']) {
$closeDepth[$treeItem['invertedDepth']] = 1;
}
// If this is the last one and does not have subitems, we need to close
// the tree as long as the upper levels have last items too
if ($treeItem['isLast'] && !$treeItem['hasSub']) {
for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++) {
$closeDepth[$i] = 0;
$out .= '</ul></li>';
}
}
}
$out = '<ul class="list-tree" id="treeRoot">' . $out . '</ul>';
return $out;
}
......@@ -116,16 +133,17 @@ class ElementBrowserPageTreeView extends BrowseTreeView {
* @param string $icon HTML string to wrap, probably an image tag.
* @param string $cmd Command for 'PM' get var
* @param bool $bMark If set, the link will have a anchor point (=$bMark) and a name attribute (=$bMark)
* @param bool $isOpen
* @return string Link-wrapped input string
*/
public function PM_ATagWrap($icon, $cmd, $bMark = '') {
public function PM_ATagWrap($icon, $cmd, $bMark = '', $isOpen = FALSE) {
$name = '';
if ($bMark) {
$anchor = '#' . $bMark;
$name = ' name=' . $bMark;
}
$aOnClick = 'return jumpToUrl(' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($this->getThisScript() . 'PM=' . $cmd) . ',' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($anchor) . ');';
return '<a href="#"' . htmlspecialchars($name) . ' onclick="' . htmlspecialchars($aOnClick) . '">' . $icon . '</a>';
return '<a class="list-tree-control ' . ($isOpen ? 'list-tree-control-open' : 'list-tree-control-closed') . '" href="#"' . htmlspecialchars($name) . ' onclick="' . htmlspecialchars($aOnClick) . '"><i class="fa"></i></a>';
}
/**
......
......@@ -99,9 +99,7 @@ class FolderTreeView extends AbstractTreeView {
* @see \TYPO3\CMS\Backend\Tree\View\PageTreeView::PMicon()
*/
public function PMicon(\TYPO3\CMS\Core\Resource\Folder $folderObject, $subFolderCounter, $totalSubFolders, $nextCount, $isExpanded) {
$PM = $nextCount ? ($isExpanded ? 'minus' : 'plus') : 'join';
$BTM = $subFolderCounter == $totalSubFolders ? 'bottom' : '';
$icon = '<img' . IconUtility::skinImg($this->backPath, ('gfx/ol/' . $PM . $BTM . '.gif'), 'width="18" height="16"') . ' alt="" />';
$icon = '';
if ($nextCount) {
$cmd = $this->generateExpandCollapseParameter($this->bank, !$isExpanded, $folderObject);
$icon = $this->PMiconATagWrap($icon, $cmd, !$isExpanded);
......@@ -137,7 +135,7 @@ class FolderTreeView extends AbstractTreeView {
$scopeData = serialize($this->scope);
$scopeHash = GeneralUtility::hmac($scopeData);
$js = htmlspecialchars('Tree.load(' . GeneralUtility::quoteJSvalue($cmd) . ', ' . (int)$isExpand . ', this, ' . GeneralUtility::quoteJSvalue($scopeData) . ', ' . GeneralUtility::quoteJSvalue($scopeHash) . ');');
return '<a class="pm" onclick="' . $js . '">' . $icon . '</a>';
return '<a class="list-tree-control' . (!$isExpand ? ' list-tree-control-open' : ' list-tree-control-closed') . '" onclick="' . $js . '"><i class="fa"></i></a>';
} else {
return $icon;
}
......@@ -245,11 +243,6 @@ class FolderTreeView extends AbstractTreeView {
$this->getBrowseableTreeForStorage($storageObject);
// Add tree:
$treeItems = array_merge($treeItems, $this->tree);
// if this is an AJAX call, don't run through all mounts, only
// show the expansion of the current one, not the rest of the mounts
if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
}
}
return $this->printTree($treeItems);
}
......@@ -294,18 +287,14 @@ class FolderTreeView extends AbstractTreeView {
// Set PM icon:
$cmd = $this->generateExpandCollapseParameter($this->bank, !$isOpen, $rootLevelFolder);
if (!$storageObject->isBrowsable() || $this->getNumberOfSubfolders($rootLevelFolder) === 0) {
$rootIcon = 'blank';
} elseif (!$isOpen) {
$rootIcon = 'plusonly';
$firstHtml = '';
} else {
$rootIcon = 'minusonly';
}
$icon = '<img' . IconUtility::skinImg($this->backPath, ('gfx/ol/' . $rootIcon . '.gif')) . ' alt="" />';
// Only link icon if storage is browseable
if (in_array($rootIcon, array('minusonly', 'plusonly'))) {
$firstHtml = $this->PM_ATagWrap($icon, $cmd);
} else {
$firstHtml = $icon;
// Only show and link icon if storage is browseable
$link = '';
if ($this->thisScript) {
$link = ' href="' . htmlspecialchars($this->getThisScript() . 'PM=' . $cmd) . '"';
}
$firstHtml = '<a class="list-tree-control list-tree-control-' . ($isOpen ? 'open' : 'closed') . '"' . $link . '><i class="fa"></i></a>';
}
// Mark a storage which is not online, as offline
// maybe someday there will be a special icon for this
......@@ -443,7 +432,7 @@ class FolderTreeView extends AbstractTreeView {
$out = '
<!-- TYPO3 folder tree structure. -->
<ul class="tree" id="treeRoot">
<ul id="treeRoot" class="list-tree">
';
// Evaluate AJAX request
if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX) {
......@@ -471,21 +460,16 @@ class FolderTreeView extends AbstractTreeView {
// If this item is the start of a new level,
// then a new level <ul> is needed, but not in ajax mode
if ($treeItem['isFirst'] && !$doCollapse && !($doExpand && $isExpandedFolderIdentifier)) {
$itemHTML = '<ul>
';
$itemHTML = '<ul class="list-tree">';
}
// Add CSS classes to the list item
if ($treeItem['hasSub']) {
$classAttr .= ' expanded';
}
if ($treeItem['isLast']) {
$classAttr .= ' last';
$classAttr .= ' list-tree-control-open';
}
$itemHTML .= '
<li id="' . $idAttr . '" ' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '') . '><div class="treeLinkItem">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLength), $folderObject, $treeItem['bank']) . '</div>';
<li id="' . $idAttr . '" ' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '') . '><span class="list-tree-group">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLength), $folderObject, $treeItem['bank']) . '</span>';
if (!$treeItem['hasSub']) {
$itemHTML .= '</li>
';
$itemHTML .= '</li>';
}
// We have to remember if this is the last one
// on level X so the last child on level X+1 closes the <ul>-tag
......@@ -497,8 +481,7 @@ class FolderTreeView extends AbstractTreeView {
if ($treeItem['isLast'] && !$treeItem['hasSub'] && !$doCollapse && !($doExpand && $isExpandedFolderIdentifier)) {
for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++) {
$closeDepth[$i] = 0;
$itemHTML .= '</ul></li>
';
$itemHTML .= '</ul></li>';
}
}
// Ajax request: collapse
......
......@@ -46,9 +46,10 @@ class LocalPageTree extends \TYPO3\CMS\Backend\Tree\View\BrowseTreeView {
* @param string $icon Icon HTML
* @param mixed $cmd (See parent class)
* @param mixed $bMark (See parent class)
* @param bool $isOpen
* @return string Icon HTML
*/
public function PM_ATagWrap($icon, $cmd, $bMark = '') {
public function PM_ATagWrap($icon, $cmd, $bMark = '', $isOpen = '') {
return $icon;
}
......
......@@ -45,32 +45,47 @@ class PageTree extends \TYPO3\CMS\Backend\Tree\View\ElementBrowserPageTreeView {
$treeArr = $this->tree;
}
$out = '';
$c = 0;
foreach ($treeArr as $k => $v) {
$c++;
$bgColorClass = ($c + 1) % 2 ? 'bgColor' : 'bgColor-10';
if ($GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid'] == $v['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']) {
$arrCol = '<td><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR" alt="" /></td>';
$bgColorClass = 'bgColor4';
$closeDepth = array();
foreach ($treeArr as $treeItem) {
$classAttr = $treeItem['row']['_CSSCLASS'];
if ($treeItem['isFirst']) {
$out .= '<ul class="list-tree">';
}
// Add CSS classes to the list item
if ($treeItem['hasSub']) {
$classAttr .= ' list-tree-control-open';
}
if ($GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid'] == $treeItem['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']) {
$arrCol = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR pull-right" alt="" />';
} else {
$arrCol = '<td></td>';
$arrCol = '';
}
$aOnClick = 'return jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=' . $GLOBALS['SOBE']->browser->act . '&editorNo=' . $GLOBALS['SOBE']->browser->editorNo . '&contentTypo3Language=' . $GLOBALS['SOBE']->browser->contentTypo3Language . '&mode=' . $GLOBALS['SOBE']->browser->mode . '&expandPage=' . $v['row']['uid']) . ');';
$cEbullet = $this->ext_isLinkable($v['row']['doktype'], $v['row']['uid']) ? '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/ol/arrowbullet.gif', 'width="18" height="16"') . ' alt="" /></a>' : '';
$out .= '
<tr class="' . $bgColorClass . '">
<td nowrap="nowrap"' . ($v['row']['_CSSCLASS'] ? ' class="' . $v['row']['_CSSCLASS'] . '"' : '') . '>' . $v['HTML'] . $this->wrapTitle($this->getTitleStr($v['row'], $titleLen), $v['row'], $this->ext_pArrPages) . '</td>' . $arrCol . '<td>' . $cEbullet . '</td>
</tr>';
}
$out = '
$aOnClick = 'return jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=' . $GLOBALS['SOBE']->browser->act . '&editorNo=' . $GLOBALS['SOBE']->browser->editorNo . '&contentTypo3Language=' . $GLOBALS['SOBE']->browser->contentTypo3Language . '&mode=' . $GLOBALS['SOBE']->browser->mode . '&expandPage=' . $treeItem['row']['uid']) . ');';
$cEbullet = $this->ext_isLinkable($treeItem['row']['doktype'], $treeItem['row']['uid']) ? '<a href="#" class="pull-right" onclick="' . htmlspecialchars($aOnClick) . '"><img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/ol/arrowbullet.gif', 'width="18" height="16"') . ' alt="" /></a>' : '';
$out .= '<li' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '') . '><span class="list-tree-group">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLen), $treeItem['row'], $this->ext_pArrPages) . $cEbullet . $arrCol . '</span>';
if (!$treeItem['hasSub']) {
$out .= '</li>';
}
<!--
Navigation Page Tree:
-->
<table border="0" cellpadding="0" cellspacing="0" id="typo3-tree">
' . $out . '
</table>';
// We have to remember if this is the last one
// on level X so the last child on level X+1 closes the <ul>-tag
if ($treeItem['isLast']) {
$closeDepth[$treeItem['invertedDepth']] = 1;
}
// If this is the last one and does not have subitems, we need to close
// the tree as long as the upper levels have last items too
if ($treeItem['isLast'] && !$treeItem['hasSub']) {
for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++) {
$closeDepth[$i] = 0;
$out .= '</ul></li>';
}
}
}
$out = '<ul class="list-tree" id="treeRoot">' . $out . '</ul>';
return $out;
}
......
......@@ -132,6 +132,29 @@ body#typo3-alt-db-navframe-php div.c-notice {
width: 95%;
}
/** CSS-based tree for Foldertree */
ul#treeRoot {
li:last-child:before {
background-color: #ececec;
}
&:before {
border: 0;
}
> li:before {
border: 0;
}
> li {
border-left: 0;
}
}
// change background color for folder nav frame
body#ext-backend-Modules-FileSystemNavigationFrame-index-php ul#treeRoot li:last-child:before {
background-color: #f5f5f5;
}
//
// Configuration trees, used in Admin Tools => Configuration
//
......@@ -157,10 +180,12 @@ body#ext-backend-Modules-FileSystemNavigationFrame-index-php {
padding: 0;
}
body#typo3-pagetree #typo3-inner-docbody,
body#ext-backend-Modules-FileSystemNavigationFrame-index-php #typo3-inner-docbody {
body#typo3-pagetree #typo3-inner-docbody {
padding: 0 0 10px 0;
}
body#ext-backend-Modules-FileSystemNavigationFrame-index-php #typo3-inner-docbody {
padding: 10px 0;
}
ul.tree {
line-height: 12px;
......@@ -300,8 +325,7 @@ ul.tree div.treeLinkItem span.dragIcon {
visibility: hidden;
}
#typo3-pagetree #typo3-docheader img,
#ext-backend-Modules-FileSystemNavigationFrame-index-php #typo3-docheader img {
#typo3-pagetree #typo3-docheader img {
margin: 2px;
}
......
......@@ -10865,6 +10865,22 @@ body#typo3-alt-db-navframe-php div.c-notice {
padding: 5px 5px 5px 5px;
width: 95%;
}
/** CSS-based tree for Foldertree */
ul#treeRoot li:last-child:before {
background-color: #ececec;