From d21978467a8328f2143c5354c0406bf9c78a0cef Mon Sep 17 00:00:00 2001 From: Matthew Beale Date: Sun, 1 Aug 2021 08:48:30 -0400 Subject: [PATCH] [BUGFIX release] Deprecate htmlSafe via prototype In Ember 3.24 various string methods added to the `String.prototype` were deprecated for removal in Ember 4.0. `htmlSafe` (the version available via string prototype) was supposed to be included in those deprecations, however dues to its implementation being different it was missed. This omission can be understood as a bug. This patch deprecates `String.prototype.htmlSafe` targeting Ember 4.0. This will allow the removal of *all* string prototype extensions in 4.0 as intended by the original deprecation. See also: https://github.com/emberjs/ember.js/pull/19654#issuecomment-890386906 --- .../glimmer/tests/utils/string-test.js | 40 +++++++++++++++++++ packages/ember/index.js | 13 ++++++ 2 files changed, 53 insertions(+) diff --git a/packages/@ember/-internals/glimmer/tests/utils/string-test.js b/packages/@ember/-internals/glimmer/tests/utils/string-test.js index 139c6c3846d..343ea352474 100644 --- a/packages/@ember/-internals/glimmer/tests/utils/string-test.js +++ b/packages/@ember/-internals/glimmer/tests/utils/string-test.js @@ -1,4 +1,5 @@ import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { ENV } from '@ember/-internals/environment'; import { SafeString, htmlSafe, isHTMLSafe } from './helpers'; @@ -11,6 +12,19 @@ moduleFor( this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); } + ['@test [deprecated] htmlSafe via string prototype should return an instance of SafeString']() { + if (ENV.EXTEND_PROTOTYPES.String) { + let safeString; + expectDeprecation(() => { + safeString = 'you need to be more bold'.htmlSafe(); + }, /String prototype extensions are deprecated/); + + this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); + } else { + this.assert.expect(0); + } + } + ['@test htmlSafe should return an empty string for null']() { let safeString = htmlSafe(null); @@ -24,6 +38,32 @@ moduleFor( this.assert.equal(safeString instanceof SafeString, true, 'should be a SafeString'); this.assert.equal(safeString.toString(), '', 'should return an empty string'); } + + ['@test [deprecated] htmlSafe via string prototype should return an instance of SafeString for an empty string']() { + if (ENV.EXTEND_PROTOTYPES.String) { + let safeString; + expectDeprecation(() => { + safeString = ''.htmlSafe(); + }, /String prototype extensions are deprecated/); + + this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); + } else { + this.assert.expect(0); + } + } + + ['@test [deprecated] String.prototype.htmlSafe is not modified without EXTEND_PROTOTYPES']( + assert + ) { + if (!ENV.EXTEND_PROTOTYPES.String) { + assert.ok( + 'undefined' === typeof String.prototype.htmlSafe, + 'String.prototype helper disabled' + ); + } else { + this.assert.expect(0); + } + } } ); diff --git a/packages/ember/index.js b/packages/ember/index.js index 7709b6b9448..e1162eccb52 100644 --- a/packages/ember/index.js +++ b/packages/ember/index.js @@ -493,6 +493,19 @@ Ember._captureRenderTree = captureRenderTree; if (ENV.EXTEND_PROTOTYPES.String) { String.prototype.htmlSafe = function () { + deprecate( + `String prototype extensions are deprecated. Please import htmlSafe from '@ember/template' instead.`, + true, + { + id: 'ember-string.prototype-extensions', + for: 'ember-source', + since: { + enabled: '3.27.1', + }, + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-string-htmlsafe-ishtmlsafe', + } + ); return htmlSafe(this); }; }