Skip to content

Commit

Permalink
improve compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Oct 4, 2021
1 parent a72f50d commit 0fcba79
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 24 deletions.
4 changes: 2 additions & 2 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,9 +1762,9 @@ export const data = {
},
'web.dom-exception': {
chrome: '46',
deno: '1.7', // ?
deno: '1.7',
firefox: '37',
safari: '10.1',
safari: '11.1',
},
'web.immediate': {
ie: '10',
Expand Down
67 changes: 58 additions & 9 deletions packages/core-js/modules/web.dom-exception.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';
var $ = require('../internals/export');
var global = require('../internals/global');
var path = require('../internals/path');
var fails = require('../internals/fails');
var create = require('../internals/object-create');
var createPropertyDescriptor = require('../internals/create-property-descriptor');
var defineProperty = require('../internals/object-define-property').f;
Expand All @@ -12,8 +13,10 @@ var $toString = require('../internals/to-string');
var setToStringTag = require('../internals/set-to-string-tag');
var InternalStateModule = require('../internals/internal-state');
var DESCRIPTORS = require('../internals/descriptors');
var IS_PURE = require('../internals/is-pure');

var DOM_EXCEPTION = 'DOMException';
var HAS_STACK = 'stack' in Error(DOM_EXCEPTION);
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(DOM_EXCEPTION);

Expand Down Expand Up @@ -64,6 +67,9 @@ var $DOMException = function DOMException() {
this.message = message;
this.code = code;
}
if (HAS_STACK) {
defineProperty(this, 'stack', createPropertyDescriptor(1, Error('DOMException: ' + message).stack));
}
};

var $DOMExceptionPrototype = $DOMException.prototype = create(Error.prototype);
Expand All @@ -85,17 +91,60 @@ redefine($DOMExceptionPrototype, 'toString', function toString() {
return state.name + ': ' + state.message;
});

setToStringTag($DOMException, DOM_EXCEPTION);
// FF36- DOMException is a function, but can't be constructed
var INCORRECT_CONSTRUCTOR = fails(function () {
return !new DOMException();
});

for (var key in errors) if (hasOwn(errors, key)) {
var constant = errors[key];
var descriptor = createPropertyDescriptor(6, constant.c);
defineProperty($DOMException, constant.s, descriptor);
defineProperty($DOMExceptionPrototype, constant.s, descriptor);
}
// Safari 10.1 / Deno 1.6.3- DOMException.prototype.toString bug
var INCORRECT_TO_STRING = INCORRECT_CONSTRUCTOR || fails(function () {
return String(new DOMException('a', 'b')) !== 'b: a';
});

// Deno 1.6.3- DOMException.prototype.code just missed
var INCORRECT_CODE = INCORRECT_CONSTRUCTOR || fails(function () {
return new DOMException(1, 'DataCloneError').code !== 25;
});

// `DOMException` constructor
// https://heycam.github.io/webidl/#idl-DOMException
$({ global: true, forced: typeof global[DOM_EXCEPTION] !== 'function' }, {
$({ global: true, forced: IS_PURE ? INCORRECT_TO_STRING || INCORRECT_CODE : INCORRECT_CONSTRUCTOR }, {
DOMException: $DOMException
});

var PolyfilledDOMException = path[DOM_EXCEPTION];
var PolyfilledDOMExceptionPrototype = PolyfilledDOMException.prototype;

if (PolyfilledDOMException !== $DOMException) {
if (INCORRECT_TO_STRING) {
redefine(PolyfilledDOMExceptionPrototype, 'toString', function toString() {
return this.name + ': ' + this.message;
});
}

if (INCORRECT_CODE && DESCRIPTORS) {
defineProperty(PolyfilledDOMExceptionPrototype, 'code', {
enumerable: true,
configurable: true,
get: function () {
var name = this.name;
return hasOwn(errors, name) && errors[name].m ? errors[name].c : 0;
}
});
}
}

// Deno 1.6.3- DOMException constants just missed, so add them after constructor polyfilling
for (var key in errors) if (hasOwn(errors, key)) {
var constant = errors[key];
var constantName = constant.s;
var descriptor = createPropertyDescriptor(6, constant.c);
if (!hasOwn(PolyfilledDOMException, constantName)) {
defineProperty(PolyfilledDOMException, constantName, descriptor);
}
if (!hasOwn(PolyfilledDOMExceptionPrototype, constantName)) {
defineProperty(PolyfilledDOMExceptionPrototype, constantName, descriptor);
}
}

setToStringTag(PolyfilledDOMException, DOM_EXCEPTION);
12 changes: 6 additions & 6 deletions tests/pure/web.dom-exception.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ QUnit.test('DOMException', assert => {
assert.same(error.message, '[object Object]', 'new DOMException({}, "Foo").message');
assert.same(error.name, 'Foo', 'new DOMException({}, "Foo").name');
assert.same(error.code, 0, 'new DOMException({}, "Foo").code');
assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))');
assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))'); // Safari 10.1 bug
assert.same(error.constructor, DOMException, 'new DOMException({}, "Foo").constructor');
assert.same(error[Symbol.toStringTag], 'DOMException', 'DOMException.prototype[Symbol.toStringTag]');

Expand All @@ -56,7 +56,7 @@ QUnit.test('DOMException', assert => {
assert.same(error.name, name, `new DOMException({}, "${ name }").name`);
if (errors[name].m) assert.same(error.code, errors[name].c, `new DOMException({}, "${ name }").code`);
else assert.same(error.code, 0, `new DOMException({}, "${ name }").code`);
assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`);
assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`); // Safari 10.1 bug

assert.same(DOMException[errors[name].s], errors[name].c, `DOMException.${ errors[name].s }`);
assert.same(DOMException.prototype[errors[name].s], errors[name].c, `DOMException.prototype.${ errors[name].s }`);
Expand All @@ -66,9 +66,9 @@ QUnit.test('DOMException', assert => {
assert.throws(() => new DOMException(Symbol(), 'DataCloneError'), "new DOMException(Symbol(), 'DataCloneError')");
assert.throws(() => new DOMException(42, Symbol()), 'new DOMException(42, Symbol())');
if (DESCRIPTORS) {
assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message');
assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name');
assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code');
assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()');
// assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message'); // FF55- , Safari 10.1 bug
// assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name'); // FF55-, Safari 10.1 bug bug
// assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code'); // Safari 10.1 bug
// assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()'); // FF55- bug
}
});
14 changes: 7 additions & 7 deletions tests/tests/web.dom-exception.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ QUnit.test('DOMException', assert => {
assert.isFunction(DOMException);
assert.arity(DOMException, 0);
assert.name(DOMException, 'DOMException');
assert.looksNative(DOMException);
// assert.looksNative(DOMException); // FF43- bug

let error = new DOMException({}, 'Foo');
assert.ok(error instanceof DOMException, 'new DOMException({}, "Foo") instanceof DOMException');
assert.same(error.message, '[object Object]', 'new DOMException({}, "Foo").message');
assert.same(error.name, 'Foo', 'new DOMException({}, "Foo").name');
assert.same(error.code, 0, 'new DOMException({}, "Foo").code');
assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))');
assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))'); // Safari 10.1 bug
assert.same(error.constructor, DOMException, 'new DOMException({}, "Foo").constructor');
assert.same(error[Symbol.toStringTag], 'DOMException', 'DOMException.prototype[Symbol.toStringTag]');

Expand All @@ -55,7 +55,7 @@ QUnit.test('DOMException', assert => {
assert.same(error.name, name, `new DOMException({}, "${ name }").name`);
if (errors[name].m) assert.same(error.code, errors[name].c, `new DOMException({}, "${ name }").code`);
else assert.same(error.code, 0, `new DOMException({}, "${ name }").code`);
assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`);
assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`); // Safari 10.1 bug

assert.same(DOMException[errors[name].s], errors[name].c, `DOMException.${ errors[name].s }`);
assert.same(DOMException.prototype[errors[name].s], errors[name].c, `DOMException.prototype.${ errors[name].s }`);
Expand All @@ -65,9 +65,9 @@ QUnit.test('DOMException', assert => {
assert.throws(() => new DOMException(Symbol(), 'DataCloneError'), "new DOMException(Symbol(), 'DataCloneError')");
assert.throws(() => new DOMException(42, Symbol()), 'new DOMException(42, Symbol())');
if (DESCRIPTORS) {
assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message');
assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name');
assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code');
assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()');
// assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message'); // FF55- , Safari 10.1 bug
// assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name'); // FF55-, Safari 10.1 bug bug
// assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code'); // Safari 10.1 bug
// assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()'); // FF55- bug
}
});

0 comments on commit 0fcba79

Please sign in to comment.