PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/yui/3.1.2/oop/oop-debug.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 361 lines | 155 code | 45 blank | 161 comment | 46 complexity | 885d0a16498ce0d876ebaf9f990579da MD5 | raw file
  1. YUI.add('oop', function(Y) {
  2. /**
  3. * Supplies object inheritance and manipulation utilities. This adds
  4. * additional functionaity to what is provided in yui-base, and the
  5. * methods are applied directly to the YUI instance. This module
  6. * is required for most YUI components.
  7. * @module oop
  8. */
  9. var L = Y.Lang,
  10. A = Y.Array,
  11. OP = Object.prototype,
  12. CLONE_MARKER = "_~yuim~_",
  13. EACH = 'each',
  14. SOME = 'some',
  15. dispatch = function(o, f, c, proto, action) {
  16. if (o && o[action] && o !== Y) {
  17. return o[action].call(o, f, c);
  18. } else {
  19. switch (A.test(o)) {
  20. case 1:
  21. return A[action](o, f, c);
  22. case 2:
  23. return A[action](Y.Array(o, 0, true), f, c);
  24. default:
  25. return Y.Object[action](o, f, c, proto);
  26. }
  27. }
  28. };
  29. /**
  30. * The following methods are added to the YUI instance
  31. * @class YUI~oop
  32. */
  33. /**
  34. * Applies prototype properties from the supplier to the receiver.
  35. * The receiver can be a constructor or an instance.
  36. * @method augment
  37. * @param {Function} r the object to receive the augmentation
  38. * @param {Function} s the object that supplies the properties to augment
  39. * @param ov {boolean} if true, properties already on the receiver
  40. * will be overwritten if found on the supplier.
  41. * @param wl {string[]} a whitelist. If supplied, only properties in
  42. * this list will be applied to the receiver.
  43. * @param args {Array | Any} arg or arguments to apply to the supplier
  44. * constructor when initializing.
  45. * @return {object} the augmented object
  46. *
  47. * @todo constructor optional?
  48. * @todo understanding what an instance is augmented with
  49. * @TODO best practices for overriding sequestered methods.
  50. */
  51. Y.augment = function(r, s, ov, wl, args) {
  52. var sProto = s.prototype,
  53. newProto = null,
  54. construct = s,
  55. a = (args) ? Y.Array(args) : [],
  56. rProto = r.prototype,
  57. target = rProto || r,
  58. applyConstructor = false,
  59. sequestered, replacements, i;
  60. // working on a class, so apply constructor infrastructure
  61. if (rProto && construct) {
  62. sequestered = {};
  63. replacements = {};
  64. newProto = {};
  65. // sequester all of the functions in the supplier and replace with
  66. // one that will restore all of them.
  67. Y.Object.each(sProto, function(v, k) {
  68. replacements[k] = function() {
  69. // Y.log('sequestered function "' + k + '" executed. Initializing EventTarget');
  70. // overwrite the prototype with all of the sequestered functions,
  71. // but only if it hasn't been overridden
  72. for (i in sequestered) {
  73. if (sequestered.hasOwnProperty(i) && (this[i] === replacements[i])) {
  74. // Y.log('... restoring ' + k);
  75. this[i] = sequestered[i];
  76. }
  77. }
  78. // apply the constructor
  79. construct.apply(this, a);
  80. // apply the original sequestered function
  81. return sequestered[k].apply(this, arguments);
  82. };
  83. if ((!wl || (k in wl)) && (ov || !(k in this))) {
  84. // Y.log('augment: ' + k);
  85. if (L.isFunction(v)) {
  86. // sequester the function
  87. sequestered[k] = v;
  88. // replace the sequestered function with a function that will
  89. // restore all sequestered functions and exectue the constructor.
  90. this[k] = replacements[k];
  91. } else {
  92. // Y.log('augment() applying non-function: ' + k);
  93. this[k] = v;
  94. }
  95. }
  96. }, newProto, true);
  97. // augmenting an instance, so apply the constructor immediately
  98. } else {
  99. applyConstructor = true;
  100. }
  101. Y.mix(target, newProto || sProto, ov, wl);
  102. if (applyConstructor) {
  103. s.apply(target, a);
  104. }
  105. return r;
  106. };
  107. /**
  108. * Applies object properties from the supplier to the receiver. If
  109. * the target has the property, and the property is an object, the target
  110. * object will be augmented with the supplier's value. If the property
  111. * is an array, the suppliers value will be appended to the target.
  112. * @method aggregate
  113. * @param {Function} r the object to receive the augmentation
  114. * @param {Function} s the object that supplies the properties to augment
  115. * @param ov {boolean} if true, properties already on the receiver
  116. * will be overwritten if found on the supplier.
  117. * @param wl {string[]} a whitelist. If supplied, only properties in
  118. * this list will be applied to the receiver.
  119. * @return {object} the extended object
  120. */
  121. Y.aggregate = function(r, s, ov, wl) {
  122. return Y.mix(r, s, ov, wl, 0, true);
  123. };
  124. /**
  125. * Utility to set up the prototype, constructor and superclass properties to
  126. * support an inheritance strategy that can chain constructors and methods.
  127. * Static members will not be inherited.
  128. *
  129. * @method extend
  130. * @param {Function} r the object to modify
  131. * @param {Function} s the object to inherit
  132. * @param {Object} px prototype properties to add/override
  133. * @param {Object} sx static properties to add/override
  134. * @return {YUI} the YUI instance
  135. */
  136. Y.extend = function(r, s, px, sx) {
  137. if (!s||!r) {
  138. // @TODO error symbols
  139. Y.error("extend failed, verify dependencies");
  140. }
  141. var sp = s.prototype, rp=Y.Object(sp);
  142. r.prototype=rp;
  143. rp.constructor=r;
  144. r.superclass=sp;
  145. // assign constructor property
  146. if (s != Object && sp.constructor == OP.constructor) {
  147. sp.constructor=s;
  148. }
  149. // add prototype overrides
  150. if (px) {
  151. Y.mix(rp, px, true);
  152. }
  153. // add object overrides
  154. if (sx) {
  155. Y.mix(r, sx, true);
  156. }
  157. return r;
  158. };
  159. /**
  160. * Executes the supplied function for each item in
  161. * a collection. Supports arrays, objects, and
  162. * Y.NodeLists
  163. * @method each
  164. * @param o the object to iterate
  165. * @param f the function to execute. This function
  166. * receives the value, key, and object as parameters
  167. * @param proto if true, prototype properties are
  168. * iterated on objects
  169. * @return {YUI} the YUI instance
  170. */
  171. Y.each = function(o, f, c, proto) {
  172. return dispatch(o, f, c, proto, EACH);
  173. };
  174. /*
  175. * Executes the supplied function for each item in
  176. * a collection. The operation stops if the function
  177. * returns true. Supports arrays, objects, and
  178. * Y.NodeLists.
  179. * @method some
  180. * @param o the object to iterate
  181. * @param f the function to execute. This function
  182. * receives the value, key, and object as parameters
  183. * @param proto if true, prototype properties are
  184. * iterated on objects
  185. * @return {boolean} true if the function ever returns true, false otherwise
  186. */
  187. Y.some = function(o, f, c, proto) {
  188. return dispatch(o, f, c, proto, SOME);
  189. };
  190. /**
  191. * Deep obj/array copy. Function clones are actually
  192. * wrappers around the original function.
  193. * Array-like objects are treated as arrays.
  194. * Primitives are returned untouched. Optionally, a
  195. * function can be provided to handle other data types,
  196. * filter keys, validate values, etc.
  197. *
  198. * @method clone
  199. * @param o what to clone
  200. * @param safe {boolean} if true, objects will not have prototype
  201. * items from the source. If false, they will. In this case, the
  202. * original is initially protected, but the clone is not completely immune
  203. * from changes to the source object prototype. Also, cloned prototype
  204. * items that are deleted from the clone will result in the value
  205. * of the source prototype being exposed. If operating on a non-safe
  206. * clone, items should be nulled out rather than deleted.
  207. * @param f optional function to apply to each item in a collection;
  208. * it will be executed prior to applying the value to
  209. * the new object. Return false to prevent the copy.
  210. * @param c optional execution context for f
  211. * @param owner Owner object passed when clone is iterating an
  212. * object. Used to set up context for cloned functions.
  213. * @return {Array|Object} the cloned object
  214. */
  215. Y.clone = function(o, safe, f, c, owner, cloned) {
  216. if (!L.isObject(o)) {
  217. return o;
  218. }
  219. // @TODO cloning YUI instances doesn't currently work
  220. if (o instanceof YUI) {
  221. return o;
  222. }
  223. var o2, marked = cloned || {}, stamp,
  224. each = Y.each || Y.Object.each;
  225. switch (L.type(o)) {
  226. case 'date':
  227. return new Date(o);
  228. case 'regexp':
  229. // return new RegExp(o.source); // if we do this we need to set the flags too
  230. return o;
  231. case 'function':
  232. // o2 = Y.bind(o, owner);
  233. // break;
  234. return o;
  235. case 'array':
  236. o2 = [];
  237. break;
  238. default:
  239. // #2528250 only one clone of a given object should be created.
  240. if (o[CLONE_MARKER]) {
  241. return marked[o[CLONE_MARKER]];
  242. }
  243. stamp = Y.guid();
  244. o2 = (safe) ? {} : Y.Object(o);
  245. o[CLONE_MARKER] = stamp;
  246. marked[stamp] = o;
  247. }
  248. // #2528250 don't try to clone element properties
  249. if (!o.addEventListener && !o.attachEvent) {
  250. each(o, function(v, k) {
  251. if (!f || (f.call(c || this, v, k, this, o) !== false)) {
  252. if (k !== CLONE_MARKER) {
  253. if (k == 'prototype') {
  254. // skip the prototype
  255. // } else if (o[k] === o) {
  256. // this[k] = this;
  257. } else {
  258. this[k] = Y.clone(v, safe, f, c, owner || o, marked);
  259. }
  260. }
  261. }
  262. }, o2);
  263. }
  264. if (!cloned) {
  265. Y.Object.each(marked, function(v, k) {
  266. delete v[CLONE_MARKER];
  267. });
  268. marked = null;
  269. }
  270. return o2;
  271. };
  272. /**
  273. * Returns a function that will execute the supplied function in the
  274. * supplied object's context, optionally adding any additional
  275. * supplied parameters to the beginning of the arguments collection the
  276. * supplied to the function.
  277. *
  278. * @method bind
  279. * @param f {Function|String} the function to bind, or a function name
  280. * to execute on the context object
  281. * @param c the execution context
  282. * @param args* 0..n arguments to include before the arguments the
  283. * function is executed with.
  284. * @return {function} the wrapped function
  285. */
  286. Y.bind = function(f, c) {
  287. var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
  288. return function () {
  289. var fn = L.isString(f) ? c[f] : f,
  290. args = (xargs) ? xargs.concat(Y.Array(arguments, 0, true)) : arguments;
  291. return fn.apply(c || fn, args);
  292. };
  293. };
  294. /**
  295. * Returns a function that will execute the supplied function in the
  296. * supplied object's context, optionally adding any additional
  297. * supplied parameters to the end of the arguments the function
  298. * is executed with.
  299. *
  300. * @method rbind
  301. * @param f {Function|String} the function to bind, or a function name
  302. * to execute on the context object
  303. * @param c the execution context
  304. * @param args* 0..n arguments to append to the end of arguments collection
  305. * supplied to the function
  306. * @return {function} the wrapped function
  307. */
  308. Y.rbind = function(f, c) {
  309. var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
  310. return function () {
  311. var fn = L.isString(f) ? c[f] : f,
  312. args = (xargs) ? Y.Array(arguments, 0, true).concat(xargs) : arguments;
  313. return fn.apply(c || fn, args);
  314. };
  315. };
  316. }, '@VERSION@' );