Add real méthod turn('destroy')

This commit is contained in:
poongaloo 2026-06-08 18:39:25 +02:00
parent b3e93deac9
commit bef2197fb7
3 changed files with 201 additions and 18 deletions

View File

@ -106,6 +106,66 @@ describe('turn.js jQuery plugin', () => {
expect($book.turn('hasPage', 5)).toBe(false); expect($book.turn('hasPage', 5)).toBe(false);
}); });
it('destroys a book, restores pages and removes turn.js state', () => {
const { $ } = fixture;
const $book = $('#book');
$book.data('externalValue', 'keep-me');
$book.turn({
width: 600,
height: 400,
display: 'double',
gradients: false,
acceleration: false
});
expect($book.find('.turn-page-wrapper').length).toBeGreaterThan(0);
expect($book.children('.page').length).toBe(0);
$book.turn('destroy');
expect($book.data('externalValue')).toBe('keep-me');
expect($book.data('opts')).toBeUndefined();
expect($book.data('pages')).toBeUndefined();
expect($book.find('.turn-page-wrapper').length).toBe(0);
expect($book.find('.turn-page').length).toBe(0);
expect($book.children('.page').length).toBe(4);
expect($book.children().map((_, el) => $(el).text()).get()).toEqual([
'Page 1',
'Page 2',
'Page 3',
'Page 4'
]);
expect($book.attr('style')).toBeUndefined();
});
it('can initialize again after destroy', () => {
const { $ } = fixture;
const $book = $('#book');
$book.turn({
width: 600,
height: 400,
display: 'double',
gradients: false,
acceleration: false
});
$book.turn('destroy');
$book.turn({
width: 320,
height: 240,
display: 'single',
gradients: false,
acceleration: false
});
expect($book.turn('size')).toEqual({ width: 320, height: 240 });
expect($book.turn('display')).toBe('single');
expect($book.turn('pages')).toBe(4);
expect($book.find('.turn-page-wrapper').length).toBeGreaterThan(0);
});
it('registers internal handlers with event namespaces', () => { it('registers internal handlers with event namespaces', () => {
fixture.window.close(); fixture.window.close();
fixture = createFixture(); fixture = createFixture();

157
turn.js
View File

@ -248,8 +248,13 @@ turnMethods = {
var i, data = this.data(), ch = this.children(); var i, data = this.data(), ch = this.children();
opts = $.extend({width: this.width(), height: this.height()}, turnOptions, opts); opts = $.extend({width: this.width(), height: this.height()}, turnOptions, opts);
data.turnOriginal = {
style: this.attr('style'),
'class': this.attr('class')
};
data.opts = opts; data.opts = opts;
data.pageObjs = {}; data.pageObjs = {};
data.pageDefaults = {};
data.pages = {}; data.pages = {};
data.pageWrap = {}; data.pageWrap = {};
data.pagePlace = {}; data.pagePlace = {};
@ -279,29 +284,140 @@ turnMethods = {
// Event listeners // Event listeners
$(this).on(events.start + turnEventNamespace, function(e) { data.eventHandlers = {
for (var page in data.pages) start: function(e) {
if (has(page, data.pages) && flipMethods._eventStart.call(data.pages[page], e)===false) for (var page in data.pages)
return false; if (has(page, data.pages) && flipMethods._eventStart.call(data.pages[page], e)===false)
}); return false;
},
$(document).on(events.move + turnEventNamespace, function(e) { move: function(e) {
for (var page in data.pages) for (var page in data.pages)
if (has(page, data.pages)) if (has(page, data.pages))
flipMethods._eventMove.call(data.pages[page], e); flipMethods._eventMove.call(data.pages[page], e);
}). },
on(events.end + turnEventNamespace, function(e) { end: function(e) {
for (var page in data.pages) for (var page in data.pages)
if (has(page, data.pages)) if (has(page, data.pages))
flipMethods._eventEnd.call(data.pages[page], e); flipMethods._eventEnd.call(data.pages[page], e);
}); }
};
$(this).on(events.start + turnEventNamespace, data.eventHandlers.start);
$(document).on(events.move + turnEventNamespace, data.eventHandlers.move).
on(events.end + turnEventNamespace, data.eventHandlers.end);
data.done = true; data.done = true;
return this; return this;
}, },
// Removes turn.js behavior and restores the original page elements
destroy: function() {
var page, original,
data = this.data();
if (!data.opts)
return this;
if (data.done)
this.turn('stop');
this.off(turnEventNamespace);
if (data.eventHandlers) {
this.off(events.start + turnEventNamespace, data.eventHandlers.start);
$(document).
off(events.move + turnEventNamespace, data.eventHandlers.move).
off(events.end + turnEventNamespace, data.eventHandlers.end);
}
for (page in data.pageObjs) {
if (!has(page, data.pageObjs) || page==='0' || !data.pageObjs[page]) continue;
turnMethods._destroyPage.call(this, page);
this.append(data.pageObjs[page]);
}
if (data.pageObjs[0])
turnMethods._destroyPage.call(this, 0);
if (data.fparent)
data.fparent.remove();
original = data.turnOriginal || {};
if (original.style===undefined)
this.removeAttr('style');
else
this.attr('style', original.style);
if (original['class']===undefined)
this.removeAttr('class');
else
this.attr('class', original['class']);
$.each(['opts', 'turnOriginal', 'pageDefaults', 'pages', 'pageObjs', 'pageWrap',
'pagePlace', 'pageMv', 'totalPages', 'page', 'tpage', 'disabled',
'done', 'display', 'fparent', 'eventHandlers'], function(i, key) {
this.removeData(key);
}.bind(this));
return this;
},
// Restores one page element and removes flip wrappers/state
_destroyPage: function(page) {
var data = this.data(),
pageObj = data.pageObjs[page],
pageData,
flipData,
original = data.pageDefaults && data.pageDefaults[page];
if (!pageObj)
return;
pageData = pageObj.data();
flipData = pageData && pageData.f;
pageObj.off(turnFlipEventNamespace).animatef(false);
pageObj.detach();
if (flipData) {
if (flipData.fwrapper)
flipData.fwrapper.remove();
if (flipData.wrapper)
flipData.wrapper.remove();
}
if (data.pageWrap[page])
data.pageWrap[page].remove();
if (original) {
if (original.style===undefined)
pageObj.removeAttr('style');
else
pageObj.attr('style', original.style);
if (original['class']===undefined)
pageObj.removeAttr('class');
else
pageObj.attr('class', original['class']);
} else {
pageObj.removeClass('turn-page p' + page + ' p-temporal');
}
pageObj.removeData('f').removeData('effect');
delete data.pages[page];
delete data.pageWrap[page];
delete data.pagePlace[page];
},
// Adds a page from external data // Adds a page from external data
addPage: function(element, page) { addPage: function(element, page) {
@ -336,7 +452,12 @@ turnMethods = {
data.totalPages = lastPage; data.totalPages = lastPage;
// Add element // Add element
data.pageObjs[page] = $(element).addClass('turn-page p' + page); data.pageObjs[page] = $(element);
data.pageDefaults[page] = {
style: data.pageObjs[page].attr('style'),
'class': data.pageObjs[page].attr('class')
};
data.pageObjs[page].addClass('turn-page p' + page);
// Add page // Add page
turnMethods._addPage.call(this, page); turnMethods._addPage.call(this, page);
@ -1926,6 +2047,8 @@ $.extend($.fn, {
this.data(data); this.data(data);
f(); f();
} else { } else {
if (data.effect && data.effect.handle)
clearInterval(data.effect.handle);
delete data['effect']; delete data['effect'];
} }
} }

2
turn.min.js vendored

File diff suppressed because one or more lines are too long