1/** 2 * Copyright © Magento, Inc. All rights reserved. 3 * See COPYING.txt for license details. 4 */ 5define('mixins', [ 6 'module' 7], function (module) { 8 'use strict'; 9 10 var contexts = require.s.contexts, 11 defContextName = '_', 12 defContext = contexts[defContextName], 13 unbundledContext = require.s.newContext('$'), 14 defaultConfig = defContext.config, 15 unbundledConfig = { 16 baseUrl: defaultConfig.baseUrl, 17 paths: defaultConfig.paths, 18 shim: defaultConfig.shim, 19 config: defaultConfig.config, 20 map: defaultConfig.map 21 }, 22 rjsMixins; 23 24 /** 25 * Prepare a separate context where modules are not assigned to bundles 26 * so we are able to get their true path and corresponding mixins. 27 */ 28 unbundledContext.configure(unbundledConfig); 29 30 /** 31 * Checks if specified string contains 32 * a plugin spacer '!' substring. 33 * 34 * @param {String} name - Name, path or alias of a module. 35 * @returns {Boolean} 36 */ 37 function hasPlugin(name) { 38 return !!~name.indexOf('!'); 39 } 40 41 /** 42 * Adds 'mixins!' prefix to the specified string. 43 * 44 * @param {String} name - Name, path or alias of a module. 45 * @returns {String} Modified name. 46 */ 47 function addPlugin(name) { 48 return 'mixins!' + name; 49 } 50 51 /** 52 * Removes base url from the provided string. 53 * 54 * @param {String} url - Url to be processed. 55 * @param {Object} config - Contexts' configuration object. 56 * @returns {String} String without base url. 57 */ 58 function removeBaseUrl(url, config) { 59 var baseUrl = config.baseUrl || '', 60 index = url.indexOf(baseUrl); 61 62 if (~index) { 63 url = url.substring(baseUrl.length - index); 64 } 65 66 return url; 67 } 68 69 /** 70 * Extracts url (without baseUrl prefix) 71 * from a module name ignoring the fact that it may be bundled. 72 * 73 * @param {String} name - Name, path or alias of a module. 74 * @param {Object} config - Context's configuration. 75 * @returns {String} 76 */ 77 function getPath(name, config) { 78 var url = unbundledContext.require.toUrl(name); 79 80 return removeBaseUrl(url, config); 81 } 82 83 /** 84 * Checks if specified string represents a relative path (../). 85 * 86 * @param {String} name - Name, path or alias of a module. 87 * @returns {Boolean} 88 */ 89 function isRelative(name) { 90 return !!~name.indexOf('./'); 91 } 92 93 /** 94 * Iteratively calls mixins passing to them 95 * current value of a 'target' parameter. 96 * 97 * @param {*} target - Value to be modified. 98 * @param {...Function} mixins - List of mixins to apply. 99 * @returns {*} Modified 'target' value. 100 */ 101 function applyMixins(target) { 102 var mixins = Array.prototype.slice.call(arguments, 1); 103 104 mixins.forEach(function (mixin) { 105 target = mixin(target); 106 }); 107 108 return target; 109 } 110 111 rjsMixins = { 112 113 /** 114 * Loads specified module along with its' mixins. 115 * This method is called for each module defined with "mixins!" prefix 116 * in its name that was added by processNames method. 117 * 118 * @param {String} name - Module to be loaded. 119 * @param {Function} req - Local "require" function to use to load other modules. 120 * @param {Function} onLoad - A function to call with the value for name. 121 * @param {Object} config - RequireJS configuration object. 122 */ 123 load: function (name, req, onLoad, config) { 124 var path = getPath(name, config), 125 mixins = this.getMixins(path), 126 deps = [name].concat(mixins); 127 128 req(deps, function () { 129 onLoad(applyMixins.apply(null, arguments)); 130 }); 131 }, 132 133 /** 134 * Retrieves list of mixins associated with a specified module. 135 * 136 * @param {String} path - Path to the module (without base URL). 137 * @returns {Array} An array of paths to mixins. 138 */ 139 getMixins: function (path) { 140 var config = module.config() || {}, 141 mixins; 142 143 // Fix for when urlArgs is set. 144 if (path.indexOf('?') !== -1) { 145 path = path.substring(0, path.indexOf('?')); 146 } 147 mixins = config[path] || {}; 148 149 return Object.keys(mixins).filter(function (mixin) { 150 return mixins[mixin] !== false; 151 }); 152 }, 153 154 /** 155 * Checks if specified module has associated with it mixins. 156 * 157 * @param {String} path - Path to the module (without base URL). 158 * @returns {Boolean} 159 */ 160 hasMixins: function (path) { 161 return this.getMixins(path).length; 162 }, 163 164 /** 165 * Modifies provided names prepending to them 166 * the 'mixins!' plugin prefix if it's necessary. 167 * 168 * @param {(Array|String)} names - Module names, paths or aliases. 169 * @param {Object} context - Current RequireJS context. 170 * @returns {Array|String} 171 */ 172 processNames: function (names, context) { 173 var config = context.config; 174 175 /** 176 * Prepends 'mixin' plugin to a single name. 177 * 178 * @param {String} name 179 * @returns {String} 180 */ 181 function processName(name) { 182 var path = getPath(name, config); 183 184 if (!hasPlugin(name) && (isRelative(name) || rjsMixins.hasMixins(path))
184) { 185 return addPlugin(name); 186 } 187 188 return name; 189 } 190 191 return typeof names !== 'string' ? 192 names.map(processName) : 193 processName(names); 194 } 195 }; 196 197 return rjsMixins; 198}); 199 200require([ 201 'mixins' 202], function (mixins) { 203 'use strict'; 204 205 var contexts = require.s.contexts, 206 defContextName = '_', 207 defContext = contexts[defContextName], 208 originalContextRequire = defContext.require, 209 processNames = mixins.processNames; 210 211 /** 212 * Wrap default context's require function which gets called every time 213 * module is requested using require call. The upside of this approach 214 * is that deps parameter is already normalized and guaranteed to be an array. 215 */ 216 defContext.require = function (deps, callback, errback) { 217 deps = processNames(deps, defContext); 218 219 return originalContextRequire(deps, callback, errback); 220 }; 221 222 /** 223 * Copy properties of original 'require' method. 224 */ 225 Object.keys(originalContextRequire).forEach(function (key) { 226 defContext.require[key] = originalContextRequire[key]; 227 }); 228 229 /** 230 * Wrap shift method from context's definitions queue. 231 * Items are added to the queue when a new module is defined and taken 232 * from it every time require call happens. 233 */ 234 defContext.defQueue.shift = function () { 235 var queueItem = Array.prototype.shift.call(this), 236 lastDeps = queueItem && queueItem[1]; 237 238 if (Array.isArray(lastDeps)) { 239 queueItem[1] = processNames(queueItem[1], defContext); 240 } 241 242 return queueItem; 243 }; 244});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.