kopia lustrzana https://github.com/OpenDroneMap/NodeODM
225 wiersze
7.0 KiB
JavaScript
225 wiersze
7.0 KiB
JavaScript
// Knockout Observable Dictionary
|
|
// (c) James Foster
|
|
// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
|
|
(function () {
|
|
function DictionaryItem(key, value, dictionary) {
|
|
var observableKey = new ko.observable(key);
|
|
|
|
this.value = new ko.observable(value);
|
|
this.key = new ko.computed({
|
|
read: observableKey,
|
|
write: function (newKey) {
|
|
var current = observableKey();
|
|
|
|
if (current == newKey) return;
|
|
|
|
// no two items are allowed to share the same key.
|
|
dictionary.remove(newKey);
|
|
|
|
observableKey(newKey);
|
|
}
|
|
});
|
|
}
|
|
|
|
ko.observableDictionary = function (dictionary, keySelector, valueSelector) {
|
|
var result = {};
|
|
|
|
result.items = new ko.observableArray();
|
|
|
|
result._wrappers = {};
|
|
result._keySelector = keySelector || function (value, key) { return key; };
|
|
result._valueSelector = valueSelector || function (value) { return value; };
|
|
|
|
if (typeof keySelector == 'string') result._keySelector = function (value) { return value[keySelector]; };
|
|
if (typeof valueSelector == 'string') result._valueSelector = function (value) { return value[valueSelector]; };
|
|
|
|
ko.utils.extend(result, ko.observableDictionary['fn']);
|
|
|
|
result.pushAll(dictionary);
|
|
|
|
return result;
|
|
};
|
|
|
|
ko.observableDictionary['fn'] = {
|
|
remove: function (valueOrPredicate) {
|
|
var predicate = valueOrPredicate;
|
|
|
|
if (valueOrPredicate instanceof DictionaryItem) {
|
|
predicate = function (item) {
|
|
return item.key() === valueOrPredicate.key();
|
|
};
|
|
}
|
|
else if (typeof valueOrPredicate != "function") {
|
|
predicate = function (item) {
|
|
return item.key() === valueOrPredicate;
|
|
};
|
|
}
|
|
|
|
ko.observableArray['fn'].remove.call(this.items, predicate);
|
|
},
|
|
|
|
push: function (key, value) {
|
|
var item = null;
|
|
|
|
if (key instanceof DictionaryItem) {
|
|
// handle the case where only a DictionaryItem is passed in
|
|
item = key;
|
|
value = key.value();
|
|
key = key.key();
|
|
}
|
|
|
|
if (value === undefined) {
|
|
value = this._valueSelector(key);
|
|
key = this._keySelector(value);
|
|
}
|
|
else {
|
|
value = this._valueSelector(value);
|
|
}
|
|
|
|
var current = this.get(key, false);
|
|
if (current) {
|
|
// update existing value
|
|
current(value);
|
|
return current;
|
|
}
|
|
|
|
if (!item) {
|
|
item = new DictionaryItem(key, value, this);
|
|
}
|
|
|
|
ko.observableArray['fn'].push.call(this.items, item);
|
|
|
|
return value;
|
|
},
|
|
|
|
pushAll: function (dictionary) {
|
|
var self = this;
|
|
var items = self.items();
|
|
|
|
if (dictionary instanceof Array) {
|
|
$.each(dictionary, function (index, item) {
|
|
var key = self._keySelector(item, index);
|
|
var value = self._valueSelector(item);
|
|
items.push(new DictionaryItem(key, value, self));
|
|
});
|
|
}
|
|
else {
|
|
for (var prop in dictionary) {
|
|
if (dictionary.hasOwnProperty(prop)) {
|
|
var item = dictionary[prop];
|
|
var key = self._keySelector(item, prop);
|
|
var value = self._valueSelector(item);
|
|
items.push(new DictionaryItem(key, value, self));
|
|
}
|
|
}
|
|
}
|
|
|
|
self.items.valueHasMutated();
|
|
},
|
|
|
|
sort: function (method) {
|
|
if (method === undefined) {
|
|
method = function (a, b) {
|
|
return defaultComparison(a.key(), b.key());
|
|
};
|
|
}
|
|
|
|
return ko.observableArray['fn'].sort.call(this.items, method);
|
|
},
|
|
|
|
indexOf: function (key) {
|
|
if (key instanceof DictionaryItem) {
|
|
return ko.observableArray['fn'].indexOf.call(this.items, key);
|
|
}
|
|
|
|
var underlyingArray = this.items();
|
|
for (var index = 0; index < underlyingArray.length; index++) {
|
|
if (underlyingArray[index].key() == key)
|
|
return index;
|
|
}
|
|
return -1;
|
|
},
|
|
|
|
get: function (key, wrap) {
|
|
if (wrap == false)
|
|
return getValue(key, this.items());
|
|
|
|
var wrapper = this._wrappers[key];
|
|
|
|
if (wrapper == null) {
|
|
wrapper = this._wrappers[key] = new ko.computed({
|
|
read: function () {
|
|
var value = getValue(key, this.items());
|
|
return value ? value() : null;
|
|
},
|
|
write: function (newValue) {
|
|
var value = getValue(key, this.items());
|
|
|
|
if (value)
|
|
value(newValue);
|
|
else
|
|
this.push(key, newValue);
|
|
}
|
|
}, this);
|
|
}
|
|
|
|
return wrapper;
|
|
},
|
|
|
|
set: function (key, value) {
|
|
return this.push(key, value);
|
|
},
|
|
|
|
keys: function () {
|
|
return ko.utils.arrayMap(this.items(), function (item) { return item.key(); });
|
|
},
|
|
|
|
values: function () {
|
|
return ko.utils.arrayMap(this.items(), function (item) { return item.value(); });
|
|
},
|
|
|
|
removeAll: function () {
|
|
this.items.removeAll();
|
|
},
|
|
|
|
toJSON: function () {
|
|
var result = {};
|
|
var items = ko.utils.unwrapObservable(this.items);
|
|
|
|
ko.utils.arrayForEach(items, function (item) {
|
|
var key = ko.utils.unwrapObservable(item.key);
|
|
var value = ko.utils.unwrapObservable(item.value);
|
|
|
|
result[key] = value;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
};
|
|
|
|
function getValue(key, items) {
|
|
var found = ko.utils.arrayFirst(items, function (item) {
|
|
return item.key() == key;
|
|
});
|
|
return found ? found.value : null;
|
|
}
|
|
})();
|
|
|
|
|
|
// Utility methods
|
|
// ---------------------------------------------
|
|
function isNumeric(n) {
|
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
}
|
|
|
|
function defaultComparison(a, b) {
|
|
if (isNumeric(a) && isNumeric(b)) return a - b;
|
|
|
|
a = a.toString();
|
|
b = b.toString();
|
|
|
|
return a == b ? 0 : (a < b ? -1 : 1);
|
|
}
|
|
// ---------------------------------------------
|