Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove @ember/string methods from native prototype #19654

Merged
merged 2 commits into from Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 2 additions & 7 deletions packages/@ember/-internals/environment/lib/env.ts
Expand Up @@ -16,7 +16,7 @@ export const ENV = {
ENABLE_OPTIONAL_FEATURES: false,

/**
Determines whether Ember should add to `Array`, `Function`, and `String`
Determines whether Ember should add to `Array`
native object prototypes, a few extra methods in order to provide a more
friendly API.

Expand All @@ -36,8 +36,6 @@ export const ENV = {
*/
EXTEND_PROTOTYPES: {
Array: true,
Function: true,
Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two commits in this PR, and the first makes this unrelated change to remove Function from this list and docs. The code deletion for function methods on prototype was done at #19663 but this removal was missed.

String: true,
},

/**
Expand Down Expand Up @@ -218,12 +216,9 @@ export const ENV = {
let { EXTEND_PROTOTYPES } = EmberENV;
if (EXTEND_PROTOTYPES !== undefined) {
if (typeof EXTEND_PROTOTYPES === 'object' && EXTEND_PROTOTYPES !== null) {
ENV.EXTEND_PROTOTYPES.String = EXTEND_PROTOTYPES.String !== false;
ENV.EXTEND_PROTOTYPES.Array = EXTEND_PROTOTYPES.Array !== false;
} else {
let isEnabled = EXTEND_PROTOTYPES !== false;
ENV.EXTEND_PROTOTYPES.String = isEnabled;
ENV.EXTEND_PROTOTYPES.Array = isEnabled;
ENV.EXTEND_PROTOTYPES.Array = EXTEND_PROTOTYPES !== false;
}
}

Expand Down
40 changes: 0 additions & 40 deletions packages/@ember/-internals/glimmer/tests/utils/string-test.js
@@ -1,5 +1,4 @@
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
import { ENV } from '@ember/-internals/environment';

import { SafeString, htmlSafe, isHTMLSafe } from './helpers';

Expand All @@ -12,19 +11,6 @@ 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 <b>bold</b>'.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);

Expand All @@ -38,32 +24,6 @@ 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);
}
}
}
);

Expand Down
142 changes: 1 addition & 141 deletions packages/@ember/string/index.ts
Expand Up @@ -4,7 +4,6 @@

export { getStrings as _getStrings, setStrings as _setStrings } from './lib/string_registry';

import { ENV } from '@ember/-internals/environment';
import { Cache } from '@ember/-internals/utils';
import { deprecate } from '@ember/debug';

Expand Down Expand Up @@ -73,17 +72,14 @@ const DECAMELIZE_CACHE = new Cache<string, string>(1000, (str) =>

/**
Defines string helper methods including string formatting and localization.
Unless `EmberENV.EXTEND_PROTOTYPES.String` is `false` these methods will also be
added to the `String.prototype` as well.

@class String
@public
*/

/**
Splits a string into separate units separated by spaces, eliminating any
empty strings in the process. This is a convenience method for split that
is mostly useful when applied to the `String.prototype`.
empty strings in the process.

```javascript
import { w } from '@ember/string';
Expand Down Expand Up @@ -267,139 +263,3 @@ export function isHTMLSafe(str: any | null | undefined): str is SafeString {

return internalIsHtmlSafe(str);
}

if (ENV.EXTEND_PROTOTYPES.String) {
let deprecateEmberStringPrototypeExtension = function (
name: string,
fn: (utility: string, ...options: any) => string | string[],
message = `String prototype extensions are deprecated. Please import ${name} from '@ember/string' instead.`
) {
return function (this: string) {
deprecate(message, false, {
id: 'ember-string.prototype-extensions',
for: 'ember-source',
since: {
enabled: '3.24',
},
until: '4.0.0',
url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-string-prototype_extensions',
});

return fn(this, ...arguments);
};
};

Object.defineProperties(String.prototype, {
/**
See [String.w](/ember/release/classes/String/methods/w?anchor=w).

@method w
@for @ember/string
@static
@private
@deprecated
*/
w: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('w', w),
},

/**
See [String.camelize](/ember/release/classes/String/methods/camelize?anchor=camelize).

@method camelize
@for @ember/string
@static
@private
@deprecated
*/
camelize: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('camelize', camelize),
},

/**
See [String.decamelize](/ember/release/classes/String/methods/decamelize?anchor=decamelize).

@method decamelize
@for @ember/string
@static
@private
@deprecated
*/
decamelize: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('decamelize', decamelize),
},

/**
See [String.dasherize](/ember/release/classes/String/methods/dasherize?anchor=dasherize).

@method dasherize
@for @ember/string
@static
@private
@deprecated
*/
dasherize: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('dasherize', dasherize),
},

/**
See [String.underscore](/ember/release/classes/String/methods/underscore?anchor=underscore).

@method underscore
@for @ember/string
@static
@private
@deprecated
*/
underscore: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('underscore', underscore),
},

/**
See [String.classify](/ember/release/classes/String/methods/classify?anchor=classify).

@method classify
@for @ember/string
@static
@private
@deprecated
*/
classify: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('classify', classify),
},

/**
See [String.capitalize](/ember/release/classes/String/methods/capitalize?anchor=capitalize).

@method capitalize
@for @ember/string
@static
@private
@deprecated
*/
capitalize: {
configurable: true,
enumerable: false,
writeable: true,
value: deprecateEmberStringPrototypeExtension('capitalize', capitalize),
},
});
}
17 changes: 0 additions & 17 deletions packages/@ember/string/tests/camelize_test.js
@@ -1,30 +1,13 @@
import { ENV } from '@ember/-internals/environment';
import { camelize } from '@ember/string';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';

function test(assert, given, expected, description) {
assert.deepEqual(camelize(given), expected, description);
if (ENV.EXTEND_PROTOTYPES.String) {
expectDeprecation(() => {
assert.deepEqual(given.camelize(), expected, description);
}, /String prototype extensions are deprecated/);
}
}

moduleFor(
'EmberStringUtils.camelize',
class extends AbstractTestCase {
['@test String.prototype.camelize is not modified without EXTEND_PROTOTYPES'](assert) {
if (!ENV.EXTEND_PROTOTYPES.String) {
assert.ok(
'undefined' === typeof String.prototype.camelize,
'String.prototype helper disabled'
);
} else {
assert.expect(0);
}
}

['@test String camelize tests'](assert) {
test(assert, 'my favorite items', 'myFavoriteItems', 'camelize normal string');
test(assert, 'I Love Ramen', 'iLoveRamen', 'camelize capitalized string');
Expand Down
17 changes: 0 additions & 17 deletions packages/@ember/string/tests/capitalize_test.js
@@ -1,30 +1,13 @@
import { ENV } from '@ember/-internals/environment';
import { capitalize } from '@ember/string';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';

function test(assert, given, expected, description) {
assert.deepEqual(capitalize(given), expected, description);
if (ENV.EXTEND_PROTOTYPES.String) {
expectDeprecation(() => {
assert.deepEqual(given.capitalize(), expected, description);
}, /String prototype extensions are deprecated/);
}
}

moduleFor(
'EmberStringUtils.capitalize',
class extends AbstractTestCase {
['@test String.prototype.capitalize is not modified without EXTEND_PROTOTYPES'](assert) {
if (!ENV.EXTEND_PROTOTYPES.String) {
assert.ok(
'undefined' === typeof String.prototype.capitalize,
'String.prototype helper disabled'
);
} else {
assert.expect(0);
}
}

['@test String capitalize tests'](assert) {
test(assert, 'my favorite items', 'My favorite items', 'capitalize normal string');
test(assert, 'css-class-name', 'Css-class-name', 'capitalize dasherized string');
Expand Down
17 changes: 0 additions & 17 deletions packages/@ember/string/tests/classify_test.js
@@ -1,30 +1,13 @@
import { ENV } from '@ember/-internals/environment';
import { classify } from '@ember/string';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';

function test(assert, given, expected, description) {
assert.deepEqual(classify(given), expected, description);
if (ENV.EXTEND_PROTOTYPES.String) {
expectDeprecation(() => {
assert.deepEqual(given.classify(), expected, description);
}, /String prototype extensions are deprecated/);
}
}

moduleFor(
'EmberStringUtils.classify',
class extends AbstractTestCase {
['@test String.prototype.classify is not modified without EXTEND_PROTOTYPES'](assert) {
if (!ENV.EXTEND_PROTOTYPES.String) {
assert.ok(
'undefined' === typeof String.prototype.classify,
'String.prototype helper disabled'
);
} else {
assert.expect(0);
}
}

['@test String classify tests'](assert) {
test(assert, 'my favorite items', 'MyFavoriteItems', 'classify normal string');
test(assert, 'css-class-name', 'CssClassName', 'classify dasherized string');
Expand Down
17 changes: 0 additions & 17 deletions packages/@ember/string/tests/dasherize_test.js
@@ -1,30 +1,13 @@
import { ENV } from '@ember/-internals/environment';
import { dasherize } from '@ember/string';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';

function test(assert, given, expected, description) {
assert.deepEqual(dasherize(given), expected, description);
if (ENV.EXTEND_PROTOTYPES.String) {
expectDeprecation(() => {
assert.deepEqual(given.dasherize(), expected, description);
}, /String prototype extensions are deprecated/);
}
}

moduleFor(
'EmberStringUtils.dasherize',
class extends AbstractTestCase {
['@test String.prototype.dasherize is not modified without EXTEND_PROTOTYPES'](assert) {
if (!ENV.EXTEND_PROTOTYPES.String) {
assert.ok(
'undefined' === typeof String.prototype.dasherize,
'String.prototype helper disabled'
);
} else {
assert.expect(0);
}
}

['@test String dasherize tests'](assert) {
test(assert, 'my favorite items', 'my-favorite-items', 'dasherize normal string');
test(assert, 'css-class-name', 'css-class-name', 'does nothing with dasherized string');
Expand Down