MOBILE-3750 a11y: Listen resize events on scrolls

main
Noel De Martin 2021-05-13 11:35:03 +02:00
parent 255aec5897
commit 0048801fa3
11 changed files with 147 additions and 29 deletions

6
package-lock.json generated
View File

@ -4224,6 +4224,12 @@
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
"dev": true
},
"@types/resize-observer-browser": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz",
"integrity": "sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ==",
"dev": true
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",

View File

@ -140,6 +140,7 @@
"@ionic/v4-migration-tslint": "^1.7.1",
"@types/faker": "^5.1.3",
"@types/node": "^12.12.64",
"@types/resize-observer-browser": "^0.1.5",
"@types/webpack-env": "^1.16.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",

View File

@ -29,9 +29,11 @@
class="core-horizontal-scroll"
(scroll)="scrollControls.updateScrollPosition()"
>
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
<ng-container *ngFor="let course of courses">
<core-courses-course-progress [course]="course" class="core-recentlyaccessedcourses"
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
</ng-container>
</div>
</div>
</core-loading>

View File

@ -12,6 +12,7 @@
class="core-horizontal-scroll"
(scroll)="scrollControls.updateScrollPosition()"
>
<div *ngIf="items" (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
<div *ngFor="let item of items">
<ion-card>
<ion-item class="core-course-module-handler item-media ion-text-wrap" detail="false" (click)="action($event, item)"
@ -33,6 +34,7 @@
</ion-card>
</div>
</div>
</div>
<core-empty-box *ngIf="items.length <= 0" image="assets/img/icons/activities.svg" inline="true"
[message]="'addon.block_recentlyaccesseditems.noitems' | translate"></core-empty-box>

View File

@ -1,7 +1,7 @@
@import "~theme/globals";
:host {
.core-horizontal-scroll > div {
.core-horizontal-scroll > div > div {
@include horizontal_scroll_item(80%, 250px, 300px);
}

View File

@ -30,9 +30,11 @@
class="core-horizontal-scroll"
(scroll)="scrollControls.updateScrollPosition()"
>
<div (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
<ng-container *ngFor="let course of courses">
<core-courses-course-progress [course]="course" class="core-block_starredcourses"
[showDownload]="downloadCourseEnabled && downloadEnabled"></core-courses-course-progress>
</ng-container>
</div>
</div>
</core-loading>

View File

@ -25,6 +25,7 @@ import { CoreLongPressDirective } from './long-press';
import { CoreSupressEventsDirective } from './supress-events';
import { CoreUserLinkDirective } from './user-link';
import { CoreAriaButtonClickDirective } from './aria-button';
import { CoreOnResizeDirective } from './on-resize';
@NgModule({
declarations: [
@ -39,6 +40,7 @@ import { CoreAriaButtonClickDirective } from './aria-button';
CoreSupressEventsDirective,
CoreUserLinkDirective,
CoreAriaButtonClickDirective,
CoreOnResizeDirective,
],
exports: [
CoreAutoFocusDirective,
@ -52,6 +54,7 @@ import { CoreAriaButtonClickDirective } from './aria-button';
CoreSupressEventsDirective,
CoreUserLinkDirective,
CoreAriaButtonClickDirective,
CoreOnResizeDirective,
],
})
export class CoreDirectivesModule {}

View File

@ -0,0 +1,99 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Directive, ElementRef, OnInit, Output, EventEmitter, OnDestroy } from '@angular/core';
import { CoreUtils } from '@services/utils/utils';
/**
* Directive to listen for element resize events.
*/
@Directive({
selector: '[onResize]',
})
export class CoreOnResizeDirective implements OnInit, OnDestroy {
@Output() onResize = new EventEmitter();
private element: HTMLElement;
private resizeObserver?: ResizeObserver;
private mutationObserver?: MutationObserver;
constructor(element: ElementRef) {
this.element = element.nativeElement;
}
/**
* @inheritdoc
*/
ngOnInit(): void {
'ResizeObserver' in window
? this.watchResize()
: this.watchMutations();
}
/**
* @inheritdoc
*/
ngOnDestroy(): void {
this.resizeObserver?.disconnect();
this.mutationObserver?.disconnect();
}
/**
* Watch resize events.
*/
private watchResize(): void {
this.resizeObserver = new ResizeObserver(() => this.onResize.emit());
this.resizeObserver.observe(this.element);
}
/**
* Watch mutation events to detect resizing.
*/
private watchMutations(): void {
let size = this.getElementSize();
const onMutation = () => {
const newSize = this.getElementSize();
if (newSize.width !== size.width || newSize.height !== size.height) {
size = newSize;
this.onResize.emit();
}
};
// Debounce 20ms to let mutations resolve before checking the new size.
this.mutationObserver = new MutationObserver(CoreUtils.debounce(onMutation, 20));
this.mutationObserver.observe(this.element, {
subtree: true,
childList: true,
characterData: true,
});
}
/**
* Get element size.
*
* @returns Element size.
*/
private getElementSize(): { width: number; height: number } {
return {
width: this.element.clientWidth,
height: this.element.clientHeight,
};
}
}

View File

@ -8,6 +8,7 @@
"cordova",
"dom-mediacapture-record",
"node",
"resize-observer-browser",
"webpack-env"
],
"paths": {

View File

@ -27,6 +27,7 @@
"faker",
"jest",
"node",
"resize-observer-browser",
"webpack-env"
],
"paths": {

View File

@ -12,7 +12,8 @@
"dom-mediacapture-record",
"faker",
"jest",
"node"
"node",
"resize-observer-browser"
],
"paths": {
"@addons/*": ["addons/*"],