123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- /**
- * Utility methods used to wrap and extend functions.
- *
- * @example Usage of a 'wrap' method with arguments delegation.
- * var multiply = function (a, b) {
- * return a * b;
- * };
- *
- * multiply = module.wrap(multiply, function (orig) {
- * return 'Result is: ' + orig();
- * });
- *
- * multiply(2, 2);
- * => 'Result is: 4'
- *
- * @example Usage of 'wrapSuper' method.
- * var multiply = function (a, b) {
- * return a * b;
- * };
- *
- * var obj = {
- * multiply: module.wrapSuper(multiply, function () {
- * return 'Result is: ' + this._super();
- * });
- * };
- *
- * obj.multiply(2, 2);
- * => 'Result is: 4'
- */
- define([
- 'underscore'
- ], function (_) {
- 'use strict';
- /**
- * Checks if string has a '_super' substring.
- */
- var superReg = /\b_super\b/;
- return {
- /**
- * Wraps target function with a specified wrapper, which will receive
- * reference to the original function as a first argument.
- *
- * @param {Function} target - Function to be wrapped.
- * @param {Function} wrapper - Wrapper function.
- * @returns {Function} Wrapper function.
- */
- wrap: function (target, wrapper) {
- if (!_.isFunction(target) || !_.isFunction(wrapper)) {
- return wrapper;
- }
- return function () {
- var args = _.toArray(arguments),
- ctx = this,
- _super;
- /**
- * Function that will be passed to the wrapper.
- * If no arguments will be passed to it, then the original
- * function will be called with an arguments of a wrapper function.
- */
- _super = function () {
- var superArgs = arguments.length ? arguments : args.slice(1);
- return target.apply(ctx, superArgs);
- };
- args.unshift(_super);
- return wrapper.apply(ctx, args);
- };
- },
- /**
- * Wraps the incoming function to implement support of the '_super' method.
- *
- * @param {Function} target - Function to be wrapped.
- * @param {Function} wrapper - Wrapper function.
- * @returns {Function} Wrapped function.
- */
- wrapSuper: function (target, wrapper) {
- if (!this.hasSuper(wrapper) || !_.isFunction(target)) {
- return wrapper;
- }
- return function () {
- var _super = this._super,
- args = arguments,
- result;
- /**
- * Temporary define '_super' method which
- * contains call to the original function.
- */
- this._super = function () {
- var superArgs = arguments.length ? arguments : args;
- return target.apply(this, superArgs);
- };
- result = wrapper.apply(this, args);
- this._super = _super;
- return result;
- };
- },
- /**
- * Checks wether the incoming method contains calls of the '_super' method.
- *
- * @param {Function} fn - Function to be checked.
- * @returns {Boolean}
- */
- hasSuper: function (fn) {
- return _.isFunction(fn) && superReg.test(fn);
- },
- /**
- * Extends target object with provided extenders.
- * If property in target and extender objects is a function,
- * then it will be wrapped using 'wrap' method.
- *
- * @param {Object} target - Object to be extended.
- * @param {...Object} extenders - Multiple extenders objects.
- * @returns {Object} Modified target object.
- */
- extend: function (target) {
- var extenders = _.toArray(arguments).slice(1),
- iterator = this._extend.bind(this, target);
- extenders.forEach(iterator);
- return target;
- },
- /**
- * Same as the 'extend' method, but operates only on one extender object.
- *
- * @private
- * @param {Object} target
- * @param {Object} extender
- */
- _extend: function (target, extender) {
- _.each(extender, function (value, key) {
- target[key] = this.wrap(target[key], extender[key]);
- }, this);
- }
- };
- });
|