Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
1 // Knockout Mapping plugin v2.1.2
2 // (c) 2012 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/
3 // License: MIT (http://www.opensource.org/licenses/mit-license.php)
6 // Module systems magic dance.
8 if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
9 // CommonJS or Node: hard-coded dependency on "knockout"
10 factory(require("knockout"), exports);
11 } else if (typeof define === "function" && define["amd"]) {
12 // AMD anonymous module with hard-coded dependency on "knockout"
13 define(["knockout", "exports"], factory);
15 // <script> tag: use the global `ko` object, attaching a `mapping` property
16 factory(ko, ko.mapping = {});
18 }(function (ko, exports) {
20 var mappingProperty = "__ko_mapping__";
21 var realKoDependentObservable = ko.dependentObservable;
22 var mappingNesting = 0;
23 var dependentObservables;
26 var _defaultOptions = {
27 include: ["_destroy"],
31 var defaultOptions = _defaultOptions;
33 exports.isMapped = function (viewModel) {
34 var unwrapped = ko.utils.unwrapObservable(viewModel);
35 return unwrapped && unwrapped[mappingProperty];
38 exports.fromJS = function (jsObject /*, inputOptions, target*/ ) {
39 if (arguments.length == 0) throw new Error("When calling ko.fromJS, pass the object you want to convert.");
41 // When mapping is completed, even with an exception, reset the nesting level
42 window.setTimeout(function () {
46 if (!mappingNesting++) {
47 dependentObservables = [];
48 visitedObjects = new objectLookup();
54 if (arguments.length == 2) {
55 if (arguments[1][mappingProperty]) {
56 target = arguments[1];
58 options = arguments[1];
61 if (arguments.length == 3) {
62 options = arguments[1];
63 target = arguments[2];
67 options = mergeOptions(target[mappingProperty], options);
69 options = mergeOptions(options);
71 options.mappedProperties = options.mappedProperties || {};
73 var result = updateViewModel(target, jsObject, options);
78 // Evaluate any dependent observables that were proxied.
79 // Do this in a timeout to defer execution. Basically, any user code that explicitly looks up the DO will perform the first evaluation. Otherwise,
80 // it will be done by this code.
81 if (!--mappingNesting) {
82 window.setTimeout(function () {
83 while (dependentObservables.length) {
84 var DO = dependentObservables.pop();
90 // Save any new mapping options in the view model, so that updateFromJS can use them later.
91 result[mappingProperty] = mergeOptions(result[mappingProperty], options);
96 exports.fromJSON = function (jsonString /*, options, target*/ ) {
97 var parsed = ko.utils.parseJson(jsonString);
98 arguments[0] = parsed;
99 return exports.fromJS.apply(this, arguments);
102 exports.updateFromJS = function (viewModel) {
103 throw new Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");
106 exports.updateFromJSON = function (viewModel) {
107 throw new Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");
110 exports.toJS = function (rootObject, options) {
111 if (arguments.length == 0) throw new Error("When calling ko.mapping.toJS, pass the object you want to convert.");
112 // Merge in the options used in fromJS
113 options = mergeOptions(rootObject[mappingProperty], options);
115 // We just unwrap everything at every level in the object graph
116 return visitModel(rootObject, function (x) {
117 return ko.utils.unwrapObservable(x)
121 exports.toJSON = function (rootObject, options) {
122 var plainJavaScriptObject = exports.toJS(rootObject, options);
123 return ko.utils.stringifyJson(plainJavaScriptObject);
126 exports.visitModel = function (rootObject, callback, options) {
127 if (arguments.length == 0) throw new Error("When calling ko.mapping.visitModel, pass the object you want to visit.");
128 // Merge in the options used in fromJS
129 options = mergeOptions(rootObject[mappingProperty], options);
131 return visitModel(rootObject, callback, options);
134 exports.defaultOptions = function () {
135 if (arguments.length > 0) {
136 defaultOptions = arguments[0];
138 return defaultOptions;
142 exports.resetDefaultOptions = function () {
144 include: _defaultOptions.include.slice(0),
145 ignore: _defaultOptions.ignore.slice(0),
146 copy: _defaultOptions.copy.slice(0)
150 exports.getType = function(x) {
151 if ((x) && (typeof (x) === "object")) {
152 if (x.constructor == (new Date).constructor) return "date";
153 if (x.constructor == (new Array).constructor) return "array";
158 function extendOptionsArray(distArray, sourceArray) {
159 return ko.utils.arrayGetDistinctValues(
160 ko.utils.arrayPushAll(distArray, sourceArray)
164 function extendOptionsObject(target, options) {
165 var type = exports.getType,
166 name, special = { "include": true, "ignore": true, "copy": true },
167 t, o, i = 1, l = arguments.length;
168 if (type(target) !== "object") {
172 options = arguments[i];
173 if (type(options) !== "object") {
176 for (name in options) {
177 t = target[name]; o = options[name];
178 if (name !== "constructor" && special[name] && type(o) !== "array") {
179 if (type(o) !== "string") {
180 throw new Error("ko.mapping.defaultOptions()." + name + " should be an array or string.");
185 case "object": // Recurse
186 t = type(t) === "object" ? t : {};
187 target[name] = extendOptionsObject(t, o);
190 t = type(t) === "array" ? t : [];
191 target[name] = extendOptionsArray(t, o);
201 function mergeOptions() {
202 var options = ko.utils.arrayPushAll([{}, defaultOptions], arguments); // Always use empty object as target to avoid changing default options
203 options = extendOptionsObject.apply(this, options);
207 // When using a 'create' callback, we proxy the dependent observable so that it doesn't immediately evaluate on creation.
208 // The reason is that the dependent observables in the user-specified callback may contain references to properties that have not been mapped yet.
209 function withProxyDependentObservable(dependentObservables, callback) {
210 var localDO = ko.dependentObservable;
211 ko.dependentObservable = function (read, owner, options) {
212 options = options || {};
214 if (read && typeof read == "object") { // mirrors condition in knockout implementation of DO's
218 var realDeferEvaluation = options.deferEvaluation;
220 var isRemoved = false;
222 // We wrap the original dependent observable so that we can remove it from the 'dependentObservables' list we need to evaluate after mapping has
223 // completed if the user already evaluated the DO themselves in the meantime.
224 var wrap = function (DO) {
225 var wrapped = realKoDependentObservable({
228 ko.utils.arrayRemoveItem(dependentObservables, DO);
231 return DO.apply(DO, arguments);
233 write: function (val) {
236 deferEvaluation: true
238 if(DEBUG) wrapped._wrapper = true;
242 options.deferEvaluation = true; // will either set for just options, or both read/options.
243 var realDependentObservable = new realKoDependentObservable(read, owner, options);
245 if (!realDeferEvaluation) {
246 realDependentObservable = wrap(realDependentObservable);
247 dependentObservables.push(realDependentObservable);
250 return realDependentObservable;
252 ko.dependentObservable.fn = realKoDependentObservable.fn;
253 ko.computed = ko.dependentObservable;
254 var result = callback();
255 ko.dependentObservable = localDO;
256 ko.computed = ko.dependentObservable;
260 function updateViewModel(mappedRootObject, rootObject, options, parentName, parent, parentPropertyName) {
261 var isArray = ko.utils.unwrapObservable(rootObject) instanceof Array;
263 // If nested object was already mapped previously, take the options from it
264 if (parentName !== undefined && exports.isMapped(mappedRootObject)) {
265 options = ko.utils.unwrapObservable(mappedRootObject)[mappingProperty];
267 parentPropertyName = "";
270 parentName = parentName || "";
271 parentPropertyName = parentPropertyName || "";
273 var callbackParams = {
278 var getCallback = function (name) {
280 if (parentName === "") {
281 callback = options[name];
282 } else if (callback = options[parentName]) {
283 callback = callback[name]
288 var hasCreateCallback = function () {
289 return getCallback("create") instanceof Function;
292 var createCallback = function (data) {
293 return withProxyDependentObservable(dependentObservables, function () {
294 return getCallback("create")({
295 data: data || callbackParams.data,
296 parent: callbackParams.parent
301 var hasUpdateCallback = function () {
302 return getCallback("update") instanceof Function;
305 var updateCallback = function (obj, data) {
307 data: data || callbackParams.data,
308 parent: callbackParams.parent,
309 target: ko.utils.unwrapObservable(obj)
312 if (ko.isWriteableObservable(obj)) {
313 params.observable = obj;
316 return getCallback("update")(params);
319 var alreadyMapped = visitedObjects.get(rootObject);
321 return alreadyMapped;
325 // For atomic types, do a direct update on the observable
326 if (!canHaveProperties(rootObject)) {
327 switch (exports.getType(rootObject)) {
329 if (hasUpdateCallback()) {
330 if (ko.isWriteableObservable(rootObject)) {
331 rootObject(updateCallback(rootObject));
332 mappedRootObject = rootObject;
334 mappedRootObject = updateCallback(rootObject);
337 mappedRootObject = rootObject;
341 if (ko.isWriteableObservable(mappedRootObject)) {
342 if (hasUpdateCallback()) {
343 mappedRootObject(updateCallback(mappedRootObject));
345 mappedRootObject(ko.utils.unwrapObservable(rootObject));
348 if (hasCreateCallback()) {
349 mappedRootObject = createCallback();
351 mappedRootObject = ko.observable(ko.utils.unwrapObservable(rootObject));
354 if (hasUpdateCallback()) {
355 mappedRootObject(updateCallback(mappedRootObject));
362 mappedRootObject = ko.utils.unwrapObservable(mappedRootObject);
363 if (!mappedRootObject) {
364 if (hasCreateCallback()) {
365 var result = createCallback();
367 if (hasUpdateCallback()) {
368 result = updateCallback(result);
373 if (hasUpdateCallback()) {
374 return updateCallback(result);
377 mappedRootObject = {};
381 if (hasUpdateCallback()) {
382 mappedRootObject = updateCallback(mappedRootObject);
385 visitedObjects.save(rootObject, mappedRootObject);
387 // For non-atomic types, visit all properties and update recursively
388 visitPropertiesOrArrayEntries(rootObject, function (indexer) {
389 var fullPropertyName = getPropertyName(parentPropertyName, rootObject, indexer);
391 if (ko.utils.arrayIndexOf(options.ignore, fullPropertyName) != -1) {
395 if (ko.utils.arrayIndexOf(options.copy, fullPropertyName) != -1) {
396 mappedRootObject[indexer] = rootObject[indexer];
400 // In case we are adding an already mapped property, fill it with the previously mapped property value to prevent recursion.
401 // If this is a property that was generated by fromJS, we should use the options specified there
402 var prevMappedProperty = visitedObjects.get(rootObject[indexer]);
403 var value = prevMappedProperty || updateViewModel(mappedRootObject[indexer], rootObject[indexer], options, indexer, mappedRootObject, fullPropertyName);
405 if (ko.isWriteableObservable(mappedRootObject[indexer])) {
406 mappedRootObject[indexer](ko.utils.unwrapObservable(value));
408 mappedRootObject[indexer] = value;
411 options.mappedProperties[fullPropertyName] = true;
417 var hasKeyCallback = getCallback("key") instanceof Function;
418 var keyCallback = hasKeyCallback ? getCallback("key") : function (x) {
421 if (!ko.isObservable(mappedRootObject)) {
422 // When creating the new observable array, also add a bunch of utility functions that take the 'key' of the array items into account.
423 mappedRootObject = ko.observableArray([]);
425 mappedRootObject.mappedRemove = function (valueOrPredicate) {
426 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) {
427 return value === keyCallback(valueOrPredicate);
429 return mappedRootObject.remove(function (item) {
430 return predicate(keyCallback(item));
434 mappedRootObject.mappedRemoveAll = function (arrayOfValues) {
435 var arrayOfKeys = filterArrayByKey(arrayOfValues, keyCallback);
436 return mappedRootObject.remove(function (item) {
437 return ko.utils.arrayIndexOf(arrayOfKeys, keyCallback(item)) != -1;
441 mappedRootObject.mappedDestroy = function (valueOrPredicate) {
442 var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) {
443 return value === keyCallback(valueOrPredicate);
445 return mappedRootObject.destroy(function (item) {
446 return predicate(keyCallback(item));
450 mappedRootObject.mappedDestroyAll = function (arrayOfValues) {
451 var arrayOfKeys = filterArrayByKey(arrayOfValues, keyCallback);
452 return mappedRootObject.destroy(function (item) {
453 return ko.utils.arrayIndexOf(arrayOfKeys, keyCallback(item)) != -1;
457 mappedRootObject.mappedIndexOf = function (item) {
458 var keys = filterArrayByKey(mappedRootObject(), keyCallback);
459 var key = keyCallback(item);
460 return ko.utils.arrayIndexOf(keys, key);
463 mappedRootObject.mappedCreate = function (value) {
464 if (mappedRootObject.mappedIndexOf(value) !== -1) {
465 throw new Error("There already is an object with the key that you specified.");
468 var item = hasCreateCallback() ? createCallback(value) : value;
469 if (hasUpdateCallback()) {
470 var newValue = updateCallback(item, value);
471 if (ko.isWriteableObservable(item)) {
477 mappedRootObject.push(item);
482 var currentArrayKeys = filterArrayByKey(ko.utils.unwrapObservable(mappedRootObject), keyCallback).sort();
483 var newArrayKeys = filterArrayByKey(rootObject, keyCallback);
484 if (hasKeyCallback) newArrayKeys.sort();
485 var editScript = ko.utils.compareArrays(currentArrayKeys, newArrayKeys);
487 var ignoreIndexOf = {};
489 var newContents = [];
490 for (var i = 0, j = editScript.length; i < j; i++) {
491 var key = editScript[i];
493 var fullPropertyName = getPropertyName(parentPropertyName, rootObject, i);
494 switch (key.status) {
496 var item = getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback);
497 mappedItem = updateViewModel(undefined, item, options, parentName, mappedRootObject, fullPropertyName);
498 if(!hasCreateCallback()) {
499 mappedItem = ko.utils.unwrapObservable(mappedItem);
502 var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf);
503 newContents[index] = mappedItem;
504 ignoreIndexOf[index] = true;
507 var item = getItemByKey(ko.utils.unwrapObservable(rootObject), key.value, keyCallback);
508 mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback);
509 updateViewModel(mappedItem, item, options, parentName, mappedRootObject, fullPropertyName);
511 var index = ignorableIndexOf(ko.utils.unwrapObservable(rootObject), item, ignoreIndexOf);
512 newContents[index] = mappedItem;
513 ignoreIndexOf[index] = true;
516 mappedItem = getItemByKey(mappedRootObject, key.value, keyCallback);
526 mappedRootObject(newContents);
528 var arrayChangedCallback = getCallback("arrayChanged");
529 if (arrayChangedCallback instanceof Function) {
530 ko.utils.arrayForEach(changes, function (change) {
531 arrayChangedCallback(change.event, change.item);
536 return mappedRootObject;
539 function ignorableIndexOf(array, item, ignoreIndices) {
540 for (var i = 0, j = array.length; i < j; i++) {
541 if (ignoreIndices[i] === true) continue;
542 if (array[i] === item) return i;
547 function mapKey(item, callback) {
549 if (callback) mappedItem = callback(item);
550 if (exports.getType(mappedItem) === "undefined") mappedItem = item;
552 return ko.utils.unwrapObservable(mappedItem);
555 function getItemByKey(array, key, callback) {
556 var filtered = ko.utils.arrayFilter(ko.utils.unwrapObservable(array), function (item) {
557 return mapKey(item, callback) === key;
560 if (filtered.length == 0) throw new Error("When calling ko.update*, the key '" + key + "' was not found!");
561 if ((filtered.length > 1) && (canHaveProperties(filtered[0]))) throw new Error("When calling ko.update*, the key '" + key + "' was not unique!");
566 function filterArrayByKey(array, callback) {
567 return ko.utils.arrayMap(ko.utils.unwrapObservable(array), function (item) {
569 return mapKey(item, callback);
576 function visitPropertiesOrArrayEntries(rootObject, visitorCallback) {
577 if (rootObject instanceof Array) {
578 for (var i = 0; i < rootObject.length; i++)
581 for (var propertyName in rootObject)
582 visitorCallback(propertyName);
586 function canHaveProperties(object) {
587 var type = exports.getType(object);
588 return (type === "object" || type === "array") && (object !== null) && (type !== "undefined");
591 // Based on the parentName, this creates a fully classified name of a property
593 function getPropertyName(parentName, parent, indexer) {
594 var propertyName = parentName || "";
595 if (parent instanceof Array) {
597 propertyName += "[" + indexer + "]";
603 propertyName += indexer;
608 function visitModel(rootObject, callback, options, parentName, fullParentName) {
609 // If nested object was already mapped previously, take the options from it
610 if (parentName !== undefined && exports.isMapped(rootObject)) {
611 //options = ko.utils.unwrapObservable(rootObject)[mappingProperty];
612 options = mergeOptions(ko.utils.unwrapObservable(rootObject)[mappingProperty], options);
616 if (parentName === undefined) { // the first call
617 visitedObjects = new objectLookup();
620 parentName = parentName || "";
622 var mappedRootObject;
623 var unwrappedRootObject = ko.utils.unwrapObservable(rootObject);
624 if (!canHaveProperties(unwrappedRootObject)) {
625 return callback(rootObject, fullParentName);
627 // Only do a callback, but ignore the results
628 callback(rootObject, fullParentName);
629 mappedRootObject = unwrappedRootObject instanceof Array ? [] : {};
632 visitedObjects.save(rootObject, mappedRootObject);
634 var origFullParentName = fullParentName;
635 visitPropertiesOrArrayEntries(unwrappedRootObject, function (indexer) {
636 if (options.ignore && ko.utils.arrayIndexOf(options.ignore, indexer) != -1) return;
638 var propertyValue = unwrappedRootObject[indexer];
639 var fullPropertyName = getPropertyName(parentName, unwrappedRootObject, indexer);
641 // If we don't want to explicitly copy the unmapped property...
642 if (ko.utils.arrayIndexOf(options.copy, indexer) === -1) {
643 // ...find out if it's a property we want to explicitly include
644 if (ko.utils.arrayIndexOf(options.include, indexer) === -1) {
645 // Options contains all the properties that were part of the original object.
646 // 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.
647 if (options.mappedProperties && !options.mappedProperties[fullPropertyName] && !(unwrappedRootObject instanceof Array)) {
653 fullParentName = getPropertyName(origFullParentName, unwrappedRootObject, indexer);
655 var propertyType = exports.getType(ko.utils.unwrapObservable(propertyValue));
656 switch (propertyType) {
660 var previouslyMappedValue = visitedObjects.get(propertyValue);
661 mappedRootObject[indexer] = (exports.getType(previouslyMappedValue) !== "undefined") ? previouslyMappedValue : visitModel(propertyValue, callback, options, fullPropertyName, fullParentName);
664 mappedRootObject[indexer] = callback(propertyValue, fullParentName);
668 return mappedRootObject;
671 function objectLookup() {
674 this.save = function (key, value) {
675 var existingIndex = ko.utils.arrayIndexOf(keys, key);
676 if (existingIndex >= 0) values[existingIndex] = value;
682 this.get = function (key) {
683 var existingIndex = ko.utils.arrayIndexOf(keys, key);
684 return (existingIndex >= 0) ? values[existingIndex] : undefined;