UNPKG

@darkobits/formation

Version:
306 lines (252 loc) 9.67 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); exports.$registerComponent = $registerComponent; exports.$getNextId = $getNextId; exports.$getShowErrorsOnStr = $getShowErrorsOnStr; exports.$getPrefixedName = $getPrefixedName; exports.registerControl = registerControl; exports.FormationConfigurator = FormationConfigurator; var _ramda = require('ramda'); var _app = require('../../app'); var _app2 = _interopRequireDefault(_app); var _FormationControl = require('../../classes/FormationControl'); var _constants = require('../constants'); var _interfaces = require('../interfaces'); var _utils = require('../utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // ----- Private Data ---------------------------------------------------------- /** * Set to true during Angular's configuration phase to prevent Formation * configuration. * * @type {boolean} */ var allowConfiguration = true; /** * @private * * Configured component prefix. * * @type {string} */ var prefix = _constants.DEFAULT_PREFIX; /** * @private * * Global setting for error behavior. * * @type {string} */ var showErrorsOnStr = void 0; /** * @private * * Counter for getNextId(), used to assign unique IDs to unnamed forms. * * @type {number} */ var counter = -1; /** * @private * * Maintains a list of all components and directives registered with the * service. * * @type {array} */ var registeredComponents = []; // ----- Semi-Private Functions ------------------------------------------------ /** * Adds the provided name to the list of registered components. * * @param {string} name */ function $registerComponent(name, definition) { registeredComponents.push(name); _app2.default.config(['$compileProvider', function ($compileProvider) { if (typeof definition === 'function') { $compileProvider.directive((0, _utils.lowercaseFirst)(name), definition); } else { $compileProvider.component((0, _utils.lowercaseFirst)(name), definition); } }]); } /** * Returns the next available ID, used for assigning ID attributes to * unnamed form instances. * * @private * * @return {number} */ function $getNextId() { return ++counter; } /** * Returns globally-configured error flags. * * @private * * @return {string} */ function $getShowErrorsOnStr() { return showErrorsOnStr; } /** * Returns a prefixed version of the provided string. * * @private * * Formation.$getPrefixedName('Input') // => 'fmInput'; * * @param {string} name * @return {string} */ function $getPrefixedName(name) { return '' + (prefix || _constants.DEFAULT_PREFIX) + (0, _utils.capitalizeFirst)(name); } /** * Curried assertType. * * Remaining arguments: * * @param {function|array} types * @param {string} label * @param {any} value * * @return {boolean} */ var check = (0, _utils.assertType)('FormationConfigurator'); // ----- Public Functions ------------------------------------------------------ /** * Registers a Formation control as an Angular component using the provided * name and component definition object. * * @param {string} name - Control name. Will be prefixed using the configured * or default prefix. * @param {object} definition - Component definition object. */ function registerControl(name, definition) { var _bindings; var normalizedName = (0, _utils.lowercaseFirst)($getPrefixedName(name)); $registerComponent(normalizedName, (0, _utils.mergeDeep)({ bindings: (_bindings = {}, _defineProperty(_bindings, _constants.COMPONENT_CONFIGURATION, '<config'), _defineProperty(_bindings, '$ngDisabled', '<ngDisabled'), _bindings), require: _defineProperty({}, _constants.FORM_CONTROLLER, '^^' + _constants.FORM_COMPONENT_NAME) }, definition)); } /** * Allows consumers to configure Formation behavior. * * @param {object} opts * @param {string} [opts.showErrorsOn] - Comma/space-delimited string of control * or form states that, when true, will cause ngMessage errors to display. * @param {string} [opts.prefix] - Overrides the default component prefix for * all formation controls. */ function FormationConfigurator(opts) { if (!allowConfiguration) { (0, _utils.throwError)('Formation cannot be configured once Angular has bootstrapped.'); } check(Object, 'options', opts); if (check([String, undefined], 'showErrorsOn', opts.showErrorsOn)) { showErrorsOnStr = opts.showErrorsOn; } if (check([String, undefined], 'prefix', opts.prefix)) { prefix = opts.prefix; } } // ----- Decorators ------------------------------------------------------------ _app2.default.config(['$provide', function ($provide) { // Disallow configuration once the application has started bootstrapping. allowConfiguration = false; var decorate = [ // Decoration spec for form/ngForm. { directives: ['formDirective', 'ngFormDirective'], require: ['?^^fm'], postLink: function postLink(scope, element, attributes, controllers) { // Get a reference to the Angular Form controller. var _controllers = _slicedToArray(controllers, 1), ngFormController = _controllers[0]; // Get a reference to parent Formation forms, if any. Use 'propEq' // here rather than 'is' to avoid a circular dependence between this // module and Form.js. var fmFormController = (0, _ramda.find)(function (controller) { return (0, _ramda.path)(['constructor', _constants.FORM_CONTROLLER], controller); }, controllers); if (fmFormController && (0, _utils.isFunction)(fmFormController[_interfaces.RegisterNgForm])) { fmFormController[_interfaces.RegisterNgForm](ngFormController); } } }, // Decoration spec for ngModel. { directives: ['ngModelDirective'], require: (0, _ramda.map)(function (component) { return '?^^' + component; }, registeredComponents), postLink: function postLink(scope, element, attributes, controllers) { // Get a reference to the ngModel controller. var _controllers2 = _slicedToArray(controllers, 1), ngModelController = _controllers2[0]; // Get a reference to parent Formation controls, if any. var fmComponentController = (0, _ramda.find)((0, _ramda.is)(_FormationControl.FormationControl), controllers); // Get a reference to parent Formation forms, if any. Use 'propEq' // here rather than 'is' to avoid a circular dependence between this // module and Form.js. var fmFormController = (0, _ramda.find)(function (controller) { return (0, _ramda.path)(['constructor', _constants.FORM_CONTROLLER], controller); }, controllers); if (fmComponentController && (0, _utils.isFunction)(fmComponentController[_interfaces.RegisterNgModel])) { // If we are the child of a Formation control, register with the // control. fmComponentController[_interfaces.RegisterNgModel](ngModelController); } else if (fmFormController && (0, _utils.isFunction)(fmFormController[_interfaces.RegisterNgModel])) { // Otherwise, if we are the child of a Formation form, register with // the form. fmFormController[_interfaces.RegisterNgModel](ngModelController); } } }]; decorate.forEach(function () { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, directives = _ref.directives, require = _ref.require, postLink = _ref.postLink; directives.forEach(function (directiveName) { $provide.decorator(directiveName, ['$delegate', function ($delegate) { var _$delegate = _slicedToArray($delegate, 1), directiveSpec = _$delegate[0]; var compile = directiveSpec.compile; // Add requires. directiveSpec.require = (0, _ramda.concat)(directiveSpec.require || [], require); directiveSpec.compile = function () { // Invoke original compile to get link object. var link = Reflect.apply(compile, this, arguments); // Return new link object. return { pre: function pre() { if ((0, _utils.isFunction)(link.pre)) { // Invoke original pre-link. Reflect.apply(link.pre, this, arguments); } }, post: function post() { if ((0, _utils.isFunction)(link.post)) { // Invoke original post-link. Reflect.apply(link.post, this, arguments); } // Invoke new post-link. Reflect.apply(postLink, this, arguments); } }; }; return $delegate; }]); }); }); }]);