diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 01fce09759c67f..e5cec17d03163e 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -185,9 +185,10 @@ and should no longer be used. ### DEP0017: Intl.v8BreakIterator -Type: Runtime +Type: End-of-Life -The `Intl.v8BreakIterator` is deprecated and will be removed or replaced soon. +`Intl.v8BreakIterator` was a non-standard extension and has been removed. +See [`Intl.Segmenter`](https://github.com/tc39/proposal-intl-segmenter). ### DEP0018: Unhandled promise rejections diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 10e5be8a44056d..dc744d61e7b8a3 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -275,8 +275,6 @@ E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type'); E('ERR_VALUE_OUT_OF_RANGE', (start, end, value) => { return `The value of "${start}" must be ${end}. Received "${value}"`; }); -E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' + - 'See https://github.com/nodejs/node/wiki/Intl'); E('ERR_VALID_PERFORMANCE_ENTRY_TYPE', 'At least one valid performance entry type is required'); E('ERR_VALUE_OUT_OF_RANGE', 'The value of "%s" must be %s. Received "%s"'); diff --git a/lib/internal/process.js b/lib/internal/process.js index c96f99ccfd8299..21a74abba7e313 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -133,20 +133,6 @@ function setupConfig(_source) { if (value === 'false') return false; return value; }); - const processConfig = process.binding('config'); - if (typeof Intl !== 'undefined' && Intl.hasOwnProperty('v8BreakIterator')) { - const oldV8BreakIterator = Intl.v8BreakIterator; - const des = Object.getOwnPropertyDescriptor(Intl, 'v8BreakIterator'); - des.value = require('internal/util').deprecate(function v8BreakIterator() { - if (processConfig.hasSmallICU && !processConfig.icuDataDir) { - // Intl.v8BreakIterator() would crash w/ fatal error, so throw instead. - throw new errors.Error('ERR_V8BREAKITERATOR'); - } - return Reflect.construct(oldV8BreakIterator, arguments); - }, 'Intl.v8BreakIterator is deprecated and will be removed soon.', - 'DEP0017'); - Object.defineProperty(Intl, 'v8BreakIterator', des); - } } diff --git a/src/node.cc b/src/node.cc index 5cd0ffc29db1e9..be92e2f8b6b7b6 100644 --- a/src/node.cc +++ b/src/node.cc @@ -4533,11 +4533,28 @@ void FreeEnvironment(Environment* env) { } +Local NewContext(Isolate* isolate, + Local object_template) { + auto context = Context::New(isolate, nullptr, object_template); + if (context.IsEmpty()) return context; + HandleScope handle_scope(isolate); + auto intl_key = FIXED_ONE_BYTE_STRING(isolate, "Intl"); + auto break_iter_key = FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator"); + Local intl_v; + Local intl; + if (context->Global()->Get(context, intl_key).ToLocal(&intl_v) && + intl_v->ToObject(context).ToLocal(&intl)) { + intl->Delete(context, break_iter_key).FromJust(); + } + return context; +} + + inline int Start(Isolate* isolate, IsolateData* isolate_data, int argc, const char* const* argv, int exec_argc, const char* const* exec_argv) { HandleScope handle_scope(isolate); - Local context = Context::New(isolate); + Local context = NewContext(isolate); Context::Scope context_scope(context); Environment env(isolate_data, context); CHECK_EQ(0, uv_key_create(&thread_local_env)); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index c2037c4cbe7354..b04bd6253e9386 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -240,7 +240,7 @@ class ContextifyContext { CreateDataWrapper(env)); object_template->SetHandler(config); - Local ctx = Context::New(env->isolate(), nullptr, object_template); + Local ctx = NewContext(env->isolate(), object_template); if (ctx.IsEmpty()) { env->ThrowError("Could not instantiate context"); diff --git a/src/node_internals.h b/src/node_internals.h index a241e671edda48..6faf2750d4d039 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -125,6 +125,14 @@ inline v8::Local PersistentToLocal( v8::Isolate* isolate, const v8::Persistent& persistent); +// Creates a new context with Node.js-specific tweaks. Currently, it removes +// the `v8BreakIterator` property from the global `Intl` object if present. +// See https://github.com/nodejs/node/issues/14909 for more info. +v8::Local NewContext( + v8::Isolate* isolate, + v8::Local object_template = + v8::Local()); + // Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // Sets address and port properties on the info object and returns it. // If |info| is omitted, a new object is returned. diff --git a/test/parallel/test-intl-v8BreakIterator.js b/test/parallel/test-intl-v8BreakIterator.js index 6e9c9dbe3a1bcb..4f501e6ef6db28 100644 --- a/test/parallel/test-intl-v8BreakIterator.js +++ b/test/parallel/test-intl-v8BreakIterator.js @@ -1,17 +1,10 @@ 'use strict'; const common = require('../common'); +const assert = require('assert'); +const vm = require('vm'); -if (!common.hasIntl || Intl.v8BreakIterator === undefined) +if (typeof Intl === 'undefined') common.skip('missing Intl'); -const assert = require('assert'); -const warning = 'Intl.v8BreakIterator is deprecated and will be removed soon.'; -common.expectWarning('DeprecationWarning', warning); - -try { - new Intl.v8BreakIterator(); - // May succeed if data is available - OK -} catch (e) { - // May throw this error if ICU data is not available - OK - assert.throws(() => new Intl.v8BreakIterator(), /ICU data/); -} +assert(!('v8BreakIterator' in Intl)); +assert(!vm.runInNewContext('"v8BreakIterator" in Intl'));