, ExtensionPoint, Saveable, ModelObjectWithChildren {
/**
* Container of this view. Set right after the construction
@@ -1068,6 +1070,12 @@ public abstract class View extends AbstractModelObject implements AccessControll
}
}
+ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception {
+ ContextMenu m = new ContextMenu();
+ for (TopLevelItem i : getItems())
+ m.add(i.getShortUrl(),i.getDisplayName());
+ return m;
+ }
/**
* A list of available view types.
diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java
index 3e538762e1..083937d8aa 100755
--- a/core/src/main/java/jenkins/model/Jenkins.java
+++ b/core/src/main/java/jenkins/model/Jenkins.java
@@ -307,7 +307,9 @@ import javax.annotation.Nullable;
* @author Kohsuke Kawaguchi
*/
@ExportedBean
-public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGroup, StaplerProxy, StaplerFallback, ViewGroup, AccessControlled, DescriptorByNameOwner, ModelObjectWithContextMenu {
+public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGroup, StaplerProxy, StaplerFallback,
+ ViewGroup, AccessControlled, DescriptorByNameOwner,
+ ModelObjectWithContextMenu, ModelObjectWithChildren {
private transient final Queue queue;
/**
@@ -3094,6 +3096,14 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
return menu;
}
+ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception {
+ ContextMenu menu = new ContextMenu();
+ for (View view : getViews()) {
+ menu.add(view.getViewUrl(),view.getDisplayName());
+ }
+ return menu;
+ }
+
/**
* Obtains the heap dump.
*/
diff --git a/core/src/main/java/jenkins/model/ModelObjectWithChildren.java b/core/src/main/java/jenkins/model/ModelObjectWithChildren.java
new file mode 100644
index 0000000000..4865693581
--- /dev/null
+++ b/core/src/main/java/jenkins/model/ModelObjectWithChildren.java
@@ -0,0 +1,23 @@
+package jenkins.model;
+
+import hudson.model.ModelObject;
+import jenkins.model.ModelObjectWithContextMenu.ContextMenu;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.StaplerResponse;
+
+/**
+ * {@link ModelObject} that has the children context menu in the breadcrumb.
+ *
+ *
+ * The children context menu is to show all the immediate children that this model object owns,
+ * thereby providing quicker navigation to ancestors' siblings in the breadcrumb.
+ *
+ * @author Kohsuke Kawaguchi
+ * @see ModelObjectWithContextMenu
+ */
+public interface ModelObjectWithChildren extends ModelObject {
+ /**
+ * Generates the context menu to list up all the children.
+ */
+ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception;
+}
diff --git a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java
index d86344aca6..954fbd8591 100644
--- a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java
+++ b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java
@@ -39,6 +39,7 @@ import java.util.List;
* shows the drop-down menu for providing quicker access to the actions to those objects.
*
* @author Kohsuke Kawaguchi
+ * @see ModelObjectWithChildren
*/
public interface ModelObjectWithContextMenu extends ModelObject {
/**
diff --git a/core/src/main/resources/lib/layout/breadcrumb.jelly b/core/src/main/resources/lib/layout/breadcrumb.jelly
index d888e207f3..a9ee939070 100644
--- a/core/src/main/resources/lib/layout/breadcrumb.jelly
+++ b/core/src/main/resources/lib/layout/breadcrumb.jelly
@@ -39,7 +39,7 @@ THE SOFTWARE.
-
+
${attrs.title}
diff --git a/core/src/main/resources/lib/layout/breadcrumbBar.jelly b/core/src/main/resources/lib/layout/breadcrumbBar.jelly
index 8ac1950dc5..f00fb45e99 100644
--- a/core/src/main/resources/lib/layout/breadcrumbBar.jelly
+++ b/core/src/main/resources/lib/layout/breadcrumbBar.jelly
@@ -58,11 +58,22 @@ THE SOFTWARE.
- -
+
-
+
+
+ -
+
+
+
+
+ -
+
+
+
diff --git a/core/src/main/resources/lib/layout/breadcrumbs.css b/core/src/main/resources/lib/layout/breadcrumbs.css
index a89bc2cd18..10dc4086dc 100644
--- a/core/src/main/resources/lib/layout/breadcrumbs.css
+++ b/core/src/main/resources/lib/layout/breadcrumbs.css
@@ -29,9 +29,8 @@
#breadcrumbs LI {
float:left;
line-height:2em;
+ height: 2em;
color:#555753;
- padding-right: 15px;
- background:url('breadcrumb.gif') no-repeat right center;
}
#breadcrumbs LI A {
@@ -49,7 +48,26 @@
color:#3465a4;
}
-#menuSelector {/* used for showing '>' on the right of the anchor */
+#breadcrumbs LI.children, #breadcrumbs LI.separator {/* '>' separator between two items */
+ width: 16px;
+ background-image: url(menu_right_arrow2.png);
+ background-position: center center;
+ background-repeat: no-repeat;
+}
+
+#breadcrumbs LI.children {
+ cursor: pointer;
+}
+
+#breadcrumbs LI.children:hover {
+ background-image: url(menu_right_arrow.png);
+}
+
+#breadcrumbs LI.separator:last-child {/* separators are for in-between only */
+ display: none;
+}
+
+#menuSelector {/* used for showing 'v' on the right of the anchor */
background-color:transparent;
background-image: url(menu_down_arrow.png);
background-position: center center;
diff --git a/core/src/main/resources/lib/layout/breadcrumbs.js b/core/src/main/resources/lib/layout/breadcrumbs.js
index 93fcd05047..c7545aebbf 100644
--- a/core/src/main/resources/lib/layout/breadcrumbs.js
+++ b/core/src/main/resources/lib/layout/breadcrumbs.js
@@ -114,7 +114,7 @@ var breadcrumbs = (function() {
this.style.visibility = "hidden";
};
menuSelector.observe("click",function () {
- handleHover(this.target);
+ invokeContextMenu(this.target);
});
// if the mouse leaves the selector, hide it
@@ -137,14 +137,18 @@ var breadcrumbs = (function() {
})();
/**
- * Called when the mouse cursor comes into the context menu hot spot.
+ * Called when the user clicks a mouse to show a context menu.
*
* If the mouse stays there for a while, a context menu gets displayed.
*
* @param {HTMLElement} e
* anchor tag
+ * @param {String} contextMenuUrl
+ * The URL that renders JSON for context menu. Optional.
*/
- function handleHover(e) {
+ function invokeContextMenu(e,contextMenuUrl) {
+ contextMenuUrl = contextMenuUrl || "contextMenu";
+
function showMenu(items) {
menu.hide();
var pos = [e, "tl", "bl"];
@@ -163,7 +167,7 @@ var breadcrumbs = (function() {
if (e.items) {// use what's already loaded
showMenu(e.items());
} else {// fetch menu on demand
- xhr = new Ajax.Request(combinePath(e.getAttribute("href"),"contextMenu"), {
+ xhr = new Ajax.Request(combinePath(e.getAttribute("href"),contextMenuUrl), {
onComplete:function (x) {
var a = x.responseText.evalJSON().items;
function fillMenuItem(e) {
@@ -210,6 +214,15 @@ var breadcrumbs = (function() {
});
});
+ Behaviour.specify("#breadcrumbs LI.children", 'breadcrumbs', 0, function (a) {
+ a.observe("mouseover",function() {
+ menuSelector.hide();
+ });
+ a.observe("click",function() {
+ invokeContextMenu(this,"childrenContextMenu");
+ })
+ });
+
/**
* @namespace breadcrumbs
* @class ContextMenu
diff --git a/core/src/main/resources/lib/layout/menu_right_arrow.png b/core/src/main/resources/lib/layout/menu_right_arrow.png
new file mode 100644
index 0000000000..71b521ea56
Binary files /dev/null and b/core/src/main/resources/lib/layout/menu_right_arrow.png differ
diff --git a/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NavigationContextMenu.java b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NavigationContextMenu.java
index bef07ddb24..591dcfdb29 100644
--- a/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NavigationContextMenu.java
+++ b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NavigationContextMenu.java
@@ -5,8 +5,6 @@ import jenkins.model.ModelObjectWithContextMenu;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
-import java.util.List;
-
/**
* @author Kohsuke Kawaguchi
*/