MOBILE-3565 directives: Implement supress-events directive

main
Dani Palou 2020-10-19 15:35:00 +02:00
parent 13ae736480
commit 73612f5138
2 changed files with 101 additions and 0 deletions

View File

@ -13,21 +13,25 @@
// limitations under the License.
import { NgModule } from '@angular/core';
import { CoreAutoFocusDirective } from './auto-focus';
import { CoreFormatTextDirective } from './format-text';
import { CoreLongPressDirective } from './long-press.directive';
import { CoreSupressEventsDirective } from './supress-events';
@NgModule({
declarations: [
CoreAutoFocusDirective,
CoreFormatTextDirective,
CoreLongPressDirective,
CoreSupressEventsDirective,
],
imports: [],
exports: [
CoreAutoFocusDirective,
CoreFormatTextDirective,
CoreLongPressDirective,
CoreSupressEventsDirective,
],
})
export class CoreDirectivesModule {}

View File

@ -0,0 +1,97 @@
// (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.
// Based on http://roblouie.com/article/198/using-gestures-in-the-ionic-2-beta/
import { Directive, ElementRef, OnInit, Input, Output, EventEmitter } from '@angular/core';
/**
* Directive to suppress all events on an element. This is useful to prevent keyboard closing when clicking this element.
*
* This directive is based on some code posted by johnthackstonanderson in
* https://github.com/ionic-team/ionic-plugin-keyboard/issues/81
*
* @description
*
* If nothing is supplied or string 'all', then all the default events will be suppressed. This is the recommended usage.
*
* If you only want to suppress a single event just pass the name of the event. If you want to suppress a set of events,
* pass an array with the names of the events to suppress.
*
* Example usage:
*
* <a ion-button [core-suppress-events] (onClick)="toggle($event)">
*/
@Directive({
selector: '[core-suppress-events]',
})
export class CoreSupressEventsDirective implements OnInit {
@Input('core-suppress-events') suppressEvents: string | string[];
@Output() onClick = new EventEmitter(); // eslint-disable-line @angular-eslint/no-output-on-prefix
protected element: HTMLElement;
constructor(el: ElementRef) {
this.element = el.nativeElement;
}
/**
* Initialize event listeners.
*/
ngOnInit(): void {
let events: string[];
if (this.suppressEvents == 'all' || typeof this.suppressEvents == 'undefined' || this.suppressEvents === null) {
// Suppress all events.
events = ['click', 'mousedown', 'touchdown', 'touchmove', 'touchstart'];
} else if (typeof this.suppressEvents == 'string') {
// It's a string, just suppress this event.
events = [this.suppressEvents];
} else if (Array.isArray(this.suppressEvents)) {
// Array supplied.
events = this.suppressEvents;
} else {
events = [];
}
// Suppress the events.
for (const evName of events) {
this.element.addEventListener(evName, this.stopBubble.bind(this));
}
// Now listen to "click" events.
this.element.addEventListener('mouseup', (event) => { // Triggered in Android & iOS.
this.onClick.emit(event);
});
this.element.addEventListener('touchend', (event) => { // Triggered desktop & browser.
this.stopBubble(event);
this.onClick.emit(event);
});
}
/**
* Stop event default and propagation.
*
* @param event Event.
*/
protected stopBubble(event: Event): void {
event.preventDefault();
event.stopPropagation();
}
}