Skip to content

Commit 0bb7d33

Browse files
committed
Migrate away from ember-cli-head for <title> updates
1 parent d3a8a86 commit 0bb7d33

File tree

13 files changed

+6229
-4857
lines changed

13 files changed

+6229
-4857
lines changed

README.md

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@ This addon provides a helper for changing the title of the page you're on.
88
ember install ember-page-title
99
```
1010

11-
Add `{{head-layout}}` to your application's `application.hbs` template.
12-
13-
<details>
14-
<summary>Fastboot vs Non-Fastboot Notes</summary>
15-
1611
### Compatibility
1712

1813
* Ember.js v3.12 or above
1914
* Ember CLI v2.13 or above
2015
* Node.js v10 or above
2116

17+
<details>
18+
<summary>Fastboot vs Non-Fastboot Notes</summary>
19+
2220
#### Post Install Cleanup
2321

2422
As of v3.0.0 this addon maintains the page title by using the `<title>` tag in your document's `<head>`. This is necessary for [FastBoot](https://github.com/tildeio/ember-cli-fastboot) compatibility.
@@ -60,21 +58,17 @@ module.exports = function (environment) {
6058
};
6159
```
6260

63-
### Fastboot
64-
65-
When working with other addons that use `ember-cli-head`, you'll need to create a custom `head.hbs` file that exposes the `<title>` tag properly:
66-
67-
```hbs
68-
<title>{{model.title}}</title>
69-
```
70-
71-
This file is added automatically if you use `ember install`. This is for all the folks using ember-cli-head addons like ember-cli-meta-tags.
72-
7361
### Deprecations
7462

7563
- Since **v5.2.2**: The `{{title}}` helper has been deprecated, use `{{page-title}}` instead, it has the same API. The
7664
`{{title}}` helper was an AST transform and will be removed in the next major release.
7765

66+
### Upgrading notes for 5.x to 6.x
67+
68+
`ember-page-title` no longer requires the usage of `ember-cli-head`.
69+
70+
Please remove `{{head-layout}}` from your application's `application.hbs` route template.
71+
7872
### Upgrading notes for 3.x to 4.x
7973

8074
From 4.x onward, you need to have `{{head-layout}}` within your application's `application.hbs` template. Without this, you will not see a page title appear.

addon/helpers/page-title.js

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import { scheduleOnce } from '@ember/runloop';
21
import { inject as service } from '@ember/service';
32
import Helper from '@ember/component/helper';
4-
import { set } from '@ember/object';
53
import { guidFor } from '@ember/object/internals';
64
import { assign } from '@ember/polyfills';
7-
import { getOwner } from '@ember/application';
8-
9-
function updateTitle(tokens) {
10-
set(this, 'title', tokens.toString());
11-
}
125

136
/**
147
`{{page-title}}` is used to communicate with
@@ -17,13 +10,15 @@ function updateTitle(tokens) {
1710
@method page-title
1811
*/
1912
export default Helper.extend({
20-
pageTitleList: service(),
21-
headData: service(),
13+
tokens: service('page-title-list'),
14+
15+
get tokenId() {
16+
return guidFor(this);
17+
},
2218

2319
init() {
24-
this._super();
25-
let tokens = this.pageTitleList;
26-
tokens.push({ id: guidFor(this) });
20+
this._super(...arguments);
21+
this.tokens.push({ id: this.tokenId });
2722
},
2823

2924
compute(params, _hash) {
@@ -35,33 +30,22 @@ export default Helper.extend({
3530
_hash._deprecate
3631
);
3732
}
38-
let tokens = this.pageTitleList;
39-
let hash = assign({}, _hash);
40-
hash.id = guidFor(this);
41-
hash.title = params.join('');
42-
tokens.push(hash);
43-
scheduleOnce('afterRender', this.headData, updateTitle, tokens);
33+
let hash = assign(
34+
{},
35+
_hash,
36+
{
37+
id: this.tokenId,
38+
title: params.join('')
39+
}
40+
);
41+
42+
this.tokens.push(hash);
43+
this.tokens.scheduleTitleUpdate();
4444
return '';
4545
},
4646

4747
destroy() {
48-
let tokens = this.pageTitleList;
49-
let id = guidFor(this);
50-
tokens.remove(id);
51-
52-
let router = getOwner(this).lookup('router:main');
53-
let routes = router._routerMicrolib || router.router;
54-
let { activeTransition } = routes || {};
55-
let headData = this.headData;
56-
if (activeTransition) {
57-
activeTransition.promise.finally(function () {
58-
if (headData.isDestroyed) {
59-
return;
60-
}
61-
scheduleOnce('afterRender', headData, updateTitle, tokens);
62-
});
63-
} else {
64-
scheduleOnce('afterRender', headData, updateTitle, tokens);
65-
}
48+
this.tokens.remove(this.tokenId);
49+
this.tokens.scheduleTitleUpdate();
6650
},
6751
});

addon/services/page-title-list.js

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import { A } from '@ember/array';
22
import { getOwner } from '@ember/application';
3+
import { inject as service } from '@ember/service';
4+
import { scheduleOnce } from '@ember/runloop';
35
import Service from '@ember/service';
46
import { set, computed } from '@ember/object';
57
import { copy } from 'ember-copy';
68
import { capitalize } from '@ember/string';
79
import { isPresent } from '@ember/utils';
810

11+
let isFastBoot = typeof FastBoot !== 'undefined';
12+
913
/**
1014
@class page-title-list
1115
@extends Ember.Service
1216
*/
1317
export default Service.extend({
18+
document: service('-document'),
1419

1520
init() {
1621
this._super();
1722
set(this, 'tokens', A());
18-
set(this, 'length', 0);
1923
this._removeExistingTitleTag();
2024

2125
let config = getOwner(this).resolveRegistration('config:environment');
@@ -112,7 +116,6 @@ export default Service.extend({
112116
let tokens = copy(this.tokens);
113117
tokens.push(token);
114118
set(this, 'tokens', A(tokens));
115-
set(this, 'length', this.length + 1);
116119
},
117120

118121
remove(id) {
@@ -131,7 +134,6 @@ export default Service.extend({
131134
let tokens = A(copy(this.tokens));
132135
tokens.removeObject(token);
133136
set(this, 'tokens', A(tokens));
134-
set(this, 'length', this.length - 1);
135137
},
136138

137139
visibleTokens: computed('tokens', {
@@ -190,6 +192,22 @@ export default Service.extend({
190192
}
191193
}),
192194

195+
scheduleTitleUpdate() {
196+
let router = getOwner(this).lookup('router:main');
197+
let routes = router._routerMicrolib || router.router;
198+
let { activeTransition } = routes || {};
199+
if (activeTransition) {
200+
activeTransition.promise.finally(() => {
201+
if (this.isDestroyed) {
202+
return;
203+
}
204+
scheduleOnce('afterRender', this, this._updateTitle);
205+
});
206+
} else {
207+
scheduleOnce('afterRender', this, this._updateTitle);
208+
}
209+
},
210+
193211
toString() {
194212
let tokens = this.sortedTokens;
195213
let title = [];
@@ -205,12 +223,26 @@ export default Service.extend({
205223
return title.join('');
206224
},
207225

226+
_updateTitle() {
227+
const toBeTitle = this.toString();
228+
229+
if (isFastBoot) {
230+
// in fastboot context "document" is instance of ember-fastboot/simple-dom document
231+
let titleEl = this.document.createElement('title');
232+
let titleContents = this.document.createTextNode(toBeTitle);
233+
titleEl.appendChild(titleContents);
234+
this.document.head.appendChild(titleEl);
235+
} else {
236+
this.document.title = toBeTitle;
237+
}
238+
},
239+
208240
/**
209241
* Remove any existing title tags from the head.
210242
* @private
211243
*/
212244
_removeExistingTitleTag() {
213-
if (this._hasFastboot()) {
245+
if (isFastBoot) {
214246
return;
215247
}
216248

@@ -219,9 +251,5 @@ export default Service.extend({
219251
let title = titles[i];
220252
title.parentNode.removeChild(title);
221253
}
222-
},
223-
224-
_hasFastboot() {
225-
return !!getOwner(this).lookup('service:fastboot');
226254
}
227255
});

app/templates/head.hbs

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)