feat(title): add dynamic document title (#645)

* feat(title): add dynamic document title

fixes #490 and #643

* fix code style
This commit is contained in:
Nolan Lawson 2018-11-12 18:28:43 -08:00 committed by GitHub
parent eee2eb288b
commit 62ac7330fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 106 additions and 76 deletions

View file

@ -0,0 +1,24 @@
<svelte:head>
<title>{instanceIndicator} · {name}{notificationsIndicator}</title>
</svelte:head>
<script>
import { store } from '../_store/store'
export default {
data: () => ({
settingsPage: false
}),
store: () => store,
computed: {
instanceIndicator: ({ $isUserLoggedIn, $currentInstance, settingsPage }) => (
// If the user is not logged in, or if they're on a settings page (which
// is more general than instance-specific), of if this is server-rendered, then
// show "Pinafore". Otherwise show the instance name.
`${($isUserLoggedIn && !settingsPage && $currentInstance) ? $currentInstance : 'Pinafore'}`
),
notificationsIndicator: ({ $hasNotifications, $numberOfNotifications }) => (
$hasNotifications ? ` (${$numberOfNotifications})` : ''
)
}
}
</script>

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Profile" />
<title>Pinafore Profile</title>
</svelte:head>
<Layout page='tags'> <Layout page='tags'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/accounts/[accountId].html' import pageComponent from '../_pages/accounts/[accountId].html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Followers" />
<title>Pinafore Followers</title>
</svelte:head>
<Layout page='tags'> <Layout page='tags'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/accounts/[accountId]/followers.html' import pageComponent from '../../_pages/accounts/[accountId]/followers.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Follows" />
<title>Pinafore Follows</title>
</svelte:head>
<Layout page='tags'> <Layout page='tags'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/accounts/[accountId]/follows.html' import pageComponent from '../../_pages/accounts/[accountId]/follows.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Blocked users" />
<title>Pinafore Blocked users</title>
</svelte:head>
<Layout page='blocked'> <Layout page='blocked'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/blocked.html' import pageComponent from './_pages/blocked.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Community" />
<title>Pinafore Community</title>
</svelte:head>
<Layout page='community'> <Layout page='community'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/community/index.html' import pageComponent from '../_pages/community/index.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Favorites" />
<title>Pinafore Favorites</title>
</svelte:head>
<Layout page='favorites'> <Layout page='favorites'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/favorites.html' import pageComponent from './_pages/favorites.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Federated" />
<title>Pinafore Federated</title>
</svelte:head>
<Layout page='federated'> <Layout page='federated'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/federated.html' import pageComponent from './_pages/federated.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Home" />
<title>Pinafore Home</title>
</svelte:head>
<Layout page='home'> <Layout page='home'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/index.html' import pageComponent from './_pages/index.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="List" />
<title>Pinafore List</title>
</svelte:head>
<Layout page='lists/{params.listId}'> <Layout page='lists/{params.listId}'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/lists/[listId].html' import pageComponent from '../_pages/lists/[listId].html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Local" />
<title>Pinafore Local</title>
</svelte:head>
<Layout page='local'> <Layout page='local'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/local.html' import pageComponent from './_pages/local.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Muted users" />
<title>Pinafore Muted users</title>
</svelte:head>
<Layout page='muted'> <Layout page='muted'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/muted.html' import pageComponent from './_pages/muted.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Notifications" />
<title>Pinafore Notifications</title>
</svelte:head>
<Layout page='notifications'> <Layout page='notifications'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/notifications.html' import pageComponent from './_pages/notifications.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Pinned toots" />
<title>Pinafore Pinned toots</title>
</svelte:head>
<Layout page='pinned'> <Layout page='pinned'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/pinned.html' import pageComponent from './_pages/pinned.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Follow requests" />
<title>Pinafore Follow requests</title>
</svelte:head>
<Layout page='muted'> <Layout page='muted'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/requests.html' import pageComponent from './_pages/requests.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Search" />
<title>Pinafore Search</title>
</svelte:head>
<Layout page='search'> <Layout page='search'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from './_components/Layout.html' import Layout from './_components/Layout.html'
import Title from './_components/Title.html'
import LazyPage from './_components/LazyPage.html' import LazyPage from './_components/LazyPage.html'
import pageComponent from './_pages/search.html' import pageComponent from './_pages/search.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="About" settingsPage={true} />
<title>Pinafore About</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/settings/about.html' import pageComponent from '../_pages/settings/about.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="General Settings" settingsPage={true} />
<title>Pinafore General Settings</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/settings/general.html' import pageComponent from '../_pages/settings/general.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Settings" settingsPage={true} />
<title>Pinafore Settings</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/settings/index.html' import pageComponent from '../_pages/settings/index.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="{params.instanceName}" settingsPage={true} />
<title>Pinafore Instance</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/settings/instances/[instanceName].html' import pageComponent from '../../_pages/settings/instances/[instanceName].html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Add instance" settingsPage={true} />
<title>Pinafore Add instance</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/settings/instances/add.html' import pageComponent from '../../_pages/settings/instances/add.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Instances" settingsPage={true} />
<title>Pinafore Instances</title>
</svelte:head>
<Layout page='settings'> <Layout page='settings'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/settings/instances/index.html' import pageComponent from '../../_pages/settings/instances/index.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Favorites" />
<title>Pinafore Favorites</title>
</svelte:head>
<Layout page='favorites'> <Layout page='favorites'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/statuses/[statusId]/favorites.html' import pageComponent from '../../_pages/statuses/[statusId]/favorites.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Status" />
<title>Pinafore Status</title>
</svelte:head>
<Layout page='statuses' > <Layout page='statuses' >
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/statuses/[statusId]/index.html' import pageComponent from '../../_pages/statuses/[statusId]/index.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Reblogs" />
<title>Pinafore Reblogs</title>
</svelte:head>
<Layout page='reblogs'> <Layout page='reblogs'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../../_components/Layout.html' import Layout from '../../_components/Layout.html'
import Title from '../../_components/Title.html'
import LazyPage from '../../_components/LazyPage.html' import LazyPage from '../../_components/LazyPage.html'
import pageComponent from '../../_pages/statuses/[statusId]/reblogs.html' import pageComponent from '../../_pages/statuses/[statusId]/reblogs.html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,17 +1,17 @@
<svelte:head> <Title name="Hashtag" />
<title>Pinafore Hashtag</title>
</svelte:head>
<Layout page='tags'> <Layout page='tags'>
<LazyPage {pageComponent} {params} /> <LazyPage {pageComponent} {params} />
</Layout> </Layout>
<script> <script>
import Layout from '../_components/Layout.html' import Layout from '../_components/Layout.html'
import Title from '../_components/Title.html'
import LazyPage from '../_components/LazyPage.html' import LazyPage from '../_components/LazyPage.html'
import pageComponent from '../_pages/tags/[tagName].html' import pageComponent from '../_pages/tags/[tagName].html'
export default { export default {
components: { components: {
Layout, Layout,
Title,
LazyPage LazyPage
}, },
data: () => ({ data: () => ({

View file

@ -1,6 +1,6 @@
import { loginAsFoobar } from '../roles' import { loginAsFoobar } from '../roles'
import { import {
getNthStatus, getUrl, homeNavButton, notificationsNavButton getNthStatus, getTitleText, getUrl, homeNavButton, notificationsNavButton
} from '../utils' } from '../utils'
import { favoriteStatusAs, postAs } from '../serverActions' import { favoriteStatusAs, postAs } from '../serverActions'
@ -12,15 +12,19 @@ test('shows unread notifications', async t => {
await loginAsFoobar(t) await loginAsFoobar(t)
await t await t
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications') .expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
.expect(getTitleText()).eql('localhost:3000 · Home')
await favoriteStatusAs('admin', id) await favoriteStatusAs('admin', id)
await t await t
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (1)') .expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (1)')
.expect(getTitleText()).eql('localhost:3000 · Home (1)')
.click(notificationsNavButton) .click(notificationsNavButton)
.expect(getUrl()).contains('/notifications') .expect(getUrl()).contains('/notifications')
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (current page)') .expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (current page)')
.expect(getTitleText()).eql('localhost:3000 · Notifications')
.expect(getNthStatus(0).innerText).contains('somebody please favorite this to validate me') .expect(getNthStatus(0).innerText).contains('somebody please favorite this to validate me')
.expect(getNthStatus(0).innerText).match(/admin\s+favorited your status/) .expect(getNthStatus(0).innerText).match(/admin\s+favorited your status/)
await t await t
.click(homeNavButton) .click(homeNavButton)
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications') .expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
.expect(getTitleText()).eql('localhost:3000 · Home')
}) })

View file

@ -79,6 +79,8 @@ export const getActiveElementInsideNthStatus = exec(() => {
return '' return ''
}) })
export const getTitleText = exec(() => document.head.querySelector('title').innerHTML)
export const goBack = exec(() => window.history.back()) export const goBack = exec(() => window.history.back())
export const forceOffline = exec(() => window.__forceOnline(false)) export const forceOffline = exec(() => window.__forceOnline(false))