PageRenderTime 70ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

/ajax/libs/breezejs/1.2.5/breeze.debug.js

https://bitbucket.org/kolbyjAFK/cdnjs
JavaScript | 13133 lines | 7750 code | 1149 blank | 4234 comment | 1306 complexity | b12e12e890b396819dfcc269bbbf6c6a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright 2012 IdeaBlade, Inc. All Rights Reserved.
  3. * Use, reproduction, distribution, and modification of this code is subject to the terms and
  4. * conditions of the IdeaBlade Breeze license, available at http://www.breezejs.com/license
  5. *
  6. * Author: Jay Traband
  7. */
  8. (function (definition) {
  9. // CommonJS
  10. if (typeof exports === "object") {
  11. module.exports = definition();
  12. // RequireJS
  13. } else if (typeof define === "function") {
  14. define(definition);
  15. // <script>
  16. } else {
  17. breeze = definition();
  18. }
  19. })(function () {
  20. var breeze = {
  21. version: "1.2.5",
  22. };
  23. // legacy properties - will not be supported after 6/1/2013
  24. breeze.entityModel = breeze;
  25. breeze.entityTracking_backingStore = "backingStore";
  26. breeze.entityTracking_ko = "ko";
  27. breeze.entityTracking_backbone = "backbone";
  28. breeze.remoteAccess_odata = "odata";
  29. breeze.remoteAccess_webApi = "webApi";
  30. /**
  31. @module core
  32. **/
  33. var __hasOwnProperty = Object.prototype.hasOwnProperty;
  34. // iterate over object
  35. function __objectForEach(obj, kvFn) {
  36. for (var key in obj) {
  37. if (__hasOwnProperty.call(obj, key)) {
  38. kvFn(key, obj[key]);
  39. }
  40. }
  41. }
  42. function __objectFirst(obj, kvPredicate) {
  43. for (var key in obj) {
  44. if (__hasOwnProperty.call(obj, key)) {
  45. var value = obj[key];
  46. if (kvPredicate(key, value)) {
  47. return { key: key, value: value };
  48. }
  49. }
  50. }
  51. return null;
  52. };
  53. function __objectMapToArray(obj, kvFn) {
  54. var results = [];
  55. for (var key in obj) {
  56. if (__hasOwnProperty.call(obj, key)) {
  57. var result = kvFn(key, obj[key]);
  58. if (result) {
  59. results.push(result);
  60. }
  61. }
  62. }
  63. return results;
  64. }
  65. // Not yet needed
  66. //// transform an object's values
  67. //function objectMapValue(obj, kvProjection) {
  68. // var value, newMap = {};
  69. // for (var key in obj) {
  70. // if (__hasOwnProperty.call(obj, key)) {
  71. // value = kvProjection(key, obj[key]);
  72. // if (value !== undefined) {
  73. // newMap[key] = value;
  74. // }
  75. // }
  76. // }
  77. // return newMap;
  78. //}
  79. //// shrink an object's surface
  80. //function objectFilter(obj, kvPredicate) {
  81. // var result = {};
  82. // for (var key in obj) {
  83. // if (__hasOwnProperty.call(obj, key)) {
  84. // var value = obj[key];
  85. // if (kvPredicate(key, value)) {
  86. // result[key] = value;
  87. // }
  88. // }
  89. // }
  90. // return result;
  91. //};
  92. // Functional extensions
  93. // can be used like: persons.filter(propEq("firstName", "John"))
  94. function __propEq(propertyName, value) {
  95. return function (obj) {
  96. return obj[propertyName] === value;
  97. };
  98. }
  99. // can be used like persons.map(pluck("firstName"))
  100. function __pluck(propertyName) {
  101. return function (obj) { return obj[propertyName]; };
  102. }
  103. // end functional extensions
  104. function __getOwnPropertyValues(source) {
  105. var result = [];
  106. for (var name in source) {
  107. if (__hasOwnProperty.call(source, name)) {
  108. result.push(source[name]);
  109. }
  110. }
  111. return result;
  112. }
  113. function __extend(target, source) {
  114. if (!source) return target;
  115. for (var name in source) {
  116. if (__hasOwnProperty.call(source, name)) {
  117. target[name] = source[name];
  118. }
  119. }
  120. return target;
  121. }
  122. function __toJson(source, addlPropNames) {
  123. var target = {};
  124. for (var name in source) {
  125. if (__hasOwnProperty.call(source, name) && name.substr(0, 1) != "_") {
  126. var value = source[name];
  127. if (__isFunction(value)) continue;
  128. if (typeof(value) === "object") {
  129. if (value && value.parentEnum) {
  130. target[name] = value.name;
  131. }
  132. } else {
  133. target[name] = value;
  134. }
  135. }
  136. }
  137. addlPropNames && addlPropNames.forEach(function(n) {
  138. target[n] = source[n];
  139. });
  140. return target;
  141. }
  142. // array functions
  143. function __arrayFirst(array, predicate) {
  144. for (var i = 0, j = array.length; i < j; i++) {
  145. if (predicate(array[i])) {
  146. return array[i];
  147. }
  148. }
  149. return null;
  150. }
  151. function __arrayIndexOf(array, predicate) {
  152. for (var i = 0, j = array.length; i < j; i++) {
  153. if (predicate(array[i])) return i;
  154. }
  155. return -1;
  156. }
  157. function __arrayRemoveItem(array, predicateOrItem) {
  158. var predicate = __isFunction(predicateOrItem) ? predicateOrItem : undefined;
  159. var l = array.length;
  160. for (var index = 0; index < l; index++) {
  161. if (predicate ? predicate(array[index]) : (array[index] === predicateOrItem)) {
  162. array.splice(index, 1);
  163. return index;
  164. }
  165. }
  166. return -1;
  167. }
  168. function __arrayZip(a1, a2, callback) {
  169. var result = [];
  170. var n = Math.min(a1.length, a2.length);
  171. for (var i = 0; i < n; ++i) {
  172. result.push(callback(a1[i], a2[i]));
  173. }
  174. return result;
  175. }
  176. function __arrayDistinct(array) {
  177. array = array || [];
  178. var result = [];
  179. for (var i = 0, j = array.length; i < j; i++) {
  180. if (result.indexOf(array[i]) < 0)
  181. result.push(array[i]);
  182. }
  183. return result;
  184. }
  185. // Not yet needed
  186. //// much faster but only works on array items with a toString method that
  187. //// returns distinct string for distinct objects. So this is safe for arrays with primitive
  188. //// types but not for arrays with object types, unless toString() has been implemented.
  189. //function arrayDistinctUnsafe(array) {
  190. // var o = {}, i, l = array.length, r = [];
  191. // for (i = 0; i < l; i += 1) {
  192. // var v = array[i];
  193. // o[v] = v;
  194. // }
  195. // for (i in o) r.push(o[i]);
  196. // return r;
  197. //}
  198. function __arrayEquals(a1, a2, equalsFn) {
  199. //Check if the arrays are undefined/null
  200. if (!a1 || !a2) return false;
  201. if (a1.length != a2.length) return false;
  202. //go thru all the vars
  203. for (var i = 0; i < a1.length; i++) {
  204. //if the var is an array, we need to make a recursive check
  205. //otherwise we'll just compare the values
  206. if (Array.isArray( a1[i])) {
  207. if (!__arrayEquals(a1[i], a2[i])) return false;
  208. } else {
  209. if (equalsFn) {
  210. if (!equalsFn(a1[i], a2[i])) return false;
  211. } else {
  212. if (a1[i] != a2[i]) return false;
  213. }
  214. }
  215. }
  216. return true;
  217. }
  218. // end of array functions
  219. function __requireLib(libNames, errMessage) {
  220. var arrNames = libNames.split(";");
  221. for (var i = 0, j = arrNames.length; i < j; i++) {
  222. var lib = __requireLibCore(arrNames[i]);
  223. if (lib) return lib;
  224. }
  225. throw new Error("Unable to initialize " + libNames + ". " + errMessage || "");
  226. }
  227. function __requireLibCore(libName) {
  228. var lib = window[libName];
  229. if (lib) return lib;
  230. if (window.require) {
  231. lib = window.require(libName);
  232. }
  233. if (lib) return lib;
  234. return null;
  235. }
  236. function __using(obj, property, tempValue, fn) {
  237. var originalValue = obj[property];
  238. if (tempValue === originalValue) {
  239. return fn();
  240. }
  241. obj[property] = tempValue;
  242. try {
  243. return fn();
  244. } finally {
  245. obj[property] = originalValue;
  246. }
  247. }
  248. function __wrapExecution(startFn, endFn, fn) {
  249. var state;
  250. try {
  251. state = startFn();
  252. return fn();
  253. } catch (e) {
  254. if (typeof(state) === 'object') {
  255. state.error = e;
  256. }
  257. throw e;
  258. } finally {
  259. endFn(state);
  260. }
  261. }
  262. function __memoize(fn) {
  263. return function () {
  264. var args = Array.prototype.slice.call(arguments),
  265. hash = "",
  266. i = args.length,
  267. currentArg = null;
  268. while (i--) {
  269. currentArg = args[i];
  270. hash += (currentArg === Object(currentArg)) ? JSON.stringify(currentArg) : currentArg;
  271. fn.memoize || (fn.memoize = {});
  272. }
  273. return (hash in fn.memoize) ?
  274. fn.memoize[hash] :
  275. fn.memoize[hash] = fn.apply(this, args);
  276. };
  277. }
  278. function __getUuid() {
  279. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  280. var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  281. return v.toString(16);
  282. });
  283. }
  284. function __durationToSeconds(duration) {
  285. // basic algorithm from https://github.com/nezasa/iso8601-js-period
  286. if (typeof duration !== "string") throw new Error("Invalid ISO8601 duration '" + duration + "'");
  287. // regex splits as follows - grp0, grp1, y, m, d, grp2, h, m, s
  288. // 0 1 2 3 4 5 6 7 8
  289. var struct = /^P((\d+Y)?(\d+M)?(\d+D)?)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.exec(duration);
  290. if (!struct) throw new Error("Invalid ISO8601 duration '" + duration + "'");
  291. var ymdhmsIndexes = [2, 3, 4, 6, 7, 8]; // -> grp1,y,m,d,grp2,h,m,s
  292. var factors = [31104000, // year (360*24*60*60)
  293. 2592000, // month (30*24*60*60)
  294. 86400, // day (24*60*60)
  295. 3600, // hour (60*60)
  296. 60, // minute (60)
  297. 1]; // second (1)
  298. var seconds = 0;
  299. for (var i = 0; i < 6; i++) {
  300. var digit = struct[ymdhmsIndexes[i]];
  301. // remove letters, replace by 0 if not defined
  302. digit = digit ? +digit.replace(/[A-Za-z]+/g, '') : 0;
  303. seconds += digit * factors[i];
  304. };
  305. return seconds;
  306. };
  307. // is functions
  308. function __classof(o) {
  309. if (o === null) {
  310. return "null";
  311. }
  312. if (o === undefined) {
  313. return "undefined";
  314. }
  315. return Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
  316. }
  317. function __isDate(o) {
  318. return __classof(o) === "date" && !isNaN(o.getTime());
  319. }
  320. function __isFunction(o) {
  321. return __classof(o) === "function";
  322. }
  323. function __isGuid(value) {
  324. return (typeof value === "string") && /[a-fA-F\d]{8}-(?:[a-fA-F\d]{4}-){3}[a-fA-F\d]{12}/.test(value);
  325. }
  326. function __isDuration(value) {
  327. return (typeof value === "string") && /^(-|)?P([0-9]+Y|)?([0-9]+M|)?([0-9]+D|)?T?([0-9]+H|)?([0-9]+M|)?([0-9]+S|)?/.test(value);
  328. }
  329. function __isEmpty(obj) {
  330. if (obj === null || obj === undefined) {
  331. return true;
  332. }
  333. for (var key in obj) {
  334. if (__hasOwnProperty.call(obj, key)) {
  335. return false;
  336. }
  337. }
  338. return true;
  339. }
  340. function __isNumeric(n) {
  341. return !isNaN(parseFloat(n)) && isFinite(n);
  342. }
  343. // end of is Functions
  344. // string functions
  345. function __stringStartsWith(str, prefix) {
  346. // returns false for empty strings too
  347. if ((!str) || !prefix) return false;
  348. return str.indexOf(prefix, 0) === 0;
  349. }
  350. function __stringEndsWith(str, suffix) {
  351. // returns false for empty strings too
  352. if ((!str) || !suffix) return false;
  353. return str.indexOf(suffix, str.length - suffix.length) !== -1;
  354. }
  355. // Based on fragment from Dean Edwards' Base 2 library
  356. // format("a %1 and a %2", "cat", "dog") -> "a cat and a dog"
  357. function __formatString(string) {
  358. var args = arguments;
  359. var pattern = RegExp("%([1-" + (arguments.length - 1) + "])", "g");
  360. return string.replace(pattern, function (match, index) {
  361. return args[index];
  362. });
  363. };
  364. // end of string functions
  365. // shims
  366. if (!Object.create) {
  367. Object.create = function (parent) {
  368. var F = function () { };
  369. F.prototype = parent;
  370. return new F();
  371. };
  372. }
  373. var core = {};
  374. core.getOwnPropertyValues = __getOwnPropertyValues;
  375. core.objectForEach= __objectForEach;
  376. core.objectMapToArray= __objectMapToArray;
  377. core.objectFirst= __objectFirst;
  378. core.extend = __extend;
  379. core.propEq = __propEq;
  380. core.pluck = __pluck;
  381. core.arrayEquals = __arrayEquals;
  382. // core.arrayDistint = __arrayDistinct;
  383. core.arrayFirst = __arrayFirst;
  384. core.arrayIndexOf = __arrayIndexOf;
  385. core.arrayRemoveItem = __arrayRemoveItem;
  386. core.arrayZip = __arrayZip;
  387. core.requireLib = __requireLib;
  388. core.using = __using;
  389. core.wrapExecution = __wrapExecution;
  390. core.memoize = __memoize;
  391. core.getUuid = __getUuid;
  392. core.durationToSeconds = __durationToSeconds;
  393. core.isDate = __isDate;
  394. core.isGuid = __isGuid;
  395. core.isDuration = __isDuration;
  396. core.isFunction= __isFunction;
  397. core.isEmpty= __isEmpty;
  398. core.isNumeric= __isNumeric;
  399. core.stringStartsWith= __stringStartsWith;
  400. core.stringEndsWith= __stringEndsWith;
  401. core.formatString = __formatString;
  402. core.parent = breeze;
  403. breeze.core = core;
  404. /**
  405. @module core
  406. **/
  407. var Param = function () {
  408. // The %1 parameter
  409. // is required
  410. // must be a %2
  411. // must be an instance of %2
  412. // must be an instance of the %2 enumeration
  413. // must have a %2 property
  414. // must be an array where each element
  415. // is optional or
  416. var ctor = function(v, name) {
  417. this.v = v;
  418. this.name = name;
  419. this._contexts = [null];
  420. };
  421. var proto = ctor.prototype;
  422. proto.isObject = function() {
  423. return this.isTypeOf("object");
  424. };
  425. proto.isBoolean = function() {
  426. return this.isTypeOf('boolean');
  427. };
  428. proto.isString = function() {
  429. return this.isTypeOf('string');
  430. };
  431. proto.isNonEmptyString = function() {
  432. return addContext(this, {
  433. fn: isNonEmptyString,
  434. msg: "must be a nonEmpty string"
  435. });
  436. };
  437. function isNonEmptyString(context, v) {
  438. if (v == null) return false;
  439. return (typeof(v) === 'string') && v.length > 0;
  440. }
  441. proto.isNumber = function() {
  442. return this.isTypeOf('number');
  443. };
  444. proto.isFunction = function() {
  445. return this.isTypeOf('function');
  446. };
  447. proto.isTypeOf = function(typeName) {
  448. return addContext(this, {
  449. fn: isTypeOf,
  450. typeName: typeName,
  451. msg: __formatString("must be a '%1'", typeName)
  452. });
  453. };
  454. function isTypeOf(context, v) {
  455. if (v == null) return false;
  456. if (typeof(v) === context.typeName) return true;
  457. return false;
  458. }
  459. proto.isInstanceOf = function(type, typeName) {
  460. return addContext(this, {
  461. fn: isInstanceOf,
  462. type: type,
  463. typeName: typeName || type.prototype._$typeName,
  464. msg: __formatString("must be an instance of '%1'", typeName)
  465. });
  466. };
  467. function isInstanceOf(context, v) {
  468. if (v == null) return false;
  469. return (v instanceof context.type);
  470. }
  471. proto.hasProperty = function(propertyName) {
  472. return addContext(this, {
  473. fn: hasProperty,
  474. propertyName: propertyName,
  475. msg: __formatString("must have a '%1' property ", propertyName)
  476. });
  477. };
  478. function hasProperty(context, v) {
  479. if (v == null) return false;
  480. return (v[context.propertyName] !== undefined);
  481. }
  482. proto.isEnumOf = function(enumType) {
  483. return addContext(this, {
  484. fn: isEnumOf,
  485. enumType: enumType,
  486. msg: __formatString("must be an instance of the '%1' enumeration", enumType.name)
  487. });
  488. };
  489. function isEnumOf(context, v) {
  490. if (v == null) return false;
  491. return context.enumType.contains(v);
  492. }
  493. proto.isRequired = function(allowNull) {
  494. return addContext(this, {
  495. fn: isRequired,
  496. allowNull: allowNull,
  497. msg: "is required"
  498. });
  499. };
  500. function isRequired(context, v) {
  501. if (context.allowNull) {
  502. return v !== undefined;
  503. } else {
  504. return v != null;
  505. }
  506. }
  507. // combinable methods.
  508. proto.isOptional = function() {
  509. var context = {
  510. fn: isOptional,
  511. prevContext: null,
  512. msg: isOptionalMessage
  513. };
  514. return addContext(this, context);
  515. };
  516. function isOptional(context, v) {
  517. if (v == null) return true;
  518. var prevContext = context.prevContext;
  519. if (prevContext) {
  520. return prevContext.fn(prevContext, v);
  521. } else {
  522. return true;
  523. }
  524. }
  525. function isOptionalMessage(context, v) {
  526. var prevContext = context.prevContext;
  527. var element = prevContext ? " or it " + getMessage(prevContext, v) : "";
  528. return "is optional" + element;
  529. }
  530. proto.isNonEmptyArray = function() {
  531. return this.isArray(true);
  532. };
  533. proto.isArray = function(mustNotBeEmpty) {
  534. var context = {
  535. fn: isArray,
  536. mustNotBeEmpty: mustNotBeEmpty,
  537. prevContext: null,
  538. msg: isArrayMessage
  539. };
  540. return addContext(this, context);
  541. };
  542. function isArray(context, v) {
  543. if (!Array.isArray(v)) {
  544. return false;
  545. }
  546. if (context.mustNotBeEmpty) {
  547. if (v.length === 0) return false;
  548. }
  549. // allow standalone is array call.
  550. var prevContext = context.prevContext;
  551. if (!prevContext) return true;
  552. return v.every(function(v1) {
  553. return prevContext.fn(prevContext, v1);
  554. });
  555. }
  556. function isArrayMessage(context, v) {
  557. var arrayDescr = context.mustNotBeEmpty ? "a nonEmpty array" : "an array";
  558. var prevContext = context.prevContext;
  559. var element = prevContext ? " where each element " + getMessage(prevContext, v) : "";
  560. return " must be " + arrayDescr + element;
  561. }
  562. function getMessage(context, v) {
  563. var msg = context.msg;
  564. if (typeof(msg) === "function") {
  565. msg = msg(context, v);
  566. }
  567. return msg;
  568. }
  569. proto.or = function() {
  570. this._contexts.push(null);
  571. this._context = null;
  572. return this;
  573. };
  574. proto.check = function(defaultValue) {
  575. var ok = exec(this);
  576. if (ok === undefined) return;
  577. if (!ok) {
  578. throw new Error(this.getMessage());
  579. }
  580. if (this.v !== undefined) {
  581. return this.v;
  582. } else {
  583. return defaultValue;
  584. }
  585. };
  586. // called from outside this file.
  587. proto._addContext = function(context) {
  588. return addContext(this, context);
  589. };
  590. function addContext(that, context) {
  591. if (that._context) {
  592. var curContext = that._context;
  593. while (curContext.prevContext != null) {
  594. curContext = curContext.prevContext;
  595. }
  596. if (curContext.prevContext === null) {
  597. curContext.prevContext = context;
  598. // just update the prevContext but don't change the curContext.
  599. return that;
  600. } else if (context.prevContext === null) {
  601. context.prevContext = that._context;
  602. } else {
  603. throw new Error("Illegal construction - use 'or' to combine checks");
  604. }
  605. }
  606. return setContext(that, context);
  607. }
  608. function setContext(that, context) {
  609. that._contexts[that._contexts.length - 1] = context;
  610. that._context = context;
  611. return that;
  612. }
  613. function exec(self) {
  614. // clear off last one if null
  615. var contexts = self._contexts;
  616. if (contexts[contexts.length - 1] == null) {
  617. contexts.pop();
  618. }
  619. if (contexts.length === 0) {
  620. return undefined;
  621. }
  622. return contexts.some(function(context) {
  623. return context.fn(context, self.v);
  624. });
  625. }
  626. proto.getMessage = function() {
  627. var that = this;
  628. var message = this._contexts.map(function(context) {
  629. return getMessage(context, that.v);
  630. }).join(", or it ");
  631. return __formatString(this.MESSAGE_PREFIX, this.name) + " " + message;
  632. };
  633. proto.withDefault = function(defaultValue) {
  634. this.defaultValue = defaultValue;
  635. return this;
  636. };
  637. proto.whereParam = function(propName) {
  638. return this.parent.whereParam(propName);
  639. };
  640. proto.applyAll = function(instance, throwIfUnknownProperty) {
  641. throwIfUnknownProperty = throwIfUnknownProperty == null ? true : throwIfUnknownProperty;
  642. var clone = __extend({}, this.parent.config);
  643. this.parent.params.forEach(function(p) {
  644. if (throwIfUnknownProperty) delete clone[p.name];
  645. p._applyOne(instance);
  646. });
  647. // should be no properties left in the clone
  648. if (throwIfUnknownProperty) {
  649. for (var key in clone) {
  650. // allow props with an undefined value
  651. if (clone[key] !== undefined) {
  652. throw new Error("Invalid property in config: " + key);
  653. }
  654. }
  655. }
  656. };
  657. proto._applyOne = function(instance) {
  658. this.check();
  659. if (this.v !== undefined) {
  660. instance[this.name] = this.v;
  661. } else {
  662. if (this.defaultValue !== undefined) {
  663. instance[this.name] = this.defaultValue;
  664. }
  665. }
  666. };
  667. proto.MESSAGE_PREFIX = "The '%1' parameter ";
  668. return ctor;
  669. }();
  670. var assertParam = function (v, name) {
  671. return new Param(v, name);
  672. };
  673. var ConfigParam = function() {
  674. var ctor = function(config) {
  675. if (typeof(config) !== "object") {
  676. throw new Error("Configuration parameter should be an object, instead it is a: " + typeof(config));
  677. }
  678. this.config = config;
  679. this.params = [];
  680. };
  681. var proto = ctor.prototype;
  682. proto.whereParam = function(propName) {
  683. var param = new Param(this.config[propName], propName);
  684. param.parent = this;
  685. this.params.push(param);
  686. return param;
  687. };
  688. return ctor;
  689. }();
  690. var assertConfig = function(config) {
  691. return new ConfigParam(config);
  692. };
  693. // Param is exposed so that additional 'is' methods can be added to the prototype.
  694. core.Param = Param;
  695. core.assertParam = assertParam;
  696. core.assertConfig = assertConfig;
  697. /**
  698. @module core
  699. **/
  700. var Enum = function() {
  701. // TODO: think about CompositeEnum (flags impl).
  702. /**
  703. Base class for all Breeze enumerations, such as EntityState, DataType, FetchStrategy, MergeStrategy etc.
  704. A Breeze Enum is a namespaced set of constant values. Each Enum consists of a group of related constants, called 'symbols'.
  705. Unlike enums in some other environments, each 'symbol' can have both methods and properties.
  706. See the example below:
  707. // Example of creating a new Enum
  708. var prototype = {
  709. nextDay: function () {
  710. var nextIndex = (this.dayIndex+1) % 7;
  711. return DayOfWeek.getSymbols()[nextIndex];
  712. }
  713. };
  714. var DayOfWeek = new Enum("DayOfWeek", prototype);
  715. DayOfWeek.Monday = DayOfWeek.addSymbol( { dayIndex: 0 });
  716. DayOfWeek.Tuesday = DayOfWeek.addSymbol( { dayIndex: 1 });
  717. DayOfWeek.Wednesday = DayOfWeek.addSymbol( { dayIndex: 2 });
  718. DayOfWeek.Thursday = DayOfWeek.addSymbol( { dayIndex: 3 });
  719. DayOfWeek.Friday = DayOfWeek.addSymbol( { dayIndex: 4 });
  720. DayOfWeek.Saturday = DayOfWeek.addSymbol( { dayIndex: 5, isWeekend: true });
  721. DayOfWeek.Sunday = DayOfWeek.addSymbol( { dayIndex: 6, isWeekend: true });
  722. DayOfWeek.seal();
  723. // custom methods
  724. ok(DayOfWeek.Monday.nextDay() === DayOfWeek.Tuesday);
  725. ok(DayOfWeek.Sunday.nextDay() === DayOfWeek.Monday);
  726. // custom properties
  727. ok(DayOfWeek.Tuesday.isWeekend === undefined);
  728. ok(DayOfWeek.Saturday.isWeekend == true);
  729. // Standard enum capabilities
  730. ok(DayOfWeek instanceof Enum);
  731. ok(Enum.isSymbol(DayOfWeek.Wednesday));
  732. ok(DayOfWeek.contains(DayOfWeek.Thursday));
  733. ok(DayOfWeek.Tuesday.parentEnum == DayOfWeek);
  734. ok(DayOfWeek.getSymbols().length === 7);
  735. ok(DayOfWeek.Friday.toString() === "Friday");
  736. @class Enum
  737. **/
  738. /**
  739. Enum constructor - may be used to create new Enums.
  740. @example
  741. var prototype = {
  742. nextDay: function () {
  743. var nextIndex = (this.dayIndex+1) % 7;
  744. return DayOfWeek.getSymbols()[nextIndex];
  745. }
  746. };
  747. var DayOfWeek = new Enum("DayOfWeek", prototype);
  748. @method <ctor> Enum
  749. @param name {String}
  750. @param [methodObj] {Object}
  751. **/
  752. var ctor = function(name, methodObj) {
  753. this.name = name;
  754. var prototype = new EnumSymbol(methodObj);
  755. prototype.parentEnum = this;
  756. this._symbolPrototype = prototype;
  757. if (methodObj) {
  758. Object.keys(methodObj).forEach(function(key) {
  759. prototype[key] = methodObj[key];
  760. });
  761. }
  762. };
  763. var proto = ctor.prototype;
  764. /**
  765. Checks if an object is an Enum 'symbol'.
  766. @example
  767. if (Enum.isSymbol(DayOfWeek.Wednesday)) {
  768. // do something ...
  769. };
  770. @method isSymbol
  771. @return {Boolean}
  772. @static
  773. **/
  774. ctor.isSymbol = function(obj) {
  775. return obj instanceof EnumSymbol;
  776. };
  777. /**
  778. Returns an Enum symbol given its name.
  779. @example
  780. var dayOfWeek = DayOfWeek.from("Thursday");
  781. // nowdayOfWeek === DayOfWeek.Thursday
  782. @method fromName
  783. @param name {String} Name for which an enum symbol should be returned.
  784. @return {EnumSymbol} The symbol that matches the name or 'undefined' if not found.
  785. **/
  786. proto.fromName = function(name) {
  787. return this[name];
  788. };
  789. /**
  790. Adds a new symbol to an Enum.
  791. @example
  792. var DayOfWeek = new Enum("DayOfWeek", prototype);
  793. DayOfWeek.Monday = DayOfWeek.addSymbol( { dayIndex: 0 });
  794. @method addSymbol
  795. @param [propertiesObj] {Object} A collection of properties that should be added to the new symbol.
  796. In other words, the 'propertiesObj' is any state that should be held by the symbol.
  797. @return {EnumSymbol} The new symbol
  798. **/
  799. proto.addSymbol = function(propertiesObj) {
  800. // TODO: check if sealed.
  801. var newSymbol = Object.create(this._symbolPrototype);
  802. if (propertiesObj) {
  803. Object.keys(propertiesObj).forEach(function(key) {
  804. newSymbol[key] = propertiesObj[key];
  805. });
  806. }
  807. setTimeout(function() { newSymbol.getName(); }, 0);
  808. return newSymbol;
  809. };
  810. /**
  811. Seals this enum so that no more symbols may be added to it. This should only be called after all symbols
  812. have already been added to the Enum.
  813. @example
  814. DayOfWeek.seal();
  815. @method seal
  816. **/
  817. proto.seal = function() {
  818. this.getSymbols().forEach(function(sym) { return sym.getName(); });
  819. };
  820. //// TODO: remove or rethink this.
  821. //Enum.prototype.combineSymbols = function () {
  822. // var proto = this._symbolPrototype;
  823. // var newSymbol = Object.create(proto);
  824. // newSymbol._symbols = Array.prototype.slice.call(arguments);
  825. // Object.keys(proto).forEach(function (key) {
  826. // var result;
  827. // var oldMethod = proto[key];
  828. // if (__isFunction(oldMethod)) {
  829. // var newMethod = function () {
  830. // if (this._symbols) {
  831. // result = this._symbols.map(function (sym) {
  832. // return oldMethod.apply(sym);
  833. // });
  834. // } else {
  835. // result = oldMethod.apply(this);
  836. // }
  837. // return result;
  838. // };
  839. // proto[key] = newMethod;
  840. // }
  841. // });
  842. // return newSymbol;
  843. //};
  844. /**
  845. Returns all of the symbols contained within this Enum.
  846. @example
  847. var symbols = DayOfWeek.getSymbols();
  848. @method getSymbols
  849. @return {Array of EnumSymbol} All of the symbols contained within this Enum.
  850. **/
  851. proto.getSymbols = function() {
  852. return this.getNames().map(function(key) {
  853. return this[key];
  854. }, this);
  855. };
  856. /**
  857. Returns the names of all of the symbols contained within this Enum.
  858. @example
  859. var symbols = DayOfWeek.getNames();
  860. @method getNames
  861. @return {Array of String} All of the names of the symbols contained within this Enum.
  862. **/
  863. proto.getNames = function() {
  864. var result = [];
  865. for (var key in this) {
  866. if (this.hasOwnProperty(key)) {
  867. if (key != "name" && key.substr(0, 1) !== "_" && !__isFunction(this[key])) {
  868. result.push(key);
  869. }
  870. }
  871. }
  872. return result;
  873. };
  874. /**
  875. Returns whether an Enum contains a specified symbol.
  876. @example
  877. var symbol = DayOfWeek.Friday;
  878. if (DayOfWeek.contains(symbol)) {
  879. // do something
  880. }
  881. @method contains
  882. @param {Object} Object or symbol to test.
  883. @return {Boolean} Whether this Enum contains the specified symbol.
  884. **/
  885. proto.contains = function(sym) {
  886. if (!(sym instanceof EnumSymbol)) {
  887. return false;
  888. }
  889. return this[sym.getName()] === sym;
  890. };
  891. /**
  892. One of the constant values that is generated by the {{#crossLink "Enum"}}{{/crossLink}} "addSymbol" method. EnumSymbols should ONLY be created via
  893. the Enum.addSymbol method.
  894. var DayOfWeek = new Enum("DayOfWeek");
  895. DayOfWeek.Monday = DayOfWeek.addSymbol();
  896. @class EnumSymbol
  897. **/
  898. function EnumSymbol() {
  899. }
  900. /**
  901. The {{#crossLink "Enum"}}{{/crossLink}} to which this symbol belongs.
  902. __readOnly__
  903. @property parentEnum {Enum}
  904. **/
  905. /**
  906. Returns the name of this symbol.
  907. @example
  908. var name = DayOfWeek.Monday.getName();
  909. // name === "Monday"
  910. @method getName
  911. **/
  912. EnumSymbol.prototype.getName = function() {
  913. if (!this.name) {
  914. var that = this;
  915. this.name = __arrayFirst(this.parentEnum.getNames(), function(name) {
  916. return that.parentEnum[name] === that;
  917. });
  918. }
  919. return this.name;
  920. };
  921. /**
  922. Same as the getName method. Returns the name of this symbol.
  923. @example
  924. var name = DayOfWeek.Monday.toString();
  925. // name === "Monday"
  926. @method toString
  927. **/
  928. EnumSymbol.prototype.toString = function() {
  929. return this.getName();
  930. };
  931. EnumSymbol.prototype.toJSON = function() {
  932. return {
  933. _$typeName: this.parentEnum.name,
  934. name: this.name
  935. };
  936. };
  937. return ctor;
  938. }();
  939. core.Enum = Enum;
  940. /**
  941. @module core
  942. **/
  943. var Event = function() {
  944. var __eventNameMap = {};
  945. /**
  946. Class to support basic event publication and subscription semantics.
  947. @class Event
  948. **/
  949. /**
  950. Constructor for an Event
  951. @example
  952. salaryEvent = new Event("salaryEvent", person);
  953. @method <ctor> Event
  954. @param name {String}
  955. @param publisher {Object} The object that will be doing the publication. i.e. the object to which this event is attached.
  956. @param [defaultErrorCallback] {Function} If omitted then subscriber notification failures will be ignored.
  957. errorCallback([e])
  958. @param [defaultErrorCallback.e] {Error} Any error encountered during subscription execution.
  959. **/
  960. var ctor = function(name, publisher, defaultErrorCallback) {
  961. assertParam(name, "eventName").isNonEmptyString().check();
  962. assertParam(publisher, "publisher").isObject().check();
  963. this.name = name;
  964. // register the name
  965. __eventNameMap[name] = true;
  966. this.publisher = publisher;
  967. this._nextUnsubKey = 1;
  968. if (defaultErrorCallback) {
  969. this._defaultErrorCallback = defaultErrorCallback;
  970. }
  971. };
  972. var proto = ctor.prototype;
  973. /**
  974. Publish data for this event.
  975. @example
  976. // Assume 'salaryEvent' is previously constructed Event
  977. salaryEvent.publish( { eventType: "payRaise", amount: 100 });
  978. This event can also be published asychonously
  979. @example
  980. salaryEvent.publish( { eventType: "payRaise", amount: 100 }, true);
  981. And we can add a handler in case the subscriber 'mishandles' the event.
  982. @example
  983. salaryEvent.publish( { eventType: "payRaise", amount: 100 }, true, function(error) {
  984. // do something with the 'error' object
  985. });
  986. @method publish
  987. @param data {Object} Data to publish
  988. @param [publishAsync=false] Whether to publish asynchonously or not.
  989. @param [errorCallback] {Function} Will be called for any errors that occur during publication. If omitted,
  990. errors will be eaten.
  991. errorCallback([e])
  992. @param [errorCallback.e] {Error} Any error encountered during publication execution.
  993. @return {Boolean} false if event is disabled; true otherwise.
  994. **/
  995. proto.publish = function(data, publishAsync, errorCallback) {
  996. if (!ctor._isEnabled(this.name, this.publisher)) return false;
  997. if (publishAsync === true) {
  998. setTimeout(publishCore, 0, this, data, errorCallback);
  999. } else {
  1000. publishCore(this, data, errorCallback);
  1001. }
  1002. return true;
  1003. };
  1004. function publishCore(that, data, errorCallback) {
  1005. var subscribers = that._subscribers;
  1006. if (!subscribers) return true;
  1007. // subscribers from outer scope.
  1008. subscribers.forEach(function(s) {
  1009. try {
  1010. s.callback(data);
  1011. } catch(e) {
  1012. e.context = "unable to publish on topic: " + that.name;
  1013. if (errorCallback) {
  1014. errorCallback(e);
  1015. } else if (that._defaultErrorCallback) {
  1016. that._defaultErrorCallback(e);
  1017. } else {
  1018. fallbackErrorHandler(e);
  1019. }
  1020. }
  1021. });
  1022. }
  1023. /**
  1024. Publish data for this event asynchronously.
  1025. @example
  1026. // Assume 'salaryEvent' is previously constructed Event
  1027. salaryEvent.publishAsync( { eventType: "payRaise", amount: 100 });
  1028. And we can add a handler in case the subscriber 'mishandles' the event.
  1029. @example
  1030. salaryEvent.publishAsync( { eventType: "payRaise", amount: 100 }, function(error) {
  1031. // do something with the 'error' object
  1032. });
  1033. @method publishAsync
  1034. @param data {Object} Data to publish
  1035. @param [errorCallback] {Function} Will be called for any errors that occur during publication. If omitted,
  1036. errors will be eaten.
  1037. errorCallback([e])
  1038. @param [errorCallback.e] {Error} Any error encountered during publication execution.
  1039. **/
  1040. proto.publishAsync = function(data, errorCallback) {
  1041. this.publish(data, true, errorCallback);
  1042. };
  1043. /**
  1044. Subscribe to this event.
  1045. @example
  1046. // Assume 'salaryEvent' is previously constructed Event
  1047. salaryEvent.subscribe(function (eventArgs) {
  1048. if (eventArgs.eventType === "payRaise") {
  1049. // do something
  1050. }
  1051. });
  1052. There are several built in Breeze events, such as EntityAspect.propertyChanged, EntityAspect.validationErrorsChanged as well.
  1053. @example
  1054. // Assume order is a preexisting 'order' entity
  1055. order.entityAspect.propertyChanged.subscribe(function (pcEvent) {
  1056. if ( pcEvent.propertyName === "OrderDate") {
  1057. // do something
  1058. }
  1059. });
  1060. @method subscribe
  1061. @param [callback] {Function} Will be called whenever 'data' is published for this event.
  1062. callback([data])
  1063. @param [callback.data] {Object} Whatever 'data' was published. This should be documented on the specific event.
  1064. @return {Number} This is a key for 'unsubscription'. It can be passed to the 'unsubscribe' method.
  1065. **/
  1066. proto.subscribe = function(callback) {
  1067. if (!this._subscribers) {
  1068. this._subscribers = [];
  1069. }
  1070. var unsubKey = this._nextUnsubKey;
  1071. this._subscribers.push({ unsubKey: unsubKey, callback: callback });
  1072. ++this._nextUnsubKey;
  1073. return unsubKey;
  1074. };
  1075. /**
  1076. Unsubscribe from this event.
  1077. @example
  1078. // Assume order is a preexisting 'order' entity
  1079. var token = order.entityAspect.propertyChanged.subscribe(function (pcEvent) {
  1080. // do something
  1081. });
  1082. // sometime later
  1083. order.entityAspect.propertyChanged.unsubscribe(token);
  1084. @method unsubscribe
  1085. @param unsubKey {Number} The value returned from the 'subscribe' method may be used to unsubscribe here.
  1086. @return {Boolean} Whether unsubscription occured. This will return false if already unsubscribed or if the key simply
  1087. cannot be found.
  1088. **/
  1089. proto.unsubscribe = function(unsubKey) {
  1090. if (!this._subscribers) return false;
  1091. var subs = this._subscribers;
  1092. var ix = __arrayIndexOf(subs, function(s) {
  1093. return s.unsubKey === unsubKey;
  1094. });
  1095. if (ix !== -1) {
  1096. subs.splice(ix, 1);
  1097. if (subs.length === 0) {
  1098. this._subscribers = null;
  1099. }
  1100. return true;
  1101. } else {
  1102. return false;
  1103. }
  1104. };
  1105. proto.clear = function() {
  1106. this._subscribers = null;
  1107. };
  1108. // event bubbling - document later.
  1109. ctor.bubbleEvent = function(target, getParentFn) {
  1110. target._getEventParent = getParentFn;
  1111. };
  1112. /**
  1113. Enables or disables the named event for an object and all of its children.
  1114. @example
  1115. Event.enable(“propertyChanged”, myEntityManager, false)
  1116. will disable all EntityAspect.propertyChanged events within a EntityManager.
  1117. @example
  1118. Event.enable(“propertyChanged”, myEntityManager, true)
  1119. will enable all EntityAspect.propertyChanged events within a EntityManager.
  1120. @example
  1121. Event.enable(“propertyChanged”, myEntity.entityAspect, false)
  1122. will disable EntityAspect.propertyChanged events for a specific entity.
  1123. @example
  1124. Event.enable(“propertyChanged”, myEntity.entityAspect, null)
  1125. will removes any enabling / disabling at the entity aspect level so now any 'Event.enable' calls at the EntityManager level,
  1126. made either previously or in the future, will control notification.
  1127. @example
  1128. Event.enable(“validationErrorsChanged”, myEntityManager, function(em) {
  1129. return em.customTag === “blue”;
  1130. })
  1131. will either enable or disable myEntityManager based on the current value of a ‘customTag’ property on myEntityManager.
  1132. Note that this is dynamic, changing the customTag value will cause events to be enabled or disabled immediately.
  1133. @method enable
  1134. @static
  1135. @param eventName {String} The name of the event.
  1136. @param target {Object} The object at which enabling or disabling will occur. All event notifications that occur to this object or
  1137. children of this object will be enabled or disabled.
  1138. @param isEnabled {Boolean|null|Function} A boolean, a null or a function that returns either a boolean or a null.
  1139. **/
  1140. ctor.enable = function(eventName, obj, isEnabled) {
  1141. assertParam(eventName, "eventName").isNonEmptyString().check();
  1142. assertParam(obj, "obj").isObject().check();
  1143. assertParam(isEnabled, "isEnabled").isBoolean().isOptional().or().isFunction().check();
  1144. eventName = getFullEventName(eventName);
  1145. if (!obj._$eventMap) {
  1146. obj._$eventMap = {};
  1147. }
  1148. obj._$eventMap[eventName] = isEnabled;
  1149. };
  1150. ctor._enableFast = function(event, obj, isEnabled) {
  1151. if (!obj._$eventMap) {
  1152. obj._$eventMap = {};
  1153. }
  1154. obj._$eventMap[event.name] = isEnabled;
  1155. };
  1156. /**
  1157. Returns whether for a specific event and a specific object and its children, notification is enabled or disabled or not set.
  1158. @example
  1159. Event.isEnabled(“propertyChanged”, myEntityManager)
  1160. @method isEnabled
  1161. @static
  1162. @param eventName {String} The name of the event.
  1163. @param target {Object} The object for which we want to know if notifications are enabled.
  1164. @return {Boolean|null} A null is returned if this value has not been set.
  1165. **/
  1166. ctor.isEnabled = function(eventName, obj) {
  1167. assertParam(eventName, "eventName").isNonEmptyString().check();
  1168. assertParam(obj, "obj").isObject().check();
  1169. if (!obj._getEventParent) {
  1170. throw new Error("This object does not support event enabling/disabling");
  1171. }
  1172. return ctor._isEnabled(obj, getFullEventName(eventName));
  1173. };
  1174. ctor._isEnabled = function(eventName, obj) {
  1175. var isEnabled = null;
  1176. var eventMap = obj._$eventMap;
  1177. if (eventMap) {
  1178. isEnabled = eventMap[eventName];
  1179. }
  1180. if (isEnabled != null) {
  1181. if (typeof isEnabled === 'function') {
  1182. return isEnabled(obj);
  1183. } else {
  1184. return !!isEnabled;
  1185. }
  1186. } else {
  1187. var parent = obj._getEventParent && obj._getEventParent();
  1188. if (parent) {
  1189. return ctor._isEnabled(eventName, parent);
  1190. } else {
  1191. // default if not explicitly disabled.
  1192. return true;
  1193. }
  1194. }
  1195. };
  1196. function getFullEventName(eventName) {
  1197. if (__eventNameMap[eventName]) return eventName;
  1198. // find the closest event name that matches
  1199. var fullEventName = __arrayFirst(Object.keys(__eventNameMap), function(name) {
  1200. return name.indexOf(eventName) === 0;
  1201. });
  1202. if (!fullEventName) {
  1203. throw new Error("Unable to find any registered event that matches: " + eventName);
  1204. }
  1205. return fullEventName;
  1206. }
  1207. function fallbackErrorHandler(e) {
  1208. // TODO: maybe log this
  1209. // for now do nothing;
  1210. }
  1211. return ctor;
  1212. }();
  1213. core.Event = Event;
  1214. /**
  1215. @module breeze
  1216. **/
  1217. var __config = function () {
  1218. // alias for within fns with a config param
  1219. var __config = {};
  1220. __config.functionRegistry = {};
  1221. __config.typeRegistry = {};
  1222. __config.objectRegistry = {};
  1223. __config.interfaceInitialized = new Event("interfaceInitialized_config", __config);
  1224. var InterfaceDef = function(name) {
  1225. this.name = name;
  1226. this.defaultInstance = null;
  1227. this._implMap = {};
  1228. };
  1229. InterfaceDef.prototype.registerCtor = function(adapterName, ctor) {
  1230. this._implMap[adapterName.toLowerCase()] = { ctor: ctor, defaultInstance: null };
  1231. };
  1232. InterfaceDef.prototype.getImpl = function(adapterName) {
  1233. return this._implMap[adapterName.toLowerCase()];
  1234. };
  1235. InterfaceDef.prototype.getFirstImpl = function() {
  1236. var kv = __objectFirst(this._implMap, function() { return true; });
  1237. return kv ? kv.value : null;
  1238. };
  1239. __config.interfaceRegistry = {
  1240. ajax: new InterfaceDef("ajax"),
  1241. modelLibrary: new InterfaceDef("modelLibrary"),
  1242. dataService: new InterfaceDef("dataService")
  1243. };
  1244. __config.interfaceRegistry.modelLibrary.getDefaultInstance = function() {
  1245. if (!this.defaultInstance) {
  1246. throw new Error("Unable to locate the default implementation of the '" + this.name
  1247. + "' interface. Possible options are 'ko', 'backingStore' or 'backbone'. See the breeze.config.initializeAdapterInstances method.");
  1248. }
  1249. return this.defaultInstance;
  1250. };
  1251. /**
  1252. A singleton object that is the repository of all configuration options.
  1253. config.initializeAdapterInstance( {
  1254. modelLibrary: "ko",
  1255. dataService: "webApi"
  1256. });
  1257. @class config
  1258. **/
  1259. /**
  1260. This method is now OBSOLETE. Use the "initializeAdapterInstances" to accomplish the same result.
  1261. @method setProperties
  1262. @deprecated
  1263. @param config {Object}
  1264. @param [config.remoteAccessImplementation] { implementation of remoteAccess-interface }
  1265. @param [config.trackingImplementation] { implementation of entityTracking-interface }
  1266. @param [config.ajaxImplementation] {implementation of ajax-interface }
  1267. **/
  1268. __config.setProperties = function(config) {
  1269. assertConfig(config)
  1270. .whereParam("remoteAccessImplementation").isOptional()
  1271. .whereParam("trackingImplementation").isOptional()
  1272. .whereParam("ajaxImplementation").isOptional()
  1273. .applyAll(config);
  1274. if (config.remoteAccessImplementation) {
  1275. __config.initializeAdapterInstance("dataService", config.remoteAccessImplementation);
  1276. }
  1277. if (config.trackingImplementation) {
  1278. // note the name change
  1279. __config.initializeAdapterInstance("modelLibrary", config.trackingImplementation);
  1280. }
  1281. if (config.ajaxImplementation) {
  1282. __config.initializeAdapterInstance("ajax", config.ajaxImplementation);
  1283. }
  1284. };
  1285. /**
  1286. Method use to register implementations of standard breeze interfaces. Calls to this method are usually
  1287. made as the last step within an adapter implementation.
  1288. @method registerAdapter
  1289. @param interfaceName {String} - one of the following interface names "ajax", "dataService" or "modelLibrary"
  1290. @param adapterCtor {Function} - an ctor function that returns an instance of the specified interface.
  1291. **/
  1292. __config.registerAdapter = function(interfaceName, adapterCtor) {
  1293. assertParam(interfaceName, "interfaceName").isNonEmptyString().check();
  1294. assertParam(adapterCtor, "adapterCtor").isFunction().check();
  1295. // this impl will be thrown away after the name is retrieved.
  1296. var impl = new adapterCtor();
  1297. var implName = impl.name;
  1298. if (!implName) {
  1299. throw new Error("Unable to locate a 'name' property on the constructor passed into the 'registerAdapter' call.");
  1300. }
  1301. var idef = getInterfaceDef(interfaceName);
  1302. idef.registerCtor(implName, adapterCtor);
  1303. };
  1304. /**
  1305. Returns the ctor function used to implement a specific interface with a specific adapter name.
  1306. @method getAdapter
  1307. @param interfaceName {String} One of the following interface names "ajax", "dataService" or "modelLibrary"
  1308. @param [adapterName] {String} The name of any previously registered adapter. If this parameter is omitted then
  1309. this method returns the "default" adapter for this interface. If there is no default adapter, then a null is returned.
  1310. @return {Function|null} Returns either a ctor function or null.
  1311. **/
  1312. __config.getAdapter = function(interfaceName, adapterName) {
  1313. var idef = getInterfaceDef(interfaceName);
  1314. if (adapterName) {
  1315. var impl = idef.getImpl(adapterName);
  1316. return impl ? impl.ctor : null;
  1317. } else {
  1318. return idef.defaultInstance ? idef.defaultInstance._$impl.ctor : null;
  1319. }
  1320. };
  1321. /**
  1322. Initializes a collection of adapter implementations and makes each one the default for its corresponding interface.
  1323. @method initializeAdapterInstances
  1324. @param config {Object}
  1325. @param [config.ajax] {String} - the name of a previously registered "ajax" adapter
  1326. @param [config.dataService] {String} - the name of a previously registered "dataService" adapter
  1327. @param [config.modelLibrary] {String} - the name of a previously registered "modelLibrary" adapter
  1328. @return [array of instances]
  1329. **/
  1330. __config.initializeAdapterInstances = function(config) {
  1331. assertConfig(config)
  1332. .whereParam("dataService").isOptional()
  1333. .whereParam("modelLibrary").isOptional()
  1334. .whereParam("ajax").isOptional();
  1335. return __objectMapToArray(config, __config.initializeAdapterInstance);
  1336. };
  1337. /**
  1338. Initializes a single adapter implementation. Initialization means either newing a instance of the
  1339. specified interface and then calling "initialize" on it or simply calling "initialize" on the instance
  1340. if it already exists.
  1341. @method initializeAdapterInstance
  1342. @param interfaceName {String} The name of the interface to which the adapter to initialize belongs.
  1343. @param adapterName {String} - The name of a previously registered adapter to initialize.
  1344. @param [isDefault=true] {Boolean} - Whether to make this the default "adapter" for this interface.
  1345. @return {an instance of the specified adapter}
  1346. **/
  1347. __config.initializeAdapterInstance = function(interfaceName, adapterName, isDefault) {
  1348. isDefault = isDefault === undefined ? true : isDefault;
  1349. assertParam(interfaceName, "interfaceName").isNonEmptyString().check();
  1350. assertParam(adapterName, "adapterName").isNonEmptyString().check();
  1351. assertParam(isDefault, "isDefault").isBoolean().check();
  1352. var idef = getInterfaceDef(interfaceName);
  1353. var impl = idef.getImpl(adapterName);
  1354. if (!impl) {
  1355. throw new Error("Unregistered adapter. Interface: " + interfaceName + " AdapterName: " + adapterName);
  1356. }
  1357. return initializeAdapterInstanceCore(idef, impl, isDefault);
  1358. };
  1359. /**
  1360. Returns the adapter instance corresponding to the specified interface and adapter names.
  1361. @method getAdapterInstance
  1362. @param interfaceName {String} The name of the interface.
  1363. @param [adapterName] {String} - The name of a previously registered adapter. If this parameter is
  1364. omitted then the default implementation of the specified interface is returned. If there is
  1365. no defaultInstance of this interface, then the first registered instance of this interface is returned.
  1366. @return {an instance of the specified adapter}
  1367. **/
  1368. __config.getAdapterInstance = function(interfaceName, adapterName) {
  1369. var idef = getInterfaceDef(interfaceName);
  1370. var impl;
  1371. if (adapterName & adapterName !== "") {
  1372. impl = idef.getImpl(adapterName);
  1373. return impl ? impl.defaultInstance : null;
  1374. } else {
  1375. if (idef.defaultIns…

Large files files are truncated, but you can click here to view the full file