@@ -171,9 +171,13 @@ export interface AlRouteDefinition {
171171 /* The caption of the menu item */
172172 caption :string ;
173173
174- /* An arbitrary id associated with this menu item. This is most useful (practically) for retrieving specific menu items by code. */
174+ /* An arbitrary identifier associated with this menu item. This is most useful (practically) for retrieving specific menu items by code. */
175175 id ?:string ;
176176
177+ /* An arbitrary name associated with this menu item. These augment named routes for conditional schema branches. And if that sounds vaguely
178+ * gibberishy -- (wasntme) */
179+ name ?:string ;
180+
177181 /* An arbitrary bookmark code for this menu item. This allows a specific submenu to be retrieved and worked with programmatically. */
178182 bookmarkId ?:string ;
179183
@@ -184,6 +188,10 @@ export interface AlRouteDefinition {
184188 * If the provided value is a string, it will be treated as a reference to a named route in the current schema. */
185189 action ?:AlRouteAction | string ;
186190
191+ /* A condition that can be evaluated to calculated the `enabled` property at any given moment.
192+ * This can be a fixed boolean value, a shared condition ID (see AlNavigationSchema.conditions), or a condition literal. */
193+ enabled ?:AlRouteCondition | string | boolean ;
194+
187195 /* A condition that can be evaluated to calculate the `visible` property at any given moment.
188196 * This can be a fixed boolean value, a shared condition ID (see AlNavigationSchema.conditions), or a condition literal. */
189197 visible ?:AlRouteCondition | string | boolean ;
@@ -248,7 +256,7 @@ export class AlRoute {
248256 /* Is the menu item visible? */
249257 visible :boolean = true ;
250258
251- /* Is the menu item enabled? This is provided for use by custom menu implementations, and no managed by this module . */
259+ /* Is the menu item enabled? Disabled menu items and their children will not be considered for activation . */
252260 enabled :boolean = true ;
253261
254262 /* Is the menu item locked? This prevents refresh cycles from changing its state. */
@@ -374,6 +382,15 @@ export class AlRoute {
374382 return ;
375383 }
376384
385+ if ( this . definition . enabled ) {
386+ this . enabled = this . evaluateCondition ( this . definition . enabled ) ;
387+ if ( ! this . enabled ) {
388+ this . visible = false ;
389+ // This item and its family tree are disabled, and thus not considered for visibility or activation.
390+ return ;
391+ }
392+ }
393+
377394 state . depth ++ ;
378395
379396 /* Evaluate visibility */
@@ -728,7 +745,29 @@ export class AlRoute {
728745 return child || null ;
729746 }
730747
731-
748+ /**
749+ * Generic method for recursing a menu hierarchy, using a callback to match the route.
750+ *
751+ * @param callback is a method that accepts a route (and optionally its definition) and returns
752+ * `true` if the route is the correct one, in which case it is the result of the search method.
753+ * `false` if the route is incorrect but its children should be iterated.
754+ * `null` if the route is incorrect and its children should be ignored
755+ */
756+ search ( matcher :{ ( route :AlRoute , definition ?:AlRouteDefinition ) :boolean } , enabledOnly :boolean = true ) :AlRoute | undefined {
757+ if ( this . enabled !== enabledOnly ) {
758+ return ;
759+ }
760+ if ( matcher ( this , this . definition ) ) {
761+ return this ;
762+ } else {
763+ for ( let i = 0 ; i < this . children . length ; i ++ ) {
764+ let target = this . children [ i ] . search ( matcher , enabledOnly ) ;
765+ if ( target ) {
766+ return target ;
767+ }
768+ }
769+ }
770+ }
732771
733772 /**
734773 * This method will return the deepest activated, childless route within its first activated child. If this sounds obtuse,
0 commit comments