1(function (factory) { 2 // Module systems magic dance. 3 4 if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { 5 // CommonJS or Node: hard-coded dependency on "knockout" 6 factory(require("knockout"), exports); 7 } else if (typeof define === "function" && define["amd"]) { 8 // AMD anonymous module with hard-coded dependency on "knockout" 9 define(["knockout", "exports"], factory); 10 } else { 11 // <script> tag: use the global `ko` object, attaching a `mapping` property 12 factory(ko, ko.mapping = {}); 13 } 14}(function (ko, exports) { 15 var DEBUG=true; 16 var mappingProperty = "__ko_mapping__"; 17 var realKoDependentObservable = ko.dependentObservable; 18 var mappingNesting = 0; 19 var dependentObservables; 20 var visitedObjects; 21 var recognizedRootProperties = ["create", "update", "key", "arrayChanged"]; 22 var emptyReturn = {}; 23 24 var _defaultOptions = { 25 include: ["_destroy"], 26 ignore: [], 27 copy: [], 28 observe: [] 29 }; 30 var defaultOptions = _defaultOptions; 31 32 // Author: KennyTM @ StackOverflow 33 function unionArrays (x, y) { 34 var obj = {}; 35 for (var i = x.length - 1; i >= 0; -- i) obj[x[i]] = x[i]; 36 for (var i = y.length - 1; i >= 0; -- i) obj[y[i]] = y[i]; 37 var res = []; 38 39 for (var k in obj) { 40 res.push(obj[k]); 41 }; 42 43 return res; 44 } 45 46 function extendObject(destination, source) { 47 var destType; 48 49 for (var key in source) { 50 if (source.hasOwnProperty(key) && source[key]) { 51 destType = exports.getType(destination[key]); 52 if (key && destination[key] && destType !== "array" && destType !== "string") { 53 extendObject(destination[key], source[key]); 54 } else { 55 var bothArrays = exports.getType(destination[key]) === "array" && exports.getType(source[key]) === "array"; 56 if (bothArrays) { 57 destination[key] = unionArrays(destination[key], source[key]); 58 } else { 59 destination[key] = source[key]; 60 } 61 } 62 } 63 } 64 } 65 66 function merge(obj1, obj2) { 67 var merged = {}; 68 extendObject(merged, obj1); 69 extendObject(merged, obj2); 70 71 return merged; 72 } 73 74 exports.isMapped = function (viewModel) { 75 var unwrapped = ko.utils.unwrapObservable(viewModel); 76 return unwrapped && unwrapped[mappingProperty]; 77 } 78 79 exports.fromJS = function (jsObject /*, inputOptions, target*/ ) { 80 if (arguments.length == 0) throw new Error("When calling ko.fromJS, pass the object you want to convert."); 81 82 try { 83 if (!mappingNesting++) { 84 dependentObservables = []; 85 visitedObjects = new objectLookup(); 86 } 87 88 var options; 89 var target; 90 91 if (arguments.length == 2) { 92 if (arguments[1][mappingProperty]) { 93 target = arguments[1]; 94 } else { 95 options = arguments[1]; 96 } 97 } 98 if (arguments.length == 3) { 99 options = arguments[1]; 100 target = arguments[2]; 101 } 102 103 if (target) { 104 options = merge(options, target[mappingProperty]); 105 } 106 options = fillOptions(options); 107 108 var result = updateViewModel(target, jsObject, options); 109 if (target) { 110 result = target; 111 } 112 113 // Evaluate any dependent observables that were proxied. 114 // Do this after the model's observables have been created 115 if (!--mappingNesting) { 116 while (dependentObservables.length) { 117 var DO = dependentObservables.pop(); 118 if (DO) { 119 DO(); 120 121 // Move this magic property to the underlying dependent observable 122 DO.__DO["throttleEvaluation"] = DO["throttleEvaluation"]; 123 } 124 } 125 } 126 127 // Save any new mapping options in the view model, so that updateFromJS can use them later. 128 result[mappingProperty] = merge(result[mappingProperty], options); 129 130 return result; 131 } catch(e) { 132 mappingNesting = 0; 133 throw e; 134 } 135 }; 136 137 exports.fromJSON = function (jsonString /*, options, target*/ ) { 138 var parsed = ko.utils.parseJson(jsonString); 139 arguments[0] = parsed; 140 return exports.fromJS.apply(this, arguments); 141 }; 142 143 exports.updateFromJS = function (viewModel) { 144 throw new Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!"); 145 }; 146 147 exports.updateFromJSON = function (viewModel) { 148 throw new Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!"); 149 }; 150 151 exports.toJS = function (rootObject, options) { 152 if (!defaultOptions) exports.resetDefaultOptions(); 153 154 if (arguments.length == 0) throw new Error("When calling ko.mapping.toJS, pass the object you want to convert."); 155 if (exports.getType(defaultOptions.ignore) !== "array") throw new Error("ko.mapping.defaultOptions().ignore should be an array."); 156 if (exports.getType(defaultOptions.include) !== "array") throw new Error("ko.mapping.defaultOptions().include should be an array."); 157 if (exports.getType(defaultOptions.copy) !== "array") throw new Error("ko.mapping.defaultOptions().copy should be an array."); 158 159 // Merge in the options used in fromJS 160 options = fillOptions(options, rootObject[mappingProperty]); 161 162 // We just unwrap everything at every level in the object graph 163 return exports.visitModel(rootObject, function (x) { 164 return ko.utils.unwrapObservable(x) 165 }, options); 166 }; 167 168 exports.toJSON = function (rootObject, options) { 169 var plainJavaScriptObject = exports.toJS(rootObject, options); 170 return ko.utils.stringifyJson(plainJavaScriptObject); 171 }; 172 173 exports.defaultOptions = function () { 174 if (arguments.length > 0) { 175 defaultOptions = arguments[0]; 176 } else { 177 return defaultOptions; 178 } 179 }; 180 181 exports.resetDefaultOptions = function () { 182 defaultOptions = { 183 include: _defaultOptions.include.slice(0), 184 ignore: _defaultOptions.ignore.slice(0), 185 copy: _defaultOptions.copy.slice(0) 186 }; 187 }; 188 189 exports.getType = function(x) { 190 if ((x) && (typeof (x) === "object")) { 191 if (x.constructor === Date) return "date"; 192 if (x.constructor === Array) return "array"; 193 } 194 return typeof x; 195 } 196 197 function fillOptions(rawOptions, otherOptions) { 198 var options = merge({}, rawOptions); 199 200 // Move recognized root-level properties into a root namespace 201 for (var i = recognizedRootProperties.length - 1; i >= 0; i--) { 202 var property = recognizedRootProperties[i];
203 204 // Carry on, unless this property is present 205 if (!options[property]) continue; 206 207 // Move the property into the root namespace 208 if (!(options[""] instanceof Object)) options[""] = {}; 209 options[""][property] = options[property]; 210 delete options[property]; 211 } 212 213 if (otherOptions) { 214 options.ignore = mergeArrays(otherOptions.ignore, options.ignore); 215 options.include = mergeArrays(otherOptions.include, options.include); 216 options.copy = mergeArrays(otherOptions.copy, options.copy); 217 options.observe = mergeArrays(otherOptions.observe, options.observe); 218 } 219 options.ignore = mergeArrays(options.ignore, defaultOptions.ignore); 220 options.include = mergeArrays(options.include, defaultOptions.include); 221 options.copy = mergeArrays(options.copy, defaultOptions.copy); 222 options.observe = mergeArrays(options.observe, defaultOptions.observe); 223 224 options.mappedProperties = options.mappedProperties || {}; 225 options.copiedProperties = options.copiedProperties || {}; 226 return options; 227 } 228 229 function mergeArrays(a, b) { 230 if (exports.getType(a) !== "array") { 231 if (exports.getType(a) === "undefined") a = []; 232 else a = [a]; 233 } 234 if (exports.getType(b) !== "array") { 235 if (exports.getType(b) === "undefined") b = []; 236 else b = [b]; 237 } 238 239 return ko.utils.arrayGetDistinctValues(a.concat(b)); 240 } 241 242 // When using a 'create' callback, we proxy the dependent observable so that it doesn't immediately evaluate on creation. 243 // The reason is that the dependent observables in the user-specified callback may contain references to properties that have not been mapped yet. 244 function withProxyDependentObservable(dependentObservables, callback) { 245 var localDO = ko.dependentObservable; 246 ko.dependentObservable = function (read, owner, options) { 247 options = options || {}; 248 249 if (read && typeof read == "object") { // mirrors condition in knockout implementation of DO's 250 options = read; 251 } 252 253 var realDeferEvaluation = options.deferEvaluation; 254 255 var isRemoved = false; 256 257 // We wrap the original dependent observable so that we can remove it from the 'dependentObservables' list we need to evaluate after mapping has 258 // completed if the user already evaluated the DO themselves in the meantime. 259 var wrap = function (DO) { 260 // Temporarily revert ko.dependentObservable, since it is used in ko.isWriteableObservable 261 var tmp = ko.dependentObservable; 262 ko.dependentObservable = realKoDependentObservable; 263 var isWriteable = ko.isWriteableObservable(DO); 264 ko.dependentObservable = tmp; 265 266 var wrapped = realKoDependentObservable({ 267 read: function () { 268 if (!isRemoved) { 269 ko.utils.arrayRemoveItem(dependentObservables, DO); 270 isRemoved = true; 271 } 272 return DO.apply(DO, arguments); 273 }, 274 write: isWriteable && function (val) { 275 return DO(val); 276 }, 277 deferEvaluation: true 278 }); 279 if (DEBUG) wrapped._wrapper = true; 280 wrapped.__DO = DO; 281 return wrapped; 282 }; 283 284 options.deferEvaluation = true; // will either set for just options, or both read/options. 285 var realDependentObservable = new realKoDependentObservable(read, owner, options); 286 287 if (!realDeferEvaluation) { 288 realDependentObservable = wrap(realDependentObservable); 289 dependentObservables.push(realDependentObservable); 290 } 291 292 return realDependentObservable; 293 } 294 ko.dependentObservable.fn = realKoDependentObservable.fn; 295 ko.computed = ko.dependentObservable; 296 var result = callback(); 297 ko.dependentObservable = localDO; 298 ko.computed = ko.dependentObservable; 299 return result; 300 } 301 302 function updateViewModel(mappedRootObject, rootObject, options, parentName, parent, parentPropertyName, mappedParent) { 303 var isArray = exports.getType(ko.utils.unwrapObservable(rootObject)) === "array"; 304 305 parentPropertyName = parentPropertyName || ""; 306 307 // If this object was already mapped previously, take the options from there and merge them with our existing ones. 308 if (exports.isMapped(mappedRootObject)) { 309 var previousMapping = ko.utils.unwrapObservable(mappedRootObject)[mappingProperty]; 310 options = merge(previousMapping, options); 311 } 312 313 var callbackParams = { 314 data: rootObject, 315 parent: mappedParent || parent 316 }; 317 318 var hasCreateCallback = function () { 319 return options[parentName] && options[parentName].create instanceof Function; 320 }; 321 322 var createCallback = function (data) { 323 return withProxyDependentObservable(dependentObservables, function () { 324 325 if (ko.utils.unwrapObservable(parent) instanceof Array) { 326 return options[parentName].create({ 327 data: data || callbackParams.data, 328 parent: callbackParams.parent, 329 skip: emptyReturn 330 });
vendor: 5,749 bytes, lines 331-504
331 } else { 332 return options[parentName].create({ 333 data: data || callbackParams.data, 334 parent: callbackParams.parent 335 }); 336 } 337 }); 338 }; 339 340 var hasUpdateCallback = function () { 341 return options[parentName] && options[parentName].update instanceof Function; 342 }; 343 344 var updateCallback = function (obj, data) { 345 var params = { 346 data: data || callbackParams.data, 347 parent: callbackParams.parent, 348 target: ko.utils.unwrapObservable(obj) 349 }; 350 351 if (ko.isWriteableObservable(obj)) { 352 params.observable = obj; 353 } 354 355 return options[parentName].update(params); 356 } 357 358 var alreadyMapped = visitedObjects.get(rootObject); 359 if (alreadyMapped) { 360 return alreadyMapped; 361 } 362 363 parentName = parentName || ""; 364 365 if (!isArray) { 366 // For atomic types, do a direct update on the observable 367 if (!canHaveProperties(rootObject)) { 368 switch (exports.getType(rootObject)) { 369 case "function": 370 if (hasUpdateCallback()) { 371 if (ko.isWriteableObservable(rootObject)) { 372 rootObject(updateCallback(rootObject)); 373 mappedRootObject = rootObject; 374 } else { 375 mappedRootObject = updateCallback(rootObject); 376 } 377 } else { 378 mappedRootObject = rootObject; 379 } 380 break; 381 default: 382 if (ko.isWriteableObservable(mappedRootObject)) { 383 if (hasUpdateCallback()) { 384 var valueToWrite = updateCallback(mappedRootObject); 385 mappedRootObject(valueToWrite); 386 return valueToWrite; 387 } else { 388 var valueToWrite = ko.utils.unwrapObservable(rootObject); 389 mappedRootObject(valueToWrite); 390 return valueToWrite; 391 } 392 } else { 393 var hasCreateOrUpdateCallback = hasCreateCallback() || hasUpdateCallback(); 394 395 if (hasCreateCallback()) { 396 mappedRootObject = createCallback(); 397 } else { 398 mappedRootObject = ko.observable(ko.utils.unwrapObservable(rootObject)); 399 } 400 401 if (hasUpdateCallback()) { 402 mappedRootObject(updateCallback(mappedRootObject)); 403 } 404 405 if (hasCreateOrUpdateCallback) return mappedRootObject; 406 } 407 } 408 409 } else { 410 mappedRootObject = ko.utils.unwrapObservable(mappedRootObject); 411 if (!mappedRootObject) { 412 if (hasCreateCallback()) { 413 var result = createCallback(); 414 415 if (hasUpdateCallback()) { 416 result = updateCallback(result); 417 } 418 419 return result; 420 } else { 421 if (hasUpdateCallback()) { 422 return updateCallback(result); 423 } 424 425 mappedRootObject = {}; 426 } 427 } 428 429 if (hasUpdateCallback()) { 430 mappedRootObject = updateCallback(mappedRootObject); 431 } 432 433 visitedObjects.save(rootObject, mappedRootObject); 434 if (hasUpdateCallback()) return mappedRootObject; 435 436 // For non-atomic types, visit all properties and update recursively 437 visitPropertiesOrArrayEntries(rootObject, function (indexer) { 438 var fullPropertyName = parentPropertyName.length ? parentPropertyName + "." + indexer : indexer; 439 440 if (ko.utils.arrayIndexOf(options.ignore, fullPropertyName) != -1) { 441 return; 442 } 443 444 if (ko.utils.arrayIndexOf(options.copy, fullPropertyName) != -1) { 445 mappedRootObject[indexer] = rootObject[indexer]; 446 return; 447 } 448 449 if(typeof rootObject[indexer] != "object" && typeof rootObject[indexer] != "array" && options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) 450 { 451 mappedRootObject[indexer] = rootObject[indexer]; 452 options.copiedProperties[fullPropertyName] = true; 453 return; 454 } 455 456 // In case we are adding an already mapped property, fill it with the previously mapped property value to prevent recursion. 457 // If this is a property that was generated by fromJS, we should use the options specified there 458 var prevMappedProperty = visitedObjects.get(rootObject[indexer]); 459 var retval = updateViewModel(mappedRootObject[indexer], rootObject[indexer], options, indexer, mappedRootObject, fullPropertyName, mappedRootObject); 460 var value = prevMappedProperty || retval; 461 462 if(options.observe.length > 0 && ko.utils.arrayIndexOf(options.observe, fullPropertyName) == -1) 463 { 464 mappedRootObject[indexer] = value(); 465 options.copiedProperties[fullPropertyName] = true; 466 return; 467 } 468 469 if (ko.isWriteableObservable(mappedRootObject[indexer])) { 470 value = ko.utils.unwrapObservable(value); 471 if (mappedRootObject[indexer]() !== value) { 472 mappedRootObject[indexer](value); 473 } 474 } else { 475 value = mappedRootObject[indexer] === undefined ? value : ko.utils.unwrapObservable(value); 476 mappedRootObject[indexer] = value; 477 } 478 479 options.mappedProperties[fullPropertyName] = true; 480 }); 481 } 482 } else { //mappedRootObject is an array 483 var changes = []; 484 485 var hasKeyCallback = false; 486 var keyCallback = function (x) { 487 return x; 488 } 489 if (options[parentName] && options[parentName].key) { 490 keyCallback = options[parentName].key; 491 hasKeyCallback = true; 492 } 493 494 if (!ko.isObservable(mappedRootObject)) { 495 // When creating the new observable array, also add a bunch of utility functions that take the 'key' of the array items into account. 496 mappedRootObject = ko.observableArray([]); 497 498 mappedRootObject.mappedRemove = function (valueOrPredicate) { 499 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { 500 return value === keyCallback(valueOrPredicate); 501 }; 502 return mappedRootObject.remove(function (item) { 503 return predicate(keyCallback(item)); 504 });
505 } 506 507 mappedRootObject.mappedRemoveAll = function (arrayOfValues) { 508 var arrayOfKeys = filterArrayByKey(arrayOfValues, keyCallback); 509 return mappedRootObject.remove(function (item) { 510 return ko.utils.arrayIndexOf(arrayOfKeys, keyCallback(item)) != -1; 511 }); 512 } 513 514 mappedRootObject.mappedDestroy = function (valueOrPredicate) { 515 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { 516 return value === keyCallback(valueOrPredicate); 517 }; 518 return mappedRootObject.destroy(function (item) { 519 return predicate(keyCallback(item)); 520 }); 521 } 522 523 mappedRootObject.mappedDestroyAll = function (arrayOfValues) { 524 var arrayOfKeys = filterArrayByKey(arrayOfValues, keyCallback); 525 return mappedRootObject.destroy(function (item) { 526 return ko.utils.arrayIndexOf(arrayOfKeys, keyCallback(item)) != -1; 527 }); 528 } 529 530 mappedRootObject.mappedIndexOf = function (item) { 531 var keys = filterArrayByKey(mappedRootObject(), keyCallback); 532 var key = keyCallback(item); 533 return ko.utils.arrayIndexOf(keys, key); 534 } 535 536 mappedRootObject.mappedGet = function (item) { 537 return mappedRootObject()[mappedRootObject.mappedIndexOf(item)]; 538 } 539 540 mappedRootObject.mappedCreate = function (value) { 541 if (mappedRootObject.mappedIndexOf(value) !== -1) { 542 throw new Error("There already is an object with the key that you specified."); 543 } 544 545 var item = hasCreateCallback() ? createCallback(value) : value; 546 if (hasUpdateCallback()) { 547 var newValue = updateCallback(item, value); 548 if (ko.isWriteableObservable(item)) { 549 item(newValue); 550 } else { 551 item = newValue; 552 } 553 } 554 mappedRootObject.push(item); 555 return item; 556 } 557 } 558 559 var currentArrayKeys = filterArrayByKey(ko.utils.unwrapObservable(mappedRootObject), keyCallback).sort(); 560 var newArrayKeys = filterArrayByKey(rootObject, keyCallback); 561 if (hasKeyCallback) newArrayKeys.sort(); 562 var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys); 563 564 var ignoreIndexOf = {}; 565 566 var i, j; 567 568 var unwrappedRootObject = ko.utils.unwrapObservable(rootObject); 569 var itemsByKey = {}; 570 var optimizedKeys = true; 571 for (i = 0, j = unwrappedRootObject.length; i < j; i++) { 572 var key = keyCallback(unwrappedRootObject[i]); 573 if (key === undefined || key instanceof Object) { 574 optimizedKeys = false; 575 break; 576 } 577 itemsByKey[key] = unwrappedRootObject[i]; 578 } 579 580 var newContents = []; 581 var passedOver = 0; 582 for (i = 0, j = editScript.length; i < j; i++) { 583 var key = editScript[i]; 584 var mappedItem; 585 var fullPropertyName = parentPropertyName + "[" + i + "]"; 586 switch (key.status) { 587 case "added": 588 var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); 589 mappedItem = updateViewModel(undefined, item, options, parentName, mappedRootObject, fullPropertyName, parent); 590 if(!hasCreateCallback()) { 591 mappedItem = ko.utils.unwrapObservable(mappedItem); 592 } 593 594 var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); 595 596 if (mappedItem === emptyReturn) { 597 passedOver++; 598 } else { 599 newContents[index - passedOver] = mappedItem; 600 } 601 602 ignoreIndexOf[index] = true; 603 break; 604 case "retained": 605 var item = optimizedKeys ? itemsByKey[key.value] : getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback); 606 mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); 607 updateViewModel(mappedItem, item, options, parentName, mappedRootObject, fullPropertyName, parent); 608 609 var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf); 610 newContents[index] = mappedItem; 611 ignoreIndexOf[index] = true; 612 break; 613 case "deleted": 614 mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback); 615 break; 616 } 617 618 changes.push({ 619 event: key.status, 620 item: mappedItem 621 }); 622 } 623 624 mappedRootObject(newContents); 625 626 if (options[parentName] && options[parentName].arrayChanged) { 627 ko.utils.arrayForEach(changes, function (change) { 628 options[parentName].arrayChanged(change.event, change.item); 629 }); 630 } 631 } 632 633 return mappedRootObject; 634 } 635 636 function ignorableIndexOf(array, item, ignoreIndices) { 637 for (var i = 0, j = array.length; i < j; i++) { 638 if (ignoreIndices[i] === true) continue; 639 if (array[i] === item) return i; 640 } 641 return null; 642 } 643 644 function mapKey(item, callback) { 645 var mappedItem; 646 if (callback) mappedItem = callback(item); 647 if (exports.getType(mappedItem) === "undefined") mappedItem = item; 648 649 return ko.utils.unwrapObservable(mappedItem); 650 } 651 652 function getItemByKey(array, key, callback) { 653 array = ko.utils.unwrapObservable(array); 654 for (var i = 0, j = array.length; i < j; i++) { 655 var item = array[i]; 656 if (mapKey(item, callback) === key) return item; 657 } 658 659 throw new Error("When calling ko.update*, the key '" + key + "' was not found!"); 660 } 661 662 function filterArrayByKey(array, callback) { 663 return ko.utils.arrayMap(ko.utils.unwrapObservable(array), function (item) { 664 if (callback) { 665 return mapKey(item, callback); 666 } else { 667 return item; 668 } 669 }); 670 } 671 672 function visitPropertiesOrArrayEntries(rootObject, visitorCallback) { 673 if (exports.getType(rootObject) === "array") { 674 for (var i = 0; i < rootObject.length; i++) 675 visitorCallback(i); 676 } else { 677 for (var propertyName in rootObject) 678 visitorCallback(propertyName); 679 } 680 }; 681 682 function canHaveProperties(object) { 683 var type = exports.getType(object); 684 return ((type === "object") || (type === "array")) && (object !== null); 685 } 686 687 // Based on the parentName, this creates a fully classified name of a property 688 689 function getPropertyName(parentName, parent, indexer) { 690 var propertyName = parentName || ""; 691 if (exports.getType(parent) === "array") { 692 if (parentName) { 693 propertyName += "[" + indexer + "]"; 694 } 695 } else { 696 if (parentName) { 697 propertyName += "."; 698 } 699 propertyName += indexer; 700 } 701 return propertyName; 702 } 703 704 exports.visitModel = function (rootObject, callback, options) { 705 options = options || {}; 706 options.visitedObjects = options.visitedObjects || new objectLookup(); 707 708 var mappedRootObject; 709 var unwrappedRootObject = ko.utils.unwrapObservable(rootObject); 710 711 if (!canHaveProperties(unwrappedRootObject)) { 712 return callback(rootObject, options.parentName); 713 } else { 714 options = fillOptions(options, unwrappedRootObject[mappingProperty]); 715 716 // Only do a callback, but ignore the results 717 callback(rootObject, options.parentName); 718 mappedRootObject = exports.getType(unwrappedRootObject) === "array" ? [] : {}; 719 } 720 721 options.visitedObjects.save(rootObject, mappedRootObject); 722 723 var parentName = options.parentName; 724 visitPropertiesOrArrayEntries(unwrappedRootObject, function (indexer) { 725 if (options.ignore && ko.utils.arrayIndexOf(options.ignore, indexer) != -1) return; 726 727 var propertyValue = unwrappedRootObject[indexer]; 728 options.parentName = getPropertyName(parentName, unwrappedRootObject, indexer); 729 730 // If we don't want to explicitly copy the unmapped property... 731 if (ko.utils.arrayIndexOf(options.copy, indexer) === -1) { 732 // ...find out if it's a property we want to explicitly include 733 if (ko.utils.arrayIndexOf(options.include, indexer) === -1) {
734 // The mapped properties object contains all the properties that were part of the original object. 735 // If a property does not exist, and it is not because it is part of an array (e.g. "myProp[3]"), then it should not be unmapped. 736 if (unwrappedRootObject[mappingProperty] 737 && unwrappedRootObject[mappingProperty].mappedProperties && !unwrappedRootObject[mappingProperty].mappedProperties[indexer] 738 && unwrappedRootObject[mappingProperty].copiedProperties && !unwrappedRootObject[mappingProperty].copiedProperties[indexer] 739 && !(exports.getType(unwrappedRootObject) === "array")) { 740 return; 741 } 742 } 743 } 744 745 var outputProperty; 746 switch (exports.getType(ko.utils.unwrapObservable(propertyValue))) { 747 case "object": 748 case "array": 749 case "undefined": 750 var previouslyMappedValue = options.visitedObjects.get(propertyValue); 751 mappedRootObject[indexer] = (exports.getType(previouslyMappedValue) !== "undefined") ? previouslyMappedValue : exports.visitModel(propertyValue, callback, options); 752 break; 753 default: 754 mappedRootObject[indexer] = callback(propertyValue, options.parentName); 755 } 756 }); 757 758 return mappedRootObject; 759 } 760 761 function simpleObjectLookup() { 762 var keys = []; 763 var values = []; 764 this.save = function (key, value) { 765 var existingIndex = ko.utils.arrayIndexOf(keys, key); 766 if (existingIndex >= 0) values[existingIndex] = value; 767 else { 768 keys.push(key); 769 values.push(value); 770 } 771 }; 772 this.get = function (key) { 773 var existingIndex = ko.utils.arrayIndexOf(keys, key); 774 var value = (existingIndex >= 0) ? values[existingIndex] : undefined; 775 return value; 776 }; 777 }; 778 779 function objectLookup() { 780 var buckets = {}; 781 782 var findBucket = function(key) { 783 var bucketKey; 784 try { 785 bucketKey = key;//JSON.stringify(key); 786 } 787 catch (e) { 788 bucketKey = "$$$"; 789 } 790 791 var bucket = buckets[bucketKey]; 792 if (bucket === undefined) { 793 bucket = new simpleObjectLookup(); 794 buckets[bucketKey] = bucket; 795 } 796 return bucket; 797 }; 798 799 this.save = function (key, value) { 800 findBucket(key).save(key, value); 801 }; 802 this.get = function (key) { 803 return findBucket(key).get(key); 804 }; 805 }; 806}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.