(function () { 'use strict'; Drupal.behaviors.quicklink = { attach: function attachQuicklink(context, settings) { var debug = settings.quicklink.debug; function hydrateQuicklinkConfig() { settings.quicklink.quicklinkConfig = settings.quicklink.quicklinkConfig || {}; settings.quicklink.ignoredLinks = settings.quicklink.ignoredLinks || []; var quicklinkConfig = settings.quicklink.quicklinkConfig; quicklinkConfig.ignores = []; // Loop through all the patterns to ignore, and generate rules to ignore URL patterns. for (var i = 0; i < settings.quicklink.url_patterns_to_ignore.length; i++) { var pattern = settings.quicklink.url_patterns_to_ignore[i]; (function (i, pattern) { if (pattern.length) { quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Pattern found in href. See ignored URL patterns log.'; var ruleFunc = uri.includes(pattern); outputDebugInfo(ruleFunc, ruleName, uri, elem, pattern); return ruleFunc; }); } })(i, pattern); } // Loop through all the "ignore selectors", and generate rules. if (settings.quicklink.ignore_selectors) { for (var i = 0; i < settings.quicklink.ignore_selectors.length; i++) { var pattern = settings.quicklink.ignore_selectors[i]; (function (i, pattern) { if (pattern.length) { quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Element matches custom selectors within "ignore selectors" array. See log.'; var ruleFunc = elem.matches(pattern); outputDebugInfo(ruleFunc, ruleName, uri, elem, pattern); return ruleFunc; }); } })(i, pattern); } } if (settings.quicklink.ignore_admin_paths) { var adminLinkContainerPatterns = settings.quicklink.admin_link_container_patterns.join(); quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Exists in admin element container.'; var ruleFunc = elem.matches(adminLinkContainerPatterns); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); } if (settings.quicklink.ignore_ajax_links) { quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Link has "use-ajax" CSS class.'; var ruleFunc = elem.classList.contains('use-ajax'); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Link has "/ajax" in url.'; var ruleFunc = uri.includes('/ajax'); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); } if (settings.quicklink.ignore_file_ext) { quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Contains file extension at end of href.'; var ruleFunc = uri.match(/(\.[^\/]{1,5}\?)|(\.[^\/]{1,5}$)/); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); } if (settings.quicklink.total_request_limit) { quicklinkConfig.limit = parseInt(settings.quicklink.total_request_limit); } if (settings.quicklink.concurrency_throttle_limit) { quicklinkConfig.throttle = parseInt(settings.quicklink.concurrency_throttle_limit); } if (settings.quicklink.idle_wait_timeout) { quicklinkConfig.timeout = parseInt(settings.quicklink.idle_wait_timeout); } if (settings.quicklink.viewport_delay) { quicklinkConfig.delay = parseInt(settings.quicklink.viewport_delay); } quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Contains noprefetch attribute.'; var ruleFunc = elem.hasAttribute('noprefetch'); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); quicklinkConfig.ignores.push(function (uri, elem) { var ruleName = 'Contains download attribute.'; var ruleFunc = elem.hasAttribute('download'); outputDebugInfo(ruleFunc, ruleName, uri, elem); return ruleFunc; }); quicklinkConfig.origins = (settings.quicklink.allowed_domains) ? settings.quicklink.allowed_domains : false; } function outputDebugInfo(ruleFunc, ruleName, uri, elem, pattern) { if (debug && ruleFunc) { var debugMessage = ruleName + ' Link ignored.'; var thisLog = {}; var urlPattern = pattern || false; elem.classList.add('quicklink-ignore'); elem.textContent += '🚫'; elem.dataset.quicklinkMatch = debugMessage; thisLog.ruleName = ruleName; thisLog.uri = uri; thisLog.elem = elem; thisLog.message = debugMessage; if (urlPattern) { thisLog.urlPattern = urlPattern; } (function (thisLog) { settings.quicklink.ignoredLinks.push(thisLog); })(thisLog); } } function loadQuicklink() { var urlParams = new URLSearchParams(window.location.search); var noprefetch = urlParams.get('noprefetch') !== null || window.location.hash === '#noprefetch' ; if (noprefetch && debug) { // eslint-disable-next-line no-console console.info('The "noprefetch" parameter or hash exists in the URL. Quicklink library not loaded.'); } return window.quicklink && !noprefetch; } if (!settings.quicklink.quicklinkConfig) { hydrateQuicklinkConfig(); } settings.quicklink.quicklinkConfig.el = (settings.quicklink.selector) ? context.querySelector(settings.quicklink.selector) : context; if (loadQuicklink()) { if (settings.quicklink.prefetch_only_paths) { quicklink.prefetch(settings.quicklink.prefetch_only_paths); } else { try { quicklink.listen(settings.quicklink.quicklinkConfig); } catch(err) { console.error('quicklink.listen is not found. Please verify you are running version 2 of the Quicklink library.', err); } } } if (debug) { console.info('Quicklink config object', settings.quicklink.quicklinkConfig); // eslint-disable-line no-console console.info('Quicklink module debug log', settings.quicklink.debug_log); // eslint-disable-line no-console console.info('Quicklink ignored links', settings.quicklink.ignoredLinks); // eslint-disable-line no-console } } }; })();