bookish_admin-1.0.x-dev/modules/bookish_speed/js/speed.js

modules/bookish_speed/js/speed.js
(function (Drupal, once) {

  var lastPath = null;
  var prefetchTimer = setTimeout(function (){}, 0);
  var lastTimerUrl = null;

  // Shim for $.extend(true, ...)
  var deepExtend = function (out) {
    out = out || {};

    for (var i = 1; i < arguments.length; i++) {
      var obj = arguments[i];

      if (!obj) { continue;
      }

      for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === "object" && obj[key] !== null) {
            if (obj[key] instanceof Array) { out[key] = obj[key].slice(0);
            } else { out[key] = deepExtend(out[key], obj[key]);
            }
          } else { out[key] = obj[key];
          }
        }
      }
    }

    return out;
  };

  function requestUrl(url, search, hash, scrollTop, context) {
    clearTimeout(prefetchTimer);
    // Do some early precautions to ensure URL is local.
    url = url.replace(/^\/?/, '/').replace(/\/\//g, '/');
    // Fetch the new URL, do not allow requests/redirects to non local origins.
    fetch(url, { redirect: 'follow', mode: 'same-origin' }).then(function (response) {
      // Validate content type to prevent processing links to non-html paths.
      if (!response.headers.get('Content-Type').match(/^text\/html/)) {
        throw 'Invalid content type';
      }
      return response.text();
    }).then(function (html) {
      var domparser = new DOMParser();
      var newDocument = domparser.parseFromString(html, 'text/html');
      // Make sure <main> exists in response.
      var newMain = newDocument.querySelector('main');
      if (!newMain) {
        throw 'Cannot parse response for ' + url;
      }

      // Log the URL to prevent making requests when hash/query params change.
      lastPath = url;

      // Replace the title.
      document.title = newDocument.title;

      // Get drupalSettings.
      var newSettings = newDocument.querySelector('[data-drupal-selector="drupal-settings-json"]');
      var oldSettings = window.drupalSettings;
      if (newSettings) {
        window.drupalSettings = deepExtend({}, window.drupalSettings, JSON.parse(newSettings.textContent));
      }

      // Determine what CSS/JS files are new.
      var newCss = window.drupalSettings.bookishSpeed.css.filter(function (x) { return oldSettings.bookishSpeed.css.indexOf(x) === -1; });
      var newJs = window.drupalSettings.bookishSpeed.js.filter(function (x) { return oldSettings.bookishSpeed.js.indexOf(x) === -1; });

      // Concat the old+new CSS/JS to avoid re-loading files later.
      window.drupalSettings.bookishSpeed.css = oldSettings.bookishSpeed.css.concat(newCss);
      window.drupalSettings.bookishSpeed.js = oldSettings.bookishSpeed.js.concat(newJs);

      var loadedCssAssets = 0;
      var loadedJsAssets = 0;

      var replaced = false;
      var replaceHtml = function () {
        replaced = true;
        var main = document.querySelector('main');
        main.innerHTML = newMain.innerHTML;
        // Special scroll handling for hash links.
        if (hash && context === 'click') {
          var hashElem = document.getElementById(hash.slice(1));
          if (hashElem) {
            setTimeout(function () {
              hashElem.scrollIntoView();
              var oldState = history.state;
              oldState.scrollTop = document.documentElement.scrollTop;
              history.replaceState(oldState, '');
            }, 0);
          }
        }
        else {
          window.scrollTo({ top: scrollTop });
        }
        // Accessibility tweaks.
        var skipLink = document.querySelector('#skip-link');
        if (skipLink) {
          skipLink.classList.remove('focusable');
          skipLink.focus();
        };
        Drupal.announce(Drupal.t('Navigated to "@title"', { '@title': document.title }));
        var event = new CustomEvent('bookish-speed-html', { });
        document.dispatchEvent(event);
      };

      var triggerBehaviors = function () {
        var main = document.querySelector('main');
        Drupal.attachBehaviors(main, window.drupalSettings);
        var event = new CustomEvent('bookish-speed-javascript', { });
        document.dispatchEvent(event);
      };

      // If there are no CSS assets, we can replace now.
      var timeout;
      if (newCss.length === 0) {
        replaceHtml();
      }
      else {
        var timeout = setTimeout(replaceHtml, window.drupalSettings.bookishSpeedSettings ? window.drupalSettings.bookishSpeedSettings.wait_time : 300);
      }

      var cssLoaded = function () {
        loadedCssAssets++;
        if (!replaced && loadedCssAssets >= newCss.length) {
          clearTimeout(timeout);
          replaceHtml();
        }
      };

      // Wait to trigger behaviors until JS is loaded.
      var jsLoaded = function () {
        loadedJsAssets++;
        if (loadedJsAssets >= newJs.length) {
          // Avoid race conditions in JS/CSS loading.
          if (replaced) {
            triggerBehaviors();
          }
          else {
            var interval = setInterval(function () {
              if (replaced) {
                triggerBehaviors();
                clearInterval(interval);
              }
            }, 5);
          }
        }
      };

      if (newJs.length === 0) {
        jsLoaded();
      }

      // Append CSS/JS to head.
      newCss.forEach(function (newUrl) {
        var link = document.createElement('link');
        link.rel = "stylesheet";
        link.type = "text/css";
        link.href = newUrl + (newUrl.indexOf('?') === -1 ? '?' : '&') + window.drupalSettings.bookishSpeed.query_string;
        link.addEventListener('load', cssLoaded);
        link.addEventListener('error', cssLoaded);
        document.head.appendChild(link);
      });
      newJs.forEach(function (newUrl) {
        var script = document.createElement('script');
        script.async = false;
        script.src = newUrl + (newUrl.indexOf('?') === -1 ? '?' : '&') + window.drupalSettings.bookishSpeed.query_string;
        script.addEventListener('load', jsLoaded);
        script.addEventListener('error', jsLoaded);
        document.head.appendChild(script);
      });
    }).catch(function (error) {
      // Fall back to normal navigation.
      console.error('Cannot request ' + url, error);
      window.location = url + search + hash;
    });
  };

  function prefetchUrl(url, search) {
    // Do some early precautions to ensure URL is local.
    url = url.replace(/^\/?/, '/').replace(/\/\//g, '/');
    var link = document.createElement('link');
    link.rel = 'prefetch';
    link.href = url + search;
    document.head.appendChild(link);
  }

  Drupal.behaviors.bookishSpeed = {
    attach: function attach(context, settings) {
      // Default to excluding admin-y paths or links with extensions.
      var exclude_regex = settings.bookishSpeedSettings ? settings.bookishSpeedSettings.exclude_regex : '/(admin|node|user)|\.[a-zA-Z0-9]+$';
      exclude_regex = new RegExp(exclude_regex);
      once('bookish-speed', 'a:not([target]):not(.use-ajax):not(.no-speed)', context).forEach(function (element) {
        // Check if URL is local, a relative anchor, or fails regex check.
        if (element.getAttribute('href')[0] === '#' || element.href.match(exclude_regex) || !Drupal.url.isLocal(element.href)) {
          return;
        }
        var url = new URL(element.href);
        var pathname = url.pathname.replace(/^\/?/, '/').replace(/\/\//g, '/');
        element.addEventListener('click', function (event) {
          // Do nothing if clicking a hash URL.
          if (document.location.pathname === pathname && url.hash) {
            return;
          }
          event.preventDefault();
          history.replaceState({
            scrollTop: document.documentElement.scrollTop,
            fromBookishSpeed: true,
          }, '');
          history.pushState({
            scrollTop: 0,
            fromBookishSpeed: true,
          }, '', pathname + url.search + url.hash);
          requestUrl(pathname, url.search, url.hash, 0, 'click');
        });
        element.addEventListener('mouseover', function () {
          if (lastTimerUrl === pathname + url.search || document.querySelector('link[rel="prefetch"][href="' + pathname + url.search + '"]')) {
            return;
          }
          lastTimerUrl = pathname + url.search;
          clearTimeout(prefetchTimer);
          prefetchTimer = setTimeout(function () {
            prefetchUrl(pathname, url.search);
          }, 65);
        }, { passive: true, capture: true });
        element.addEventListener('mouseout', function () {
          clearTimeout(prefetchTimer);
        }, { passive: true, capture: true });
      });
      once('bookish-speed-history', 'body', context).forEach(function () {
        if (history.scrollRestoration) {
          history.scrollRestoration = 'manual';
        }
        window.addEventListener('popstate', function (event) {
          if (event.state && event.state.fromBookishSpeed && document.location.pathname !== lastPath) {
            var scrollTop = event.state && event.state.scrollTop ? event.state.scrollTop : 0;
            requestUrl(document.location.pathname, document.location.search, document.location.hash, scrollTop, 'popstate');
          }
        });
      });
      once('bookish-speed-skip-link', '#skip-link', context).forEach(function (element) {
        element.addEventListener('blur', function (event) {
          if (event.target !== document.activeElement) {
            element.classList.add('focusable');
          }
        });
      });
    }
  };

})(Drupal, once);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc