Skip to content

Commit

Permalink
Convert DOM events to stored functions (vufind-org#3361)
Browse files Browse the repository at this point in the history
  • Loading branch information
crhallberg authored Mar 21, 2024
1 parent 1e0c905 commit 15faf60
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 49 deletions.
2 changes: 1 addition & 1 deletion themes/bootstrap3/js/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,4 @@ function cartFormHandler(event, data) {
}
}

document.addEventListener('VuFind.lightbox.closed', VuFind.cart.updateCount, false);
VuFind.listen('lightbox.closed', VuFind.cart.updateCount);
72 changes: 57 additions & 15 deletions themes/bootstrap3/js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,62 @@ var VuFind = (function VuFind() {
var _elementBase;
var _iconsCache = {};

// Emit a custom event
// Recommendation: prefix with vf-
var emit = function emit(name, detail) {
if (typeof detail === 'undefined') {
document.dispatchEvent(new Event(name));
} else {
var event = document.createEvent('CustomEvent');
event.initCustomEvent(name, true, true, detail); // name, canBubble, cancelable, detail
document.dispatchEvent(event);
// Event controls

let listeners = {};
function unlisten(event, fn) {
if (typeof listeners[event] === "undefined") {
return;
}
};
// Listen shortcut to put everyone on the same element
var listen = function listen(name, func) {
document.addEventListener(name, func, false);
};

const index = listeners[event].indexOf(fn);

if (index > -1) {
listeners[event].splice(index, 1);
}
}

// Add a function to call when an event is emitted
//
// Options:
// - once: remove this listener after it's been called
function listen(event, fn, { once = false } = {}) {
if (typeof listeners[event] === "undefined") {
listeners[event] = [];
}

listeners[event].push(fn);
const removeListener = () => unlisten(event, fn);

if (once) {
// Remove a "once" listener after calling
// Add the function to remove the listener
// to the array, listeners are called in order
listeners[event].push(removeListener);
}

// Return a function to disable the listener
// Makes it easier to control activating and deactivating listeners
// This is common for similar libraries
return removeListener;
}

// Broadcast an event, passing arguments to all listeners
function emit(event, ...args) {
// No listeners for this event
if (typeof listeners[event] === "undefined") {
return;
}

// iterate over a copy of the listeners array
// this prevents listeners from being skipped
// if the listener before it is removed during execution
for (const fn of Array.from(listeners[event])) {
fn(...args);
}
}

// Module control

var register = function register(name, module) {
if (_submodules.indexOf(name) === -1) {
Expand Down Expand Up @@ -430,11 +471,12 @@ var VuFind = (function VuFind() {
addTranslations: addTranslations,
init: init,
emit: emit,
listen: listen,
unlisten: unlisten,
evalCallback: evalCallback,
getCspNonce: getCspNonce,
icon: icon,
isPrinting: isPrinting,
listen: listen,
refreshPage: refreshPage,
register: register,
setCspNonce: setCspNonce,
Expand Down
8 changes: 4 additions & 4 deletions themes/bootstrap3/js/cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ VuFind.register('cookie', function cookie() {
function setupConsent(_config) {
consentConfig = _config;
consentConfig.consentDialog.onFirstConsent = function onFirstConsent() {
VuFind.emit('vf-cookie-consent-first-done');
VuFind.emit('cookie-consent-first-done');
};
consentConfig.consentDialog.onConsent = function onConsent() {
updateServiceStatus();
VuFind.emit('vf-cookie-consent-done');
VuFind.emit('cookie-consent-done');
};
consentConfig.consentDialog.onChange = function onChange() {
updateServiceStatus();
VuFind.emit('vf-cookie-consent-changed');
VuFind.emit('cookie-consent-changed');
};
CookieConsent.run(consentConfig.consentDialog);
VuFind.emit('vf-cookie-consent-initialized');
VuFind.emit('cookie-consent-initialized');
}

function isCategoryAccepted(category) {
Expand Down
45 changes: 18 additions & 27 deletions themes/bootstrap3/js/lightbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,6 @@ VuFind.register('lightbox', function Lightbox() {
_lightboxTitle = false;
_modal.modal('handleUpdate');
}
function _emit(msg, _details) {
var details = _details || {};
var event;
try {
event = new CustomEvent(msg, {
detail: details,
bubbles: true,
cancelable: true
});
} catch (e) {
// Fallback to document.createEvent() if creating a new CustomEvent fails (e.g. IE 11)
event = document.createEvent('CustomEvent');
event.initCustomEvent(msg, true, true, details);
}
return document.dispatchEvent(event);
}

function _addQueryParameters(url, params) {
let fragmentSplit = url.split('#');
Expand Down Expand Up @@ -220,12 +204,20 @@ VuFind.register('lightbox', function Lightbox() {
|| obj.url.match(/MyResearch\/(?!Bulk|Delete|Recover)/)
) && flashMessages.length === 0
) {
var eventResult = _emit('VuFind.lightbox.login', {
originalUrl: _originalUrl,
formUrl: obj.url
});
let doRefresh = true;
const cancelRefresh = () => doRefresh = false;

VuFind.emit(
'lightbox.login',
{
formUrl: obj.url,
originalUrl: _originalUrl,
},
cancelRefresh // call this function to cancel refresh
);

if (_originalUrl.match(/UserLogin/) || obj.url.match(/catalogLogin/)) {
if (eventResult) {
if (doRefresh) {
VuFind.refreshPage();
}
return false;
Expand Down Expand Up @@ -338,10 +330,9 @@ VuFind.register('lightbox', function Lightbox() {
}
// onclose behavior
if ('string' === typeof $(form).data('lightboxOnclose')) {
document.addEventListener('VuFind.lightbox.closed', function lightboxClosed(e) {
this.removeEventListener('VuFind.lightbox.closed', arguments.callee);
VuFind.evalCallback($(form).data('lightboxOnclose'), e, form);
}, false);
VuFind.listen('lightbox.closed', function lightboxClosed() {
VuFind.evalCallback($(form).data('lightboxOnclose'), null, form);
}, { once: true });
}
// Prevent multiple submission of submit button in lightbox
if (submit.closest(_modal).length > 0) {
Expand Down Expand Up @@ -523,12 +514,12 @@ VuFind.register('lightbox', function Lightbox() {
}
unbindFocus();
this.setAttribute('aria-hidden', true);
_emit('VuFind.lightbox.closing');
VuFind.emit('lightbox.closing');
}
});
_modal.on('hidden.bs.modal', function lightboxHidden() {
VuFind.lightbox.reset();
_emit('VuFind.lightbox.closed');
VuFind.emit('lightbox.closed');
});
_modal.on("shown.bs.modal", function lightboxShown() {
bindFocus();
Expand Down
15 changes: 13 additions & 2 deletions themes/bootstrap3/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,12 @@ VuFind.register('search', function search() {
}
updateResultControls(pageUrl);
updateResultLinks(pageUrl);
VuFind.emit('vf-results-load', {url: pageUrl, addToHistory: addToHistory});

VuFind.emit('results-load', {
url: pageUrl,
addToHistory: addToHistory
});

fetch(VuFind.path + '/AJAX/JSON?' + queryParams.toString())
.then((response) => response.json())
.then((result) => {
Expand All @@ -338,7 +343,13 @@ VuFind.register('search', function search() {
});
VuFind.initResultScripts(jsRecordListSelector);
initPagination();
VuFind.emit('vf-results-loaded', {url: pageUrl, addToHistory: addToHistory, data: result});

VuFind.emit('results-loaded', {
url: pageUrl,
addToHistory: addToHistory,
data: result
});

recordList.classList.remove('loading');
})
.catch((error) => {
Expand Down

0 comments on commit 15faf60

Please sign in to comment.