Improved event handling
gitea/salix/dev This commit looks good Details

This commit is contained in:
Juan Ferrer 2019-10-24 10:17:32 +02:00
parent 2a4d3ae43d
commit 4685b4166b
31 changed files with 79 additions and 92 deletions

View File

@ -48,5 +48,5 @@
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
on-data-ready="$ctrl.onDataReady()"
on-close-start="$ctrl.focus()">
on-close-start="$ctrl.onDropDownClose()">
</vn-drop-down>

View File

@ -209,6 +209,10 @@ export default class Autocomplete extends Field {
this.field = value;
}
onDropDownClose() {
setTimeout(() => this.focus());
}
onContainerKeyDown(event) {
if (event.defaultPrevented) return;
@ -224,13 +228,10 @@ export default class Autocomplete extends Field {
else
return;
}
event.preventDefault();
}
onContainerClick(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.showDropDown();
}

View File

@ -15,6 +15,5 @@
</button>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
on-select="$ctrl.onDropDownSelect(item)">
</vn-drop-down>

View File

@ -44,15 +44,10 @@ export default class ButtonMenu extends Button {
onClick(event) {
if (this.disabled) return;
if (event.defaultPrevented) return;
event.preventDefault();
this.emit('open');
this.showDropDown();
}
onDropDownClick(event) {
event.preventDefault();
}
onDropDownSelect(item) {
const value = item[this.valueField];
this.field = value;

View File

@ -6,11 +6,8 @@ export default class Button extends FormInput {
constructor($element, $scope) {
super($element, $scope);
this.design = 'colored';
this.input = this.element.querySelector('button');
let element = this.element;
element.tabIndex = 0;
element.classList.add('vn-button');
this.initTabIndex();
this.classList.add('vn-button');
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
}
@ -21,16 +18,17 @@ export default class Button extends FormInput {
}
onKeyup(event) {
if (event.code == 'Space')
this.onClick(event);
if (event.defaultPrevented) return;
switch (event.code) {
case 'Space':
case 'Enter':
return this.element.click();
}
}
onClick(event) {
if (event.defaultPrevented) return;
// event.preventDefault();
// FIXME: Don't stop event propagation
if (this.disabled) event.stopImmediatePropagation();
if (this.disabled)
event.stopImmediatePropagation();
}
}
Button.$inject = ['$element', '$scope'];

View File

@ -1 +0,0 @@
<div></div>

View File

@ -218,17 +218,14 @@ export default class DropDown extends Component {
onLoadMoreClick(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.model.loadMore();
}
onContainerClick(event) {
if (event.defaultPrevented) return;
let index = getPosition(this.$.ul, event);
if (index != -1) {
event.preventDefault();
if (index != -1)
this.selectOption(index);
}
}
onDocKeyDown(event) {

View File

@ -155,7 +155,6 @@ export default class Field extends FormInput {
onClick() {
// if (event.defaultPrevented) return;
// event.preventDefault();
if (this.input !== document.activeElement)
this.focus();
@ -173,7 +172,6 @@ export default class Field extends FormInput {
onClear(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.field = null;
this.input.dispatchEvent(new Event('change'));
}

View File

@ -88,13 +88,19 @@ export default class FormInput extends Component {
}
select() {
this.inputEl.select();
if (this.inputEl.select)
this.inputEl.select();
}
focus() {
this.inputEl.focus();
}
initTabIndex() {
if (!this.element.hasAttribute('tabindex'))
this.element.tabIndex = 0;
}
refreshTabIndex() {
this.inputEl.tabIndex = this.disabled ? -1 : this.tabIndex;
}

View File

@ -68,7 +68,6 @@ export default class InputNumber extends Field {
onStep(event, way) {
if (event.defaultPrevented) return;
event.preventDefault();
if (way == 'up')
this.stepUp();

View File

@ -190,7 +190,6 @@ export default class Popover extends Component {
onBgMouseDown(event) {
if (event == this.lastMouseEvent || event.defaultPrevented) return;
event.preventDefault();
this.hide();
}
}

View File

@ -65,7 +65,6 @@ export default class Controller extends Component {
openPanel(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.$panelScope = this.$.$new();
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);

View File

@ -81,18 +81,6 @@ describe('Component vnSearchbar', () => {
});
});
describe('openPanel()', () => {
it(`should do nothing if the event is prevented`, () => {
let event = {
defaultPrevented: true,
preventDefault: jasmine.createSpy('preventDefault')
};
controller.openPanel(event);
expect(event.preventDefault).not.toHaveBeenCalledWith();
});
});
describe('onPopoverClose()', () => {
it(`should get rid of $panel and $panelScope`, () => {
controller.$panel = {

View File

@ -10,24 +10,20 @@ import './style.scss';
export default class Toggle extends FormInput {
constructor($element, $) {
super($element, $);
let element = this.element;
element.tabIndex = 0;
element.addEventListener('click', e => this.onClick(e));
element.addEventListener('keydown', e => this.onKeydown(e));
element.classList.add('vn-toggle');
this.initTabIndex();
this.classList.add('vn-toggle');
this.element.addEventListener('click', e => this.onClick(e));
this.element.addEventListener('keydown', e => this.onKeydown(e));
}
onKeydown(event) {
if (event.code == 'Space')
this.onClick(event);
if (!event.defaultPrevented && event.code == 'Space')
this.element.click();
}
onClick(event) {
if (!this.editable || event.defaultPrevented)
return true;
event.preventDefault();
}
changed() {

View File

@ -235,7 +235,6 @@ export function directive($document, $compile, $templateRequest) {
$element[0].title = '';
$element.on('mouseover', function(event) {
if (event.defaultPrevented) return;
event.preventDefault();
tooltip.show($element[0]);
});
$element.on('mouseout', function() {

View File

@ -9,12 +9,12 @@
<section class="buttons" ng-if="::!$ctrl.treeview.readOnly">
<vn-icon-button translate-attr="::{title: 'Remove'}"
icon="delete"
ng-click="$ctrl.treeview.onRemove($ctrl.item)"
ng-click="$ctrl.treeview.onRemove($event, $ctrl.item)"
ng-if="$ctrl.item.parent">
</vn-icon-button>
<vn-icon-button translate-attr="::{title: 'Create'}"
icon="add_circle"
ng-click="$ctrl.treeview.onCreate($ctrl.item)">
ng-click="$ctrl.treeview.onCreate($event, $ctrl.item)">
</vn-icon-button>
</section>
</div>

View File

@ -2,7 +2,7 @@
<ul ng-if="$ctrl.items">
<li ng-repeat="item in $ctrl.items">
<vn-treeview-child item="item" ng-class="{expanded: item.active}"
ng-click="$ctrl.onClick($event, item)">
ng-click="$ctrl.treeview.onToggle($event, item)">
</vn-treeview-child>
<vn-treeview-childs
items="item.childs">

View File

@ -1,13 +1,6 @@
import ngModule from '../../module';
import Component from '../../lib/component';
class Controller extends Component {
onClick(event, item) {
if (event.defaultPrevented || !item.sons) return;
event.preventDefault();
this.treeview.onToggle(item);
}
}
class Controller {}
ngModule.component('vnTreeviewChilds', {
template: require('./childs.html'),

View File

@ -141,7 +141,12 @@ export default class Treeview extends Component {
});
}
onToggle(item) {
onToggle(event, item) {
let ignoreEvent = event.defaultPrevented
|| event == this.lastActionEvent
|| !item.sons;
if (ignoreEvent) return;
if (item.active)
this.fold(item);
else
@ -175,7 +180,8 @@ export default class Treeview extends Component {
}).then(() => item.active = true);
}
onRemove(item) {
onRemove(event, item) {
this.lastActionEvent = event;
if (this.removeFunc)
this.removeFunc({$item: item});
}
@ -191,7 +197,8 @@ export default class Treeview extends Component {
if (parent) parent.sons--;
}
onCreate(parent) {
onCreate(event, parent) {
this.lastActionEvent = event;
if (this.createFunc)
this.createFunc({$parent: parent});
}

View File

@ -102,11 +102,16 @@ describe('Component vnTreeview', () => {
spyOn(controller, 'fold');
spyOn(controller, 'unfold');
const item = {name: 'My item'};
let event = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
const item = {name: 'My item', sons: 1};
controller.onToggle(item);
controller.onToggle(event, item);
item.active = true;
controller.onToggle(item);
controller.onToggle(event, item);
expect(controller.unfold).toHaveBeenCalledWith(item);
expect(controller.fold).toHaveBeenCalledWith(item);
@ -148,9 +153,15 @@ describe('Component vnTreeview', () => {
describe('onRemove()', () => {
it(`should call the removeFunc() method`, () => {
let event = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
spyOn(controller, 'removeFunc');
const item = {name: 'My item'};
controller.onRemove(item);
controller.onRemove(event, item);
expect(controller.removeFunc).toHaveBeenCalledWith({$item: item});
});
@ -172,9 +183,15 @@ describe('Component vnTreeview', () => {
describe('onCreate()', () => {
it(`should call the createFunc() method`, () => {
let event = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
spyOn(controller, 'createFunc');
const parent = {name: 'My item'};
controller.onCreate(parent);
controller.onCreate(event, parent);
expect(controller.createFunc).toHaveBeenCalledWith({$parent: parent});
});

View File

@ -5,8 +5,8 @@ import './style.scss';
export default class WdayPicker extends FormInput {
constructor($element, $scope, vnWeekDays) {
super($element, $scope);
this.input = {};
this.days = vnWeekDays.locales;
this.initTabIndex();
}
}
WdayPicker.$inject = ['$element', '$scope', 'vnWeekDays'];

View File

@ -1,8 +1,6 @@
@import "effects";
vn-wday-picker {
margin-top: $spacing-sm;
margin-bottom: $spacing-md;
text-align: center;
& > span {

View File

@ -2,15 +2,14 @@ import ngModule from '../module';
directive.$inject = ['$document'];
export function directive($document) {
let modifiers = ["alt", "ctrl", "meta", "shift"];
let modifiers = ['alt', 'ctrl', 'meta', 'shift'];
function checkAttributes($attrs) {
let shortcut = $attrs.vnBind.split(' ');
let keys = {};
if (shortcut[0] == "") {
if (shortcut[0] == '')
throw new Error('vnBind: Binding keys not defined');
}
if (shortcut.length == 1) {
keys.altKey = true;
@ -41,7 +40,8 @@ export function directive($document) {
let correctShortcut = true;
for (const key in shortcut) {
correctShortcut = correctShortcut && shortcut[key] == event[key];
correctShortcut = correctShortcut
&& shortcut[key] == event[key];
}
if (correctShortcut) {
event.preventDefault();
@ -49,7 +49,7 @@ export function directive($document) {
}
}
$document.on("keyup", onKeyUp);
$document.on('keyup', onKeyUp);
$element.on('$destroy', function() {
$document.off('keyup', onKeyUp);
});

View File

@ -13,11 +13,11 @@ export default function directive() {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.on('click', function(event) {
if (event.defaultPrevented) return;
let dialogKey = kebabToCamel($attrs.vnDialog);
let dialog = $scope[dialogKey];
if (dialog instanceof Dialog)
dialog.show();
event.preventDefault();
});
}
};

View File

@ -12,13 +12,13 @@ export function directive() {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.on('click', function(event) {
if (event.defaultPrevented) return;
let popoverKey = kebabToCamel($attrs.vnPopover);
let popover = $scope[popoverKey];
if (popover instanceof Popover) {
popover.parent = $element[0];
popover.show();
}
event.preventDefault();
});
}
};

View File

@ -44,7 +44,7 @@ export function directive($timeout) {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.on('click', function(event) {
event.preventDefault();
if (event.defaultPrevented) return;
let src = $attrs.zoomImage || $attrs.src;
if (src)

View File

@ -39,7 +39,6 @@ export default class SideMenu {
onEscape(event) {
if (!event.defaultPrevented && event.key == 'Escape') {
event.preventDefault();
this.hide();
this.$.$digest();
}

View File

@ -116,7 +116,8 @@
</vn-vertical>
<vn-wday-picker
ng-if="$ctrl.eventType != 'day'"
ng-model="$ctrl.selected.wdays">
ng-model="$ctrl.selected.wdays"
class="vn-mt-sm vn-mb-md">
</vn-wday-picker>
<vn-date-picker
ng-if="$ctrl.eventType == 'day'"

View File

@ -62,7 +62,6 @@ class Controller extends Section {
onEditClick(row, event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.edit(row);
}

View File

@ -19,6 +19,7 @@
ng-model="item.selected"
on-change="$ctrl.onSelection(value, item)"
triple-state="true"
ng-click="$event.preventDefault()"
label="{{::item.name}}">
</vn-check>
</vn-treeview>

View File

@ -29,10 +29,9 @@
</vn-textfield>
<vn-none>
<vn-icon-button
pointer
class="vn-my-md"
vn-tooltip="Remove contact"
icon="delete"
tabindex="-1"
ng-click="model.remove($index)">
</vn-icon-button>
</vn-none>