File: /var/www/zaklada/html/node_modules/stringmap/stringmap.js
// stringmap.js
// MIT licensed, see LICENSE file
// Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
var StringMap = (function() {
"use strict";
// to save us a few characters
var hasOwnProperty = Object.prototype.hasOwnProperty;
var create = (function() {
function hasOwnEnumerableProps(obj) {
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
return true;
}
}
return false;
}
// FF <= 3.6:
// o = {}; o.hasOwnProperty("__proto__" or "__count__" or "__parent__") => true
// o = {"__proto__": null}; Object.prototype.hasOwnProperty.call(o, "__proto__" or "__count__" or "__parent__") => false
function hasOwnPollutedProps(obj) {
return hasOwnProperty.call(obj, "__count__") || hasOwnProperty.call(obj, "__parent__");
}
var useObjectCreate = false;
if (typeof Object.create === "function") {
if (!hasOwnEnumerableProps(Object.create(null))) {
useObjectCreate = true;
}
}
if (useObjectCreate === false) {
if (hasOwnEnumerableProps({})) {
throw new Error("StringMap environment error 0, please file a bug at https://github.com/olov/stringmap/issues");
}
}
// no throw yet means we can create objects without own enumerable props (safe-guard against VMs and shims)
var o = (useObjectCreate ? Object.create(null) : {});
var useProtoClear = false;
if (hasOwnPollutedProps(o)) {
o.__proto__ = null;
if (hasOwnEnumerableProps(o) || hasOwnPollutedProps(o)) {
throw new Error("StringMap environment error 1, please file a bug at https://github.com/olov/stringmap/issues");
}
useProtoClear = true;
}
// no throw yet means we can create objects without own polluted props (safe-guard against VMs and shims)
return function() {
var o = (useObjectCreate ? Object.create(null) : {});
if (useProtoClear) {
o.__proto__ = null;
}
return o;
};
})();
// stringmap ctor
function stringmap(optional_object) {
// use with or without new
if (!(this instanceof stringmap)) {
return new stringmap(optional_object);
}
this.obj = create();
this.hasProto = false; // false (no __proto__ key) or true (has __proto__ key)
this.proto = undefined; // value for __proto__ key when hasProto is true, undefined otherwise
if (optional_object) {
this.setMany(optional_object);
}
};
// primitive methods that deals with data representation
stringmap.prototype.has = function(key) {
// The type-check of key in has, get, set and delete is important because otherwise an object
// {toString: function() { return "__proto__"; }} can avoid the key === "__proto__" test.
// The alternative to type-checking would be to force string conversion, i.e. key = String(key);
if (typeof key !== "string") {
throw new Error("StringMap expected string key");
}
return (key === "__proto__" ?
this.hasProto :
hasOwnProperty.call(this.obj, key));
};
stringmap.prototype.get = function(key) {
if (typeof key !== "string") {
throw new Error("StringMap expected string key");
}
return (key === "__proto__" ?
this.proto :
(hasOwnProperty.call(this.obj, key) ? this.obj[key] : undefined));
};
stringmap.prototype.set = function(key, value) {
if (typeof key !== "string") {
throw new Error("StringMap expected string key");
}
if (key === "__proto__") {
this.hasProto = true;
this.proto = value;
} else {
this.obj[key] = value;
}
};
stringmap.prototype.remove = function(key) {
if (typeof key !== "string") {
throw new Error("StringMap expected string key");
}
var didExist = this.has(key);
if (key === "__proto__") {
this.hasProto = false;
this.proto = undefined;
} else {
delete this.obj[key];
}
return didExist;
};
// alias remove to delete but beware:
// sm.delete("key"); // OK in ES5 and later
// sm['delete']("key"); // OK in all ES versions
// sm.remove("key"); // OK in all ES versions
stringmap.prototype['delete'] = stringmap.prototype.remove;
stringmap.prototype.isEmpty = function() {
for (var key in this.obj) {
if (hasOwnProperty.call(this.obj, key)) {
return false;
}
}
return !this.hasProto;
};
stringmap.prototype.size = function() {
var len = 0;
for (var key in this.obj) {
if (hasOwnProperty.call(this.obj, key)) {
++len;
}
}
return (this.hasProto ? len + 1 : len);
};
stringmap.prototype.keys = function() {
var keys = [];
for (var key in this.obj) {
if (hasOwnProperty.call(this.obj, key)) {
keys.push(key);
}
}
if (this.hasProto) {
keys.push("__proto__");
}
return keys;
};
stringmap.prototype.values = function() {
var values = [];
for (var key in this.obj) {
if (hasOwnProperty.call(this.obj, key)) {
values.push(this.obj[key]);
}
}
if (this.hasProto) {
values.push(this.proto);
}
return values;
};
stringmap.prototype.items = function() {
var items = [];
for (var key in this.obj) {
if (hasOwnProperty.call(this.obj, key)) {
items.push([key, this.obj[key]]);
}
}
if (this.hasProto) {
items.push(["__proto__", this.proto]);
}
return items;
};
// methods that rely on the above primitives
stringmap.prototype.setMany = function(object) {
if (object === null || (typeof object !== "object" && typeof object !== "function")) {
throw new Error("StringMap expected Object");
}
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
this.set(key, object[key]);
}
}
return this;
};
stringmap.prototype.merge = function(other) {
var keys = other.keys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
this.set(key, other.get(key));
}
return this;
};
stringmap.prototype.map = function(fn) {
var keys = this.keys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
keys[i] = fn(this.get(key), key); // re-use keys array for results
}
return keys;
};
stringmap.prototype.forEach = function(fn) {
var keys = this.keys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
fn(this.get(key), key);
}
};
stringmap.prototype.clone = function() {
var other = stringmap();
return other.merge(this);
};
stringmap.prototype.toString = function() {
var self = this;
return "{" + this.keys().map(function(key) {
return JSON.stringify(key) + ":" + JSON.stringify(self.get(key));
}).join(",") + "}";
};
return stringmap;
})();
if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
module.exports = StringMap;
}