425d48265aa0f89a6619872aadca7f7cb983addb
[platform/framework/web/crosswalk-tizen.git] /
1 'use strict';
2
3 var clear          = require('es5-ext/object/clear')
4   , setPrototypeOf = require('es5-ext/object/set-prototype-of')
5   , validValue     = require('es5-ext/object/valid-value')
6   , callable       = require('es5-ext/object/valid-callable')
7   , d              = require('d')
8   , iterator       = require('es6-iterator/valid-iterable')
9   , forOf          = require('es6-iterator/for-of')
10   , Map            = require('../polyfill')
11   , Iterator       = require('../lib/primitive-iterator')
12
13   , call = Function.prototype.call
14   , defineProperty = Object.defineProperty
15   , create = Object.create, defineProperties = Object.defineProperties
16   , hasOwnProperty = Object.prototype.hasOwnProperty
17   , PrimitiveMap;
18
19 module.exports = PrimitiveMap = function (/*iterable, serialize*/) {
20         var iterable = arguments[0], serialize = arguments[1];
21         if (!(this instanceof PrimitiveMap)) {
22                 return new PrimitiveMap(iterable, serialize);
23         }
24         if (this.__mapData__ !== undefined) {
25                 throw new TypeError(this + " cannot be reinitialized");
26         }
27         if (iterable != null) iterator(iterable);
28         if (serialize !== undefined) {
29                 callable(serialize);
30                 defineProperty(this, '_serialize', d('', serialize));
31         }
32         defineProperties(this, {
33                 __mapKeysData__: d('c', create(null)),
34                 __mapValuesData__: d('c', create(null)),
35                 __size__: d('w', 0)
36         });
37         if (!iterable) return;
38         forOf(iterable, function (value) {
39                 var key = validValue(value)[0], sKey = this._serialize(key);
40                 if (sKey == null) throw new TypeError(key + " cannot be serialized");
41                 value = value[1];
42                 if (hasOwnProperty.call(this.__mapKeysData__, sKey)) {
43                         if (this.__mapValuesData__[sKey] === value) return;
44                 } else {
45                         ++this.__size__;
46                 }
47                 this.__mapKeysData__[sKey] = key;
48                 this.__mapValuesData__[sKey] = value;
49         }, this);
50 };
51 if (setPrototypeOf) setPrototypeOf(PrimitiveMap, Map);
52
53 PrimitiveMap.prototype = create(Map.prototype, {
54         constructor: d(PrimitiveMap),
55         _serialize: d(function (value) {
56                 if (value && (typeof value.toString !== 'function')) return null;
57                 return String(value);
58         }),
59         clear: d(function () {
60                 if (!this.__size__) return;
61                 clear(this.__mapKeysData__);
62                 clear(this.__mapValuesData__);
63                 this.__size__ = 0;
64                 this.emit('_clear');
65         }),
66         delete: d(function (key) {
67                 var sKey = this._serialize(key);
68                 if (sKey == null) return false;
69                 if (!hasOwnProperty.call(this.__mapKeysData__, sKey)) return false;
70                 delete this.__mapKeysData__[sKey];
71                 delete this.__mapValuesData__[sKey];
72                 --this.__size__;
73                 this.emit('_delete', sKey);
74                 return true;
75         }),
76         entries: d(function () { return new Iterator(this, 'key+value'); }),
77         forEach: d(function (cb/*, thisArg*/) {
78                 var thisArg = arguments[1], iterator, result, sKey;
79                 callable(cb);
80                 iterator = this.entries();
81                 result = iterator._next();
82                 while (result !== undefined) {
83                         sKey = iterator.__list__[result];
84                         call.call(cb, thisArg, this.__mapValuesData__[sKey],
85                                 this.__mapKeysData__[sKey], this);
86                         result = iterator._next();
87                 }
88         }),
89         get: d(function (key) {
90                 var sKey = this._serialize(key);
91                 if (sKey == null) return;
92                 return this.__mapValuesData__[sKey];
93         }),
94         has: d(function (key) {
95                 var sKey = this._serialize(key);
96                 if (sKey == null) return false;
97                 return hasOwnProperty.call(this.__mapKeysData__, sKey);
98         }),
99         keys: d(function () { return new Iterator(this, 'key'); }),
100         size: d.gs(function () { return this.__size__; }),
101         set: d(function (key, value) {
102                 var sKey = this._serialize(key);
103                 if (sKey == null) throw new TypeError(key + " cannot be serialized");
104                 if (hasOwnProperty.call(this.__mapKeysData__, sKey)) {
105                         if (this.__mapValuesData__[sKey] === value) return this;
106                 } else {
107                         ++this.__size__;
108                 }
109                 this.__mapKeysData__[sKey] = key;
110                 this.__mapValuesData__[sKey] = value;
111                 this.emit('_add', sKey);
112                 return this;
113         }),
114         values: d(function () { return new Iterator(this, 'value'); })
115 });