ember-source 4.4.0-alpha.7 → 4.5.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  @module @ember/application
3
3
  */
4
- import { get, set, computed } from '@ember/-internals/metal';
4
+ import { get, set } from '@ember/-internals/metal';
5
5
  import * as environment from '@ember/-internals/browser-environment';
6
6
  import EngineInstance from '@ember/engine/instance';
7
7
  import { renderSettled } from '@ember/-internals/glimmer';
8
+ import { assert } from '@ember/debug';
9
+ import { Router } from '@ember/-internals/routing';
10
+ import { EventDispatcher } from '@ember/-internals/views';
8
11
  /**
9
12
  The `ApplicationInstance` encapsulates all of the stateful aspects of a
10
13
  running `Application`.
@@ -30,35 +33,21 @@ import { renderSettled } from '@ember/-internals/glimmer';
30
33
  @extends EngineInstance
31
34
  */
32
35
 
33
- const ApplicationInstance = EngineInstance.extend({
34
- /**
35
- The `Application` for which this is an instance.
36
- @property {Application} application
37
- @private
38
- */
39
- application: null,
40
-
41
- /**
42
- The DOM events for which the event dispatcher should listen.
43
- By default, the application's `Ember.EventDispatcher` listens
44
- for a set of standard DOM events, such as `mousedown` and
45
- `keyup`, and delegates them to your application's `Ember.View`
46
- instances.
47
- @private
48
- @property {Object} customEvents
49
- */
50
- customEvents: null,
36
+ class ApplicationInstance extends EngineInstance {
37
+ constructor() {
38
+ super(...arguments);
39
+ /**
40
+ The root DOM element of the Application as an element or a
41
+ CSS selector.
42
+ @private
43
+ @property {String|DOMElement} rootElement
44
+ */
51
45
 
52
- /**
53
- The root DOM element of the Application as an element or a
54
- CSS selector.
55
- @private
56
- @property {String|DOMElement} rootElement
57
- */
58
- rootElement: null,
46
+ this.rootElement = null;
47
+ }
59
48
 
60
- init() {
61
- this._super(...arguments);
49
+ init(properties) {
50
+ super.init(properties);
62
51
 
63
52
  this.application._watchInstance(this); // Register this instance in the per-instance registry.
64
53
  //
@@ -72,25 +61,26 @@ const ApplicationInstance = EngineInstance.extend({
72
61
  this.register('-application-instance:main', this, {
73
62
  instantiate: false
74
63
  });
75
- },
76
-
64
+ }
77
65
  /**
78
66
  Overrides the base `EngineInstance._bootSync` method with concerns relevant
79
67
  to booting application (instead of engine) instances.
80
- This method should only contain synchronous boot concerns. Asynchronous
68
+ This method should only contain synchronous boot concerns. Asynchronous
81
69
  boot concerns should eventually be moved to the `boot` method, which
82
70
  returns a promise.
83
- Until all boot code has been made asynchronous, we need to continue to
71
+ Until all boot code has been made asynchronous, we need to continue to
84
72
  expose this method for use *internally* in places where we need to boot an
85
73
  instance synchronously.
86
- @private
74
+ @private
87
75
  */
76
+
77
+
88
78
  _bootSync(options) {
89
79
  if (this._booted) {
90
80
  return this;
91
81
  }
92
82
 
93
- options = new BootOptions(options);
83
+ options = new _BootOptions(options);
94
84
  this.setupRegistry(options);
95
85
 
96
86
  if (options.rootElement) {
@@ -111,93 +101,104 @@ const ApplicationInstance = EngineInstance.extend({
111
101
 
112
102
  this._booted = true;
113
103
  return this;
114
- },
104
+ }
115
105
 
116
106
  setupRegistry(options) {
117
107
  this.constructor.setupRegistry(this.__registry__, options);
118
- },
108
+ }
119
109
 
120
- router: computed(function () {
121
- return this.lookup('router:main');
122
- }).readOnly(),
110
+ get router() {
111
+ if (!this._router) {
112
+ let router = this.lookup('router:main');
113
+ assert('expected an instance of Router', router instanceof Router);
114
+ this._router = router;
115
+ }
123
116
 
117
+ return this._router;
118
+ }
124
119
  /**
125
120
  This hook is called by the root-most Route (a.k.a. the ApplicationRoute)
126
121
  when it has finished creating the root View. By default, we simply take the
127
122
  view and append it to the `rootElement` specified on the Application.
128
- In cases like FastBoot and testing, we can override this hook and implement
123
+ In cases like FastBoot and testing, we can override this hook and implement
129
124
  custom behavior, such as serializing to a string and sending over an HTTP
130
125
  socket rather than appending to DOM.
131
- @param view {Ember.View} the root-most view
126
+ @param view {Ember.View} the root-most view
132
127
  @deprecated
133
128
  @private
134
129
  */
130
+
131
+
135
132
  didCreateRootView(view) {
136
133
  view.appendTo(this.rootElement);
137
- },
138
-
134
+ }
139
135
  /**
140
136
  Tells the router to start routing. The router will ask the location for the
141
137
  current URL of the page to determine the initial URL to start routing to.
142
138
  To start the app at a specific URL, call `handleURL` instead.
143
- @private
139
+ @private
144
140
  */
141
+
142
+
145
143
  startRouting() {
146
144
  this.router.startRouting();
147
- },
148
-
145
+ }
149
146
  /**
150
147
  Sets up the router, initializing the child router and configuring the
151
148
  location before routing begins.
152
- Because setup should only occur once, multiple calls to `setupRouter`
149
+ Because setup should only occur once, multiple calls to `setupRouter`
153
150
  beyond the first call have no effect.
154
- This is commonly used in order to confirm things that rely on the router
151
+ This is commonly used in order to confirm things that rely on the router
155
152
  are functioning properly from tests that are primarily rendering related.
156
- For example, from within [ember-qunit](https://github.com/emberjs/ember-qunit)'s
153
+ For example, from within [ember-qunit](https://github.com/emberjs/ember-qunit)'s
157
154
  `setupRenderingTest` calling `this.owner.setupRouter()` would allow that
158
155
  rendering test to confirm that any `<LinkTo></LinkTo>`'s that are rendered
159
156
  have the correct URL.
160
- @public
157
+ @public
161
158
  */
159
+
160
+
162
161
  setupRouter() {
163
162
  this.router.setupRouter();
164
- },
165
-
163
+ }
166
164
  /**
167
165
  Directs the router to route to a particular URL. This is useful in tests,
168
166
  for example, to tell the app to start at a particular URL.
169
- @param url {String} the URL the router should route to
167
+ @param url {String} the URL the router should route to
170
168
  @private
171
169
  */
170
+
171
+
172
172
  handleURL(url) {
173
173
  this.setupRouter();
174
174
  return this.router.handleURL(url);
175
- },
176
-
175
+ }
177
176
  /**
178
177
  @private
179
178
  */
179
+
180
+
180
181
  setupEventDispatcher() {
181
182
  let dispatcher = this.lookup('event_dispatcher:main');
183
+ assert('expected EventDispatcher', dispatcher instanceof EventDispatcher);
182
184
  let applicationCustomEvents = get(this.application, 'customEvents');
183
185
  let instanceCustomEvents = get(this, 'customEvents');
184
186
  let customEvents = Object.assign({}, applicationCustomEvents, instanceCustomEvents);
185
187
  dispatcher.setup(customEvents, this.rootElement);
186
188
  return dispatcher;
187
- },
188
-
189
+ }
189
190
  /**
190
191
  Returns the current URL of the app instance. This is useful when your
191
192
  app does not update the browsers URL bar (i.e. it uses the `'none'`
192
193
  location adapter).
193
- @public
194
+ @public
194
195
  @return {String} the current URL
195
196
  */
197
+
198
+
196
199
  getURL() {
197
200
  return this.router.url;
198
- },
199
-
200
- // `instance.visit(url)` should eventually replace `instance.handleURL()`;
201
+ } // `instance.visit(url)` should eventually replace `instance.handleURL()`;
201
202
  // the test helpers can probably be switched to use this implementation too
202
203
 
203
204
  /**
@@ -205,10 +206,12 @@ const ApplicationInstance = EngineInstance.extend({
205
206
  example, or to tell the app to start at a particular URL. This method
206
207
  returns a promise that resolves with the app instance when the transition
207
208
  is complete, or rejects if the transion was aborted due to an error.
208
- @public
209
+ @public
209
210
  @param url {String} the destination URL
210
211
  @return {Promise<ApplicationInstance>}
211
212
  */
213
+
214
+
212
215
  visit(url) {
213
216
  this.setupRouter();
214
217
 
@@ -238,43 +241,39 @@ const ApplicationInstance = EngineInstance.extend({
238
241
  }
239
242
  };
240
243
 
241
- let location = get(router, 'location'); // Keeps the location adapter's internal URL in-sync
244
+ let location = get(router, 'location');
245
+ assert('location has been initialized', typeof location !== 'string'); // Keeps the location adapter's internal URL in-sync
242
246
 
243
247
  location.setURL(url); // getURL returns the set url with the rootURL stripped off
244
248
 
245
249
  return router.handleURL(location.getURL()).then(handleTransitionResolve, handleTransitionReject);
246
- },
250
+ }
247
251
 
248
252
  willDestroy() {
249
- this._super(...arguments);
253
+ super.willDestroy();
250
254
 
251
255
  this.application._unwatchInstance(this);
252
256
  }
253
-
254
- });
255
- ApplicationInstance.reopenClass({
256
257
  /**
257
258
  @private
258
259
  @method setupRegistry
259
260
  @param {Registry} registry
260
261
  @param {BootOptions} options
261
262
  */
262
- setupRegistry(registry, options = {}) {
263
- if (!options.toEnvironment) {
264
- options = new BootOptions(options);
265
- }
266
263
 
267
- registry.register('-environment:main', options.toEnvironment(), {
264
+
265
+ static setupRegistry(registry, options = {}) {
266
+ let coptions = options instanceof _BootOptions ? options : new _BootOptions(options);
267
+ registry.register('-environment:main', coptions.toEnvironment(), {
268
268
  instantiate: false
269
269
  });
270
- registry.register('service:-document', options.document, {
270
+ registry.register('service:-document', coptions.document, {
271
271
  instantiate: false
272
272
  });
273
-
274
- this._super(registry, options);
273
+ super.setupRegistry(registry, coptions);
275
274
  }
276
275
 
277
- });
276
+ }
278
277
  /**
279
278
  A list of boot-time configuration options for customizing the behavior of
280
279
  an `ApplicationInstance`.
@@ -298,44 +297,22 @@ ApplicationInstance.reopenClass({
298
297
  @public
299
298
  */
300
299
 
301
- class BootOptions {
302
- constructor(options = {}) {
303
- /**
304
- Interactive mode: whether we need to set up event delegation and invoke
305
- lifecycle callbacks on Components.
306
- @property isInteractive
307
- @type boolean
308
- @default auto-detected
309
- @private
310
- */
311
- this.isInteractive = Boolean(environment.hasDOM); // This default is overridable below
312
300
 
301
+ class _BootOptions {
302
+ constructor(options = {}) {
313
303
  /**
314
- @property _renderMode
304
+ If present, overrides the router's `location` property with this
305
+ value. This is useful for environments where trying to modify the
306
+ URL would be inappropriate.
307
+ @property location
315
308
  @type string
316
- @default undefined
317
- @private
309
+ @default null
310
+ @public
318
311
  */
312
+ this.location = null;
313
+ this.isInteractive = Boolean(environment.hasDOM); // This default is overridable below
319
314
 
320
315
  this._renderMode = options._renderMode;
321
- /**
322
- Run in a full browser environment.
323
- When this flag is set to `false`, it will disable most browser-specific
324
- and interactive features. Specifically:
325
- * It does not use `jQuery` to append the root view; the `rootElement`
326
- (either specified as a subsequent option or on the application itself)
327
- must already be an `Element` in the given `document` (as opposed to a
328
- string selector).
329
- * It does not set up an `EventDispatcher`.
330
- * It does not run any `Component` lifecycle hooks (such as `didInsertElement`).
331
- * It sets the `location` option to `"none"`. (If you would like to use
332
- the location adapter specified in the app's router instead, you can also
333
- specify `{ location: null }` to specifically opt-out.)
334
- @property isBrowser
335
- @type boolean
336
- @default auto-detected
337
- @public
338
- */
339
316
 
340
317
  if (options.isBrowser !== undefined) {
341
318
  this.isBrowser = Boolean(options.isBrowser);
@@ -347,17 +324,6 @@ class BootOptions {
347
324
  this.isInteractive = false;
348
325
  this.location = 'none';
349
326
  }
350
- /**
351
- Disable rendering completely.
352
- When this flag is set to `false`, it will disable the entire rendering
353
- pipeline. Essentially, this puts the app into "routing-only" mode. No
354
- templates will be rendered, and no Components will be created.
355
- @property shouldRender
356
- @type boolean
357
- @default true
358
- @public
359
- */
360
-
361
327
 
362
328
  if (options.shouldRender !== undefined) {
363
329
  this.shouldRender = Boolean(options.shouldRender);
@@ -368,46 +334,12 @@ class BootOptions {
368
334
  if (!this.shouldRender) {
369
335
  this.isInteractive = false;
370
336
  }
371
- /**
372
- If present, render into the given `Document` object instead of the
373
- global `window.document` object.
374
- In practice, this is only useful in non-browser environment or in
375
- non-interactive mode, because Ember's `jQuery` dependency is
376
- implicitly bound to the current document, causing event delegation
377
- to not work properly when the app is rendered into a foreign
378
- document object (such as an iframe's `contentDocument`).
379
- In non-browser mode, this could be a "`Document`-like" object as
380
- Ember only interact with a small subset of the DOM API in non-
381
- interactive mode. While the exact requirements have not yet been
382
- formalized, the `SimpleDOM` library's implementation is known to
383
- work.
384
- @property document
385
- @type Document
386
- @default the global `document` object
387
- @public
388
- */
389
-
390
337
 
391
338
  if (options.document) {
392
339
  this.document = options.document;
393
340
  } else {
394
341
  this.document = typeof document !== 'undefined' ? document : null;
395
342
  }
396
- /**
397
- If present, overrides the application's `rootElement` property on
398
- the instance. This is useful for testing environment, where you
399
- might want to append the root view to a fixture area.
400
- In non-browser mode, because Ember does not have access to jQuery,
401
- this options must be specified as a DOM `Element` object instead of
402
- a selector string.
403
- See the documentation on `Application`'s `rootElement` for
404
- details.
405
- @property rootElement
406
- @type String|Element
407
- @default null
408
- @public
409
- */
410
-
411
343
 
412
344
  if (options.rootElement) {
413
345
  this.rootElement = options.rootElement;
@@ -415,16 +347,6 @@ class BootOptions {
415
347
  // defaults from the "combo" options like `isBrowser` (although in
416
348
  // practice, the resulting combination is probably invalid)
417
349
 
418
- /**
419
- If present, overrides the router's `location` property with this
420
- value. This is useful for environments where trying to modify the
421
- URL would be inappropriate.
422
- @property location
423
- @type string
424
- @default null
425
- @public
426
- */
427
-
428
350
 
429
351
  if (options.location !== undefined) {
430
352
  this.location = options.location;
@@ -437,13 +359,13 @@ class BootOptions {
437
359
 
438
360
  toEnvironment() {
439
361
  // Do we really want to assign all of this!?
440
- let env = Object.assign({}, environment); // For compatibility with existing code
441
-
442
- env.hasDOM = this.isBrowser;
443
- env.isInteractive = this.isInteractive;
444
- env._renderMode = this._renderMode;
445
- env.options = this;
446
- return env;
362
+ return Object.assign(Object.assign({}, environment), {
363
+ // For compatibility with existing code
364
+ hasDOM: this.isBrowser,
365
+ isInteractive: this.isInteractive,
366
+ _renderMode: this._renderMode,
367
+ options: this
368
+ });
447
369
  }
448
370
 
449
371
  }