Merge pull request #14 from PoongalOO/modern-events/ticket7

modernisation des événements d’entrée
This commit is contained in:
PoongalOO 2026-06-08 23:22:48 +02:00 committed by GitHub
commit c4fea9c6b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 84 additions and 15 deletions

View File

@ -15,6 +15,7 @@ La compatibilité avec tous les navigateurs et appareils modernes n'est pas enco
## Modifications réalisées
- Migration des enregistrements d'événements internes depuis les anciens patterns jQuery `.bind()` / `.unbind()` vers `.on()` / `.off()`.
- Modernisation des événements d'entrée pour privilégier Pointer Events quand ils sont disponibles, tout en conservant les chemins touch et souris en fallback.
- Ajout de namespaces d'événements :
- `.turn` pour les événements du livre et du document ;
- `.turnFlip` pour les événements internes des pages pliées.

View File

@ -15,6 +15,7 @@ Compatibility is not yet guaranteed for every modern browser or device. Safari/W
## What Changed
- Updated internal event registration from deprecated jQuery `.bind()` / `.unbind()` patterns to `.on()` / `.off()`.
- Modernized input events to prefer Pointer Events when available, with the existing touch and mouse paths kept as fallbacks.
- Added event namespaces:
- `.turn` for book-level and document-level turn.js events.
- `.turnFlip` for internal flip-page events.

View File

@ -23,6 +23,11 @@ function createFixture(pageCount = 4, windowOptions = {}) {
});
Object.entries(windowOptions).forEach(([key, value]) => {
if (value === undefined) {
delete dom.window[key];
return;
}
Object.defineProperty(dom.window, key, {
value,
configurable: true,
@ -718,16 +723,67 @@ describe('turn.js jQuery plugin', () => {
.map(call => call[0])
.filter(name => typeof name === 'string');
const pointerEvents = $.isTouch
? ['touchstart.turn', 'touchmove.turn', 'touchend.turn']
: ['mousedown.turn', 'mousemove.turn', 'mouseup.turn'];
expect(eventNames).toContain('turned.turn');
expect(eventNames).toEqual(expect.arrayContaining(pointerEvents));
expect(eventNames).toContain('pointerdown.turn');
expect(eventNames).toContain('pointermove.turn');
expect(eventNames).toContain('pointerup.turn pointercancel.turn');
expect(eventNames).toContain('pressed.turnFlip');
expect(eventNames).toContain('released.turnFlip');
expect(eventNames).toContain('start.turnFlip');
expect(eventNames).toContain('end.turnFlip');
expect(eventNames).toContain('flip.turnFlip');
});
it('falls back to touch events when Pointer Events are unavailable', () => {
fixture.window.close();
fixture = createFixture(4, {
PointerEvent: undefined
});
const { $ } = fixture;
const onSpy = vi.spyOn($.fn, 'on');
$('#book').turn({
width: 600,
height: 400,
display: 'double',
gradients: false,
acceleration: false
});
const eventNames = onSpy.mock.calls
.map(call => call[0])
.filter(name => typeof name === 'string');
expect(eventNames).toContain('touchstart.turn');
expect(eventNames).toContain('touchmove.turn');
expect(eventNames).toContain('touchend.turn');
});
it('removes pointer event handlers on destroy', () => {
fixture.window.close();
fixture = createFixture();
const { $ } = fixture;
const offSpy = vi.spyOn($.fn, 'off');
const $book = $('#book');
$book.turn({
width: 600,
height: 400,
display: 'double',
gradients: false,
acceleration: false
});
$book.turn('destroy');
const eventNames = offSpy.mock.calls
.map(call => call[0])
.filter(name => typeof name === 'string');
expect(eventNames).toContain('pointerdown.turn');
expect(eventNames).toContain('pointermove.turn');
expect(eventNames).toContain('pointerup.turn pointercancel.turn');
});
});

29
turn.js
View File

@ -29,9 +29,14 @@ var has3d,
A90 = PI/2,
hasPointer = 'PointerEvent' in window,
isTouch = 'ontouchstart' in window,
events = (isTouch) ? {start: 'touchstart', move: 'touchmove', end: 'touchend'}
usesTouchEvents = !hasPointer && isTouch,
events = (hasPointer) ? {start: 'pointerdown', move: 'pointermove', end: 'pointerup pointercancel'}
: (usesTouchEvents) ? {start: 'touchstart', move: 'touchmove', end: 'touchend'}
: {start: 'mousedown', move: 'mousemove', end: 'mouseup'},
frameTime = (window.performance && window.performance.now) ?
@ -207,6 +212,12 @@ var has3d,
return Object.prototype.hasOwnProperty.call(object, property);
},
namespacedEvents = function(names, namespace) {
return $.map(names.split(' '), function(name) {
return name + namespace;
}).join(' ');
},
clamp = function(value, min, max) {
value = parseFloat(value);
return Math.max(min, Math.min(max, isNaN(value) ? min : value));
@ -474,10 +485,10 @@ turnMethods = {
}
};
$(this).on(events.start + turnEventNamespace, data.eventHandlers.start);
$(this).on(namespacedEvents(events.start, turnEventNamespace), data.eventHandlers.start);
$(document).on(events.move + turnEventNamespace, data.eventHandlers.move).
on(events.end + turnEventNamespace, data.eventHandlers.end);
$(document).on(namespacedEvents(events.move, turnEventNamespace), data.eventHandlers.move).
on(namespacedEvents(events.end, turnEventNamespace), data.eventHandlers.end);
data.done = true;
@ -500,10 +511,10 @@ turnMethods = {
this.off(turnEventNamespace);
if (data.eventHandlers) {
this.off(events.start + turnEventNamespace, data.eventHandlers.start);
this.off(namespacedEvents(events.start, turnEventNamespace), data.eventHandlers.start);
$(document).
off(events.move + turnEventNamespace, data.eventHandlers.move).
off(events.end + turnEventNamespace, data.eventHandlers.end);
off(namespacedEvents(events.move, turnEventNamespace), data.eventHandlers.move).
off(namespacedEvents(events.end, turnEventNamespace), data.eventHandlers.end);
}
for (page in data.pageObjs) {
@ -1569,7 +1580,7 @@ flipMethods = {
return false;
}
e = (isTouch) ? e.originalEvent.touches : [e];
e = (usesTouchEvents) ? e.originalEvent.touches : [e];
var data = flipData(this),
pos = data.parent.offset(),
@ -2066,7 +2077,7 @@ flipMethods = {
var data = this.data().f;
if (!data.disabled) {
e = (isTouch) ? e.originalEvent.touches : [e];
e = (usesTouchEvents) ? e.originalEvent.touches : [e];
if (data.corner) {

2
turn.min.js vendored

File diff suppressed because one or more lines are too long