• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  Error,
5  ObjectDefineProperties,
6  ObjectDefineProperty,
7  SafeWeakMap,
8  SafeMap,
9  SymbolToStringTag,
10  TypeError,
11} = primordials;
12
13class ERR_INVALID_THIS extends TypeError {
14  constructor(type) {
15    super('Value of "this" must be of ' + type);
16  }
17
18  get code() { return 'ERR_INVALID_THIS'; }
19}
20
21let internalsMap;
22let nameToCodeMap;
23let isInitialized = false;
24
25// We need to instantiate the maps lazily because they render
26// the snapshot non-rehashable.
27// https://bugs.chromium.org/p/v8/issues/detail?id=6593
28function ensureInitialized() {
29  if (isInitialized) {
30    return;
31  }
32  internalsMap = new SafeWeakMap();
33  nameToCodeMap = new SafeMap();
34  forEachCode((name, codeName, value) => {
35    nameToCodeMap.set(name, value);
36  });
37  isInitialized = true;
38}
39
40class DOMException extends Error {
41  constructor(message = '', name = 'Error') {
42    ensureInitialized();
43    super();
44    internalsMap.set(this, {
45      message: `${message}`,
46      name: `${name}`
47    });
48  }
49
50  get name() {
51    ensureInitialized();
52    const internals = internalsMap.get(this);
53    if (internals === undefined) {
54      throw new ERR_INVALID_THIS('DOMException');
55    }
56    return internals.name;
57  }
58
59  get message() {
60    ensureInitialized();
61    const internals = internalsMap.get(this);
62    if (internals === undefined) {
63      throw new ERR_INVALID_THIS('DOMException');
64    }
65    return internals.message;
66  }
67
68  get code() {
69    ensureInitialized();
70    const internals = internalsMap.get(this);
71    if (internals === undefined) {
72      throw new ERR_INVALID_THIS('DOMException');
73    }
74    const code = nameToCodeMap.get(internals.name);
75    return code === undefined ? 0 : code;
76  }
77}
78
79ObjectDefineProperties(DOMException.prototype, {
80  [SymbolToStringTag]: { configurable: true, value: 'DOMException' },
81  name: { enumerable: true, configurable: true },
82  message: { enumerable: true, configurable: true },
83  code: { enumerable: true, configurable: true }
84});
85
86function forEachCode(fn) {
87  fn('IndexSizeError', 'INDEX_SIZE_ERR', 1);
88  fn('DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2);
89  fn('HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3);
90  fn('WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4);
91  fn('InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5);
92  fn('NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6);
93  fn('NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7);
94  fn('NotFoundError', 'NOT_FOUND_ERR', 8);
95  fn('NotSupportedError', 'NOT_SUPPORTED_ERR', 9);
96  fn('InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10);
97  fn('InvalidStateError', 'INVALID_STATE_ERR', 11);
98  fn('SyntaxError', 'SYNTAX_ERR', 12);
99  fn('InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13);
100  fn('NamespaceError', 'NAMESPACE_ERR', 14);
101  fn('InvalidAccessError', 'INVALID_ACCESS_ERR', 15);
102  fn('ValidationError', 'VALIDATION_ERR', 16);
103  fn('TypeMismatchError', 'TYPE_MISMATCH_ERR', 17);
104  fn('SecurityError', 'SECURITY_ERR', 18);
105  fn('NetworkError', 'NETWORK_ERR', 19);
106  fn('AbortError', 'ABORT_ERR', 20);
107  fn('URLMismatchError', 'URL_MISMATCH_ERR', 21);
108  fn('QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22);
109  fn('TimeoutError', 'TIMEOUT_ERR', 23);
110  fn('InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24);
111  fn('DataCloneError', 'DATA_CLONE_ERR', 25);
112  // There are some more error names, but since they don't have codes assigned,
113  // we don't need to care about them.
114}
115
116forEachCode((name, codeName, value) => {
117  const desc = { enumerable: true, value };
118  ObjectDefineProperty(DOMException, codeName, desc);
119  ObjectDefineProperty(DOMException.prototype, codeName, desc);
120});
121
122exports.DOMException = DOMException;
123