All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.loader.js Maven / Gradle / Ivy

import {
  minErr,
  getNgAttribute,
  ngAttrPrefixes,
  assertNotHasOwnProperty,
  errorHandlingConfig,
} from "./shared/utils";
import { JQLite } from "./shared/jqlite/jqlite";
import { annotate, createInjector } from "./core/di/injector";
import { NgModule } from "./core/di/ng-module";
import { CACHE } from "./core/cache/cache";
import { publishExternalAPI } from "./public";
import { VERSION } from "./public";
import { services } from "./router/common/coreservices";
import { unnestR } from "./shared/common";

const ngMinErr = minErr("ng");
const $injectorMinErr = minErr("$injector");

/** @type {Object.} */
const modules = {};

/**
 * Configuration option for AngularTS bootstrap process.
 *
 * @typedef {Object} AngularBootstrapConfig
 * @property {boolean} [strictDi] - Disable automatic function annotation for the application. This is meant to assist in finding bugs which break minified code. Defaults to `false`.
 */

export class Angular {
  constructor() {
    CACHE.clear(); // a ensure new instance of angular gets a clean cache

    /** @type {Map} */
    this.cache = CACHE;

    /** @type {string} */
    this.version = VERSION;

    /** @type {typeof import('./shared/jqlite/jqlite').JQLite} */
    this.element = JQLite;

    /** @type {!Array} */
    this.bootsrappedModules = [];

    /** @type {Function} */
    this.doBootstrap;
    publishExternalAPI(this);
  }

  /**
   * Configure several aspects of error handling if used as a setter or return the
   * current configuration if used as a getter.
   *
   * Omitted or undefined options will leave the corresponding configuration values unchanged.
   *
   * @param {import('./shared/utils').ErrorHandlingConfig} [config]
   * @returns {import('./shared/utils').ErrorHandlingConfig}
   */
  errorHandlingConfig(config) {
    return errorHandlingConfig(config);
  }

  /**
   * Use this function to manually start up AngularJS application.
   *
   * AngularJS will detect if it has been loaded into the browser more than once and only allow the
   * first loaded script to be bootstrapped and will report a warning to the browser console for
   * each of the subsequent scripts. This prevents strange results in applications, where otherwise
   * multiple instances of AngularJS try to work on the DOM.
   *   *
   * 
* **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion}, * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}. * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector}, * causing animations to stop working and making the injector inaccessible from outside the app. *
* * ```html * * * *
* {{greeting}} *
* * * * * * ``` * * @param {string | Element | Document} element DOM element which is the root of AngularJS application. * @param {Array} [modules] an array of modules to load into the application. * Each item in the array should be the name of a predefined module or a (DI annotated) * function that will be invoked by the injector as a `config` block. * See: {@link angular.module modules} * @param {AngularBootstrapConfig} [config] an object for defining configuration options for the application. The * following keys are supported: * * * `strictDi` - disable automatic function annotation for the application. This is meant to * assist in finding bugs which break minified code. Defaults to `false`. * * @returns {any} InjectorService - Returns the newly created injector for this app. */ bootstrap(element, modules, config) { config = config || { strictDi: false, }; const jqLite = JQLite(element); if (jqLite.injector()) { throw ngMinErr("btstrpd", "App already bootstrapped"); } if (Array.isArray(modules)) { this.bootsrappedModules = modules; } this.bootsrappedModules.unshift([ "$provide", ($provide) => { $provide.value("$rootElement", jqLite); }, ]); this.bootsrappedModules.unshift("ng"); const injector = createInjector(this.bootsrappedModules, config.strictDi); injector.invoke([ "$rootScope", "$rootElement", "$compile", "$injector", /** * @param {import('./core/scope/scope').Scope} scope * @param {JQLite} el * @param {*} compile * @param {import("./core/di/internal-injector").InjectorService} $injector */ function (scope, el, compile, $injector) { scope.$apply(() => { el.data("$injector", $injector); compile(el)(scope); }); // ng-route deps services.$injector = $injector; // https://github.com/angular-ui/ui-router/issues/3678 if (!Object.prototype.hasOwnProperty.call($injector, "strictDi")) { try { $injector.invoke(() => {}); } catch (error) { $injector.strictDi = !!/strict mode/.exec( error && error.toString(), ); } } $injector .get("$stateRegistry") .get() .map((x) => x.$$state().resolvables) .reduce(unnestR, []) .filter((x) => x.deps === "deferred") .forEach( (resolvable) => (resolvable.deps = annotate( resolvable.resolveFn, $injector.strictDi, )), ); }, ]); return injector; } /** * * @param {any[]} modules * @param {boolean?} strictDi * @returns {import("./core/di/internal-injector").InjectorService} */ injector(modules, strictDi) { return createInjector(modules, strictDi); } resumeBootstrap(extraModules) { extraModules.forEach((module) => { this.bootsrappedModules.push(module); }); return this.doBootstrap(); } /** * @param {Element|Document} element */ init(element) { let appElement; let module; const config = {}; // The element `element` has priority over any other element. ngAttrPrefixes.forEach((prefix) => { const name = `${prefix}app`; if ( /** @type {Element} */ (element).hasAttribute && /** @type {Element} */ (element).hasAttribute(name) ) { appElement = element; module = /** @type {Element} */ (element).getAttribute(name); } }); ngAttrPrefixes.forEach((prefix) => { const name = `${prefix}app`; let candidate; if ( !appElement && (candidate = element.querySelector(`[${name.replace(":", "\\:")}]`)) ) { appElement = candidate; module = candidate.getAttribute(name); } }); if (appElement) { config.strictDi = getNgAttribute(appElement, "strict-di") !== null; this.bootstrap(appElement, module ? [module] : [], config); } } /** * * The `angular.module` is a global place for creating, registering and retrieving AngularJS * modules. * All modules (AngularJS core or 3rd party) that should be available to an application must be * registered using this mechanism. * * Passing one argument retrieves an existing {@link import('./types').Module}, * whereas passing more than one argument creates a new {@link import('./types').Module} * * * # Module * * A module is a collection of services, directives, controllers, filters, and configuration information. * `angular.module` is used to configure the {@link auto.$injector $injector}. * * ```js * // Create a new module * let myModule = angular.module('myModule', []); * * // register a new service * myModule.value('appName', 'MyCoolApp'); * * // configure existing services inside initialization blocks. * myModule.config(['$locationProvider', function($locationProvider) { * // Configure existing providers * $locationProvider.hashPrefix('!'); * }]); * ``` * * Then you can create an injector and load your modules like this: * * ```js * let injector = angular.injector(['ng', 'myModule']) * ``` * * However it's more likely that you'll just use * {@link ng.directive:ngApp ngApp} or * {@link angular.bootstrap} to simplify this process for you. * * @param {string} name The name of the module to create or retrieve. * @param {Array.} [requires] If specified then new module is being created. If * unspecified then the module is being retrieved for further configuration. * @param {Array|Function} [configFn] Optional configuration function for the module. Same as * {@link import('./types').Module#config Module#config()}. * @returns {NgModule} A newly registered module. */ module(name, requires, configFn) { assertNotHasOwnProperty(name, "module"); if (requires && Object.prototype.hasOwnProperty.call(modules, name)) { modules[name] = null; } return ensure(modules, name, () => { if (!requires) { throw $injectorMinErr( "nomod", "Module '{0}' is not available. Possibly misspelled or not loaded", name, ); } const moduleInstance = new NgModule( name, requires, /** @type {Function} */ (configFn), ); return moduleInstance; }); } } function ensure(obj, name, factory) { return obj[name] || (obj[name] = factory()); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy