735eb676b23c9b51032f95c2ae7c5aac6363c79d
[platform/framework/web/crosswalk-tizen.git] /
1 'use strict';
2
3 var d              = require('d')
4   , validateSymbol = require('./validate-symbol')
5
6   , create = Object.create, defineProperties = Object.defineProperties
7   , defineProperty = Object.defineProperty, objPrototype = Object.prototype
8   , Symbol, HiddenSymbol, globalSymbols = create(null);
9
10 var generateName = (function () {
11         var created = create(null);
12         return function (desc) {
13                 var postfix = 0, name;
14                 while (created[desc + (postfix || '')]) ++postfix;
15                 desc += (postfix || '');
16                 created[desc] = true;
17                 name = '@@' + desc;
18                 defineProperty(objPrototype, name, d.gs(null, function (value) {
19                         defineProperty(this, name, d(value));
20                 }));
21                 return name;
22         };
23 }());
24
25 HiddenSymbol = function Symbol(description) {
26         if (this instanceof HiddenSymbol) throw new TypeError('TypeError: Symbol is not a constructor');
27         return Symbol(description);
28 };
29 module.exports = Symbol = function Symbol(description) {
30         var symbol;
31         if (this instanceof Symbol) throw new TypeError('TypeError: Symbol is not a constructor');
32         symbol = create(HiddenSymbol.prototype);
33         description = (description === undefined ? '' : String(description));
34         return defineProperties(symbol, {
35                 __description__: d('', description),
36                 __name__: d('', generateName(description))
37         });
38 };
39 defineProperties(Symbol, {
40         for: d(function (key) {
41                 if (globalSymbols[key]) return globalSymbols[key];
42                 return (globalSymbols[key] = Symbol(String(key)));
43         }),
44         keyFor: d(function (s) {
45                 var key;
46                 validateSymbol(s);
47                 for (key in globalSymbols) if (globalSymbols[key] === s) return key;
48         }),
49         hasInstance: d('', Symbol('hasInstance')),
50         isConcatSpreadable: d('', Symbol('isConcatSpreadable')),
51         iterator: d('', Symbol('iterator')),
52         match: d('', Symbol('match')),
53         replace: d('', Symbol('replace')),
54         search: d('', Symbol('search')),
55         species: d('', Symbol('species')),
56         split: d('', Symbol('split')),
57         toPrimitive: d('', Symbol('toPrimitive')),
58         toStringTag: d('', Symbol('toStringTag')),
59         unscopables: d('', Symbol('unscopables'))
60 });
61 defineProperties(HiddenSymbol.prototype, {
62         constructor: d(Symbol),
63         toString: d('', function () { return this.__name__; })
64 });
65
66 defineProperties(Symbol.prototype, {
67         toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
68         valueOf: d(function () { return validateSymbol(this); })
69 });
70 defineProperty(Symbol.prototype, Symbol.toPrimitive, d('',
71         function () { return validateSymbol(this); }));
72 defineProperty(Symbol.prototype, Symbol.toStringTag, d('c', 'Symbol'));
73
74 defineProperty(HiddenSymbol.prototype, Symbol.toPrimitive,
75         d('c', Symbol.prototype[Symbol.toPrimitive]));
76 defineProperty(HiddenSymbol.prototype, Symbol.toStringTag,
77         d('c', Symbol.prototype[Symbol.toStringTag]));