/ajax/libs/breezejs/1.2.5/breeze.debug.js
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
- /*
- * Copyright 2012 IdeaBlade, Inc. All Rights Reserved.
- * Use, reproduction, distribution, and modification of this code is subject to the terms and
- * conditions of the IdeaBlade Breeze license, available at http://www.breezejs.com/license
- *
- * Author: Jay Traband
- */
- (function (definition) {
- // CommonJS
- if (typeof exports === "object") {
- module.exports = definition();
- // RequireJS
- } else if (typeof define === "function") {
- define(definition);
- // <script>
- } else {
- breeze = definition();
- }
- })(function () {
- var breeze = {
- version: "1.2.5",
- };
- // legacy properties - will not be supported after 6/1/2013
- breeze.entityModel = breeze;
- breeze.entityTracking_backingStore = "backingStore";
- breeze.entityTracking_ko = "ko";
- breeze.entityTracking_backbone = "backbone";
- breeze.remoteAccess_odata = "odata";
- breeze.remoteAccess_webApi = "webApi";
-
- /**
- @module core
- **/
- var __hasOwnProperty = Object.prototype.hasOwnProperty;
- // iterate over object
- function __objectForEach(obj, kvFn) {
- for (var key in obj) {
- if (__hasOwnProperty.call(obj, key)) {
- kvFn(key, obj[key]);
- }
- }
- }
-
-
- function __objectFirst(obj, kvPredicate) {
- for (var key in obj) {
- if (__hasOwnProperty.call(obj, key)) {
- var value = obj[key];
- if (kvPredicate(key, value)) {
- return { key: key, value: value };
- }
- }
- }
- return null;
- };
- function __objectMapToArray(obj, kvFn) {
- var results = [];
- for (var key in obj) {
- if (__hasOwnProperty.call(obj, key)) {
- var result = kvFn(key, obj[key]);
- if (result) {
- results.push(result);
- }
- }
- }
- return results;
- }
-
- // Not yet needed
- //// transform an object's values
- //function objectMapValue(obj, kvProjection) {
- // var value, newMap = {};
- // for (var key in obj) {
- // if (__hasOwnProperty.call(obj, key)) {
- // value = kvProjection(key, obj[key]);
- // if (value !== undefined) {
- // newMap[key] = value;
- // }
- // }
- // }
- // return newMap;
- //}
- //// shrink an object's surface
- //function objectFilter(obj, kvPredicate) {
- // var result = {};
- // for (var key in obj) {
- // if (__hasOwnProperty.call(obj, key)) {
- // var value = obj[key];
- // if (kvPredicate(key, value)) {
- // result[key] = value;
- // }
- // }
- // }
- // return result;
- //};
-
-
- // Functional extensions
- // can be used like: persons.filter(propEq("firstName", "John"))
- function __propEq(propertyName, value) {
- return function (obj) {
- return obj[propertyName] === value;
- };
- }
- // can be used like persons.map(pluck("firstName"))
- function __pluck(propertyName) {
- return function (obj) { return obj[propertyName]; };
- }
- // end functional extensions
- function __getOwnPropertyValues(source) {
- var result = [];
- for (var name in source) {
- if (__hasOwnProperty.call(source, name)) {
- result.push(source[name]);
- }
- }
- return result;
- }
- function __extend(target, source) {
- if (!source) return target;
- for (var name in source) {
- if (__hasOwnProperty.call(source, name)) {
- target[name] = source[name];
- }
- }
- return target;
- }
- function __toJson(source, addlPropNames) {
- var target = {};
- for (var name in source) {
- if (__hasOwnProperty.call(source, name) && name.substr(0, 1) != "_") {
- var value = source[name];
- if (__isFunction(value)) continue;
- if (typeof(value) === "object") {
- if (value && value.parentEnum) {
- target[name] = value.name;
- }
- } else {
- target[name] = value;
- }
- }
- }
- addlPropNames && addlPropNames.forEach(function(n) {
- target[n] = source[n];
- });
- return target;
- }
- // array functions
- function __arrayFirst(array, predicate) {
- for (var i = 0, j = array.length; i < j; i++) {
- if (predicate(array[i])) {
- return array[i];
- }
- }
- return null;
- }
- function __arrayIndexOf(array, predicate) {
- for (var i = 0, j = array.length; i < j; i++) {
- if (predicate(array[i])) return i;
- }
- return -1;
- }
- function __arrayRemoveItem(array, predicateOrItem) {
- var predicate = __isFunction(predicateOrItem) ? predicateOrItem : undefined;
- var l = array.length;
- for (var index = 0; index < l; index++) {
- if (predicate ? predicate(array[index]) : (array[index] === predicateOrItem)) {
- array.splice(index, 1);
- return index;
- }
- }
- return -1;
- }
- function __arrayZip(a1, a2, callback) {
- var result = [];
- var n = Math.min(a1.length, a2.length);
- for (var i = 0; i < n; ++i) {
- result.push(callback(a1[i], a2[i]));
- }
- return result;
- }
- function __arrayDistinct(array) {
- array = array || [];
- var result = [];
- for (var i = 0, j = array.length; i < j; i++) {
- if (result.indexOf(array[i]) < 0)
- result.push(array[i]);
- }
- return result;
- }
- // Not yet needed
- //// much faster but only works on array items with a toString method that
- //// returns distinct string for distinct objects. So this is safe for arrays with primitive
- //// types but not for arrays with object types, unless toString() has been implemented.
- //function arrayDistinctUnsafe(array) {
- // var o = {}, i, l = array.length, r = [];
- // for (i = 0; i < l; i += 1) {
- // var v = array[i];
- // o[v] = v;
- // }
- // for (i in o) r.push(o[i]);
- // return r;
- //}
- function __arrayEquals(a1, a2, equalsFn) {
- //Check if the arrays are undefined/null
- if (!a1 || !a2) return false;
- if (a1.length != a2.length) return false;
- //go thru all the vars
- for (var i = 0; i < a1.length; i++) {
- //if the var is an array, we need to make a recursive check
- //otherwise we'll just compare the values
- if (Array.isArray( a1[i])) {
- if (!__arrayEquals(a1[i], a2[i])) return false;
- } else {
- if (equalsFn) {
- if (!equalsFn(a1[i], a2[i])) return false;
- } else {
- if (a1[i] != a2[i]) return false;
- }
- }
- }
- return true;
- }
- // end of array functions
-
- function __requireLib(libNames, errMessage) {
- var arrNames = libNames.split(";");
- for (var i = 0, j = arrNames.length; i < j; i++) {
- var lib = __requireLibCore(arrNames[i]);
- if (lib) return lib;
- }
- throw new Error("Unable to initialize " + libNames + ". " + errMessage || "");
- }
-
- function __requireLibCore(libName) {
- var lib = window[libName];
- if (lib) return lib;
- if (window.require) {
- lib = window.require(libName);
- }
- if (lib) return lib;
- return null;
- }
- function __using(obj, property, tempValue, fn) {
- var originalValue = obj[property];
- if (tempValue === originalValue) {
- return fn();
- }
- obj[property] = tempValue;
- try {
- return fn();
- } finally {
- obj[property] = originalValue;
- }
- }
-
- function __wrapExecution(startFn, endFn, fn) {
- var state;
- try {
- state = startFn();
- return fn();
- } catch (e) {
- if (typeof(state) === 'object') {
- state.error = e;
- }
- throw e;
- } finally {
- endFn(state);
- }
- }
- function __memoize(fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments),
- hash = "",
- i = args.length,
- currentArg = null;
- while (i--) {
- currentArg = args[i];
- hash += (currentArg === Object(currentArg)) ? JSON.stringify(currentArg) : currentArg;
- fn.memoize || (fn.memoize = {});
- }
- return (hash in fn.memoize) ?
- fn.memoize[hash] :
- fn.memoize[hash] = fn.apply(this, args);
- };
- }
- function __getUuid() {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
- }
-
- function __durationToSeconds(duration) {
- // basic algorithm from https://github.com/nezasa/iso8601-js-period
- if (typeof duration !== "string") throw new Error("Invalid ISO8601 duration '" + duration + "'");
- // regex splits as follows - grp0, grp1, y, m, d, grp2, h, m, s
- // 0 1 2 3 4 5 6 7 8
- var struct = /^P((\d+Y)?(\d+M)?(\d+D)?)?(T(\d+H)?(\d+M)?(\d+S)?)?$/.exec(duration);
- if (!struct) throw new Error("Invalid ISO8601 duration '" + duration + "'");
-
- var ymdhmsIndexes = [2, 3, 4, 6, 7, 8]; // -> grp1,y,m,d,grp2,h,m,s
- var factors = [31104000, // year (360*24*60*60)
- 2592000, // month (30*24*60*60)
- 86400, // day (24*60*60)
- 3600, // hour (60*60)
- 60, // minute (60)
- 1]; // second (1)
- var seconds = 0;
- for (var i = 0; i < 6; i++) {
- var digit = struct[ymdhmsIndexes[i]];
- // remove letters, replace by 0 if not defined
- digit = digit ? +digit.replace(/[A-Za-z]+/g, '') : 0;
- seconds += digit * factors[i];
- };
- return seconds;
- };
-
- // is functions
- function __classof(o) {
- if (o === null) {
- return "null";
- }
- if (o === undefined) {
- return "undefined";
- }
- return Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
- }
- function __isDate(o) {
- return __classof(o) === "date" && !isNaN(o.getTime());
- }
- function __isFunction(o) {
- return __classof(o) === "function";
- }
- function __isGuid(value) {
- return (typeof value === "string") && /[a-fA-F\d]{8}-(?:[a-fA-F\d]{4}-){3}[a-fA-F\d]{12}/.test(value);
- }
-
- function __isDuration(value) {
- 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);
- }
- function __isEmpty(obj) {
- if (obj === null || obj === undefined) {
- return true;
- }
- for (var key in obj) {
- if (__hasOwnProperty.call(obj, key)) {
- return false;
- }
- }
- return true;
- }
- function __isNumeric(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
- }
- // end of is Functions
- // string functions
- function __stringStartsWith(str, prefix) {
- // returns false for empty strings too
- if ((!str) || !prefix) return false;
- return str.indexOf(prefix, 0) === 0;
- }
- function __stringEndsWith(str, suffix) {
- // returns false for empty strings too
- if ((!str) || !suffix) return false;
- return str.indexOf(suffix, str.length - suffix.length) !== -1;
- }
- // Based on fragment from Dean Edwards' Base 2 library
- // format("a %1 and a %2", "cat", "dog") -> "a cat and a dog"
- function __formatString(string) {
- var args = arguments;
- var pattern = RegExp("%([1-" + (arguments.length - 1) + "])", "g");
- return string.replace(pattern, function (match, index) {
- return args[index];
- });
- };
- // end of string functions
- // shims
- if (!Object.create) {
- Object.create = function (parent) {
- var F = function () { };
- F.prototype = parent;
- return new F();
- };
- }
- var core = {};
- core.getOwnPropertyValues = __getOwnPropertyValues;
- core.objectForEach= __objectForEach;
- core.objectMapToArray= __objectMapToArray;
- core.objectFirst= __objectFirst;
- core.extend = __extend;
- core.propEq = __propEq;
- core.pluck = __pluck;
- core.arrayEquals = __arrayEquals;
- // core.arrayDistint = __arrayDistinct;
- core.arrayFirst = __arrayFirst;
- core.arrayIndexOf = __arrayIndexOf;
- core.arrayRemoveItem = __arrayRemoveItem;
- core.arrayZip = __arrayZip;
- core.requireLib = __requireLib;
- core.using = __using;
- core.wrapExecution = __wrapExecution;
- core.memoize = __memoize;
- core.getUuid = __getUuid;
- core.durationToSeconds = __durationToSeconds;
- core.isDate = __isDate;
- core.isGuid = __isGuid;
- core.isDuration = __isDuration;
- core.isFunction= __isFunction;
- core.isEmpty= __isEmpty;
- core.isNumeric= __isNumeric;
- core.stringStartsWith= __stringStartsWith;
- core.stringEndsWith= __stringEndsWith;
- core.formatString = __formatString;
- core.parent = breeze;
- breeze.core = core;
- /**
- @module core
- **/
- var Param = function () {
- // The %1 parameter
- // is required
- // must be a %2
- // must be an instance of %2
- // must be an instance of the %2 enumeration
- // must have a %2 property
- // must be an array where each element
- // is optional or
- var ctor = function(v, name) {
- this.v = v;
- this.name = name;
- this._contexts = [null];
- };
- var proto = ctor.prototype;
- proto.isObject = function() {
- return this.isTypeOf("object");
- };
- proto.isBoolean = function() {
- return this.isTypeOf('boolean');
- };
- proto.isString = function() {
- return this.isTypeOf('string');
- };
- proto.isNonEmptyString = function() {
- return addContext(this, {
- fn: isNonEmptyString,
- msg: "must be a nonEmpty string"
- });
- };
- function isNonEmptyString(context, v) {
- if (v == null) return false;
- return (typeof(v) === 'string') && v.length > 0;
- }
- proto.isNumber = function() {
- return this.isTypeOf('number');
- };
- proto.isFunction = function() {
- return this.isTypeOf('function');
- };
- proto.isTypeOf = function(typeName) {
- return addContext(this, {
- fn: isTypeOf,
- typeName: typeName,
- msg: __formatString("must be a '%1'", typeName)
- });
- };
- function isTypeOf(context, v) {
- if (v == null) return false;
- if (typeof(v) === context.typeName) return true;
- return false;
- }
- proto.isInstanceOf = function(type, typeName) {
- return addContext(this, {
- fn: isInstanceOf,
- type: type,
- typeName: typeName || type.prototype._$typeName,
- msg: __formatString("must be an instance of '%1'", typeName)
- });
- };
- function isInstanceOf(context, v) {
- if (v == null) return false;
- return (v instanceof context.type);
- }
- proto.hasProperty = function(propertyName) {
- return addContext(this, {
- fn: hasProperty,
- propertyName: propertyName,
- msg: __formatString("must have a '%1' property ", propertyName)
- });
- };
- function hasProperty(context, v) {
- if (v == null) return false;
- return (v[context.propertyName] !== undefined);
- }
- proto.isEnumOf = function(enumType) {
- return addContext(this, {
- fn: isEnumOf,
- enumType: enumType,
- msg: __formatString("must be an instance of the '%1' enumeration", enumType.name)
- });
- };
- function isEnumOf(context, v) {
- if (v == null) return false;
- return context.enumType.contains(v);
- }
- proto.isRequired = function(allowNull) {
- return addContext(this, {
- fn: isRequired,
- allowNull: allowNull,
- msg: "is required"
- });
- };
- function isRequired(context, v) {
- if (context.allowNull) {
- return v !== undefined;
- } else {
- return v != null;
- }
- }
- // combinable methods.
- proto.isOptional = function() {
- var context = {
- fn: isOptional,
- prevContext: null,
- msg: isOptionalMessage
- };
- return addContext(this, context);
- };
- function isOptional(context, v) {
- if (v == null) return true;
- var prevContext = context.prevContext;
- if (prevContext) {
- return prevContext.fn(prevContext, v);
- } else {
- return true;
- }
- }
- function isOptionalMessage(context, v) {
- var prevContext = context.prevContext;
- var element = prevContext ? " or it " + getMessage(prevContext, v) : "";
- return "is optional" + element;
- }
- proto.isNonEmptyArray = function() {
- return this.isArray(true);
- };
- proto.isArray = function(mustNotBeEmpty) {
- var context = {
- fn: isArray,
- mustNotBeEmpty: mustNotBeEmpty,
- prevContext: null,
- msg: isArrayMessage
- };
- return addContext(this, context);
- };
- function isArray(context, v) {
- if (!Array.isArray(v)) {
- return false;
- }
- if (context.mustNotBeEmpty) {
- if (v.length === 0) return false;
- }
- // allow standalone is array call.
- var prevContext = context.prevContext;
- if (!prevContext) return true;
- return v.every(function(v1) {
- return prevContext.fn(prevContext, v1);
- });
- }
- function isArrayMessage(context, v) {
- var arrayDescr = context.mustNotBeEmpty ? "a nonEmpty array" : "an array";
- var prevContext = context.prevContext;
- var element = prevContext ? " where each element " + getMessage(prevContext, v) : "";
- return " must be " + arrayDescr + element;
- }
- function getMessage(context, v) {
- var msg = context.msg;
- if (typeof(msg) === "function") {
- msg = msg(context, v);
- }
- return msg;
- }
- proto.or = function() {
- this._contexts.push(null);
- this._context = null;
- return this;
- };
- proto.check = function(defaultValue) {
- var ok = exec(this);
- if (ok === undefined) return;
- if (!ok) {
- throw new Error(this.getMessage());
- }
- if (this.v !== undefined) {
- return this.v;
- } else {
- return defaultValue;
- }
- };
- // called from outside this file.
- proto._addContext = function(context) {
- return addContext(this, context);
- };
- function addContext(that, context) {
- if (that._context) {
- var curContext = that._context;
- while (curContext.prevContext != null) {
- curContext = curContext.prevContext;
- }
- if (curContext.prevContext === null) {
- curContext.prevContext = context;
- // just update the prevContext but don't change the curContext.
- return that;
- } else if (context.prevContext === null) {
- context.prevContext = that._context;
- } else {
- throw new Error("Illegal construction - use 'or' to combine checks");
- }
- }
- return setContext(that, context);
- }
- function setContext(that, context) {
- that._contexts[that._contexts.length - 1] = context;
- that._context = context;
- return that;
- }
- function exec(self) {
- // clear off last one if null
- var contexts = self._contexts;
- if (contexts[contexts.length - 1] == null) {
- contexts.pop();
- }
- if (contexts.length === 0) {
- return undefined;
- }
- return contexts.some(function(context) {
- return context.fn(context, self.v);
- });
- }
- proto.getMessage = function() {
- var that = this;
- var message = this._contexts.map(function(context) {
- return getMessage(context, that.v);
- }).join(", or it ");
- return __formatString(this.MESSAGE_PREFIX, this.name) + " " + message;
- };
- proto.withDefault = function(defaultValue) {
- this.defaultValue = defaultValue;
- return this;
- };
- proto.whereParam = function(propName) {
- return this.parent.whereParam(propName);
- };
- proto.applyAll = function(instance, throwIfUnknownProperty) {
- throwIfUnknownProperty = throwIfUnknownProperty == null ? true : throwIfUnknownProperty;
- var clone = __extend({}, this.parent.config);
- this.parent.params.forEach(function(p) {
- if (throwIfUnknownProperty) delete clone[p.name];
- p._applyOne(instance);
- });
- // should be no properties left in the clone
- if (throwIfUnknownProperty) {
- for (var key in clone) {
- // allow props with an undefined value
- if (clone[key] !== undefined) {
- throw new Error("Invalid property in config: " + key);
- }
- }
- }
- };
- proto._applyOne = function(instance) {
- this.check();
- if (this.v !== undefined) {
- instance[this.name] = this.v;
- } else {
- if (this.defaultValue !== undefined) {
- instance[this.name] = this.defaultValue;
- }
- }
- };
- proto.MESSAGE_PREFIX = "The '%1' parameter ";
- return ctor;
- }();
- var assertParam = function (v, name) {
- return new Param(v, name);
- };
- var ConfigParam = function() {
- var ctor = function(config) {
- if (typeof(config) !== "object") {
- throw new Error("Configuration parameter should be an object, instead it is a: " + typeof(config));
- }
- this.config = config;
- this.params = [];
- };
- var proto = ctor.prototype;
- proto.whereParam = function(propName) {
- var param = new Param(this.config[propName], propName);
- param.parent = this;
- this.params.push(param);
- return param;
- };
- return ctor;
- }();
- var assertConfig = function(config) {
- return new ConfigParam(config);
- };
- // Param is exposed so that additional 'is' methods can be added to the prototype.
- core.Param = Param;
- core.assertParam = assertParam;
- core.assertConfig = assertConfig;
- /**
- @module core
- **/
- var Enum = function() {
- // TODO: think about CompositeEnum (flags impl).
- /**
- Base class for all Breeze enumerations, such as EntityState, DataType, FetchStrategy, MergeStrategy etc.
- A Breeze Enum is a namespaced set of constant values. Each Enum consists of a group of related constants, called 'symbols'.
- Unlike enums in some other environments, each 'symbol' can have both methods and properties.
- See the example below:
- // Example of creating a new Enum
- var prototype = {
- nextDay: function () {
- var nextIndex = (this.dayIndex+1) % 7;
- return DayOfWeek.getSymbols()[nextIndex];
- }
- };
- var DayOfWeek = new Enum("DayOfWeek", prototype);
- DayOfWeek.Monday = DayOfWeek.addSymbol( { dayIndex: 0 });
- DayOfWeek.Tuesday = DayOfWeek.addSymbol( { dayIndex: 1 });
- DayOfWeek.Wednesday = DayOfWeek.addSymbol( { dayIndex: 2 });
- DayOfWeek.Thursday = DayOfWeek.addSymbol( { dayIndex: 3 });
- DayOfWeek.Friday = DayOfWeek.addSymbol( { dayIndex: 4 });
- DayOfWeek.Saturday = DayOfWeek.addSymbol( { dayIndex: 5, isWeekend: true });
- DayOfWeek.Sunday = DayOfWeek.addSymbol( { dayIndex: 6, isWeekend: true });
- DayOfWeek.seal();
- // custom methods
- ok(DayOfWeek.Monday.nextDay() === DayOfWeek.Tuesday);
- ok(DayOfWeek.Sunday.nextDay() === DayOfWeek.Monday);
- // custom properties
- ok(DayOfWeek.Tuesday.isWeekend === undefined);
- ok(DayOfWeek.Saturday.isWeekend == true);
- // Standard enum capabilities
- ok(DayOfWeek instanceof Enum);
- ok(Enum.isSymbol(DayOfWeek.Wednesday));
- ok(DayOfWeek.contains(DayOfWeek.Thursday));
- ok(DayOfWeek.Tuesday.parentEnum == DayOfWeek);
- ok(DayOfWeek.getSymbols().length === 7);
- ok(DayOfWeek.Friday.toString() === "Friday");
- @class Enum
- **/
- /**
- Enum constructor - may be used to create new Enums.
- @example
- var prototype = {
- nextDay: function () {
- var nextIndex = (this.dayIndex+1) % 7;
- return DayOfWeek.getSymbols()[nextIndex];
- }
- };
- var DayOfWeek = new Enum("DayOfWeek", prototype);
- @method <ctor> Enum
- @param name {String}
- @param [methodObj] {Object}
- **/
- var ctor = function(name, methodObj) {
- this.name = name;
- var prototype = new EnumSymbol(methodObj);
- prototype.parentEnum = this;
- this._symbolPrototype = prototype;
- if (methodObj) {
- Object.keys(methodObj).forEach(function(key) {
- prototype[key] = methodObj[key];
- });
- }
- };
- var proto = ctor.prototype;
- /**
- Checks if an object is an Enum 'symbol'.
- @example
- if (Enum.isSymbol(DayOfWeek.Wednesday)) {
- // do something ...
- };
- @method isSymbol
- @return {Boolean}
- @static
- **/
- ctor.isSymbol = function(obj) {
- return obj instanceof EnumSymbol;
- };
- /**
- Returns an Enum symbol given its name.
- @example
- var dayOfWeek = DayOfWeek.from("Thursday");
- // nowdayOfWeek === DayOfWeek.Thursday
- @method fromName
- @param name {String} Name for which an enum symbol should be returned.
- @return {EnumSymbol} The symbol that matches the name or 'undefined' if not found.
- **/
- proto.fromName = function(name) {
- return this[name];
- };
- /**
- Adds a new symbol to an Enum.
- @example
- var DayOfWeek = new Enum("DayOfWeek", prototype);
- DayOfWeek.Monday = DayOfWeek.addSymbol( { dayIndex: 0 });
- @method addSymbol
- @param [propertiesObj] {Object} A collection of properties that should be added to the new symbol.
- In other words, the 'propertiesObj' is any state that should be held by the symbol.
- @return {EnumSymbol} The new symbol
- **/
- proto.addSymbol = function(propertiesObj) {
- // TODO: check if sealed.
- var newSymbol = Object.create(this._symbolPrototype);
- if (propertiesObj) {
- Object.keys(propertiesObj).forEach(function(key) {
- newSymbol[key] = propertiesObj[key];
- });
- }
- setTimeout(function() { newSymbol.getName(); }, 0);
- return newSymbol;
- };
- /**
- Seals this enum so that no more symbols may be added to it. This should only be called after all symbols
- have already been added to the Enum.
- @example
- DayOfWeek.seal();
- @method seal
- **/
- proto.seal = function() {
- this.getSymbols().forEach(function(sym) { return sym.getName(); });
- };
- //// TODO: remove or rethink this.
- //Enum.prototype.combineSymbols = function () {
- // var proto = this._symbolPrototype;
- // var newSymbol = Object.create(proto);
- // newSymbol._symbols = Array.prototype.slice.call(arguments);
- // Object.keys(proto).forEach(function (key) {
- // var result;
- // var oldMethod = proto[key];
- // if (__isFunction(oldMethod)) {
- // var newMethod = function () {
- // if (this._symbols) {
- // result = this._symbols.map(function (sym) {
- // return oldMethod.apply(sym);
- // });
- // } else {
- // result = oldMethod.apply(this);
- // }
- // return result;
- // };
- // proto[key] = newMethod;
- // }
- // });
- // return newSymbol;
- //};
- /**
- Returns all of the symbols contained within this Enum.
- @example
- var symbols = DayOfWeek.getSymbols();
- @method getSymbols
- @return {Array of EnumSymbol} All of the symbols contained within this Enum.
- **/
- proto.getSymbols = function() {
- return this.getNames().map(function(key) {
- return this[key];
- }, this);
- };
- /**
- Returns the names of all of the symbols contained within this Enum.
- @example
- var symbols = DayOfWeek.getNames();
- @method getNames
- @return {Array of String} All of the names of the symbols contained within this Enum.
- **/
- proto.getNames = function() {
- var result = [];
- for (var key in this) {
- if (this.hasOwnProperty(key)) {
- if (key != "name" && key.substr(0, 1) !== "_" && !__isFunction(this[key])) {
- result.push(key);
- }
- }
- }
- return result;
- };
- /**
- Returns whether an Enum contains a specified symbol.
- @example
- var symbol = DayOfWeek.Friday;
- if (DayOfWeek.contains(symbol)) {
- // do something
- }
- @method contains
- @param {Object} Object or symbol to test.
- @return {Boolean} Whether this Enum contains the specified symbol.
- **/
- proto.contains = function(sym) {
- if (!(sym instanceof EnumSymbol)) {
- return false;
- }
- return this[sym.getName()] === sym;
- };
- /**
- One of the constant values that is generated by the {{#crossLink "Enum"}}{{/crossLink}} "addSymbol" method. EnumSymbols should ONLY be created via
- the Enum.addSymbol method.
- var DayOfWeek = new Enum("DayOfWeek");
- DayOfWeek.Monday = DayOfWeek.addSymbol();
- @class EnumSymbol
- **/
- function EnumSymbol() {
- }
- /**
- The {{#crossLink "Enum"}}{{/crossLink}} to which this symbol belongs.
- __readOnly__
- @property parentEnum {Enum}
- **/
- /**
- Returns the name of this symbol.
- @example
- var name = DayOfWeek.Monday.getName();
- // name === "Monday"
- @method getName
- **/
- EnumSymbol.prototype.getName = function() {
- if (!this.name) {
- var that = this;
- this.name = __arrayFirst(this.parentEnum.getNames(), function(name) {
- return that.parentEnum[name] === that;
- });
- }
- return this.name;
- };
- /**
- Same as the getName method. Returns the name of this symbol.
- @example
- var name = DayOfWeek.Monday.toString();
- // name === "Monday"
- @method toString
- **/
- EnumSymbol.prototype.toString = function() {
- return this.getName();
- };
- EnumSymbol.prototype.toJSON = function() {
- return {
- _$typeName: this.parentEnum.name,
- name: this.name
- };
- };
- return ctor;
- }();
- core.Enum = Enum;
- /**
- @module core
- **/
- var Event = function() {
-
- var __eventNameMap = {};
- /**
- Class to support basic event publication and subscription semantics.
- @class Event
- **/
- /**
- Constructor for an Event
- @example
- salaryEvent = new Event("salaryEvent", person);
- @method <ctor> Event
- @param name {String}
- @param publisher {Object} The object that will be doing the publication. i.e. the object to which this event is attached.
- @param [defaultErrorCallback] {Function} If omitted then subscriber notification failures will be ignored.
- errorCallback([e])
- @param [defaultErrorCallback.e] {Error} Any error encountered during subscription execution.
- **/
- var ctor = function(name, publisher, defaultErrorCallback) {
- assertParam(name, "eventName").isNonEmptyString().check();
- assertParam(publisher, "publisher").isObject().check();
- this.name = name;
- // register the name
- __eventNameMap[name] = true;
- this.publisher = publisher;
- this._nextUnsubKey = 1;
- if (defaultErrorCallback) {
- this._defaultErrorCallback = defaultErrorCallback;
- }
- };
- var proto = ctor.prototype;
- /**
- Publish data for this event.
- @example
- // Assume 'salaryEvent' is previously constructed Event
- salaryEvent.publish( { eventType: "payRaise", amount: 100 });
- This event can also be published asychonously
- @example
- salaryEvent.publish( { eventType: "payRaise", amount: 100 }, true);
- And we can add a handler in case the subscriber 'mishandles' the event.
- @example
- salaryEvent.publish( { eventType: "payRaise", amount: 100 }, true, function(error) {
- // do something with the 'error' object
- });
- @method publish
- @param data {Object} Data to publish
- @param [publishAsync=false] Whether to publish asynchonously or not.
- @param [errorCallback] {Function} Will be called for any errors that occur during publication. If omitted,
- errors will be eaten.
- errorCallback([e])
- @param [errorCallback.e] {Error} Any error encountered during publication execution.
- @return {Boolean} false if event is disabled; true otherwise.
- **/
- proto.publish = function(data, publishAsync, errorCallback) {
- if (!ctor._isEnabled(this.name, this.publisher)) return false;
- if (publishAsync === true) {
- setTimeout(publishCore, 0, this, data, errorCallback);
- } else {
- publishCore(this, data, errorCallback);
- }
- return true;
- };
- function publishCore(that, data, errorCallback) {
- var subscribers = that._subscribers;
- if (!subscribers) return true;
- // subscribers from outer scope.
- subscribers.forEach(function(s) {
- try {
- s.callback(data);
- } catch(e) {
- e.context = "unable to publish on topic: " + that.name;
- if (errorCallback) {
- errorCallback(e);
- } else if (that._defaultErrorCallback) {
- that._defaultErrorCallback(e);
- } else {
- fallbackErrorHandler(e);
- }
- }
- });
- }
- /**
- Publish data for this event asynchronously.
- @example
- // Assume 'salaryEvent' is previously constructed Event
- salaryEvent.publishAsync( { eventType: "payRaise", amount: 100 });
- And we can add a handler in case the subscriber 'mishandles' the event.
- @example
- salaryEvent.publishAsync( { eventType: "payRaise", amount: 100 }, function(error) {
- // do something with the 'error' object
- });
- @method publishAsync
- @param data {Object} Data to publish
- @param [errorCallback] {Function} Will be called for any errors that occur during publication. If omitted,
- errors will be eaten.
- errorCallback([e])
- @param [errorCallback.e] {Error} Any error encountered during publication execution.
- **/
- proto.publishAsync = function(data, errorCallback) {
- this.publish(data, true, errorCallback);
- };
- /**
- Subscribe to this event.
- @example
- // Assume 'salaryEvent' is previously constructed Event
- salaryEvent.subscribe(function (eventArgs) {
- if (eventArgs.eventType === "payRaise") {
- // do something
- }
- });
- There are several built in Breeze events, such as EntityAspect.propertyChanged, EntityAspect.validationErrorsChanged as well.
- @example
- // Assume order is a preexisting 'order' entity
- order.entityAspect.propertyChanged.subscribe(function (pcEvent) {
- if ( pcEvent.propertyName === "OrderDate") {
- // do something
- }
- });
- @method subscribe
- @param [callback] {Function} Will be called whenever 'data' is published for this event.
- callback([data])
- @param [callback.data] {Object} Whatever 'data' was published. This should be documented on the specific event.
- @return {Number} This is a key for 'unsubscription'. It can be passed to the 'unsubscribe' method.
- **/
- proto.subscribe = function(callback) {
- if (!this._subscribers) {
- this._subscribers = [];
- }
- var unsubKey = this._nextUnsubKey;
- this._subscribers.push({ unsubKey: unsubKey, callback: callback });
- ++this._nextUnsubKey;
- return unsubKey;
- };
- /**
- Unsubscribe from this event.
- @example
- // Assume order is a preexisting 'order' entity
- var token = order.entityAspect.propertyChanged.subscribe(function (pcEvent) {
- // do something
- });
- // sometime later
- order.entityAspect.propertyChanged.unsubscribe(token);
- @method unsubscribe
- @param unsubKey {Number} The value returned from the 'subscribe' method may be used to unsubscribe here.
- @return {Boolean} Whether unsubscription occured. This will return false if already unsubscribed or if the key simply
- cannot be found.
- **/
- proto.unsubscribe = function(unsubKey) {
- if (!this._subscribers) return false;
- var subs = this._subscribers;
- var ix = __arrayIndexOf(subs, function(s) {
- return s.unsubKey === unsubKey;
- });
- if (ix !== -1) {
- subs.splice(ix, 1);
- if (subs.length === 0) {
- this._subscribers = null;
- }
- return true;
- } else {
- return false;
- }
- };
- proto.clear = function() {
- this._subscribers = null;
- };
- // event bubbling - document later.
- ctor.bubbleEvent = function(target, getParentFn) {
- target._getEventParent = getParentFn;
- };
- /**
- Enables or disables the named event for an object and all of its children.
- @example
- Event.enable(“propertyChanged”, myEntityManager, false)
- will disable all EntityAspect.propertyChanged events within a EntityManager.
- @example
- Event.enable(“propertyChanged”, myEntityManager, true)
- will enable all EntityAspect.propertyChanged events within a EntityManager.
- @example
- Event.enable(“propertyChanged”, myEntity.entityAspect, false)
- will disable EntityAspect.propertyChanged events for a specific entity.
- @example
- Event.enable(“propertyChanged”, myEntity.entityAspect, null)
- will removes any enabling / disabling at the entity aspect level so now any 'Event.enable' calls at the EntityManager level,
- made either previously or in the future, will control notification.
- @example
- Event.enable(“validationErrorsChanged”, myEntityManager, function(em) {
- return em.customTag === “blue”;
- })
- will either enable or disable myEntityManager based on the current value of a ‘customTag’ property on myEntityManager.
- Note that this is dynamic, changing the customTag value will cause events to be enabled or disabled immediately.
- @method enable
- @static
- @param eventName {String} The name of the event.
- @param target {Object} The object at which enabling or disabling will occur. All event notifications that occur to this object or
- children of this object will be enabled or disabled.
- @param isEnabled {Boolean|null|Function} A boolean, a null or a function that returns either a boolean or a null.
- **/
- ctor.enable = function(eventName, obj, isEnabled) {
- assertParam(eventName, "eventName").isNonEmptyString().check();
- assertParam(obj, "obj").isObject().check();
- assertParam(isEnabled, "isEnabled").isBoolean().isOptional().or().isFunction().check();
- eventName = getFullEventName(eventName);
- if (!obj._$eventMap) {
- obj._$eventMap = {};
- }
- obj._$eventMap[eventName] = isEnabled;
- };
- ctor._enableFast = function(event, obj, isEnabled) {
- if (!obj._$eventMap) {
- obj._$eventMap = {};
- }
- obj._$eventMap[event.name] = isEnabled;
- };
- /**
- Returns whether for a specific event and a specific object and its children, notification is enabled or disabled or not set.
- @example
- Event.isEnabled(“propertyChanged”, myEntityManager)
-
- @method isEnabled
- @static
- @param eventName {String} The name of the event.
- @param target {Object} The object for which we want to know if notifications are enabled.
- @return {Boolean|null} A null is returned if this value has not been set.
- **/
- ctor.isEnabled = function(eventName, obj) {
- assertParam(eventName, "eventName").isNonEmptyString().check();
- assertParam(obj, "obj").isObject().check();
- if (!obj._getEventParent) {
- throw new Error("This object does not support event enabling/disabling");
- }
- return ctor._isEnabled(obj, getFullEventName(eventName));
- };
- ctor._isEnabled = function(eventName, obj) {
- var isEnabled = null;
- var eventMap = obj._$eventMap;
- if (eventMap) {
- isEnabled = eventMap[eventName];
- }
- if (isEnabled != null) {
- if (typeof isEnabled === 'function') {
- return isEnabled(obj);
- } else {
- return !!isEnabled;
- }
- } else {
- var parent = obj._getEventParent && obj._getEventParent();
- if (parent) {
- return ctor._isEnabled(eventName, parent);
- } else {
- // default if not explicitly disabled.
- return true;
- }
- }
- };
- function getFullEventName(eventName) {
- if (__eventNameMap[eventName]) return eventName;
- // find the closest event name that matches
- var fullEventName = __arrayFirst(Object.keys(__eventNameMap), function(name) {
- return name.indexOf(eventName) === 0;
- });
- if (!fullEventName) {
- throw new Error("Unable to find any registered event that matches: " + eventName);
- }
- return fullEventName;
- }
- function fallbackErrorHandler(e) {
- // TODO: maybe log this
- // for now do nothing;
- }
- return ctor;
- }();
- core.Event = Event;
- /**
- @module breeze
- **/
- var __config = function () {
- // alias for within fns with a config param
- var __config = {};
- __config.functionRegistry = {};
- __config.typeRegistry = {};
- __config.objectRegistry = {};
- __config.interfaceInitialized = new Event("interfaceInitialized_config", __config);
- var InterfaceDef = function(name) {
- this.name = name;
- this.defaultInstance = null;
- this._implMap = {};
- };
- InterfaceDef.prototype.registerCtor = function(adapterName, ctor) {
- this._implMap[adapterName.toLowerCase()] = { ctor: ctor, defaultInstance: null };
- };
- InterfaceDef.prototype.getImpl = function(adapterName) {
- return this._implMap[adapterName.toLowerCase()];
- };
- InterfaceDef.prototype.getFirstImpl = function() {
- var kv = __objectFirst(this._implMap, function() { return true; });
- return kv ? kv.value : null;
- };
- __config.interfaceRegistry = {
- ajax: new InterfaceDef("ajax"),
- modelLibrary: new InterfaceDef("modelLibrary"),
- dataService: new InterfaceDef("dataService")
- };
- __config.interfaceRegistry.modelLibrary.getDefaultInstance = function() {
- if (!this.defaultInstance) {
- throw new Error("Unable to locate the default implementation of the '" + this.name
- + "' interface. Possible options are 'ko', 'backingStore' or 'backbone'. See the breeze.config.initializeAdapterInstances method.");
- }
- return this.defaultInstance;
- };
- /**
- A singleton object that is the repository of all configuration options.
- config.initializeAdapterInstance( {
- modelLibrary: "ko",
- dataService: "webApi"
- });
-
- @class config
- **/
- /**
- This method is now OBSOLETE. Use the "initializeAdapterInstances" to accomplish the same result.
- @method setProperties
- @deprecated
- @param config {Object}
- @param [config.remoteAccessImplementation] { implementation of remoteAccess-interface }
- @param [config.trackingImplementation] { implementation of entityTracking-interface }
- @param [config.ajaxImplementation] {implementation of ajax-interface }
- **/
- __config.setProperties = function(config) {
- assertConfig(config)
- .whereParam("remoteAccessImplementation").isOptional()
- .whereParam("trackingImplementation").isOptional()
- .whereParam("ajaxImplementation").isOptional()
- .applyAll(config);
- if (config.remoteAccessImplementation) {
- __config.initializeAdapterInstance("dataService", config.remoteAccessImplementation);
- }
- if (config.trackingImplementation) {
- // note the name change
- __config.initializeAdapterInstance("modelLibrary", config.trackingImplementation);
- }
- if (config.ajaxImplementation) {
- __config.initializeAdapterInstance("ajax", config.ajaxImplementation);
- }
- };
- /**
- Method use to register implementations of standard breeze interfaces. Calls to this method are usually
- made as the last step within an adapter implementation.
- @method registerAdapter
- @param interfaceName {String} - one of the following interface names "ajax", "dataService" or "modelLibrary"
- @param adapterCtor {Function} - an ctor function that returns an instance of the specified interface.
- **/
- __config.registerAdapter = function(interfaceName, adapterCtor) {
- assertParam(interfaceName, "interfaceName").isNonEmptyString().check();
- assertParam(adapterCtor, "adapterCtor").isFunction().check();
- // this impl will be thrown away after the name is retrieved.
- var impl = new adapterCtor();
- var implName = impl.name;
- if (!implName) {
- throw new Error("Unable to locate a 'name' property on the constructor passed into the 'registerAdapter' call.");
- }
- var idef = getInterfaceDef(interfaceName);
- idef.registerCtor(implName, adapterCtor);
- };
- /**
- Returns the ctor function used to implement a specific interface with a specific adapter name.
- @method getAdapter
- @param interfaceName {String} One of the following interface names "ajax", "dataService" or "modelLibrary"
- @param [adapterName] {String} The name of any previously registered adapter. If this parameter is omitted then
- this method returns the "default" adapter for this interface. If there is no default adapter, then a null is returned.
- @return {Function|null} Returns either a ctor function or null.
- **/
- __config.getAdapter = function(interfaceName, adapterName) {
- var idef = getInterfaceDef(interfaceName);
- if (adapterName) {
- var impl = idef.getImpl(adapterName);
- return impl ? impl.ctor : null;
- } else {
- return idef.defaultInstance ? idef.defaultInstance._$impl.ctor : null;
- }
- };
- /**
- Initializes a collection of adapter implementations and makes each one the default for its corresponding interface.
- @method initializeAdapterInstances
- @param config {Object}
- @param [config.ajax] {String} - the name of a previously registered "ajax" adapter
- @param [config.dataService] {String} - the name of a previously registered "dataService" adapter
- @param [config.modelLibrary] {String} - the name of a previously registered "modelLibrary" adapter
- @return [array of instances]
- **/
- __config.initializeAdapterInstances = function(config) {
- assertConfig(config)
- .whereParam("dataService").isOptional()
- .whereParam("modelLibrary").isOptional()
- .whereParam("ajax").isOptional();
- return __objectMapToArray(config, __config.initializeAdapterInstance);
- };
- /**
- Initializes a single adapter implementation. Initialization means either newing a instance of the
- specified interface and then calling "initialize" on it or simply calling "initialize" on the instance
- if it already exists.
- @method initializeAdapterInstance
- @param interfaceName {String} The name of the interface to which the adapter to initialize belongs.
- @param adapterName {String} - The name of a previously registered adapter to initialize.
- @param [isDefault=true] {Boolean} - Whether to make this the default "adapter" for this interface.
- @return {an instance of the specified adapter}
- **/
- __config.initializeAdapterInstance = function(interfaceName, adapterName, isDefault) {
- isDefault = isDefault === undefined ? true : isDefault;
- assertParam(interfaceName, "interfaceName").isNonEmptyString().check();
- assertParam(adapterName, "adapterName").isNonEmptyString().check();
- assertParam(isDefault, "isDefault").isBoolean().check();
- var idef = getInterfaceDef(interfaceName);
- var impl = idef.getImpl(adapterName);
- if (!impl) {
- throw new Error("Unregistered adapter. Interface: " + interfaceName + " AdapterName: " + adapterName);
- }
- return initializeAdapterInstanceCore(idef, impl, isDefault);
- };
- /**
- Returns the adapter instance corresponding to the specified interface and adapter names.
- @method getAdapterInstance
- @param interfaceName {String} The name of the interface.
- @param [adapterName] {String} - The name of a previously registered adapter. If this parameter is
- omitted then the default implementation of the specified interface is returned. If there is
- no defaultInstance of this interface, then the first registered instance of this interface is returned.
- @return {an instance of the specified adapter}
- **/
- __config.getAdapterInstance = function(interfaceName, adapterName) {
- var idef = getInterfaceDef(interfaceName);
- var impl;
- if (adapterName & adapterName !== "") {
- impl = idef.getImpl(adapterName);
- return impl ? impl.defaultInstance : null;
- } else {
- if (idef.defaultIns…
Large files files are truncated, but you can click here to view the full file