MediaWiki:Gadget-autosave.js: различия между версиями
Лишняя инфа |
+ |
||
| (не показаны 2 промежуточные версии этого же участника) | |||
| Строка 5: | Строка 5: | ||
// Автосохранение срабатывает через 3 сек. после того, как вы перестали печатать | // Автосохранение срабатывает через 3 сек. после того, как вы перестали печатать | ||
// При выходе со страницы сохранение происходит мгновенно (без задержки) | // При выходе со страницы сохранение происходит мгновенно (без задержки) | ||
// | // Доступно ручное сохранение через Ctrl+S | ||
// Работает даже без интернета (если страница уже загружена) | // Работает даже без интернета (если страница уже загружена) | ||
// Не нагружает сервер, обработка на стороне устройства пользователя | // Не нагружает сервер, обработка на стороне устройства пользователя | ||
| Строка 21: | Строка 21: | ||
// Проверяем, находимся ли мы на странице редактирования | // Проверяем, находимся ли мы на странице редактирования | ||
if ( mw.config.get( 'wgAction' ) !== 'edit' && mw.config.get( 'wgAction' ) !== 'submit' ) { | if ( mw.config.get( 'wgAction' ) !== 'edit' && mw.config.get( 'wgAction' ) !== 'submit' ) { | ||
return; | return; | ||
} | } | ||
| Строка 30: | Строка 30: | ||
if ( !$textbox.length ) { | if ( !$textbox.length ) { | ||
return; | return; | ||
} | } | ||
// Настройки | // Настройки времени | ||
var config = { | var config = { | ||
saveDelay: 3000, | saveDelay: 3000, | ||
| Строка 49: | Строка 48: | ||
if ( !currentContent || currentContent.trim() === '' ) { | if ( !currentContent || currentContent.trim() === '' ) { | ||
return false; | return false; | ||
} | } | ||
if ( currentContent === lastSavedContent ) { | if ( currentContent === lastSavedContent ) { | ||
return false; | return false; | ||
} | } | ||
| Строка 67: | Строка 64: | ||
localStorage.setItem( storageKey, JSON.stringify( draftData ) ); | localStorage.setItem( storageKey, JSON.stringify( draftData ) ); | ||
lastSavedContent = currentContent; | lastSavedContent = currentContent; | ||
if ( !silent ) { | if ( !silent ) { | ||
| Строка 79: | Строка 71: | ||
return true; | return true; | ||
} catch ( e ) { | } catch ( e ) { | ||
showNotification( 'Ошибка сохранения черновика', 'error' ); | showNotification( 'Ошибка сохранения черновика', 'error' ); | ||
return false; | return false; | ||
| Строка 85: | Строка 76: | ||
} | } | ||
// Функция уведомлений | // Функция уведомлений | ||
function showNotification( message, type ) { | function showNotification( message, type ) { | ||
if ( typeof mw.notify === 'function' ) { | if ( typeof mw.notify === 'function' ) { | ||
| Строка 96: | Строка 87: | ||
} | } | ||
// Функция восстановления | // Функция восстановления | ||
function restoreDraft() { | function restoreDraft() { | ||
try { | try { | ||
var saved = localStorage.getItem( storageKey ); | var saved = localStorage.getItem( storageKey ); | ||
if ( !saved ) { | if ( !saved ) { | ||
return; | return; | ||
} | } | ||
| Строка 108: | Строка 98: | ||
var currentContent = $textbox.val(); | var currentContent = $textbox.val(); | ||
if ( draftData.page !== pageName ) { | if ( draftData.page !== pageName ) { | ||
return; | return; | ||
} | } | ||
var now = Date.now(); | var now = Date.now(); | ||
var daysOld = ( now - draftData.timestamp ) / ( 1000 * 60 * 60 * 24 ); | var daysOld = ( now - draftData.timestamp ) / ( 1000 * 60 * 60 * 24 ); | ||
if ( daysOld > config.maxDraftAge ) { | if ( daysOld > config.maxDraftAge ) { | ||
localStorage.removeItem( storageKey ); | localStorage.removeItem( storageKey ); | ||
return; | return; | ||
} | } | ||
if ( draftData.content === currentContent ) { | if ( draftData.content === currentContent ) { | ||
lastSavedContent = currentContent; | lastSavedContent = currentContent; | ||
return; | return; | ||
} | } | ||
if ( confirm( 'Найден несохранённый черновик от ' + | if ( confirm( 'Найден несохранённый черновик от ' + | ||
new Date( draftData.timestamp ).toLocaleString() + | new Date( draftData.timestamp ).toLocaleString() + | ||
| Строка 141: | Строка 122: | ||
lastSavedContent = draftData.content; | lastSavedContent = draftData.content; | ||
$textbox.css( 'border', '2px solid #00af89' ); | $textbox.css( 'border', '2px solid #00af89' ); | ||
setTimeout( function() { | setTimeout( function() { | ||
| Строка 148: | Строка 128: | ||
showNotification( 'Черновик восстановлен', 'success' ); | showNotification( 'Черновик восстановлен', 'success' ); | ||
} | } | ||
} catch ( e ) { | } catch ( e ) { | ||
// Тихо игнорируем ошибки восстановления | |||
} | } | ||
} | } | ||
| Строка 190: | Строка 139: | ||
$( '#wpSave' ).on( 'click', function() { | $( '#wpSave' ).on( 'click', function() { | ||
localStorage.removeItem( storageKey ); | localStorage.removeItem( storageKey ); | ||
} ); | } ); | ||
} | } | ||
// Ctrl+S — ручное сохранение | |||
$( document ).on( 'keydown', function( e ) { | |||
if ( e.ctrlKey && e.key === 's' ) { | |||
e.preventDefault(); | |||
saveDraft( false ); | |||
} | |||
} ); | |||
// Автосохранение при вводе | // Автосохранение при вводе | ||
| Строка 200: | Строка 156: | ||
} | } | ||
saveTimeout = setTimeout( function() { | saveTimeout = setTimeout( function() { | ||
saveDraft( true ); | saveDraft( true ); | ||
}, config.saveDelay ); | }, config.saveDelay ); | ||
} ); | } ); | ||
| Строка 214: | Строка 170: | ||
// Инициализация | // Инициализация | ||
$( document ).ready( function() { | $( document ).ready( function() { | ||
setTimeout( function() { | setTimeout( function() { | ||
restoreDraft(); | restoreDraft(); | ||
clearOnSave(); | clearOnSave(); | ||
}, 500 ); | }, 500 ); | ||
// Проверка localStorage (тихая) | |||
// Проверка localStorage | |||
try { | try { | ||
localStorage.setItem( 'autosave_test', 'test' ); | localStorage.setItem( 'autosave_test', 'test' ); | ||
localStorage.removeItem( 'autosave_test' ); | localStorage.removeItem( 'autosave_test' ); | ||
} catch ( e ) { | } catch ( e ) { | ||
// localStorage недоступен — скрипт просто не будет работать | |||
} | } | ||
} ); | } ); | ||
} )(); | } )(); | ||