kopia lustrzana https://github.com/nolanlawson/pinafore
				
				
				
			
							rodzic
							
								
									1c6387a0a4
								
							
						
					
					
						commit
						f10e9dbcf3
					
				|  | @ -680,5 +680,12 @@ export default { | |||
|   statusOptions: 'Status options', | ||||
|   confirm: 'Confirm', | ||||
|   closeDialog: 'Close dialog', | ||||
|   postPrivacy: 'Post privacy' | ||||
|   postPrivacy: 'Post privacy', | ||||
|   homeOnInstance: 'Home on {instance}', | ||||
|   statusesTimelineOnInstance: 'Statuses: {timeline} timeline on {instance}', | ||||
|   statusesHashtag: 'Statuses: #{hashtag} hashtag', | ||||
|   statusesThread: 'Statuses: thread', | ||||
|   statusesAccountTimeline: 'Statuses: account timeline', | ||||
|   statusesList: 'Statuses: list', | ||||
|   notificationsOnInstance: 'Notifications on {instance}' | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,5 @@ | |||
| {#if level === 2} | ||||
|   <h2 class={className || ''}><slot></slot></h2> | ||||
| {:else} | ||||
|   <h1 class={className || ''}><slot></slot></h1> | ||||
| {/if} | ||||
|  | @ -3,6 +3,7 @@ | |||
|      without a div wrapper due to sticky-positioned compose button. | ||||
|      TODO: this is a bit hacky due to code duplication | ||||
|  --> | ||||
| <h1 class="sr-only">{headingLabel}</h1> | ||||
| <div class="timeline-home-page" aria-busy={hideTimeline}> | ||||
|   {#if hidePage} | ||||
|     <LoadingPage /> | ||||
|  | @ -30,6 +31,7 @@ | |||
|   import { store } from '../_store/store.js' | ||||
|   import LoadingPage from './LoadingPage.html' | ||||
|   import LazyComposeBox from './compose/LazyComposeBox.html' | ||||
|   import { formatIntl } from '../_utils/formatIntl.js' | ||||
| 
 | ||||
|   export default { | ||||
|     oncreate () { | ||||
|  | @ -40,7 +42,8 @@ | |||
|     }, | ||||
|     computed: { | ||||
|       hidePage: ({ $timelineInitialized, $timelinePreinitialized }) => !$timelineInitialized && !$timelinePreinitialized, | ||||
|       hideTimeline: ({ $timelineInitialized }) => !$timelineInitialized | ||||
|       hideTimeline: ({ $timelineInitialized }) => !$timelineInitialized, | ||||
|       headingLabel: ({ $currentInstance }) => formatIntl('intl.homeOnInstance', { instance: $currentInstance }) | ||||
|     }, | ||||
|     store: () => store, | ||||
|     components: { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| {#if realm === 'home'} | ||||
|   <h1 class="sr-only">{intl.composeStatus}</h1> | ||||
|   <h2 class="sr-only">{intl.composeStatus}</h2> | ||||
| {/if} | ||||
| <ComposeFileDrop {realm} > | ||||
|   <div class="{computedClassName} {hideAndFadeIn}"> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <h1 class="sr-only">{label}</h1> | ||||
| <DynamicHeading className="sr-only" level={headingLevel}>{label}</DynamicHeading> | ||||
| <FocusRestoration realm={focusRealm}> | ||||
|   <div class="timeline" role="feed"> | ||||
|     {#if components} | ||||
|  | @ -26,6 +26,7 @@ | |||
| <ScrollListShortcuts /> | ||||
| <script> | ||||
|   import { store } from '../../_store/store.js' | ||||
|   import DynamicHeading from '../DynamicHeading.html' | ||||
|   import Status from '../status/Status.html' | ||||
|   import LoadingFooter from './LoadingFooter.html' | ||||
|   import MoreHeaderVirtualWrapper from './MoreHeaderVirtualWrapper.html' | ||||
|  | @ -51,6 +52,7 @@ | |||
|   import { createMakeProps } from '../../_actions/createMakeProps.js' | ||||
|   import { showMoreAndScrollToTop } from '../../_actions/showMoreAndScrollToTop.js' | ||||
|   import FocusRestoration from '../FocusRestoration.html' | ||||
|   import { formatIntl } from '../../_utils/formatIntl.js' | ||||
| 
 | ||||
|   export default { | ||||
|     oncreate () { | ||||
|  | @ -89,20 +91,23 @@ | |||
|       ), | ||||
|       label: ({ timeline, $currentInstance, timelineType, timelineValue }) => { | ||||
|         if (timelines[timeline]) { | ||||
|           return `Statuses: ${timelines[timeline].label} timeline on ${$currentInstance}` | ||||
|           return formatIntl('intl.statusesTimelineOnInstance', { | ||||
|             timeline: timelines[timeline].label, | ||||
|             instance: $currentInstance | ||||
|           }) | ||||
|         } | ||||
| 
 | ||||
|         switch (timelineType) { | ||||
|           case 'tag': | ||||
|             return `Statuses: #${timelineValue} hashtag` | ||||
|             return formatIntl('intl.statusesHashtag', { hashtag: timelineValue }) | ||||
|           case 'status': | ||||
|             return 'Statuses: thread' | ||||
|             return 'intl.statusesThread' | ||||
|           case 'account': | ||||
|             return 'Statuses: account timeline' | ||||
|             return 'intl.statusesAccountTimeline' | ||||
|           case 'list': | ||||
|             return 'Statuses: list' | ||||
|             return 'intl.statusesList' | ||||
|           case 'notifications': | ||||
|             return `Notifications on ${$currentInstance}` | ||||
|             return formatIntl('intl.notificationsOnInstance', { instance: $currentInstance }) | ||||
|         } | ||||
|       }, | ||||
|       timelineType: ({ $currentTimelineType }) => $currentTimelineType, | ||||
|  | @ -127,7 +132,8 @@ | |||
|           onClick: showMoreItemsForCurrentTimeline | ||||
|         } | ||||
|       }, | ||||
|       focusRealm: ({ $currentInstance, timeline }) => `${$currentInstance}-${timeline}` | ||||
|       focusRealm: ({ $currentInstance, timeline }) => `${$currentInstance}-${timeline}`, | ||||
|       headingLevel: ({ timeline, timelineType }) => timeline === 'home' || timelineType === 'status' ? 2 : 1 | ||||
|     }, | ||||
|     store: () => store, | ||||
|     methods: { | ||||
|  | @ -232,7 +238,8 @@ | |||
|     components: { | ||||
|       ScrollListShortcuts, | ||||
|       Shortcut, | ||||
|       FocusRestoration | ||||
|       FocusRestoration, | ||||
|       DynamicHeading | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| {#if $isUserLoggedIn} | ||||
| <h1 class="sr-only">{intl.community}</h1> | ||||
| <div class="community-page"> | ||||
| 
 | ||||
|   <FocusRestoration realm="community"> | ||||
|     <RadioGroup | ||||
|       id="pinnables" | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| {#if $isUserLoggedIn} | ||||
| <h1 class="sr-only">{intl.search}</h1> | ||||
| <div class="search-page"> | ||||
|   <Search></Search> | ||||
| </div> | ||||
|  |  | |||
|  | @ -0,0 +1,52 @@ | |||
| import { | ||||
|   settingsNavButton, | ||||
|   notificationsNavButton, | ||||
|   localTimelineNavButton, | ||||
|   communityNavButton, | ||||
|   searchNavButton, | ||||
|   getNumElementsMatchingSelector, | ||||
|   getUrl, getNthStatus | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| 
 | ||||
| fixture`042-headings.js` | ||||
|   .page`http://localhost:4002` | ||||
| 
 | ||||
| async function testHeadings (t, loggedIn) { | ||||
|   const navButtons = [ | ||||
|     { button: notificationsNavButton, url: 'notifications' }, | ||||
|     { button: localTimelineNavButton, url: 'local' }, | ||||
|     { button: communityNavButton, url: 'community' }, | ||||
|     { button: searchNavButton, url: 'search' }, | ||||
|     { button: settingsNavButton, url: 'settings' } | ||||
|   ] | ||||
| 
 | ||||
|   // home page
 | ||||
|   await t | ||||
|     .expect(getNumElementsMatchingSelector('h1')()).eql(1) | ||||
| 
 | ||||
|   if (loggedIn) { | ||||
|     // status page
 | ||||
|     await t | ||||
|       .click(getNthStatus(1)) | ||||
|       .expect(getUrl()).contains('status') | ||||
|       .expect(getNumElementsMatchingSelector('h1')()).eql(1) | ||||
|   } | ||||
| 
 | ||||
|   // non-home pages
 | ||||
|   for (const { button, url } of navButtons) { | ||||
|     await t | ||||
|       .click(button) | ||||
|       .expect(getUrl()).contains(url) | ||||
|       .expect(getNumElementsMatchingSelector('h1')()).eql(1) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| test('Only one <h1> when not logged in', async t => { | ||||
|   await testHeadings(t, false) | ||||
| }) | ||||
| 
 | ||||
| test('Only one <h1> when logged in', async t => { | ||||
|   await loginAsFoobar(t) | ||||
|   await testHeadings(t, true) | ||||
| }) | ||||
|  | @ -570,6 +570,12 @@ export function getNthPinnedStatusFavoriteButton (n) { | |||
|   return $(`${getNthPinnedStatusSelector(n)} .status-toolbar button:nth-child(3)`) | ||||
| } | ||||
| 
 | ||||
| export const getNumElementsMatchingSelector = (selector) => (exec(() => { | ||||
|   return document.querySelectorAll(selector).length | ||||
| }, { | ||||
|   dependencies: { selector } | ||||
| })) | ||||
| 
 | ||||
| export async function validateTimeline (t, timeline) { | ||||
|   const timeout = 30000 | ||||
|   for (let i = 0; i < timeline.length; i++) { | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Nolan Lawson
						Nolan Lawson