File tree Expand file tree Collapse file tree 5 files changed +157
-1
lines changed Expand file tree Collapse file tree 5 files changed +157
-1
lines changed Original file line number Diff line number Diff line change @@ -15,6 +15,8 @@ module.exports = {
15
15
'ember-best-practices/no-attrs' : 2 ,
16
16
'ember-best-practices/no-observers' : 2 ,
17
17
'ember-best-practices/require-dependent-keys' : 2 ,
18
- 'ember-best-practices/no-lifecycle-events' : 2
18
+ 'ember-best-practices/no-lifecycle-events' : 2 ,
19
+ 'ember-best-practices/no-timers' : 2 ,
20
+ 'ember-best-practices/no-unguarded-document' : 2
19
21
}
20
22
} ;
Original file line number Diff line number Diff line change 1
1
# No Timers
2
2
3
+ ** TL;DR: You should avoid using timers in favor of Ember.later**
4
+
5
+ In general, it's best to avoid the use of ` setTimeout ` and ` setInterval ` in Ember.
6
+
7
+ From the Ember documentation:
8
+
9
+ > You should use this method whenever you need to run some action after a period of time instead of
10
+ using setTimeout(). This method will ensure that items that expire during the same script execution
11
+ cycle all execute together, which is often more efficient than using a real setTimeout.
12
+
13
+ While ` setTimeout ` maps to ` Ember.run.later ` , there isn't a direct equivalent of ` setInterval ` . You
14
+ can accomplish the rough equivalent of ` setInterval ` by using a recursive ` setTimeout ` .
15
+
16
+ Example:
17
+
18
+ ``` js
19
+ Ember .Component .extend ({
20
+ init () {
21
+ this ._super (... arguments );
22
+ this .intervalToken = this .schedule (() => alert (' Alert' ));
23
+ this .interval = 1000 ;
24
+ }
25
+
26
+ schedule (fn ) {
27
+ return Ember .run .later (() => {
28
+ fn ()
29
+ this .set (' intervalToken' , this .schedule (fn));
30
+ }, this .interval );
31
+ }
32
+
33
+ willDestroy () {
34
+ this ._super (... arguments );
35
+ Ember .run .cancel (this .intervalToken );
36
+ }
37
+ });
38
+ ```
Original file line number Diff line number Diff line change
1
+ # No Unguarded Document References
2
+
3
+ ** TL;DR: Ensure that all document references are guarded inside an if block with the condition ` environment.isBrowser() ` **
4
+
5
+ Unguarded document references will break when used with FastBoot. This is due to the Node environment
6
+ not having a global ` document ` object.
7
+
8
+ To protect against errors during server side rendering, you should ensure you're guarding the usages
9
+ of ` document ` with a check to ` environment.isBrowser() ` .
10
+
11
+ Example:
12
+
13
+ ``` js
14
+ import Ember from ' ember' ;
15
+
16
+ Ember .component .extend ({
17
+ init () {
18
+ if (environment .isBrowser ()) {
19
+ this .element = document .querySelector (' .my-element' );
20
+ }
21
+ }
22
+ });
23
+ ```
Original file line number Diff line number Diff line change
1
+ const { isGuarded } = require ( '../utils/fast-boot' ) ;
2
+
3
+ const MESSAGE = 'Do not use unguarded document references. Please see the following guide for more infromation: http://github.com/chadhietala/ember-best-practices/files/guides/no-unguarded-document.md' ;
4
+
5
+ function isDocumentReference ( node ) {
6
+ return node . callee . object . name === 'document' ;
7
+ }
8
+
9
+ module . exports = {
10
+ meta : {
11
+ message : MESSAGE
12
+ } ,
13
+ create ( context ) {
14
+ return {
15
+ CallExpression ( node ) {
16
+ if ( isDocumentReference ( node ) && ! isGuarded ( node ) ) {
17
+ context . report ( node , MESSAGE ) ;
18
+ }
19
+ }
20
+ } ;
21
+ }
22
+ } ;
Original file line number Diff line number Diff line change
1
+ const rule = require ( '../../../lib/rules/no-unguarded-document' ) ;
2
+ const MESSAGE = rule . meta . message ;
3
+ const RuleTester = require ( 'eslint' ) . RuleTester ;
4
+ const ruleTester = new RuleTester ( ) ;
5
+
6
+ ruleTester . run ( 'no-timers' , rule , {
7
+ valid : [
8
+ {
9
+ code : `
10
+ export default Ember.Component.extend({
11
+ actions: {
12
+ foo() {
13
+ if (environment.isBrowser()) {
14
+ const node = document.querySelector('blah');
15
+ }
16
+ }
17
+ }
18
+ });` ,
19
+ parserOptions : {
20
+ ecmaVersion : 6 ,
21
+ sourceType : 'module'
22
+ }
23
+ } ,
24
+ {
25
+ code : `
26
+ export default Ember.Component.extend({
27
+ guarded() {
28
+ if (environment.isBrowser()) {
29
+ const node = document.querySelector('blah');
30
+ }
31
+ }
32
+ });` ,
33
+ parserOptions : {
34
+ ecmaVersion : 6 ,
35
+ sourceType : 'module'
36
+ }
37
+ }
38
+ ] ,
39
+ invalid : [
40
+ {
41
+ code : `
42
+ export default Ember.Component({
43
+ actions: {
44
+ bar() {
45
+ const node = document.querySelector('blah');
46
+ }
47
+ }
48
+ });` ,
49
+ parserOptions : {
50
+ ecmaVersion : 6 ,
51
+ sourceType : 'module'
52
+ } ,
53
+ errors : [ {
54
+ message : MESSAGE
55
+ } ]
56
+ } ,
57
+ {
58
+ code : `
59
+ export default Ember.Component({
60
+ baz() {
61
+ const node = document.querySelector('blah');
62
+ }
63
+ });` ,
64
+ parserOptions : {
65
+ ecmaVersion : 6 ,
66
+ sourceType : 'module'
67
+ } ,
68
+ errors : [ {
69
+ message : MESSAGE
70
+ } ]
71
+ }
72
+ ]
73
+ } ) ;
You can’t perform that action at this time.
0 commit comments