1- import { filter , tail , unnestR } from "../../shared/common.js" ;
1+ import { tail , unnestR } from "../../shared/common.js" ;
22import { hasAnimate , isDefined , isFunction } from "../../shared/utils.js" ;
33import { parse } from "../../shared/hof.js" ;
44import { ResolveContext } from "../resolve/resolve-context.js" ;
@@ -210,12 +210,12 @@ export function $ViewDirective($view, $animate, $anchorScroll, $interpolate) {
210210 ) ( scope ) || "$default" ;
211211
212212 /**
213- * @type {HTMLElement }
213+ * @type {HTMLElement | null }
214214 */
215215 let previousEl ;
216216
217217 /**
218- * @type {HTMLElement }
218+ * @type {HTMLElement | null }
219219 */
220220 let currentEl ;
221221
@@ -229,6 +229,7 @@ export function $ViewDirective($view, $animate, $anchorScroll, $interpolate) {
229229 */
230230 let viewConfig ;
231231
232+ /** @type {import("../view/interface.ts").ActiveUIView } */
232233 const activeUIView = {
233234 id : /** @type {number } */ ( directive . count ) ++ , // Global sequential ID for ng-view tags added to DOM
234235 name, // ng-view name (<div ng-view="name"></div>
@@ -333,24 +334,39 @@ export function $ViewDirective($view, $animate, $anchorScroll, $interpolate) {
333334 * @param {string } viewName Name of the view.
334335 */
335336 newScope . $emit ( "$viewContentLoading" , name ) ;
336- currentEl = $transclude ( newScope , function ( clone ) {
337- setCacheData ( clone , "$ngViewAnim" , $ngViewAnim ) ;
338- setCacheData ( clone , "$ngView" , $ngViewData ) ;
339- renderer . enter ( clone , $element , function ( ) {
340- animEnter . resolve ( ) ;
341-
342- if ( currentScope )
343- currentScope . $emit ( "$viewContentAnimationEnded" ) ;
344-
345- if (
346- ( isDefined ( autoScrollExp ) && ! autoScrollExp ) ||
347- ( autoScrollExp && scope . $eval ( autoScrollExp ) )
348- ) {
349- /** @type {ng.AnchorScrollService } */ ( $anchorScroll ) ( clone ) ;
350- }
351- } ) ;
352- cleanupLastView ( ) ;
353- } ) ;
337+ currentEl = /** @type {HTMLElement } */ (
338+ /** @type {ng.TranscludeFn } */ ( $transclude ) ( newScope , ( clone ) => {
339+ setCacheData (
340+ /** @type {HTMLElement } */ ( clone ) ,
341+ "$ngViewAnim" ,
342+ $ngViewAnim ,
343+ ) ;
344+ setCacheData (
345+ /** @type {HTMLElement } */ ( clone ) ,
346+ "$ngView" ,
347+ $ngViewData ,
348+ ) ;
349+ renderer . enter (
350+ /** @type {HTMLElement } */ ( clone ) ,
351+ $element ,
352+ ( ) => {
353+ animEnter . resolve ( undefined ) ;
354+
355+ if ( currentScope )
356+ currentScope . $emit ( "$viewContentAnimationEnded" ) ;
357+
358+ if (
359+ ( isDefined ( autoScrollExp ) && ! autoScrollExp ) ||
360+ ( autoScrollExp && scope . $eval ( autoScrollExp ) )
361+ ) {
362+ $anchorScroll ( /** @type {HTMLElement } */ ( clone ) ) ;
363+ }
364+ } ,
365+ ) ;
366+ cleanupLastView ( ) ;
367+ } )
368+ ) ;
369+
354370 currentScope = newScope ;
355371 /**
356372 * Fired once the view is **loaded**, *after* the DOM is rendered.
@@ -497,9 +513,9 @@ let _uiCanExitId = 0;
497513/**
498514 * @ignore TODO: move these callbacks to $view and/or `/hooks/components.ts` or something
499515 * @param {ng.TransitionService } $transitions
500- * @param {object | (() => object) } controllerInstance
516+ * @param {any } controllerInstance
501517 * @param {ng.Scope } $scope
502- * @param {{ viewDecl: { component: any; componentProvider: any; }; path: string | any []; } } cfg
518+ * @param {{ viewDecl: { component: any; componentProvider: any; }; path: import("../transition/transition.js").PathNode []; } } cfg
503519 */
504520function registerControllerCallbacks (
505521 $transitions ,
@@ -525,50 +541,79 @@ function registerControllerCallbacks(
525541 const viewCreationTrans = resolveContext . getResolvable ( "$transition$" ) . data ;
526542
527543 // Fire callback on any successful transition
528- const paramsUpdated = ( $transition$ ) => {
544+ const paramsUpdated = (
545+ /** @type {ng.Transition | undefined } */ $transition$ ,
546+ ) => {
547+ if ( ! $transition$ ) return ;
548+
529549 // Exit early if the $transition$ is the same as the view was created within.
530550 // Exit early if the $transition$ will exit the state the view is for.
531551 if (
532552 $transition$ === viewCreationTrans ||
533553 $transition$ . exiting ( ) . indexOf ( viewState ) !== - 1
534- )
554+ ) {
535555 return ;
556+ }
557+
536558 const toParams = $transition$ . params ( "to" ) ;
537559
538560 const fromParams = $transition$ . params ( "from" ) ;
539561
540- const getNodeSchema = ( node ) => node . paramSchema ;
562+ const getNodeSchema = ( /** @type {{ paramSchema: any } } */ node ) =>
563+ node . paramSchema ;
541564
542- const toSchema = $transition$
543- . treeChanges ( "to" )
544- . map ( getNodeSchema )
545- . reduce ( unnestR , [ ] ) ;
565+ const treeChanges = $transition$ && $transition$ . treeChanges ;
546566
547- const fromSchema = $transition$
548- . treeChanges ( "from" )
549- . map ( getNodeSchema )
550- . reduce ( unnestR , [ ] ) ;
567+ const toNodes = isFunction ( treeChanges )
568+ ? ( treeChanges . call ( $transition$ , "to" ) ?? [ ] )
569+ : [ ] ;
551570
552- // Find the to params that have different values than the from params
553- const changedToParams = toSchema . filter ( ( param ) => {
554- const idx = fromSchema . indexOf ( param ) ;
571+ const fromNodes = isFunction ( treeChanges )
572+ ? ( treeChanges . call ( $transition$ , "from" ) ?? [ ] )
573+ : [ ] ;
555574
556- return (
557- idx === - 1 ||
558- ! fromSchema [ idx ] . type . equals ( toParams [ param . id ] , fromParams [ param . id ] )
559- ) ;
560- } ) ;
575+ const toSchema =
576+ /** @type {import("../transition/transition.js").PathNode[] } */ (
577+ toNodes
578+ )
579+ . map ( getNodeSchema )
580+ . reduce ( unnestR , [ ] ) ;
581+
582+ const fromSchema =
583+ /** @type {import("../transition/transition.js").PathNode[] } */ (
584+ fromNodes
585+ )
586+ . map ( getNodeSchema )
587+ . reduce ( unnestR , [ ] ) ;
588+
589+ // Find the to params that have different values than the from params
590+ const changedToParams = toSchema . filter (
591+ ( /** @type {{ id: string | number; } } */ param ) => {
592+ const idx = fromSchema . indexOf ( param ) ;
593+
594+ return (
595+ idx === - 1 ||
596+ ! fromSchema [ idx ] . type . equals (
597+ toParams [ param . id ] ,
598+ fromParams [ param . id ] ,
599+ )
600+ ) ;
601+ } ,
602+ ) ;
561603
562604 // Only trigger callback if a to param has changed or is new
563605 if ( changedToParams . length ) {
564- const changedKeys = changedToParams . map ( ( x ) => x . id ) ;
606+ const changedKeys = /** @type {any[] } */ (
607+ changedToParams . map ( ( /** @type {{ id: any; } } */ x ) => x . id )
608+ ) ;
565609
566610 // Filter the params to only changed/new to params. `$transition$.params()` may be used to get all params.
567- const newValues = filter (
568- toParams ,
569- ( val , key ) => changedKeys . indexOf ( key ) !== - 1 ,
570- ) ;
611+ /** @type {Record<string, any> } */
612+ const newValues = { } ;
571613
614+ changedKeys . forEach ( ( key ) => {
615+ if ( key in toParams ) newValues [ key ] = toParams [ key ] ;
616+ } ) ;
572617 controllerInstance . uiOnParamsChanged ( newValues , $transition$ ) ;
573618 }
574619 } ;
@@ -585,14 +630,22 @@ function registerControllerCallbacks(
585630
586631 const cacheProp = "_uiCanExitIds" ;
587632
588- // Returns true if a redirect transition already answered truthy
589- const prevTruthyAnswer = ( trans ) =>
633+ /**
634+ * Returns true if any transition in the redirect chain already answered truthy
635+ * @param {import("../transition/transition.js").Transition | null | undefined } trans
636+ * @returns {boolean }
637+ */
638+ const prevTruthyAnswer = (
639+ /** @type {ng.Transition & Record<String, any> } */ trans ,
640+ ) =>
590641 ! ! trans &&
591642 ( ( trans [ cacheProp ] && trans [ cacheProp ] [ id ] === true ) ||
592643 prevTruthyAnswer ( trans . redirectedFrom ( ) ) ) ;
593644
594645 // If a user answered yes, but the transition was later redirected, don't also ask for the new redirect transition
595- const wrappedHook = ( trans ) => {
646+ const wrappedHook = (
647+ /** @type {ng.Transition & Record<String, any> } */ trans ,
648+ ) => {
596649 let promise ;
597650
598651 const ids = ( trans [ cacheProp ] = trans [ cacheProp ] || { } ) ;
0 commit comments