bookmark-pages/Resources/Public/Scripts/JavaScript/bookmark_pages.js
2021-08-16 16:15:21 +02:00

163 lines
5.9 KiB
JavaScript

(function ($) {
const settings = {
_$bookmarks: null,
_$listItemTemplate: null,
// If set bookmarks are stored locally in localStorage
_storeLocal: false,
// Time in seconds during which the bookmarks are valid hence not queried from server
_localStorageTTL: 3600,
init () {
this._$bookmarks = $('#bookmarks');
this._$listItemTemplate = $($('#bookmark-template').html().trim());
// Assign settings defined by host
let pluginSettings = this._$bookmarks.data('settings');
if (typeof pluginSettings !== 'object') {
return;
}
if (pluginSettings.storeLocal !== 'undefined') {
this._storeLocal = Boolean(parseInt(pluginSettings.storeLocal));
}
if (pluginSettings.localStorageTTL !== 'undefined') {
this._localStorageTTL = parseInt(pluginSettings.localStorageTTL);
}
},
get updateAjaxUri () { return this._$bookmarks.data('update-ajaxuri'); },
get addAjaxUri () { return this._$bookmarks.data('add-ajaxuri') },
get removeAjaxUri () { return this._$bookmarks.data('remove-ajaxuri') },
get currentBookmark () { return this._$bookmarks.data('bookmark') },
get $listItemTemplate () { return this._$listItemTemplate },
get storeLocal() { return this._storeLocal; },
get localStorageTTL() { return this._localStorageTTL }
}
const storage = {
/**
* @return JSON object from bookmarks list held in local storage from browser
*/
get list() {
return JSON.parse(localStorage.getItem('txBookmarkPagesBookmarks')) ?? {};
},
/**
* @param bookmarks Array from bookmarks
*/
set list(bookmarks) {
if (settings.storeLocal) {
localStorage.setItem('txBookmarkPagesBookmarks', JSON.stringify(bookmarks));
localStorage.setItem('txBookmarkPagesTimestamp', Date.now());
localStorage.setItem('txBookmarkPagesReload', '0');
}
},
/**
* @return {boolean}
*/
get isOutdated() {
// Check storage age
let $expired = true;
let timestamp = localStorage.getItem('txBookmarkPagesTimestamp');
if (timestamp) {
$expired = ((Date.now() - timestamp) / 1000) > settings.localStorageTTL;
}
// Check if a reload is requested
let $reloadRequested = Boolean(parseInt(localStorage.getItem('txBookmarkPagesReload')));
return $expired || $reloadRequested;
},
containsBookmark (bookmark) {
return typeof this.list[bookmark.id] === 'object';
}
}
const assistant = {
updateLinks () {
if (storage.containsBookmark(settings.currentBookmark)) {
$('.bookmark-this-page').addClass('is-bookmarked');
} else {
$('.bookmark-this-page').removeClass('is-bookmarked');
}
},
/**
* Ajax callback function to update the bookmarks list and the links to bookmark a page.
*
* @param ajaxResult Object with properties `list` and `isBookmarked`
*/
listQueryHandler (ajaxResult) {
this.initList(ajaxResult.bookmarks);
storage.list = ajaxResult.bookmarks;
this.updateLinks();
},
ajax (url, data = {}) {
data = {...data, 'tx_wsbookmarkpages_bookmarks[localBookmarks]': storage.list}
$.ajax({
url: url,
type: 'post',
data: data
}).done($.proxy(this.listQueryHandler, this));
},
initList (bookmarks) {
let $bookmarksList = $('.bookmarks-list');
$bookmarksList.empty();
Object.values(bookmarks).forEach(bookmark => {
let $item = settings.$listItemTemplate.clone();
$('.bookmark-link', $item)
.attr('title', bookmark.title)
.attr('href', bookmark.url)
.text(bookmark.title);
$('.bookmark-ajax-submit', $item).data('remove', bookmark.id)
$bookmarksList.append($item);
});
},
initListFromStorage () {
let bookmarks = storage.list;
this.initList(bookmarks);
}
}
const bookmarks = {
init () {
if (settings.storeLocal && !storage.isOutdated) {
assistant.initListFromStorage();
assistant.updateLinks();
} else {
assistant.ajax(settings.updateAjaxUri);
}
},
add () {
assistant.ajax(settings.addAjaxUri);
},
remove (removeID) {
assistant.ajax(
settings.removeAjaxUri,
{'tx_wsbookmarkpages_bookmarks[id]': removeID ?? settings.currentBookmark.id}
);
}
}
/**
* Bind event handlers and initialize the app when DOM is ready
*/
$(function () {
// doing it this way:
// $('.bookmark-ajax-submit').on('click', function (event) {
// would not work for initially hidden elements
$('.bookmark-pages').on('click', '.bookmark-ajax-submit', function (event) {
event.preventDefault();
let $this = $(this),
removeID = $(this).data('remove');
if ($this.hasClass('bookmark-this-page')){
bookmarks.add();
} else if ($this.hasClass('remove-this-page')) {
bookmarks.remove()
} else if (removeID) {
bookmarks.remove(removeID)
}
});
// Initialize the app
settings.init();
bookmarks.init();
});
})(jQuery);