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

[DEPRECATION canary] Deprecate Ember.String and prototype extension #15739

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ember-application/lib/system/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { dictionary } from 'ember-utils';
import { get, findNamespace } from 'ember-metal';
import { assert, info } from 'ember-debug';
import { String as StringUtils, Object as EmberObject } from 'ember-runtime';
import { StringUtils, Object as EmberObject } from 'ember-runtime';
import validateType from '../utils/validate-type';
import { getTemplate } from 'ember-glimmer';
import { DEBUG } from 'ember-env-flags';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
A as emberA,
typeOf,
String as StringUtils,
Namespace,
Object as EmberObject,
} from 'ember-runtime';
import { A as emberA, typeOf, StringUtils, Namespace, Object as EmberObject } from 'ember-runtime';

/**
@module @ember/debug
Expand Down
9 changes: 8 additions & 1 deletion packages/ember-glimmer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,14 @@ export { default as LinkComponent } from './lib/components/link-to';
export { default as Component, ROOT_REF } from './lib/component';
export { default as Helper, helper } from './lib/helper';
export { default as Environment } from './lib/environment';
export { SafeString, escapeExpression, htmlSafe, isHTMLSafe } from './lib/utils/string';
export {
SafeString,
deprecatedHTMLSafe,
deprecatedIsHTMLSafe,
escapeExpression,
htmlSafe,
isHTMLSafe,
} from './lib/utils/string';
export {
Renderer,
InertRenderer,
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { assert, deprecate } from 'ember-debug';
import { DEBUG } from 'ember-env-flags';
import { ENV } from 'ember-environment';
import { _instrumentStart, get } from 'ember-metal';
import { String as StringUtils } from 'ember-runtime';
import { StringUtils } from 'ember-runtime';
import { assign, getOwner, guidFor } from 'ember-utils';
import { addChildView, OwnedTemplateMeta, setViewElement } from 'ember-views';
import { BOUNDS, DIRTY_TAG, HAS_BLOCK, IS_DISPATCHING_ATTRS, ROOT_REF } from '../component';
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-glimmer/lib/helpers/-class.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Arguments, VM } from '@glimmer/runtime';
import { String as StringUtils } from 'ember-runtime';
import { StringUtils } from 'ember-runtime';
import { InternalHelperReference } from '../utils/references';

function classHelper({ positional }: any) {
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-glimmer/lib/helpers/-normalize-class.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Arguments, VM } from '@glimmer/runtime';
import { String as StringUtils } from 'ember-runtime';
import { StringUtils } from 'ember-runtime';
import { InternalHelperReference } from '../utils/references';

function normalizeClass({ positional }: any) {
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-glimmer/lib/helpers/loc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@module ember
*/

import { String as StringUtils } from 'ember-runtime';
import { StringUtils } from 'ember-runtime';
import { helper } from '../helper';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-glimmer/lib/utils/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ElementOperations, PrimitiveReference } from '@glimmer/runtime';
import { Core, Ops } from '@glimmer/wire-format';
import { assert } from 'ember-debug';
import { get } from 'ember-metal';
import { String as StringUtils } from 'ember-runtime';
import { StringUtils } from 'ember-runtime';
import { ROOT_REF } from '../component';
import { Component } from './curly-component-state-bucket';
import { referenceFromParts } from './references';
Expand Down
30 changes: 30 additions & 0 deletions packages/ember-glimmer/lib/utils/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
@module @ember/string
*/

import { deprecate } from 'ember-debug';

export class SafeString {
public string: string;

Expand Down Expand Up @@ -74,6 +76,7 @@ export function escapeExpression(string: any): string {
@static
@return {Handlebars.SafeString} A string that will not be HTML escaped by Handlebars.
@public
@deprecated
*/
export function htmlSafe(str: string) {
if (str === null || str === undefined) {
Expand All @@ -84,6 +87,19 @@ export function htmlSafe(str: string) {
return new SafeString(str);
}

export function deprecatedHTMLSafe(str: string) {
deprecate(
'Ember.String namespace is deprecated. Please, import `htmlSafe` from `@ember/template`.',
false,
{
id: 'ember-glimmer.ember-string-html-safe',
until: '3.5.0',
url: '',
}
);
return htmlSafe(str);
}

/**
Detects if a string was decorated using `htmlSafe`.

Expand All @@ -102,7 +118,21 @@ export function htmlSafe(str: string) {
@static
@return {Boolean} `true` if the string was decorated with `htmlSafe`, `false` otherwise.
@public
@deprecated
*/
export function isHTMLSafe(str: any | null | undefined): str is SafeString {
return str !== null && typeof str === 'object' && typeof str.toHTML === 'function';
}

export function deprecatedIsHTMLSafe(str: any | null | undefined): str is SafeString {
deprecate(
'Ember.String namespace is deprecated. Please, import `isHTMLSafe` from `@ember/template`.',
false,
{
id: 'ember-glimmer.ember-string-is-html-safe',
until: '3.5.0',
url: '',
}
);
return isHTMLSafe(str);
}
2 changes: 2 additions & 0 deletions packages/ember-glimmer/tests/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export {
InteractiveRender,
InertRenderer,
htmlSafe,
deprecatedHTMLSafe,
SafeString,
DOMChanges,
isHTMLSafe,
deprecatedIsHTMLSafe,
} from 'ember-glimmer';
19 changes: 18 additions & 1 deletion packages/ember-glimmer/tests/utils/string-test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import { SafeString, htmlSafe, isHTMLSafe } from './helpers';
import {
SafeString,
htmlSafe,
deprecatedHTMLSafe,
isHTMLSafe,
deprecatedIsHTMLSafe,
} from './helpers';
import { TestCase } from './abstract-test-case';
import { moduleFor } from './test-case';

moduleFor(
'SafeString',
class extends TestCase {
['@test deprecated version is deprecated']() {
expectDeprecation(/ember\/template/);
let safeString = deprecatedHTMLSafe('Hello');

this.assert.ok(safeString instanceof SafeString, 'should be a SafeString');
}

['@test htmlSafe should return an instance of SafeString']() {
let safeString = htmlSafe('you need to be more <b>bold</b>');

Expand All @@ -30,6 +43,10 @@ moduleFor(
moduleFor(
'SafeString isHTMLSafe',
class extends TestCase {
['@test deprecated version is deprecated']() {
expectDeprecation(/ember\/template/);
deprecatedIsHTMLSafe('Hello');
}
['@test isHTMLSafe should detect SafeString']() {
let safeString = htmlSafe('<em>Emphasize</em> the important things.');

Expand Down
2 changes: 1 addition & 1 deletion packages/ember-routing/lib/system/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { DEBUG } from 'ember-env-flags';
import {
typeOf,
copy,
String as StringUtils,
StringUtils,
Object as EmberObject,
A as emberA,
Evented,
Expand Down
12 changes: 12 additions & 0 deletions packages/ember-runtime/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,15 @@ export const String: {
export function isEmberArray(arr: any): boolean;

export function _contentFor(proxy: any): any;

export const StringUtils: {
fmt(s: string, ...args: any[]): string,
loc(s: string, ...args: any[]): string,
w(s: string): string[],
decamelize(s: string): string,
dasherize(s: string): string,
camelize(s: string): string,
classify(s: string): string,
underscore(s: string): string,
capitalize(s: string): string
}
53 changes: 29 additions & 24 deletions packages/ember-runtime/lib/ext/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import { ENV } from 'ember-environment';
import { deprecate } from 'ember-debug';
import {
w,
loc,
Expand All @@ -16,6 +17,23 @@ import {

const StringPrototype = String.prototype;

function deprecateEmberStringPrototypeExtension(name, fn, opts = {}) {
return function() {
deprecate(
opts.message ||
`String prototype extensions are deprecated. Please, us ${name} from '@ember/string' instead.`,
false,
opts.options || {
id: 'ember-string.prototype_extensions',
until: '3.5.0',
url: 'https://emberjs.com/deprecations/v2.x/#toc_ember-string-prototype-extensions',
}
);

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

if (ENV.EXTEND_PROTOTYPES.String) {
/**
See [String.w](/api/ember/release/classes/String/methods/w?anchor=w).
Expand All @@ -29,9 +47,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return w(this);
},
value: deprecateEmberStringPrototypeExtension('w', w),
});

/**
Expand All @@ -46,9 +62,10 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function(...args) {
return loc(this, args);
},
value: deprecateEmberStringPrototypeExtension('loc', loc, {
message:
'`loc` is deprecated. Please, use an i18n addon instead. See https://emberobserver.com/categories/internationalization for a list of them.',
}),
});

/**
Expand All @@ -63,9 +80,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return camelize(this);
},
value: deprecateEmberStringPrototypeExtension('camelize', camelize),
});

/**
Expand All @@ -80,9 +95,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return decamelize(this);
},
value: deprecateEmberStringPrototypeExtension('decamelize', decamelize),
});

/**
Expand All @@ -97,9 +110,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return dasherize(this);
},
value: deprecateEmberStringPrototypeExtension('dasherize', dasherize),
});

/**
Expand All @@ -114,9 +125,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return underscore(this);
},
value: deprecateEmberStringPrototypeExtension('underscore', underscore),
});

/**
Expand All @@ -131,9 +140,7 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return classify(this);
},
value: deprecateEmberStringPrototypeExtension('classify', classify),
});

/**
Expand All @@ -148,8 +155,6 @@ if (ENV.EXTEND_PROTOTYPES.String) {
configurable: true,
enumerable: false,
writeable: true,
value: function() {
return capitalize(this);
},
value: deprecateEmberStringPrototypeExtension('capitalize', capitalize),
});
}
2 changes: 1 addition & 1 deletion packages/ember-runtime/lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as Object, FrameworkObject } from './system/object';
export { default as String } from './system/string';
export { default as String, StringUtils } from './system/string';
export { default as RegistryProxyMixin } from './mixins/registry_proxy';
export { default as ContainerProxyMixin } from './mixins/container_proxy';
export { default as copy } from './copy';
Expand Down
Loading