MOBILE-3744 a11y: Use button property on ion-items when using onclick

main
Pau Ferrer Ocaña 2021-04-29 13:52:38 +02:00
parent a8c0d12c71
commit 603190c3c5
68 changed files with 135 additions and 124 deletions

View File

@ -17,7 +17,7 @@
</core-empty-box>
<ion-list *ngIf="!badges.empty" class="ion-no-margin">
<ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [title]="badge.name"
<ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [attr.aria-label]="badge.name"
(click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)">
<ion-avatar slot="start">
<img [src]="badge.badgeurl" [alt]="badge.name" core-external-content>

View File

@ -4,7 +4,8 @@
</ion-label>
</ion-item-divider>
<core-loading [hideUntil]="loaded" class="core-loading-center">
<ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="false" (click)="gotoCoureListModType(entry)">
<ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="false" button
(click)="gotoCoureListModType(entry)">
<img slot="start" [src]="entry.icon" alt="" role="presentation" class="core-module-icon">
<ion-label>{{ entry.name }}</ion-label>
</ion-item>

View File

@ -4,7 +4,7 @@
</ion-item-divider>
<ng-container *ngFor="let event of dayEvents.events">
<ion-item class="ion-text-wrap core-course-module-handler item-media" detail="false" (click)="action($event, event.url)"
[title]="event.name">
[attr.aria-label]="event.name" button>
<img slot="start" [src]="event.iconUrl" alt="" role="presentation" *ngIf="event.iconUrl" class="core-module-icon">
<ion-label>
<!-- Add the icon title so accessibility tools read it. -->

View File

@ -54,7 +54,7 @@
<core-tag-list [tags]="entry.tags"></core-tag-list>
</ion-label>
</ion-item>
<ion-item *ngIf="commentsEnabled" detail>
<ion-item *ngIf="commentsEnabled" detail="true">
<ion-label>
<core-comments [component]="this.component" [itemId]="entry.id" area="format_blog"
[instanceId]="entry.userid" contextLevel="user">

View File

@ -4,7 +4,7 @@
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ng-container *ngFor="let event of filteredEvents">
<ion-item class="ion-text-wrap addon-calendar-event" [title]="event.name" (click)="eventClicked(event)"
<ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
<img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
role="presentation">

View File

@ -59,8 +59,8 @@
<ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
<ng-container *ngFor="let event of filteredEvents">
<ion-item class="addon-calendar-event ion-text-wrap" [title]="event.name" (click)="gotoEvent(event.id)"
[class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
<ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)"
[class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>
<img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
role="presentation">
<ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">

View File

@ -121,7 +121,7 @@
<!-- Advanced options. -->
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()"
[attr.aria-label]="(advanced ? 'core.showless' : 'core.showmore') | translate">
[attr.aria-label]="(advanced ? 'core.showless' : 'core.showmore') | translate" role="button">
<ion-icon *ngIf="!advanced" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
@ -162,14 +162,14 @@
<ion-radio slot="end" value="0"></ion-radio>
<ion-label>{{ 'addon.calendar.durationnone' | translate }}</ion-label>
</ion-item>
<ion-item (click)="selectDuration('1')">
<ion-item button (click)="selectDuration('1')">
<ion-radio slot="end" value="1"></ion-radio>
<ion-label>{{ 'addon.calendar.durationuntil' | translate }}</ion-label>
<ion-datetime formControlName="timedurationuntil"
[placeholder]="'addon.calendar.durationuntil' | translate"
[displayFormat]="dateFormat" [disabled]="form.controls.duration.value != 1"></ion-datetime>
</ion-item>
<ion-item (click)="selectDuration('2')">
<ion-item button (click)="selectDuration('2')">
<ion-radio slot="end" value="2"></ion-radio>
<ion-label>{{ 'addon.calendar.durationminutes' | translate }}</ion-label>
<ion-input type="number" name="timedurationminutes" slot="end"

View File

@ -42,9 +42,9 @@
<ion-item-divider *ngIf="event.showDate">
<ion-label>{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</ion-label>
</ion-item-divider>
<ion-item class="addon-calendar-event ion-text-wrap" [title]="event.name" (click)="gotoEvent(event.id)"
<ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)"
[attr.aria-current]="event.id == eventId ? 'page' : 'false'"
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
[ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>
<img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
role="presentation">
<ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start"

View File

@ -14,8 +14,8 @@
<core-loading [hideUntil]="competencies.loaded">
<ion-list>
<ion-item class="ion-text-wrap" *ngFor="let competency of competencies.items"
[title]="competency.competency.shortname" (click)="competencies.select(competency)"
[attr.aria-current]="competencies.getItemAriaCurrent(competency)">
[attr.aria-label]="competency.competency.shortname" (click)="competencies.select(competency)"
[attr.aria-current]="competencies.getItemAriaCurrent(competency)" button>
<ion-label>
<h2>{{ competency.competency.shortname }} <em>{{competency.competency.idnumber}}</em></h2>
</ion-label>

View File

@ -73,8 +73,8 @@
<p *ngIf="coursemodules.length == 0">
{{ 'addon.competency.noactivities' | translate }}
</p>
<ion-item class="ion-text-wrap" *ngFor="let activity of coursemodules" [href]="activity.url" [title]="activity.name"
core-link capture="true">
<ion-item class="ion-text-wrap" *ngFor="let activity of coursemodules" [href]="activity.url"
[attr.aria-label]="activity.name" core-link capture="true">
<img slot="start" core-external-content [src]="activity.iconurl" alt="" *ngIf="activity.iconurl"
class="core-module-icon">
<ion-label>

View File

@ -56,7 +56,7 @@
<div *ngIf="competencies">
<ion-card *ngFor="let competency of competencies.competencies">
<ion-item class="ion-text-wrap" (click)="openCompetency(competency.competency.id)"
[title]="competency.competency.shortname" detail="true">
[attr.aria-label]="competency.competency.shortname" detail="true" button>
<ion-label>
<h2><strong>{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></strong></h2>
</ion-label>
@ -103,8 +103,8 @@
<p *ngIf="competency.coursemodules.length == 0">
{{ 'addon.competency.noactivities' | translate }}
</p>
<ion-item class="ion-text-wrap core-course-module-handler item-media" [title]="activity.name" core-link
*ngFor="let activity of competency.coursemodules" [href]="activity.url" capture="true">
<ion-item class="ion-text-wrap core-course-module-handler item-media" [attr.aria-label]="activity.name"
core-link *ngFor="let activity of competency.coursemodules" [href]="activity.url" capture="true">
<img slot="start" [src]="activity.iconurl" core-external-content alt=""
*ngIf="activity.iconurl" class="core-module-icon">
<ion-label>
@ -120,7 +120,7 @@
{{ 'addon.competency.nouserplanswithcompetency' | translate }}
</p>
<ion-item class="ion-text-wrap" *ngFor="let plan of competency.plans" [href]="plan.url"
[title]="plan.name" core-link capture="true">
[attr.aria-label]="plan.name" core-link capture="true">
<ion-label>
<core-format-text [text]="plan.name" contextLevel="user" [contextInstanceId]="plan.userid">
</core-format-text>

View File

@ -75,7 +75,7 @@
</ion-item>
<ion-item class="ion-text-wrap" *ngFor="let competency of plan.competencies"
(click)="openCompetency(competency.competency.id)"
[title]="competency.competency.shortname" detail="true">
[attr.aria-label]="competency.competency.shortname" detail="true" button>
<ion-label><h2>{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></h2></ion-label>
<ion-badge *ngIf="competency.usercompetencyplan" slot="end"
[color]="competency.usercompetencyplan.proficiency ? 'success' : 'danger'">

View File

@ -16,8 +16,8 @@
</core-empty-box>
<ion-list *ngIf="!plans.empty" class="ion-no-margin">
<ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [title]="plan.name" (click)="plans.select(plan)"
[attr.aria-current]="plans.getItemAriaCurrent(plan)">
<ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name"
(click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button>
<ion-label>
<h2>{{ plan.name }}</h2>
<p *ngIf="plan.duedate > 0">

View File

@ -33,7 +33,7 @@
</ion-item>
<ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let member of members"
(click)="closeModal(member.id)" detail>
(click)="closeModal(member.id)" detail="true" button>
<core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" slot="start">
</core-user-avatar>
<ion-label>

View File

@ -38,7 +38,7 @@
<!-- Don't show deleted users -->
<ion-item class="ion-text-wrap addon-messages-conversation-item"
*ngIf="contact.profileimageurl || contact.profileimageurlsmall"
[title]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail
[attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button
[attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar>
<ion-label><h2>{{ contact.fullname }}</h2></ion-label>

View File

@ -26,9 +26,9 @@
</ion-refresher>
<core-loading [hideUntil]="confirmedLoaded" class="core-loading-center">
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap addon-messages-conversation-item"
*ngFor="let contact of confirmedContacts" [title]="contact.fullname" detail
(click)="selectUser(contact.id)" [attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'">
<ion-item class="ion-text-wrap addon-messages-conversation-item" (click)="selectUser(contact.id)" button
*ngFor="let contact of confirmedContacts" [attr.aria-label]="contact.fullname" detail="true"
[attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'">
<core-user-avatar slot="start" [user]="contact"
[checkOnline]="contact.showonlinestatus" [linkProfile]="false">
</core-user-avatar>
@ -64,8 +64,8 @@
<core-loading [hideUntil]="requestsLoaded" class="core-loading-center">
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let request of requests"
[title]="request.fullname" (click)="selectUser(request.id)"
[attr.aria-current]="request.id == selectedUserId ? 'page' : 'false'" detail>
[attr.aria-label]="request.fullname" (click)="selectUser(request.id)" button
[attr.aria-current]="request.id == selectedUserId ? 'page' : 'false'" detail="true">
<core-user-avatar slot="start" [user]="request" [linkProfile]="false"></core-user-avatar>
<ion-label>
<core-format-text [text]="request.fullname" contextLevel="system" [contextInstanceId]="0">

View File

@ -26,7 +26,7 @@
<ion-list class="ion-no-margin">
<ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
[attr.aria-label]="'addon.messages.contacts' | translate" detail>
[attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
<ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon>
<ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label>
</ion-item>
@ -38,8 +38,8 @@
</ion-label>
<ion-note slot="end" class="ion-padding-end"><ion-badge>{{ search.results.length }}</ion-badge></ion-note>
</ion-item-divider>
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" [title]="result.fullname"
(click)="gotoDiscussion(result.userid, result.messageid)"
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button
[attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)"
[attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar>
<ion-label>
@ -50,8 +50,8 @@
</ion-item>
</ng-container>
<ng-container *ngIf="!search.showResults">
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions"
[title]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions" button
[attr.aria-label]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
[attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' : 'false'">
<core-user-avatar [user]="discussion" slot="start" checkOnline="false"></core-user-avatar>
<ion-label>

View File

@ -26,7 +26,7 @@
<core-loading [hideUntil]="loaded" [message]="loadingMessage">
<ion-list>
<ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
[attr.aria-label]="'addon.messages.contacts' | translate" detail>
[attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
<ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon>
<ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label>
<ion-badge *ngIf="contactRequestsCount > 0" slot="end">{{contactRequestsCount}}</ion-badge>
@ -34,7 +34,7 @@
<!-- Favourite conversations. -->
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(favourites)" sticky="true"
[attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate"
[attr.aria-expanded]="favourites.expanded" role="heading">
[attr.aria-expanded]="favourites.expanded" role="heading button">
<ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="favourites.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'core.favourites' | translate }} ({{ favourites.count }})</ion-label>
@ -57,7 +57,7 @@
<!-- Group conversations. -->
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(group)" sticky="true"
[attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate"
[attr.aria-expanded]="group.expanded" role="heading">
[attr.aria-expanded]="group.expanded" role="heading button">
<ion-icon *ngIf="!group.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="group.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</ion-label>
@ -79,7 +79,7 @@
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(individual)" sticky="true"
[attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate"
[attr.aria-expanded]="individual.expanded" role="heading">
[attr.aria-expanded]="individual.expanded" role="heading button">
<ion-icon *ngIf="!individual.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.messages.individualconversations' | translate }} ({{ individual.count }})</ion-label>
@ -106,8 +106,8 @@
<!-- Template to render a list of conversations. -->
<ng-template #conversationsTemplate let-conversations="conversations">
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" [title]="conversation.name"
(click)="gotoConversation(conversation.id, conversation.userid)"
<ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" button
[attr.aria-label]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)"
[attr.aria-current]="((conversation.id && conversation.id == selectedConversationId) ||
(conversation.userid && conversation.userid == selectedUserId)) ? 'page': 'false'"
id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}">

View File

@ -42,8 +42,9 @@
</ion-item-divider>
<!-- List of results -->
<ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [title]="result.fullname"
(click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail>
<ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname"
(click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail="true"
button>
<core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
<ion-label>
<h2>

View File

@ -84,7 +84,8 @@
</ion-item>
<!-- Summary of all submissions. -->
<ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail>
<ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail="true"
button>
<ion-label>
<h2 *ngIf="assign.teamsubmission">{{ 'addon.mod_assign.numberofteams' | translate }}</h2>
<h2 *ngIf="!assign.teamsubmission">{{ 'addon.mod_assign.numberofparticipants' | translate }}</h2>
@ -97,6 +98,7 @@
<!-- Summary of submissions with draft status. -->
<ion-item class="ion-text-wrap" *ngIf="assign.submissiondrafts && summary && summary.submissionsenabled"
[detail]="!showNumbers || summary.submissiondraftscount"
[button]="!showNumbers || summary.submissiondraftscount"
(click)="goToSubmissionList(submissionStatusDraft, !!summary.submissiondraftscount)">
<ion-label><h2>{{ 'addon.mod_assign.numberofdraftsubmissions' | translate }}</h2></ion-label>
<ion-badge slot="end" *ngIf="showNumbers" color="primary">
@ -107,6 +109,7 @@
<!-- Summary of submissions with submitted status. -->
<ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled"
[detail]="!showNumbers || summary.submissionssubmittedcount"
[button]="!showNumbers || summary.submissionssubmittedcount"
(click)="goToSubmissionList(submissionStatusSubmitted, !!summary.submissionssubmittedcount)">
<ion-label><h2>{{ 'addon.mod_assign.numberofsubmittedassignments' | translate }}</h2></ion-label>
<ion-badge slot="end" *ngIf="showNumbers" color="primary">
@ -116,7 +119,7 @@
<!-- Summary of submissions that need grading. -->
<ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled && !assign.teamsubmission && showNumbers"
[detail]="needsGradingAvalaible"
[detail]="needsGradingAvalaible" [button]="needsGradingAvalaible"
(click)="goToSubmissionList(needGrading, needsGradingAvalaible)">
<ion-label><h2>{{ 'addon.mod_assign.numberofsubmissionsneedgrading' | translate }}</h2></ion-label>
<ion-badge slot="end" color="primary">

View File

@ -2,7 +2,7 @@
<!-- User and status of the submission. -->
<ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId"
[title]="user!.fullname">
[attr.aria-label]="user!.fullname">
<core-user-avatar [user]="user" slot="start"></core-user-avatar>
<ion-label>
<h2>{{ user!.fullname }}</h2>
@ -183,7 +183,7 @@
<ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && !blindMarking">
<ng-container *ngFor="let user of membersToSubmit">
<ion-item class="ion-text-wrap" core-user-link [userId]="user.id"
[courseId]="courseId" [title]="user.fullname">
[courseId]="courseId" [attr.aria-label]="user.fullname">
<core-user-avatar [user]="user" slot="start"></core-user-avatar>
<ion-label><h2>{{ user.fullname }}</h2></ion-label>
</ion-item>
@ -329,7 +329,7 @@
<!-- Data about the grader (teacher who graded). -->
<ion-item class="ion-text-wrap" *ngIf="grader" core-user-link [userId]="grader!.id" [courseId]="courseId"
[title]="grader!.fullname" detail="true">
[attr.aria-label]="grader!.fullname" detail="true">
<core-user-avatar [user]="grader" slot="start"></core-user-avatar>
<ion-label>
<h2>{{ 'addon.mod_assign.gradedby' | translate }}</h2>

View File

@ -39,7 +39,7 @@
</ion-item>
<!-- List of submissions. -->
<ng-container *ngFor="let submission of submissions.items">
<ion-item class="ion-text-wrap" (click)="submissions.select(submission)"
<ion-item class="ion-text-wrap" (click)="submissions.select(submission)" button
[attr.aria-current]="submissions.getItemAriaCurrent(submission)">
<core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar>
<ion-label>

View File

@ -1,4 +1,4 @@
<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="false">
<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="false" button>
<ion-label>
<h2>{{plugin.name}}</h2>
<core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments"

View File

@ -12,7 +12,7 @@
<nav>
<ion-list>
<ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)"
[attr.aria-current]="selected == chapter.id ? 'page' : 'false'"
[attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button
[class.item-dimmed]="chapter.hidden">
<ion-label>
<p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null">

View File

@ -141,7 +141,7 @@
</ion-label>
</ion-item-divider>
<ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseId"
[userId]="user.userid" [title]="user.fullname" class="ion-text-wrap">
[userId]="user.userid" [attr.aria-label]="user.fullname" class="ion-text-wrap">
<core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
<ion-label><p>{{user.fullname}}</p></ion-label>
</ion-item>

View File

@ -68,14 +68,15 @@
</ion-select-option>
</ion-select>
</ion-item>
<ion-item class="ion-text-wrap" (click)="openRespondents()" [detail]="access.canviewreports && completedCount > 0">
<ion-item class="ion-text-wrap" (click)="openRespondents()" [detail]="access.canviewreports && completedCount > 0"
button>
<ion-label>
<h2>{{ 'addon.mod_feedback.completed_feedbacks' | translate }}</h2>
</ion-label>
<ion-badge slot="end">{{completedCount}}</ion-badge>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="!access.isanonymous && access.canviewreports" (click)="openNonRespondents()"
detail="true" tappable="true">
detail="true" button>
<ion-label>
<h2>{{ 'addon.mod_feedback.show_nonrespondents' | translate }}</h2>
</ion-label>

View File

@ -15,7 +15,7 @@
<core-loading [hideUntil]="loaded">
<ion-list class="ion-no-margin" *ngIf="attempt || anonAttempt">
<ion-item *ngIf="attempt" class="ion-text-wrap" core-user-link [userId]="attempt.userid"
[attr.aria-label]=" 'core.user.viewprofile' | translate" [courseId]="attempt.courseid" [title]="attempt.fullname">
[attr.aria-label]=" 'core.user.viewprofile' | translate" [courseId]="attempt.courseid">
<core-user-avatar [user]="attempt" slot="start"></core-user-avatar>
<ion-label>
<h2>{{attempt.fullname}}</h2>

View File

@ -32,7 +32,7 @@
{{ 'addon.mod_feedback.non_anonymous_entries' | translate : {$a: responses.responses.total } }}
</ion-label>
</ion-item-divider>
<ion-item *ngFor="let attempt of responses.responses.attempts" class="ion-text-wrap" tappable detail="true"
<ion-item *ngFor="let attempt of responses.responses.attempts" class="ion-text-wrap" button detail="true"
(click)="responses.select(attempt)" [attr.aria-current]="responses.getItemAriaCurrent(attempt)">
<core-user-avatar [user]="attempt" slot="start"></core-user-avatar>
<ion-label>
@ -57,7 +57,7 @@
{{ 'addon.mod_feedback.anonymous_entries' |translate : {$a: responses.anonResponses.total } }}
</ion-label>
</ion-item-divider>
<ion-item *ngFor="let attempt of responses.anonResponses.attempts" class="ion-text-wrap" tappable detail="true"
<ion-item *ngFor="let attempt of responses.anonResponses.attempts" class="ion-text-wrap" button detail="true"
(click)="responses.select(attempt)" [attr.aria-current]="responses.getItemAriaCurrent(attempt)">
<ion-label>
<h2>{{ 'addon.mod_feedback.response_nr' |translate }}: {{attempt.number}}</h2>

View File

@ -25,7 +25,7 @@
(contentChanged)="onMessageChange($event)">
</core-rich-text-editor>
</ion-item>
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()" role="heading"
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()" role="heading button"
[attr.aria-expanded]="advanced" [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate">
<ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>

View File

@ -123,7 +123,7 @@
</ion-item>
<ng-container *ngIf="forum.id && forum.maxattachments > 0">
<ion-item-divider class="core-expandable ion-text-wrap" (click)="toggleAdvanced()" [attr.aria-expanded]="advanced"
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate">
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate" role="button">
<ion-label>
<ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>

View File

@ -32,7 +32,7 @@
</core-rich-text-editor>
</ion-item>
<ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()" [attr.aria-expanded]="advanced"
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate" role="heading">
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate" role="heading button">
<ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
<ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.mod_forum.advanced' | translate }}</ion-label>

View File

@ -66,7 +66,7 @@
<ion-item-divider>
<ion-label>{{ 'addon.mod_glossary.entriestobesynced' | translate }}</ion-label>
</ion-item-divider>
<ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false"
<ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false" button
[attr.aria-current]="entries.getItemAriaCurrent(entry)">
<ion-label>
<core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="glossary!.coursemodule"

View File

@ -18,7 +18,7 @@
<ng-container *ngIf="attempt">
<!-- Attempt number and user that did the attempt. -->
<ion-item class="ion-text-wrap" *ngIf="user" core-user-link [userId]="user.id" [courseId]="courseId"
[title]="user.fullname">
[attr.aria-label]="user.fullname">
<core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
<ion-label>
<h2>{{ 'addon.mod_h5pactivity.attempt' | translate }} #{{attempt.attempt}}: {{user.fullname}}</h2>

View File

@ -17,7 +17,7 @@
<core-loading [hideUntil]="loaded">
<!-- User viewed. -->
<ion-item class="ion-text-wrap" *ngIf="user && !isCurrentUser" core-user-link [userId]="user.id" [courseId]="courseId"
[title]="user.fullname">
[attr.aria-label]="user.fullname">
<core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
<ion-label>
<h2>{{ user.fullname }}</h2>

View File

@ -12,7 +12,7 @@
<nav>
<ion-list>
<ion-item *ngFor="let item of items" (click)="loadItem(item.href)"
[attr.aria-current]="selected == item.href ? 'page' : 'false'">
[attr.aria-current]="selected == item.href ? 'page' : 'false'" button>
<ion-label [class.core-bold]="!item.href">
<span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}}
</ion-label>

View File

@ -14,7 +14,7 @@
<core-loading [hideUntil]="loaded">
<div *ngIf="student">
<!-- Student data. -->
<ion-item class="ion-text-wrap" core-user-link [userId]="student.id" [courseId]="courseId" [title]="student.fullname">
<ion-item class="ion-text-wrap" core-user-link [userId]="student.id" [courseId]="courseId" [attr.aria-label]="student.fullname">
<core-user-avatar [user]="student" slot="start" [userId]="student.id" [courseId]="courseId">
</core-user-avatar>
<ion-label>

View File

@ -131,7 +131,7 @@
<ng-container *ngFor="let question of summaryQuestions">
<ion-item *ngIf="question.number" (click)="changePage(question.page, false, question.slot)"
[attr.aria-label]="'core.question.questionno' | translate:{$a: question.number}"
[detail]="!isSequential && canReturn" [attr.button]="!isSequential && canReturn ? true : null">
[detail]="!isSequential && canReturn" [button]="!isSequential && canReturn">
<ion-label>
<ion-row class="ion-align-items-center">
<ion-col size="3" class="ion-text-center">{{ question.number }}</ion-col>

View File

@ -32,7 +32,7 @@
<ion-item *ngIf="sco.isvisible" class="ion-text-wrap" [detail]="sco.prereq && sco.launch"
[ngClass]="'core-padding-' + sco.level + ' addon-mod_scorm-type-' + sco.scormtype"
[attr.aria-current]="selected == sco.id ? 'page' : 'false'" (click)="loadSco(sco)"
[disabled]="!sco.prereq || !sco.launch ? true : null" tappable>
[disabled]="!sco.prereq || !sco.launch ? true : null" [button]="sco.prereq && sco.launch">
<ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start">
</ion-icon>
<ion-label>

View File

@ -12,7 +12,7 @@
<nav>
<ion-list>
<!-- Go to "home". -->
<ion-item class="ion-text-wrap" *ngIf="homeView" (click)="goToWikiHome()" tappable>
<ion-item class="ion-text-wrap" *ngIf="homeView" (click)="goToWikiHome()" button>
<ion-icon name="fas-home" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'addon.mod_wiki.gowikihome' | translate }}</ion-label>
</ion-item>
@ -21,7 +21,7 @@
<ion-label>{{ letter.label }}</ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)"
[attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" tappable>
[attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button>
<ion-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon>
<ion-label>
<core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId"

View File

@ -4,7 +4,8 @@
<ion-label><strong>{{ group.label }}</strong></ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
[attr.disabled]="!subwiki.canedit && subwiki.id <= 0 ? true : null" tappable
[attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
[button]="subwiki.canedit || subwiki.id > 0"
[attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
<ion-label>{{ subwiki.name }}</ion-label>
<ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>

View File

@ -1,5 +1,6 @@
<core-loading [hideUntil]="loaded">
<ion-item class="ion-text-wrap" [detail]="canViewAssessment && !canSelfAssess" (click)="gotoAssessment($event)">
<ion-item class="ion-text-wrap" [detail]="canViewAssessment && !canSelfAssess" (click)="gotoAssessment($event)"
[button]="canViewAssessment && !canSelfAssess">
<core-user-avatar [user]="profile" slot="start" [courseId]="courseId" [userId]="profile?.id"></core-user-avatar>
<ion-label>
<h2 *ngIf="profile && profile.fullname">{{profile.fullname}}</h2>

View File

@ -28,14 +28,14 @@
<!-- Content. -->
<core-loading [hideUntil]="loaded" class="core-loading-center">
<ion-card class="with-borders" *ngIf="phases">
<ion-item (click)="viewPhaseInfo()" detail="true">
<ion-item button (click)="viewPhaseInfo()" detail="true">
<ion-label>
<h2 class="ion-text-wrap">{{ phases[workshop!.phase].title }}</h2>
</ion-label>
</ion-item>
<ng-container *ngIf="phases && phases[workshop!.phase] && phases[workshop!.phase].tasks &&
phases[workshop!.phase].tasks.length">
<ion-item class="ion-text-wrap" *ngFor="let task of phases[workshop!.phase].tasks"
<ion-item button class="ion-text-wrap" *ngFor="let task of phases[workshop!.phase].tasks"
[class.item-dimmed]="task.code == 'submit' && !showSubmit" (click)="runTask(task)" detail="false">
<ion-icon slot="start" name="far-circle" *ngIf="task.completed == null" aria-hidden="true"></ion-icon>
<ion-icon slot="start" name="fas-times-circle" color="danger" *ngIf="task.completed == ''" aria-hidden="true">

View File

@ -31,7 +31,7 @@
</ion-item>
<ion-item class="ion-text-wrap" *ngFor="let task of phase.tasks"
[class.item-dimmed]="phase.code != workshopPhase || (task.code == 'submit' && !showSubmit)"
(click)="runTask(task)" detail="false">
(click)="runTask(task)" detail="false" button>
<ion-icon slot="start" name="far-circle" *ngIf="task.completed == null"
[attr.aria-label]="'addon.mod_workshop.tasktodo' | translate"></ion-icon>
<ion-icon slot="start" name="fas-times-circle" color="danger" *ngIf="task.completed == ''"

View File

@ -65,7 +65,8 @@
</ion-item>
</div>
<ion-item class="ion-text-wrap" *ngIf="summary" [detail]="submission.timemodified" (click)="gotoSubmission()">
<ion-item class="ion-text-wrap" *ngIf="summary" [detail]="submission.timemodified" (click)="gotoSubmission()"
[button]="submission.timemodified">
<core-user-avatar [user]="profile" slot="start" [courseId]="courseId" [userId]="profile?.id">
</core-user-avatar>
<ion-label>

View File

@ -3,8 +3,8 @@
<ion-label>{{title}}</ion-label>
</ion-list-header>
<ion-item class="ion-text-wrap" *ngFor="let item of items" core-link [capture]="item.captureLink" [autoLogin]="item.autoLogin"
[href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden"
[detail]="(item.href && !item.iconAction) || null" role="menuitem">
[href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden"
[detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)">
<ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" [attr.aria-label]="item.ariaDescription" slot="start">
</ion-icon>
<ion-label><core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text></ion-label>

View File

@ -1,7 +1,7 @@
<form (ngSubmit)="changeName(newFileName, $event)" #nameForm>
<ion-item class="ion-text-wrap item-file" (click)="fileClicked($event)"> <!-- [class.item-input]="editMode" -->
<ion-item class="ion-text-wrap item-file" (click)="fileClicked($event)" button> <!-- [class.item-input]="editMode" -->
<ion-thumbnail slot="start">
<img [src]="fileIcon" alt="{{fileExtension}}" role="presentation" />
<img [src]="fileIcon" [alt]="fileExtension" role="presentation" />
</ion-thumbnail>
<ion-label>

View File

@ -1,4 +1,4 @@
<ion-item-divider class="ion-text-wrap" (click)="gotoBlock()">
<ion-item-divider class="ion-text-wrap" (click)="gotoBlock()" role="button">
<ion-label><h2>{{ title | translate }}</h2></ion-label>
<ion-icon class="item-detail-icon" name="chevron-forward-outline" slot="end" flip-rtl aria-hidden="true"></ion-icon>
</ion-item-divider>

View File

@ -15,7 +15,7 @@
<p>{{ url }}</p>
</ion-label>
</ion-item>
<ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)" detail="false">
<ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)" detail="false" button>
<ion-avatar slot="start">
<img [src]="site.avatar" core-external-content [siteId]="site.id"
alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}"

View File

@ -1,8 +1,9 @@
<ion-item *ngIf="module && module.handlerData && module.visibleoncoursepage !== 0 && !module.handlerData.loading"
id="core-course-module-{{module.id}}" class="ion-text-wrap core-course-module-handler {{module.handlerData.class}}"
(click)="moduleClicked($event)" [title]="module.handlerData.a11yTitle" detail="false"
(click)="moduleClicked($event)" [attr.aria-label]="module.handlerData.a11yTitle" detail="false"
[ngClass]="{'item-media': module.handlerData.icon, 'item-dimmed': module.visible === 0 || module.uservisible === false,
'core-not-clickable': !module.handlerData.action || module.uservisible === false}">
'core-not-clickable': !module.handlerData.action || module.uservisible === false}"
[button]="module.handlerData.action || module.uservisible">
<img slot="start" *ngIf="module.handlerData.icon" [src]="module.handlerData.icon" [alt]="modNameTranslated"
class="core-module-icon">
@ -68,7 +69,7 @@
<!-- Loading. -->
<ion-item *ngIf="module && module.handlerData && module.visibleoncoursepage !== 0 && module.handlerData.loading" role="status"
class="ion-text-wrap" id="core-course-module-{{module.id}}" [title]="module.handlerData.a11yTitle"
class="ion-text-wrap" id="core-course-module-{{module.id}}" [attr.aria-label]="module.handlerData.a11yTitle"
[ngClass]="['core-course-module-handler', 'core-module-loading', module.handlerData.class]" detail="false">
<ion-label><ion-spinner></ion-spinner></ion-label>
</ion-item>

View File

@ -1,4 +1,5 @@
<ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [title]="item.courseName">
<ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [attr.aria-label]="item.courseName"
button>
<ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ item.courseName }}</h2>

View File

@ -19,8 +19,8 @@
</div>
</div>
<div class="core-course-thumb-parallax-content" *ngIf="course">
<ion-item class="ion-text-wrap" (click)="openCourse()" [title]="course.fullname"
[detail]="!avoidOpenCourse && canAccessCourse">
<ion-item class="ion-text-wrap" (click)="openCourse()" [attr.aria-label]="course.fullname"
[detail]="!avoidOpenCourse && canAccessCourse" [button]="!avoidOpenCourse && canAccessCourse">
<ion-icon name="fas-graduation-cap" fixed-width slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>
@ -103,7 +103,7 @@
<ion-label><p>{{ 'core.courses.notenrollable' | translate }}</p></ion-label>
</ion-item>
<ion-item *ngIf="canAccessCourse && downloadCourseEnabled" (click)="prefetchCourse()" detail="false"
[attr.aria-label]="prefetchCourseData.statusTranslatable | translate">
[attr.aria-label]="prefetchCourseData.statusTranslatable | translate" button>
<ion-icon *ngIf="(prefetchCourseData.status != statusDownloaded) && !prefetchCourseData.loading"
[name]="prefetchCourseData.icon" slot="start" aria-hidden="true">
</ion-icon>
@ -114,11 +114,11 @@
<ion-spinner *ngIf="prefetchCourseData.loading" slot="start"></ion-spinner>
<ion-label><h2>{{ 'core.course.downloadcourse' | translate }}</h2></ion-label>
</ion-item>
<ion-item (click)="openCourse()" [title]="course.fullname" *ngIf="!avoidOpenCourse && canAccessCourse">
<ion-item button (click)="openCourse()" [attr.aria-label]="course.fullname" *ngIf="!avoidOpenCourse && canAccessCourse">
<ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon>
<ion-label><h2>{{ 'core.course.contents' | translate }}</h2></ion-label>
</ion-item>
<ion-item [href]="courseUrl" core-link [title]="course.fullname">
<ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname">
<ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
<ion-label><h2>{{ 'core.openinbrowser' | translate }}</h2></ion-label>
</ion-item>

View File

@ -1,5 +1,5 @@
<ion-item class="ion-text-wrap" (click)="openCourse()" [class.item-disabled]="course.visible == 0"
[title]="course.displayname || course.fullname" detail>
[attr.aria-label]="course.displayname || course.fullname" detail="true" button>
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" slot="start" class="course-icon"
[attr.course-color]="course.color ? null : course.colorNumber" [style.color]="course.color"></ion-icon>
<ion-avatar *ngIf="course.courseImage" slot="start">

View File

@ -3,7 +3,7 @@
[style.background-color]="course.color">
<img *ngIf="course.courseImage" [src]="course.courseImage" core-external-content alt=""/>
</div>
<ion-item button lines="none" (click)="openCourse()" [title]="course.displayname || course.fullname"
<ion-item button lines="none" (click)="openCourse()" [attr.aria-label]="course.displayname || course.fullname"
class="core-course-header" [class.item-disabled]="course.visible == 0"
[class.core-course-more-than-title]="course.progress! >= 0">
<ion-label

View File

@ -40,8 +40,8 @@
</ion-item-divider>
<section *ngFor="let category of categories">
<ion-item class="ion-text-wrap" router-direction="forward"
[routerLink]="['/main/home/courses/categories', category.id]"
[title]="category.name" detail>
[routerLink]="['/main/home/courses/categories', category.id]"
[attr.aria-label]="category.name" detail="true">
<ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.category' | translate"></ion-icon>
<ion-label>
<h2>

View File

@ -21,11 +21,11 @@
<ion-list *ngIf="!courses.empty">
<ion-item
*ngFor="let course of courses.items"
[title]="course.courseFullName"
[attr.aria-label]="course.courseFullName"
[attr.aria-current]="courses.getItemAriaCurrent(course)"
class="ion-text-wrap"
button
detail
detail="true"
(click)="courses.select(course)"
>
<ion-label>

View File

@ -74,7 +74,7 @@
<ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label>
</ion-item>
<ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon"
(click)="oauthClicked(provider)" title="{{provider.name}}">
(click)="oauthClicked(provider)" [attr.aria-label]="provider.name">
<img [src]="provider.iconurl" alt="" width="32" height="32" slot="start">
<ion-label>{{provider.name}}</ion-label>
</ion-item>

View File

@ -85,7 +85,7 @@
<ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label>
</ion-item>
<ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon"
(click)="oauthClicked(provider)" title="{{provider.name}}">
(click)="oauthClicked(provider)" [attr.aria-label]="provider.name">
<img [src]="provider.iconurl" alt="" width="32" height="32" slot="start">
<ion-label>{{provider.name}}</ion-label>
</ion-item>

View File

@ -119,7 +119,7 @@
<!-- Template site selector. -->
<ng-template #site let-site="site">
<ion-item button (click)="connect($event, site.url, site)" [title]="site.name" detail>
<ion-item button (click)="connect($event, site.url, site)" [attr.aria-label]="site.name" detail="true">
<ion-thumbnail *ngIf="siteFinderSettings.displayimage" slot="start">
<img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'">
<img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon">

View File

@ -25,7 +25,7 @@
<ion-label><ion-spinner></ion-spinner></ion-label>
</ion-item>
<ion-item button *ngFor="let handler of handlers" [ngClass]="['core-moremenu-handler', handler.class || '']"
(click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true" detail>
(click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true" detail="true">
<ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ handler.title | translate}}</h2>
@ -36,48 +36,48 @@
</ion-item>
<ng-container *ngFor="let item of customItems">
<ion-item button *ngIf="item.type != 'embedded'" [href]="item.url" [attr.aria-label]="item.label" core-link
[capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail>
[capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail="true">
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{item.label}}</h2>
</ion-label>
</ion-item>
<ion-item button *ngIf="item.type == 'embedded'" (click)="openItem(item)" [attr.aria-label]="item.label"
class="core-moremenu-customitem" detail>
class="core-moremenu-customitem" detail="true">
<ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{item.label}}</h2>
</ion-label>
</ion-item>
</ng-container>
<ion-item button *ngIf="showScanQR" (click)="scanQR()" detail>
<ion-item button *ngIf="showScanQR" (click)="scanQR()" detail="true">
<ion-icon name="fas-qrcode" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.scanqr' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item button *ngIf="showWeb && siteInfo" [href]="siteInfo.siteurl" core-link autoLogin="yes"
[attr.aria-label]="'core.mainmenu.website' | translate" detail>
[attr.aria-label]="'core.mainmenu.website' | translate" detail="true">
<ion-icon name="fas-globe" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.mainmenu.website' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item button *ngIf="showHelp" [href]="docsUrl" core-link autoLogin="no"
[attr.aria-label]="'core.mainmenu.help' | translate" detail>
[attr.aria-label]="'core.mainmenu.help' | translate" detail="true">
<ion-icon name="far-life-ring" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.mainmenu.help' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item button router-direction="forward" routerLink="preferences"
[attr.aria-label]="'core.settings.preferences' | translate" detail>
[attr.aria-label]="'core.settings.preferences' | translate" detail="true">
<ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.settings.preferences' | translate }}</h2>
</ion-label>
</ion-item>
<ion-item button (click)="logout()" [attr.aria-label]="logoutLabel | translate" detail>
<ion-item button (click)="logout()" [attr.aria-label]="logoutLabel | translate" detail="true">
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ logoutLabel | translate }}</h2>
@ -85,7 +85,7 @@
</ion-item>
<ion-item-divider><ion-label></ion-label></ion-item-divider>
<ion-item button router-direction="forward" routerLink="settings"
[attr.aria-label]="'core.settings.appsettings' | translate" detail>
[attr.aria-label]="'core.settings.appsettings' | translate" detail="true">
<ion-icon name="fas-cogs" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.settings.appsettings' | translate }}</h2>

View File

@ -1,5 +1,5 @@
<ion-item *ngIf="item && item!.canviewaggregate && labelKey && !disabled" class="ion-text-wrap"
[detail]="ratingInfo.canviewall && item!.count" (click)="openRatings()">
[detail]="ratingInfo.canviewall && item!.count" (click)="openRatings()" [button]="ratingInfo.canviewall && item!.count">
<ion-label>
{{ labelKey | translate }}{{ 'core.labelsep' | translate }} {{ item!.aggregatestr || '-' }}
<span *ngIf="showCount && item!.count && item!.count! > 0">({{ item!.count! }})</span>

View File

@ -13,15 +13,15 @@
<ion-item class="ion-text-wrap">
<ion-label><h2>{{ appName }} {{ versionName }}</h2></ion-label>
</ion-item>
<ion-item button class="ion-text-wrap" (click)="openPage('licenses')" detail>
<ion-item button class="ion-text-wrap" (click)="openPage('licenses')" detail="true">
<ion-icon name="far-copyright" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'core.settings.opensourcelicenses' | translate }}</ion-label>
</ion-item>
<ion-item button class="ion-text-wrap" *ngIf="privacyPolicy" [href]="privacyPolicy" core-link auto-login="no" detail>
<ion-item button class="ion-text-wrap" *ngIf="privacyPolicy" [href]="privacyPolicy" core-link auto-login="no" detail="true">
<ion-icon name="fas-user-shield" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'core.settings.privacypolicy' | translate }}</ion-label>
</ion-item>
<ion-item button class="ion-text-wrap" (click)="openPage('deviceinfo')" detail>
<ion-item button class="ion-text-wrap" (click)="openPage('deviceinfo')" detail="true">
<ion-icon name="fas-mobile" slot="start" aria-hidden="true"></ion-icon>
<ion-label>{{ 'core.settings.deviceinfo' | translate }}</ion-label>
</ion-item>

View File

@ -28,7 +28,7 @@
<ion-item-divider><ion-label></ion-label></ion-item-divider>
<ion-item *ngFor="let handler of handlers.items" [ngClass]="['core-settings-handler', handler.class]"
[title]="handler.title | translate" detail="true" (click)="handlers.select(handler)" button
[attr.aria-label]="handler.title | translate" detail="true" (click)="handlers.select(handler)" button
[attr.aria-current]="handlers.getItemAriaCurrent(handler)">
<ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon" aria-hidden="true">
</ion-icon>

View File

@ -15,7 +15,7 @@
<p>{{fileName}}</p>
</ion-label>
</ion-item>
<ion-item *ngFor="let site of sites" (click)="storeInSite(site.id)" detail="false">
<ion-item *ngFor="let site of sites" (click)="storeInSite(site.id)" detail="false" button>
<ion-avatar slot="start" aria-hidden="true">
<img [src]="site.avatar" core-external-content [siteId]="site.id"
alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}"

View File

@ -61,7 +61,7 @@
</ion-content>
<ng-template #allCourseList>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/all" detail>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/all" detail="true">
<ion-icon name="fas-graduation-cap" fixed-width slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.courses.availablecourses' | translate}}</h2>
@ -75,7 +75,7 @@
</ng-template>
<ng-template #categories>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/categories" detail>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/categories" detail="true">
<ion-icon name="fas-folder" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.courses.categories' | translate}}</h2>
@ -84,7 +84,7 @@
</ng-template>
<ng-template #enrolledCourseList>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/my" detail>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/my" detail="true">
<ion-icon name="fas-graduation-cap" fixed-width slot="start" aria-hidden="true">
</ion-icon>
<ion-label><h2>{{ 'core.courses.mycourses' | translate}}</h2></ion-label>
@ -92,7 +92,7 @@
</ng-template>
<ng-template #courseSearch>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/search" detail>
<ion-item button class="ion-text-wrap" router-direction="forward" routerLink="/main/home/courses/search" detail="true">
<ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
<ion-label><h2>{{ 'core.courses.searchcourses' | translate}}</h2></ion-label>
</ion-item>

View File

@ -1,4 +1,4 @@
<ion-item-divider class="ion-text-wrap" detail="true" (click)="gotoBlock()">
<ion-item-divider class="ion-text-wrap" detail="true" (click)="gotoBlock()" role="button">
<ion-label>
<h2>{{ title | translate }}</h2>
</ion-label>

View File

@ -18,8 +18,8 @@
<ion-icon slot="start" name="fas-exclamation-triangle" color="warning" aria-hidden="true"></ion-icon>
<ion-label class="ion-text-wrap">{{ 'core.tag.warningareasnotsupported' | translate }}</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngFor="let area of areas" [title]="area.nameKey | translate"
(click)="openArea(area)" [attr.aria-current]="area!.id == selectedAreaId ? 'page' : 'false'">
<ion-item class="ion-text-wrap" *ngFor="let area of areas" [attr.aria-label]="area.nameKey | translate"
(click)="openArea(area)" [attr.aria-current]="area!.id == selectedAreaId ? 'page' : 'false'" button>
<ion-label>
<h2>{{ area!.nameKey | translate }}</h2>
</ion-label>

View File

@ -29,7 +29,7 @@
<ion-list *ngIf="!participants.empty">
<ion-item *ngFor="let participant of participants.items"
class="ion-text-wrap" [attr.aria-current]="participants.getItemAriaCurrent(participant)"
[title]="participant.fullname" (click)="participants.select(participant)">
[attr.aria-label]="participant.fullname" (click)="participants.select(participant)" button>
<core-user-avatar [user]="participant" [linkProfile]="false" [checkOnline]="true" slot="start">
</core-user-avatar>

View File

@ -49,7 +49,7 @@
<ion-item button class="ion-text-wrap core-user-profile-handler" (click)="openUserDetails()"
[attr.aria-label]="'core.user.details' | translate" detail>
[attr.aria-label]="'core.user.details' | translate" detail="true">
<ion-icon name="fa-user" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ 'core.user.details' | translate }}</h2>
@ -61,7 +61,7 @@
<ion-item button *ngFor="let handler of newPageHandlers" class="ion-text-wrap" (click)="handlerClicked($event, handler)"
[ngClass]="['core-user-profile-handler', handler.class || '']" [hidden]="handler.hidden"
[attr.aria-label]="handler.title | translate" detail>
[attr.aria-label]="handler.title | translate" detail="true">
<ion-icon *ngIf="handler.icon" [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<h2>{{ handler.title | translate }}</h2>