Commiting initial version of fix for bug 251656: Redesign dependency
tree, part 1: fix the tree itself. Changes the way bullets are displayed, allow for control-click expansion and contraction, and simplify styling of the links themselves. Still needs some refinement. git-svn-id: svn://10.0.0.236/branches/kiko_UI_20040909-BRANCH@162017 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
89
mozilla/webtools/bugzilla/css/dependency-tree.css
Normal file
89
mozilla/webtools/bugzilla/css/dependency-tree.css
Normal file
@@ -0,0 +1,89 @@
|
||||
/* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Bugzilla Bug Tracking System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Christian Reis <kiko@async.com.br>
|
||||
*/
|
||||
|
||||
ul.tree {
|
||||
padding-left: 0em;
|
||||
margin-left: 1em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.tree ul {
|
||||
padding-top: 3px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.tree li {
|
||||
/* see http://www.kryogenix.org/code/browser/aqlists/ for idea */
|
||||
padding-top: 3px;
|
||||
text-indent: -1.2em;
|
||||
padding-left: 0.5em;
|
||||
list-style-type: none;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
ul.tree li a.b {
|
||||
padding-left: 12px;
|
||||
margin-right: 2px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul.tree li a.b_open {
|
||||
background: url("../images/tree-open.png") center no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul.tree li a.b_closed {
|
||||
background: url("../images/tree-closed.png") center no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.summ_info {
|
||||
/* change to inline if you would like to see the full bug details
|
||||
* displayed in the list */
|
||||
display: none;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 90%;
|
||||
margin: 0.2em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
.hint h3, .hint ul {
|
||||
margin-top: 0.1em;
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
|
||||
/* uncomment this if you would like summary text of closed classes to be
|
||||
* striked through */
|
||||
/*
|
||||
.bz_closed + .summ_text {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
*/
|
||||
|
||||
/* for styling summaries that are leaves or not */
|
||||
.summ, .summ_deep {
|
||||
}
|
||||
|
||||
.summ_deep {
|
||||
}
|
||||
BIN
mozilla/webtools/bugzilla/images/tree-closed.png
Normal file
BIN
mozilla/webtools/bugzilla/images/tree-closed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 B |
BIN
mozilla/webtools/bugzilla/images/tree-open.png
Normal file
BIN
mozilla/webtools/bugzilla/images/tree-open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 B |
117
mozilla/webtools/bugzilla/js/expanding-tree.js
Normal file
117
mozilla/webtools/bugzilla/js/expanding-tree.js
Normal file
@@ -0,0 +1,117 @@
|
||||
/* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Bugzilla Bug Tracking System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Mike Shaver <shaver@mozilla.org>
|
||||
* Christian Reis <kiko@async.com.br>
|
||||
*/
|
||||
|
||||
if (!Node) {
|
||||
/* MSIE doesn't define Node, so provide a compatibility object */
|
||||
var Node = { TEXT_NODE: 3 }
|
||||
}
|
||||
|
||||
function doToggle(node, event)
|
||||
{
|
||||
var deep = event.altKey || event.ctrlKey;
|
||||
|
||||
if (node.nodeType == Node.TEXT_NODE)
|
||||
node = node.parentNode;
|
||||
|
||||
var toggle = node.nextSibling;
|
||||
while (toggle && toggle.tagName != "UL")
|
||||
toggle = toggle.nextSibling;
|
||||
|
||||
if (toggle) {
|
||||
if (deep) {
|
||||
var direction = toggleDisplay(toggle, node);
|
||||
changeChildren(toggle, direction);
|
||||
} else {
|
||||
toggleDisplay(toggle, node);
|
||||
}
|
||||
}
|
||||
/* avoid problems with default actions on links (mozilla's
|
||||
* ctrl/shift-click defaults, for instance */
|
||||
event.preventBubble();
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function changeChildren(node, direction) {
|
||||
var item = node.firstChild;
|
||||
while (item) {
|
||||
/* find the LI inside the UL I got */
|
||||
while (item && item.tagName != "LI")
|
||||
item = item.nextSibling;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
/* got it, now find the first A */
|
||||
var child = item.firstChild;
|
||||
while (child && child.tagName != "A")
|
||||
child = child.nextSibling;
|
||||
if (!child) {
|
||||
return
|
||||
}
|
||||
var bullet = child;
|
||||
|
||||
/* and check if it has its own sublist */
|
||||
var sublist = item.firstChild;
|
||||
while (sublist && sublist.tagName != "UL")
|
||||
sublist = sublist.nextSibling;
|
||||
if (sublist) {
|
||||
if (direction && isClosed(sublist)) {
|
||||
openNode(sublist, bullet);
|
||||
} else if (!direction && !isClosed(sublist)) {
|
||||
closeNode(sublist, bullet);
|
||||
}
|
||||
changeChildren(sublist, direction)
|
||||
}
|
||||
item = item.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function openNode(node, bullet)
|
||||
{
|
||||
node.style.display = "block";
|
||||
bullet.className = "b b_open";
|
||||
}
|
||||
|
||||
function closeNode(node, bullet)
|
||||
{
|
||||
node.style.display = "none";
|
||||
bullet.className = "b b_closed";
|
||||
}
|
||||
|
||||
function isClosed(node) {
|
||||
/* XXX we should in fact check our *computed* style, not the display
|
||||
* attribute of the current node, which may be inherited and not
|
||||
* set. However, this really only matters when changing the default
|
||||
* appearance of the tree through a parent style. */
|
||||
return node.style.display == "none";
|
||||
}
|
||||
|
||||
function toggleDisplay(node, bullet)
|
||||
{
|
||||
if (isClosed(node)) {
|
||||
openNode(node, bullet);
|
||||
return true;
|
||||
}
|
||||
|
||||
closeNode(node, bullet);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 };
|
||||
# have to embed a conditional statement into each query.
|
||||
my $milestone_column = Param('usetargetmilestone') ? "target_milestone" : "''";
|
||||
|
||||
# The greatest depth to which either tree goes.
|
||||
# Stores the greatest depth to which either tree goes.
|
||||
my $realdepth = 0;
|
||||
|
||||
# Generate the tree of bugs that this bug depends on and a list of IDs
|
||||
@@ -149,6 +149,7 @@ sub GetBug {
|
||||
if (Bugzilla->user->can_see_bug($id)) {
|
||||
SendSQL("SELECT 1,
|
||||
bug_status,
|
||||
resolution,
|
||||
short_desc,
|
||||
$milestone_column,
|
||||
assignee.userid,
|
||||
@@ -160,6 +161,7 @@ sub GetBug {
|
||||
|
||||
($bug->{'exists'},
|
||||
$bug->{'status'},
|
||||
$bug->{'resolution'},
|
||||
$bug->{'summary'},
|
||||
$bug->{'milestone'},
|
||||
$bug->{'assignee_id'},
|
||||
|
||||
@@ -25,135 +25,121 @@
|
||||
|
||||
[% PROCESS global/header.html.tmpl
|
||||
title = "Dependency tree for $terms.Bug $bugid"
|
||||
h1 = "Dependency tree for <a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>"
|
||||
h1 = "Dependency tree for
|
||||
<a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>"
|
||||
javascript_urls = ["js/expanding-tree.js"]
|
||||
style_urls = ["css/dependency-tree.css"]
|
||||
%]
|
||||
|
||||
[% PROCESS depthControlToolbar %]
|
||||
|
||||
[%# Display the tree of bugs that this bug depends on. %]
|
||||
<h3>
|
||||
[% IF hide_resolved %]
|
||||
Open [% terms.bugs %]
|
||||
[% ELSE %]
|
||||
[% terms.Bugs %]
|
||||
[% END %]
|
||||
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
|
||||
depends on</h3>
|
||||
[% IF dependson_ids.size > 0 %]
|
||||
(
|
||||
[% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %]
|
||||
<a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]">view as [% terms.bug %] list</a>
|
||||
[% IF canedit && dependson_ids.size > 1 %]
|
||||
| <a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]&tweak=1">change several</a>
|
||||
[% END %])
|
||||
[% INCLUDE display_tree tree=dependson_tree bug_id=bugid %]
|
||||
[% ELSE %]
|
||||
</h3>
|
||||
<p>None</p>
|
||||
[% END %]
|
||||
[% INCLUDE tree_section ids=dependson_ids bugid=bugid
|
||||
tree_name="dependson_tree" text="depends on" %]
|
||||
|
||||
[%# Display the tree of bugs that this bug blocks. %]
|
||||
<h3>
|
||||
[% IF hide_resolved %]
|
||||
Open [% terms.bugs %]
|
||||
[% ELSE %]
|
||||
[% terms.Bugs %]
|
||||
[% END %]
|
||||
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
|
||||
blocks</h3>
|
||||
[% IF blocked_ids.size > 0 %]
|
||||
(
|
||||
[% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %]
|
||||
<a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]">view as [% terms.bug %] list</a>
|
||||
[% IF canedit && blocked_ids.size > 1 %]
|
||||
| <a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]&tweak=1">change several</a>
|
||||
[% END %])
|
||||
[% INCLUDE display_tree tree=blocked_tree bug_id=bugid %]
|
||||
[% ELSE %]
|
||||
</h3>
|
||||
<p>None</p>
|
||||
[% END %]
|
||||
[% INCLUDE tree_section ids=blocked_ids bugid=bugid
|
||||
tree_name="blocked_tree" text = "blocks" %]
|
||||
|
||||
[% PROCESS depthControlToolbar %]
|
||||
|
||||
<div class="hint">
|
||||
<h3>Usage Hints</h3>
|
||||
<ul>
|
||||
<li>Click on expander icons to expand or contract a portion of the tree.
|
||||
<li>Control-clicking on expander icons performs a "deep" change:<br>
|
||||
all children [% terms.bugs %] are also expanded or contracted accordingly.
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
[% PROCESS global/footer.html.tmpl %]
|
||||
|
||||
[%###########################################################################%]
|
||||
[%# Tree-drawing blocks #%]
|
||||
[%###########################################################################%]
|
||||
|
||||
[%###########################################################################%]
|
||||
[%# Block to display a tree #%]
|
||||
[%###########################################################################%]
|
||||
[% BLOCK tree_section %]
|
||||
[%# INTERFACE
|
||||
# - tree_name: the name of the tree type ("dependson_tree" or "blocks_tree")
|
||||
# - bugid: the ID of the toplevel bug being displayed
|
||||
# - ids: a list of bug IDs to be displayed as children
|
||||
# GLOBALS
|
||||
# - seen: Maintains a global hash of bugs that have been displayed
|
||||
#%]
|
||||
[% global.seen = {} %]
|
||||
[%# Display the tree of bugs that this bug depends on. %]
|
||||
<h3>
|
||||
[% IF hide_resolved %]
|
||||
Open [% terms.bugs %]
|
||||
[% ELSE %]
|
||||
[% terms.Bugs %]
|
||||
[%- END %]
|
||||
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
|
||||
[% text FILTER html %]
|
||||
</h3>
|
||||
[% IF ids.size > 0 %]([% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END -%]<a href="buglist.cgi?bug_id=[% ids.join(",") %]">view as [% terms.bug %] list</a>
|
||||
[% IF canedit && ids.size > 1 %]
|
||||
| <a href="buglist.cgi?bug_id=[% ids.join(",") %]&tweak=1">change several</a>
|
||||
[% END %])
|
||||
<ul class="tree">
|
||||
[% INCLUDE display_tree tree=$tree_name bugid=bugid %]
|
||||
</ul>
|
||||
<b>Total [% terms.bugs %] displayed: [% ids.size %]</b>
|
||||
<p>
|
||||
[% ELSE %]
|
||||
<p>None</p>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[% BLOCK display_tree %]
|
||||
[% tree.$bug_id.seen = 1 %]
|
||||
<ul>
|
||||
[% FOREACH dep_id = tree.$bug_id.dependencies %]
|
||||
[% dep = tree.$dep_id %]
|
||||
<li>
|
||||
[% "<script>document.write('<a href=\"#\" class=\"toggle\" onclick=\"listToggle(event); return false\">[-]</a>')</script>"
|
||||
IF dep.dependencies.size > 0 && !dep.seen %]
|
||||
[% isclosed = !dep.open %]
|
||||
[% FILTER closed(isclosed) %]
|
||||
<a href="show_bug.cgi?id=[% dep_id %]">[% dep_id %]
|
||||
[[% IF dep.milestone %][% dep.milestone FILTER html %], [% END %]
|
||||
[% dep.assignee_email FILTER html %]] -
|
||||
[% IF dep.seen %]
|
||||
<i>This [% terms.bug %] appears elsewhere in this tree.</i></a>
|
||||
[% ELSE %]
|
||||
[% dep.summary FILTER html %].</a>
|
||||
[%# INTERFACE
|
||||
# - bugid: the ID of the bug being displayed
|
||||
# - tree: a hash of bug objects
|
||||
#%]
|
||||
[% bug = tree.$bugid %]
|
||||
<li>[%- INCLUDE bullet bugid=bugid bug=bug -%]<span class="summ[% "_deep" IF bug.dependencies.size %]">[%- INCLUDE buglink bug=bug bugid=bugid %]</span>
|
||||
[% IF global.seen.$bugid %]
|
||||
<b>(<a title="Already displayed above; click to locate"
|
||||
href="#b[% bugid %]">*</a>)</b>
|
||||
[% ELSIF bug.dependencies.size %]
|
||||
<ul>
|
||||
[% FOREACH depid = bug.dependencies %]
|
||||
[% INCLUDE display_tree bugid=depid %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% INCLUDE display_tree bug_id=dep_id
|
||||
IF dep.dependencies.size > 0 && !dep.seen %]
|
||||
</li>
|
||||
</ul>
|
||||
[% END %]
|
||||
</li>
|
||||
[% global.seen.$bugid = 1 %]
|
||||
[% END %]
|
||||
|
||||
[% BLOCK bullet %]
|
||||
[% IF bug.dependencies.size > 0 && ! global.seen.$bugid %]
|
||||
[% extra_class = " b_open" %]
|
||||
[% extra_args = 'href="#" onclick="return doToggle(this, event)"' %]
|
||||
[% END %]
|
||||
</ul>
|
||||
<a name="b[% bugid %]" class="b [%+ extra_class %]" [% extra_args %]> </a>
|
||||
[% END %]
|
||||
|
||||
[% BLOCK buglink %]
|
||||
[% isclosed = !bug.open %]
|
||||
[% FILTER closed(isclosed) -%]<a title="[% INCLUDE buginfo bug=bug %]" href="show_bug.cgi?id=[% bugid %]"><b>[% terms.bug %] [%+ bugid %]</b></a>[% END %]<span class="summ_text">: [%+ bug.summary FILTER html %]</span><span class="summ_info">[[% INCLUDE buginfo %]]</span>
|
||||
[% END %]
|
||||
|
||||
[% BLOCK buginfo %]
|
||||
[% bug.status FILTER html %]
|
||||
[%+ bug.resolution FILTER html %]; assigned to [% bug.assignee_email FILTER html %];
|
||||
[% "Target: " _ bug.milestone IF bug.milestone %]
|
||||
[% END %]
|
||||
|
||||
[%###########################################################################%]
|
||||
[%# Block for depth control toolbar #%]
|
||||
[%###########################################################################%]
|
||||
|
||||
<script type="text/javascript" language="JavaScript">
|
||||
if (!Node) {
|
||||
/* MSIE doesn't define Node, so provide a compatibility array */
|
||||
var Node = { TEXT_NODE: 3, };
|
||||
}
|
||||
|
||||
function toggleDisplay(node)
|
||||
{
|
||||
var display = node.style.display;
|
||||
if (display == "none") {
|
||||
node.style.display =
|
||||
("oldDisplay" in node) ? node.oldDisplay : "block";
|
||||
return true;
|
||||
}
|
||||
|
||||
node.oldDisplay = display;
|
||||
node.style.display = "none";
|
||||
return false;
|
||||
}
|
||||
|
||||
function listToggle(event)
|
||||
{
|
||||
var node = event.target;
|
||||
if (node.nodeType == Node.TEXT_NODE)
|
||||
node = node.parentNode;
|
||||
var toggle = node.nextSibling;
|
||||
while (toggle && toggle.tagName != "UL")
|
||||
toggle = toggle.nextSibling;
|
||||
if (toggle) {
|
||||
node.firstChild.data = toggleDisplay(toggle) ? "[-]" : "[+]";
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
[% BLOCK depthControlToolbar %]
|
||||
<table cellpadding="3" border="0" cellspacing="0" bgcolor="#d0d0d0">
|
||||
<table cellpadding="3" border="0" cellspacing="0" bgcolor="#e0e0e0">
|
||||
<tr>
|
||||
[%# Hide/show resolved button
|
||||
Swaps text depending on the state of hide_resolved %]
|
||||
<td align="center">
|
||||
<form method="get" action="showdependencytree.cgi"
|
||||
<form method="get" action="showdependencytree.cgi"
|
||||
style="display: inline; margin: 0px;">
|
||||
<input name="id" type="hidden" value="[% bugid %]">
|
||||
[% IF maxdepth %]
|
||||
@@ -162,7 +148,7 @@ function listToggle(event)
|
||||
<input type="hidden" name="hide_resolved" value="[% hide_resolved ? 0 : 1 %]">
|
||||
<input type="submit"
|
||||
value="[% IF hide_resolved %]Show[% ELSE %]Hide[% END %] Resolved">
|
||||
</form>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@@ -228,8 +214,7 @@ function listToggle(event)
|
||||
[% END %]
|
||||
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
|
||||
<input type="submit" value=" > "
|
||||
[% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]
|
||||
%]>
|
||||
[% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
|
||||
@@ -323,10 +323,8 @@
|
||||
'bug/dependency-tree.html.tmpl' => [
|
||||
'bugid',
|
||||
'maxdepth',
|
||||
'dependson_ids.join(",")',
|
||||
'blocked_ids.join(",")',
|
||||
'dep_id',
|
||||
'hide_resolved',
|
||||
'ids.join(",")',
|
||||
'maxdepth + 1',
|
||||
'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""',
|
||||
'maxdepth == 1 ? 1
|
||||
|
||||
Reference in New Issue
Block a user