Merge pull request #11165 from ahocevar/dragrotate-defaultcondition

Use drag-pan default condition with onFocusOnly
This commit is contained in:
Andreas Hocevar
2020-06-13 09:56:44 +02:00
committed by GitHub
5 changed files with 104 additions and 26 deletions

View File

@@ -13,6 +13,29 @@ import {assert} from '../asserts.js';
* @typedef {function(this: ?, import("../MapBrowserEvent.js").default): boolean} Condition
*/
/**
* Creates a condition function that passes when all provided conditions pass.
* @param {...Condition} var_args Conditions to check.
* @return {Condition} Condition function.
*/
export function all(var_args) {
const conditions = arguments;
/**
* @param {import("../MapBrowserEvent.js").default} event Event.
* @return {boolean} All conditions passed.
*/
return function (event) {
let pass = true;
for (let i = 0, ii = conditions.length; i < ii; ++i) {
pass = pass && conditions[i](event);
if (!pass) {
break;
}
}
return pass;
};
}
/**
* Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when
* additionally the shift-key is pressed).

View File

@@ -12,7 +12,6 @@ import Kinetic from './Kinetic.js';
import MouseWheelZoom from './interaction/MouseWheelZoom.js';
import PinchRotate from './interaction/PinchRotate.js';
import PinchZoom from './interaction/PinchZoom.js';
import {focusWithTabindex} from './events/condition.js';
export {default as DoubleClickZoom} from './interaction/DoubleClickZoom.js';
export {default as DragAndDrop} from './interaction/DragAndDrop.js';
@@ -112,7 +111,7 @@ export function defaults(opt_options) {
if (dragPan) {
interactions.push(
new DragPan({
condition: options.onFocusOnly ? focusWithTabindex : undefined,
onFocusOnly: options.onFocusOnly,
kinetic: kinetic,
})
);
@@ -149,7 +148,7 @@ export function defaults(opt_options) {
if (mouseWheelZoom) {
interactions.push(
new MouseWheelZoom({
condition: options.onFocusOnly ? focusWithTabindex : undefined,
onFocusOnly: options.onFocusOnly,
duration: options.zoomDuration,
})
);

View File

@@ -5,8 +5,13 @@ import PointerInteraction, {
centroid as centroidFromPointers,
} from './Pointer.js';
import {FALSE} from '../functions.js';
import {
all,
focusWithTabindex,
noModifierKeys,
primaryAction,
} from '../events/condition.js';
import {easeOut} from '../easing.js';
import {noModifierKeys, primaryAction} from '../events/condition.js';
import {
rotate as rotateCoordinate,
scale as scaleCoordinate,
@@ -17,8 +22,8 @@ import {
* @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean
* to indicate whether that event should be handled.
* Default is {@link module:ol/events/condition~noModifierKeys} and {@link module:ol/events/condition~primaryAction}.
* In addition, if there is a `tabindex` attribute on the map element,
* {@link module:ol/events/condition~focus} will also be applied.
* @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,
* the interaction will only handle events when the map has the focus.
* @property {import("../Kinetic.js").default} [kinetic] Kinetic inertia to apply to the pan.
*/
@@ -59,11 +64,17 @@ class DragPan extends PointerInteraction {
*/
this.panning_ = false;
const condition = options.condition
? options.condition
: all(noModifierKeys, primaryAction);
/**
* @private
* @type {import("../events/condition.js").Condition}
*/
this.condition_ = options.condition ? options.condition : defaultCondition;
this.condition_ = options.onFocusOnly
? all(focusWithTabindex, condition)
: condition;
/**
* @private
@@ -175,12 +186,4 @@ class DragPan extends PointerInteraction {
}
}
/**
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.
* @return {boolean} Combined condition result.
*/
function defaultCondition(mapBrowserEvent) {
return noModifierKeys(mapBrowserEvent) && primaryAction(mapBrowserEvent);
}
export default DragPan;

View File

@@ -4,7 +4,7 @@
import EventType from '../events/EventType.js';
import Interaction, {zoomByDelta} from './Interaction.js';
import {DEVICE_PIXEL_RATIO, FIREFOX} from '../has.js';
import {always} from '../events/condition.js';
import {all, always, focusWithTabindex} from '../events/condition.js';
import {clamp} from '../math.js';
/**
@@ -21,8 +21,8 @@ export const Mode = {
* takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
* boolean to indicate whether that event should be handled. Default is
* {@link module:ol/events/condition~always}.
* In addition, if there is a `tabindex` attribute on the map element,
* {@link module:ol/events/condition~focus} will also be applied.
* @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,
* the interaction will only handle events when the map has the focus.
* @property {number} [maxDelta=1] Maximum mouse wheel delta.
* @property {number} [duration=250] Animation duration in milliseconds.
* @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.
@@ -96,11 +96,15 @@ class MouseWheelZoom extends Interaction {
? options.constrainResolution
: false;
const condition = options.condition ? options.condition : always;
/**
* @private
* @type {import("../events/condition.js").Condition}
*/
this.condition_ = options.condition ? options.condition : always;
this.condition_ = options.onFocusOnly
? all(focusWithTabindex, condition)
: condition;
/**
* @private

View File

@@ -27,7 +27,6 @@ import {
useGeographic,
} from '../../../src/ol/proj.js';
import {defaults as defaultInteractions} from '../../../src/ol/interaction.js';
import {focusWithTabindex} from '../../../src/ol/events/condition.js';
describe('ol.Map', function () {
describe('constructor', function () {
@@ -703,7 +702,7 @@ describe('ol.Map', function () {
});
describe('create interactions', function () {
let options;
let options, event, hasTabIndex, hasFocus, isPrimary;
beforeEach(function () {
options = {
@@ -716,6 +715,33 @@ describe('ol.Map', function () {
pinchRotate: false,
pinchZoom: false,
};
hasTabIndex = true;
hasFocus = true;
isPrimary = true;
event = {
map: {
getTargetElement: function () {
return {
hasAttribute: function (attribute) {
return hasTabIndex;
},
};
},
},
originalEvent: {
isPrimary: isPrimary,
button: 0,
},
target: {
getTargetElement: function () {
return {
contains: function () {
return hasFocus;
},
};
},
},
};
});
describe('create mousewheel interaction', function () {
@@ -729,11 +755,19 @@ describe('ol.Map', function () {
expect(interactions.item(0).useAnchor_).to.eql(false);
expect(interactions.item(0).condition_).to.be(TRUE);
});
it('uses the focus condition when onFocusOnly option is set', function () {
it('does not use the default condition when onFocusOnly option is set', function () {
options.onFocusOnly = true;
options.mouseWheelZoom = true;
const interactions = defaultInteractions(options);
expect(interactions.item(0).condition_).to.be(focusWithTabindex);
expect(interactions.item(0).condition_).to.not.be(TRUE);
hasTabIndex = true;
hasFocus = true;
expect(interactions.item(0).condition_(event)).to.be(true);
hasTabIndex = true;
hasFocus = false;
expect(interactions.item(0).condition_(event)).to.be(false);
hasTabIndex = false;
expect(interactions.item(0).condition_(event)).to.be(true);
});
});
@@ -743,13 +777,28 @@ describe('ol.Map', function () {
const interactions = defaultInteractions(options);
expect(interactions.getLength()).to.eql(1);
expect(interactions.item(0)).to.be.a(DragPan);
expect(interactions.item(0).condition_).to.not.be(focusWithTabindex);
expect(interactions.item(0).condition_(event)).to.be(true);
hasTabIndex = true;
hasFocus = false;
expect(interactions.item(0).condition_(event)).to.be(true);
event.originalEvent.altKey = true;
expect(interactions.item(0).condition_(event)).to.be(false);
delete event.originalEvent.altKey;
event.originalEvent.button = 1;
expect(interactions.item(0).condition_(event)).to.be(false);
});
it('uses the focus condition when onFocusOnly option is set', function () {
it('does not use the default condition when onFocusOnly option is set', function () {
options.onFocusOnly = true;
options.dragPan = true;
const interactions = defaultInteractions(options);
expect(interactions.item(0).condition_).to.be(focusWithTabindex);
hasTabIndex = true;
hasFocus = true;
expect(interactions.item(0).condition_(event)).to.be(true);
hasTabIndex = true;
hasFocus = false;
expect(interactions.item(0).condition_(event)).to.be(false);
hasTabIndex = false;
expect(interactions.item(0).condition_(event)).to.be(true);
});
});