UNPKG

angular-hot-loader

Version:

🔥 Webpack Hot Module Replacement for Angular 1.x applications.

135 lines (114 loc) • 3.9 kB
const toFactory = require('to-factory'); const logger = require('./logger'); let hotAngular; /** * Angular Hot Loader. * @param {Object} settings - hot loader setiings. */ const HotAngular = function(settings) { const toString = Function.prototype.toString; this.ANGULAR_MODULE; this.settings = settings || {}; // Create cahing objects. this.MODULE_CACHE = {}; this.cache = {}; this.configCache = function() {}; this.constantCache = {}; this.controllerCache = {}; this.decoratorCache = {}; this.factoryCache = {}; this.filterCache = {}; this.serviceCache = {}; this.valueCache = {}; this.templateCache = {}; this.name; this.bootstrapElement; /** * Gets transpiled function body. * @param {Function} fn - transpiled function source. */ function fnBody(fn) { return toString.call(fn).replace(/^[^{]*{\s*/,'').replace(/\s*}[^}]*$/,''); } /** * Checks if function is es6 or Babel class. * @param {Function} fn - transpiled function source. */ function isClass(fn) { return (typeof fn === 'function' && (/^class\s/.test(toString.call(fn)) || // babel class definition. (/.*classCallCheck\(?/.test(fnBody(fn))))); } /** * Wraps class functions in factory. */ this.classTransform = function(fn) { return isClass(fn) ? toFactory(fn) : fn; }; this.logger = this.settings.log ? logger : function() {}; /** * Document load handler. */ function loadHandler() { this.element = document.querySelector(this.settings.rootElement); this.originalContent = this.element.innerHTML; } // Module may have been lazy loaded after document load. if (document.readyState === 'complete') { loadHandler.call(this); } else { document.addEventListener('DOMContentLoaded', loadHandler.bind(this), false); } }; // Angular functions to replace HotAngular.prototype.animation = require('./interceptors/animation'); HotAngular.prototype.component = require('./interceptors/component'); HotAngular.prototype.config = require('./interceptors/config'); HotAngular.prototype.constant = require('./interceptors/constant'); HotAngular.prototype.controller = require('./interceptors/controller'); HotAngular.prototype.decorator = require('./interceptors/decorator'); HotAngular.prototype.directive = require('./interceptors/directive'); HotAngular.prototype.factory = require('./interceptors/factory'); HotAngular.prototype.filter = require('./interceptors/filter'); HotAngular.prototype.info = require('./interceptors/info'); HotAngular.prototype.module = require('./interceptors/module'); HotAngular.prototype.provider = require('./interceptors/provider'); HotAngular.prototype.run = require('./interceptors/run'); HotAngular.prototype.service = require('./interceptors/service'); HotAngular.prototype.value = require('./interceptors/value'); HotAngular.prototype.reloadState = function() { const elm = this.bootstrapElement; if (elm) { if (elm.injector().has('$state')) { this.logger('Reloading UI Router State', 'info'); const $state = elm.injector().get('$state'); $state.transitionTo($state.current, $state.params, { reload: true, inherit: false, notify: true }); } else { this.logger('Recompile App', 'info'); elm.injector().get('$compile')(elm.contents())(elm.scope()); } } }; HotAngular.prototype.recompile = function() { const elm = this.bootstrapElement; if (elm) { this.logger('Recompile App', 'info'); elm.injector().get('$compile')(elm.contents())(elm.scope()); } else { this.logger('Reload Page', 'info'); window.location.reload(); } }; // HotAngular must be a singleton so the cache remains the // same across consecutive updates. module.exports = function (settings) { if (!hotAngular) { hotAngular = new HotAngular(settings); } return hotAngular; };