/**
 * # URL subsystem
 *
 * Contains code related to managing the URL
 *
 * The primary API is found in [[UrlService]], [[UrlService.config]], and [[UrlService.rules]].
 *
 * @preferred
 * @coreapi
 * @module url
 */ /** */
import { LocationConfig } from '../common/coreservices';
import { ParamType } from '../params/paramType';
import { Param } from '../params/param';
import { UIRouter } from '../router';
import { TargetState } from '../state/targetState';
import { TargetStateDef } from '../state/interface';
import { UrlMatcher } from './urlMatcher';
import { StateObject } from '../state/stateObject';
import { ParamTypeDefinition } from '../params/interface';
/** @internalapi */
export interface ParamFactory {
    /** Creates a new [[Param]] from a CONFIG block */
    fromConfig(id: string, type: ParamType, config: any): Param;
    /** Creates a new [[Param]] from a url PATH */
    fromPath(id: string, type: ParamType, config: any): Param;
    /** Creates a new [[Param]] from a url SEARCH */
    fromSearch(id: string, type: ParamType, config: any): Param;
}
/**
 * An API to customize the URL behavior and retrieve URL configuration
 *
 *
 * This API can customize the behavior of the URL.
 * This includes optional trailing slashes ([[strictMode]]), case sensitivity ([[caseInsensitive]]),
 * and custom parameter encoding (custom [[type]]).
 *
 * It also has information about the location (url) configuration such as [[port]] and [[baseHref]].
 * This information can be used to build absolute URLs, such as
 * `https://example.com:443/basepath/state/substate?param1=a#hashvalue`;
 *
 * This API is found on [[UrlService.config]].
 */
export interface UrlConfigApi extends LocationConfig, UrlMatcherConfig {
}
export interface UrlMatcherConfig {
    /**
     * Defines whether URL matching should be case sensitive (the default behavior), or not.
     *
     * #### Example:
     * ```js
     * // Allow case insensitive url matches
     * urlService.config.caseInsensitive(true);
     * ```
     *
     * @param value `false` to match URL in a case sensitive manner; otherwise `true`;
     * @returns the current value of caseInsensitive
     */
    caseInsensitive(value?: boolean): boolean;
    /**
     * Defines whether URLs should match trailing slashes, or not (the default behavior).
     *
     * #### Example:
     * ```js
     * // Allow optional trailing slashes
     * urlService.config.strictMode(false);
     * ```
     *
     * @param value `false` to match trailing slashes in URLs, otherwise `true`.
     * @returns the current value of strictMode
     */
    strictMode(value?: boolean): boolean;
    /**
     * Sets the default behavior when generating or matching URLs with default parameter values.
     *
     * #### Example:
     * ```js
     * // Remove default parameter values from the url
     * urlService.config.defaultSquashPolicy(true);
     * ```
     *
     * @param value A string that defines the default parameter URL squashing behavior.
     *    - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL
     *    - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the
     *      parameter is surrounded by slashes, squash (remove) one slash from the URL
     *    - any other string, e.g. "~": When generating an href with a default parameter value, squash (remove)
     *      the parameter value from the URL and replace it with this string.
     * @returns the current value of defaultSquashPolicy
     */
    defaultSquashPolicy(value?: boolean | string): boolean | string;
    /**
     * Creates and registers a custom [[ParamTypeDefinition]] object
     *
     * A custom parameter type can be used to generate URLs with typed parameters or custom encoding/decoding.
     *
     * #### Note: Register custom types *before using them* in a state definition.
     *
     * #### Example:
     * ```js
     * // Encode object parameter as JSON string
     * urlService.config.type('myjson', {
     *   encode: (obj) => JSON.stringify(obj),
     *   decode: (str) => JSON.parse(str),
     *   is: (val) => typeof(val) === 'object',
     *   pattern: /[^/]+/,
     *   equals: (a, b) => _.isEqual(a, b),
     * });
     * ```
     *
     * @param name  The type name.
     * @param type The type definition. See [[ParamTypeDefinition]] for examples and information.
     *
     * @returns if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined
     */
    type(name: string, type?: ParamTypeDefinition): ParamType;
}
/** @internalapi */
export interface UrlSyncApi {
    /**
     * Checks the URL for a matching [[UrlRule]]
     *
     * Checks the current URL for a matching url rule, then invokes that rule's handler.
     * This method is called internally any time the URL has changed.
     *
     * This effectively activates the state which matches the current URL.
     *
     * #### Example:
     * ```js
     * urlService.deferIntercept();
     *
     * $http.get('/states.json').then(function(resp) {
     *   resp.data.forEach(state => $stateRegistry.register(state));
     *   urlService.listen();
     *   // Find the matching URL and invoke the handler.
     *   urlService.sync();
     * });
     * ```
     */
    sync(evt?: any): void;
    /**
     * Starts or stops listening for URL changes
     *
     * Call this sometime after calling [[deferIntercept]] to start monitoring the url.
     * This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.
     *
     * If called with `false`, will stop listening.  Call listen() again to start listening
     *
     * #### Example:
     * ```js
     * urlService.deferIntercept();
     *
     * $http.get('/states.json').then(function(resp) {
     *   resp.data.forEach(state => $stateRegistry.register(state));
     *   // Start responding to URL changes
     *   urlService.listen();
     *   urlService.sync();
     * });
     * ```
     */
    listen(enabled?: boolean): Function;
    /**
     * Disables monitoring of the URL.
     *
     * Call this method before UI-Router has bootstrapped.
     * It will stop UI-Router from performing the initial url sync.
     *
     * This can be useful to perform some asynchronous initialization before the router starts.
     * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.
     *
     * #### Example:
     * ```js
     * // Prevent $urlRouter from automatically intercepting URL changes when it starts;
     * urlService.deferIntercept();
     *
     * $http.get('/states.json').then(function(resp) {
     *   resp.data.forEach(state => $stateRegistry.register(state));
     *   urlService.listen();
     *   urlService.sync();
     * });
     * ```
     *
     * @param defer Indicates whether to defer location change interception.
     *        Passing no parameter is equivalent to `true`.
     */
    deferIntercept(defer?: boolean): any;
}
/**
 * API for managing URL rules
 *
 * This API can be used to create and manage URL rules.
 * URL rules are a mechanism to respond to specific URL patterns.
 *
 * The most commonly used methods are [[otherwise]] and [[when]].
 */
export interface UrlRulesApi {
    /**
     * Defines URL Rule priorities
     *
     * More than one rule ([[UrlRule]]) might match a given URL.
     * This `compareFn` is used to sort the rules by priority.
     * Higher priority rules should sort earlier.
     *
     * The [[defaultRuleSortFn]] is used by default.
     *
     * You only need to call this function once.
     * The `compareFn` will be used to sort the rules as each is registered.
     *
     * If called without any parameter, it will re-sort the rules.
     *
     * ---
     *
     * Url rules may come from multiple sources: states's urls ([[StateDeclaration.url]]), [[when]], and [[rule]].
     * Each rule has a (user-provided) [[UrlRule.priority]], a [[UrlRule.type]], and a [[UrlRule.$id]]
     * The `$id` is is the order in which the rule was registered.
     *
     * The sort function should use these data, or data found on a specific type
     * of [[UrlRule]] (such as [[StateRule.state]]), to order the rules as desired.
     *
     * #### Example:
     * This compare function prioritizes rules by the order in which the rules were registered.
     * A rule registered earlier has higher priority.
     *
     * ```js
     * function compareFn(a, b) {
     *   return a.$id - b.$id;
     * }
     * ```
     *
     * @param compareFn a function that compares to [[UrlRule]] objects.
     *    The `compareFn` should abide by the `Array.sort` compare function rules.
     *    Given two rules, `a` and `b`, return a negative number if `a` should be higher priority.
     *    Return a positive number if `b` should be higher priority.
     *    Return `0` if the rules are identical.
     *
     *    See the [mozilla reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Description)
     *    for details.
     */
    sort(compareFn?: (a: UrlRule, b: UrlRule) => number): any;
    /**
     * Registers a `matcher` and `handler` for custom URLs handling.
     *
     * The `matcher` can be:
     *
     * - a [[UrlMatcher]]: See: [[UrlMatcherFactory.compile]]
     * - a `string`: The string is compiled to a [[UrlMatcher]]
     * - a `RegExp`: The regexp is used to match the url.
     *
     * The `handler` can be:
     *
     * - a string: The url is redirected to the value of the string.
     * - a function: The url is redirected to the return value of the function.
     *
     * ---
     *
     * When the `handler` is a `string` and the `matcher` is a `UrlMatcher` (or string), the redirect
     * string is interpolated with parameter values.
     *
     * #### Example:
     * When the URL is `/foo/123` the rule will redirect to `/bar/123`.
     * ```js
     * .when("/foo/:param1", "/bar/:param1")
     * ```
     *
     * ---
     *
     * When the `handler` is a string and the `matcher` is a `RegExp`, the redirect string is
     * interpolated with capture groups from the RegExp.
     *
     * #### Example:
     * When the URL is `/foo/123` the rule will redirect to `/bar/123`.
     * ```js
     * .when(new RegExp("^/foo/(.*)$"), "/bar/$1");
     * ```
     *
     * ---
     *
     * When the handler is a function, it receives the matched value, the current URL, and the `UIRouter` object (See [[UrlRuleHandlerFn]]).
     * The "matched value" differs based on the `matcher`.
     * For [[UrlMatcher]]s, it will be the matched state params.
     * For `RegExp`, it will be the match array from `regexp.exec()`.
     *
     * If the handler returns a string, the URL is redirected to the string.
     *
     * #### Example:
     * When the URL is `/foo/123` the rule will redirect to `/bar/123`.
     * ```js
     * .when(new RegExp("^/foo/(.*)$"), match => "/bar/" + match[1]);
     * ```
     *
     * Note: the `handler` may also invoke arbitrary code, such as `$state.go()`
     *
     * @param matcher A pattern `string` to match, compiled as a [[UrlMatcher]], or a `RegExp`.
     * @param handler The path to redirect to, or a function that returns the path.
     * @param options `{ priority: number }`
     *
     * @return the registered [[UrlRule]]
     */
    when(matcher: RegExp | UrlMatcher | string, handler: string | UrlRuleHandlerFn, options?: {
        priority: number;
    }): UrlRule;
    /**
     * Defines the state, url, or behavior to use when no other rule matches the URL.
     *
     * This rule is matched when *no other rule* matches.
     * It is generally used to handle unknown URLs (similar to "404" behavior, but on the client side).
     *
     * - If `handler` a string, it is treated as a url redirect
     *
     * #### Example:
     * When no other url rule matches, redirect to `/index`
     * ```js
     * .otherwise('/index');
     * ```
     *
     * - If `handler` is an object with a `state` property, the state is activated.
     *
     * #### Example:
     * When no other url rule matches, redirect to `home` and provide a `dashboard` parameter value.
     * ```js
     * .otherwise({ state: 'home', params: { dashboard: 'default' } });
     * ```
     *
     * - If `handler` is a function, the function receives the current url ([[UrlParts]]) and the [[UIRouter]] object.
     *   The function can perform actions, and/or return a value.
     *
     * #### Example:
     * When no other url rule matches, manually trigger a transition to the `home` state
     * ```js
     * .otherwise((matchValue, urlParts, router) => {
     *   router.stateService.go('home');
     * });
     * ```
     *
     * #### Example:
     * When no other url rule matches, go to `home` state
     * ```js
     * .otherwise((matchValue, urlParts, router) => {
     *   return { state: 'home' };
     * });
     * ```
     *
     * @param handler The url path to redirect to, or a function which returns the url path (or performs custom logic).
     */
    otherwise(handler: string | UrlRuleHandlerFn | TargetState | TargetStateDef): void;
    /**
     * Defines the initial state, path, or behavior to use when the app starts.
     *
     * This rule defines the initial/starting state for the application.
     *
     * This rule is triggered the first time the URL is checked (when the app initially loads).
     * The rule is triggered only when the url matches either `""` or `"/"`.
     *
     * Note: The rule is intended to be used when the root of the application is directly linked to.
     * When the URL is *not* `""` or `"/"` and doesn't match other rules, the [[otherwise]] rule is triggered.
     * This allows 404-like behavior when an unknown URL is deep-linked.
     *
     * #### Example:
     * Start app at `home` state.
     * ```js
     * .initial({ state: 'home' });
     * ```
     *
     * #### Example:
     * Start app at `/home` (by url)
     * ```js
     * .initial('/home');
     * ```
     *
     * #### Example:
     * When no other url rule matches, go to `home` state
     * ```js
     * .initial((matchValue, url, router) => {
     *   console.log('initial state');
     *   return { state: 'home' };
     * })
     * ```
     *
     * @param handler The initial state or url path, or a function which returns the state or url path (or performs custom logic).
     */
    initial(handler: string | UrlRuleHandlerFn | TargetState | TargetStateDef, options?: {
        priority: number;
    }): void;
    /**
     * Gets all registered rules
     *
     * @returns an array of all the registered rules
     */
    rules(): UrlRule[];
    /**
     * Manually adds a URL Rule.
     *
     * Usually, a url rule is added using [[StateDeclaration.url]] or [[when]].
     * This api can be used directly for more control (to register [[BaseUrlRule]], for example).
     * Rules can be created using [[UrlRouter.urlRuleFactory]], or create manually as simple objects.
     *
     * @return a function that deregisters the rule
     */
    rule(rule: UrlRule): Function;
    /**
     * Remove a rule previously registered
     *
     * @param rule the matcher rule that was previously registered using [[rule]]
     */
    removeRule(rule: UrlRule): void;
}
/**
 * An object containing the three parts of a URL
 */
export interface UrlParts {
    path: string;
    search?: {
        [key: string]: any;
    };
    hash?: string;
}
/**
 * A UrlRule match result
 *
 * The result of UrlRouter.match()
 */
export interface MatchResult {
    /** The matched value from a [[UrlRule]] */
    match: any;
    /** The rule that matched */
    rule: UrlRule;
    /** The match result weight */
    weight: number;
}
/**
 * A function that matches the URL for a [[UrlRule]]
 *
 * Implementations should match against the provided [[UrlParts]] and return the matched value (truthy) if the rule matches.
 * If this rule is selected, the matched value is passed to the [[UrlRuleHandlerFn]].
 *
 * @return the matched value, either truthy or falsey
 */
export interface UrlRuleMatchFn {
    (url?: UrlParts, router?: UIRouter): any;
}
/**
 * Handler invoked when a rule is matched
 *
 * The matched value from the rule's [[UrlRuleMatchFn]] is passed as the first argument
 * The handler should return a string (to redirect), a [[TargetState]]/[[TargetStateDef]], or void
 *
 * If the handler returns a string, the url is replaced with the string.
 * If the handler returns a [[TargetState]], the target state is activated.
 */
export interface UrlRuleHandlerFn {
    (matchValue?: any, url?: UrlParts, router?: UIRouter): string | TargetState | TargetStateDef | void;
}
/** @internalapi */
export declare type UrlRuleType = 'STATE' | 'URLMATCHER' | 'REGEXP' | 'RAW' | 'OTHER';
/**
 * The interface for a URL Rule
 *
 * If you are creating a rule for use with [[UrlRulesApi.rule]], it should implement this interface.
 */
export interface UrlRule {
    /**
     * The rule's ID.
     *
     * IDs are auto-assigned when the rule is registered, in increasing order.
     */
    $id: number;
    /**
     * The rule's priority (defaults to 0).
     *
     * This can be used to explicitly modify the rule's priority.
     * Higher numbers are higher priority.
     */
    priority: number;
    /** The type of the rule */
    type: UrlRuleType;
    /**
     * This function should match the url and return the match details
     *
     * See [[UrlRuleMatchFn]] for details
     */
    match: UrlRuleMatchFn;
    /**
     * This function is called if the rule matched, and was selected as the "best match".
     * This function handles the rule match event.
     *
     * See [[UrlRuleHandlerFn]] for details
     */
    handler: UrlRuleHandlerFn;
    /**
     * The priority of a given match.
     *
     * Sometimes more than one UrlRule might have matched.
     * This method is used to choose the best match.
     *
     * If multiple rules matched, each rule's `matchPriority` is called with the value from [[match]].
     * The rule with the highest `matchPriority` has its [[handler]] called.
     */
    matchPriority(match: any): number;
}
/** @internalapi */
export interface MatcherUrlRule extends UrlRule {
    type: 'URLMATCHER' | 'STATE';
    urlMatcher: UrlMatcher;
}
/** @internalapi */
export interface StateRule extends MatcherUrlRule {
    type: 'STATE';
    state: StateObject;
}
/** @internalapi */
export interface RegExpRule extends UrlRule {
    type: 'REGEXP';
    regexp: RegExp;
}
