Skip to content

Commit

Permalink
[FEATURE ember-string-ishtmlsafe] Added Ember.String.isHtmlSafe (embe…
Browse files Browse the repository at this point in the history
…rjs/rfcs#139). Reintroduced deprecation of `new Ember.Handlebars.SafeString()`.
  • Loading branch information
Wesley Workman authored and toddjordan committed Sep 9, 2016
1 parent 7be41f7 commit 20080fc
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 28 deletions.
14 changes: 13 additions & 1 deletion FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,17 @@ for a detailed explanation.

* `ember-runtime-enumerable-includes`

Deprecates `Enumerable#contains` and `Array#contains` in favor of `Enumerable#includes` and `Array#includes`
Deprecates `Enumerable#contains` and `Array#contains` in favor of `Enumerable#includes` and `Array#includes`
to stay in line with ES standards (see [RFC](https://github.com/emberjs/rfcs/blob/master/text/0136-contains-to-includes.md)).

* `ember-string-ishtmlsafe`

Introduces an API to detect if strings are decorated as htmlSafe. Example:

```javascript
var plainString = 'plain string',
safeString = Ember.String.htmlSafe('<div>someValue</div>');

Ember.String.isHtmlSafe(plainString); // false
Ember.String.isHtmlSafe(safeString); // true
```
3 changes: 2 additions & 1 deletion features.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"ember-glimmer": null,
"ember-runtime-computed-uniq-by": true,
"ember-improved-instrumentation": null,
"ember-runtime-enumerable-includes": null
"ember-runtime-enumerable-includes": null,
"ember-string-ishtmlsafe": null
}
}
32 changes: 32 additions & 0 deletions packages/ember-glimmer/tests/compat/safe-string-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import EmberHandlebars from 'ember-htmlbars/compat';
import { isHtmlSafe } from 'ember-htmlbars/utils/string';
import { TestCase } from '../utils/abstract-test-case';
import { moduleFor } from '../utils/test-case';


moduleFor('compat - SafeString', class extends TestCase {
['@test using new results in a deprecation']() {
let result;

expectDeprecation(() => {
result = new EmberHandlebars.SafeString('<b>test</b>');
}, 'Ember.Handlebars.SafeString is deprecated in favor of Ember.String.htmlSafe');

this.assert.equal(result.toHTML(), '<b>test</b>');

// Ensure this functionality is maintained for backwards compat, but also deprecated.
expectDeprecation(() => {
this.assert.ok(result instanceof EmberHandlebars.SafeString);
}, 'Ember.Handlebars.SafeString is deprecated in favor of Ember.String.htmlSafe');
}

['@test isHtmlSafe should detect SafeString']() {
let safeString;

expectDeprecation(() => {
safeString = new EmberHandlebars.SafeString('<b>test</b>');
}, 'Ember.Handlebars.SafeString is deprecated in favor of Ember.String.htmlSafe');

this.assert.ok(isHtmlSafe(safeString));
}
});
45 changes: 45 additions & 0 deletions packages/ember-glimmer/tests/utils/string-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import SafeString from 'htmlbars-util/safe-string';
import { htmlSafe, isHtmlSafe } from 'ember-htmlbars/utils/string';
import isEnabled from 'ember-metal/features';
import { TestCase } from './abstract-test-case';
import { moduleFor } from './test-case';

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

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

['@test htmlSafe should return an empty string for null']() {
let safeString = htmlSafe(null);

this.assert.equal(safeString instanceof SafeString, true, 'should be a SafeString');
this.assert.equal(safeString.toString(), '', 'should return an empty string');
}

['@test htmlSafe should return an instance of SafeString']() {
let safeString = htmlSafe();

this.assert.equal(safeString instanceof SafeString, true, 'should be a SafeString');
this.assert.equal(safeString.toString(), '', 'should return an empty string');
}
});

if (isEnabled('ember-string-ishtmlsafe')) {
moduleFor('SafeString isHtmlSafe', class extends TestCase {
['@test isHtmlSafe should detect SafeString']() {
let safeString = htmlSafe('<em>Emphasize</em> the important things.');

this.assert.ok(isHtmlSafe(safeString));
}

['@test isHtmlSafe should not detect SafeString on primatives']() {
this.assert.notOk(isHtmlSafe('Hello World'));
this.assert.notOk(isHtmlSafe({}));
this.assert.notOk(isHtmlSafe([]));
this.assert.notOk(isHtmlSafe(10));
this.assert.notOk(isHtmlSafe(null));
}
});
}
19 changes: 17 additions & 2 deletions packages/ember-htmlbars/lib/compat.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import Ember from 'ember-metal/core'; // for Handlebars export
import { deprecate } from 'ember-metal/debug';
import {
SafeString,
escapeExpression
} from 'ember-htmlbars/utils/string';

const EmberHandlebars = Ember.Handlebars = Ember.Handlebars || {};
let EmberHandlebars = Ember.Handlebars = Ember.Handlebars || {};
Object.defineProperty(EmberHandlebars, 'SafeString', {
get() {
deprecate(
'Ember.Handlebars.SafeString is deprecated in favor of Ember.String.htmlSafe',
false,
{
id: 'ember-htmlbars.ember-handlebars-safestring',
until: '3.0.0',
url: 'http://emberjs.com/deprecations/v2.x#toc_use-ember-string-htmlsafe-over-ember-handlebars-safestring'
}
);

return SafeString;
}
});

EmberHandlebars.SafeString = SafeString;
EmberHandlebars.Utils = {
escapeExpression: escapeExpression
};
Expand Down
27 changes: 27 additions & 0 deletions packages/ember-htmlbars/lib/utils/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { ENV } from 'ember-environment';
import EmberStringUtils from 'ember-runtime/system/string';
import { SafeString, escapeExpression } from 'htmlbars-util';
import isEnabled from 'ember-metal/features';

/**
Mark a string as safe for unescaped output with Ember templates. If you
Expand Down Expand Up @@ -38,8 +39,34 @@ if (ENV.EXTEND_PROTOTYPES.String) {
};
}

/**
Detects if a string was decorated using `Ember.String.htmlSafe`.
```javascript
var plainString = 'plain string',
safeString = Ember.String.htmlSafe('<div>someValue</div>');
Ember.String.isHtmlSafe(plainString); // false
Ember.String.isHtmlSafe(safeString); // true
```
@method isHtmlSafe
@for Ember.String
@static
@return {Boolean} `true` if the string was decorated with `htmlSafe`, `false` otherwise.
@public
*/
function isHtmlSafe(str) {
return str && typeof str.toHTML === 'function';
}

if (isEnabled('ember-string-ishtmlsafe')) {
EmberStringUtils.isHtmlSafe = isHtmlSafe;
}

export {
SafeString,
htmlSafe,
isHtmlSafe,
escapeExpression
};
1 change: 1 addition & 0 deletions packages/ember-htmlbars/tests/compat/safe-string-test.js
1 change: 1 addition & 0 deletions packages/ember-htmlbars/tests/utils/string-test.js
24 changes: 0 additions & 24 deletions packages/ember-htmlbars/tests/utils/string_test.js

This file was deleted.

0 comments on commit 20080fc

Please sign in to comment.