[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/vendor/bootstrap/js/ -> dom.js (source)

   1  /**
   2   * --------------------------------------------------------------------------
   3   * Bootstrap (v5.1.3): util/index.js
   4   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
   5   * --------------------------------------------------------------------------
   6   */
   7  const MAX_UID = 1000000;
   8  const MILLISECONDS_MULTIPLIER = 1000;
   9  const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
  10  
  11  const toType = obj => {
  12    if (obj === null || obj === undefined) {
  13      return `$obj}`;
  14    }
  15  
  16    return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
  17  };
  18  /**
  19   * --------------------------------------------------------------------------
  20   * Public Util Api
  21   * --------------------------------------------------------------------------
  22   */
  23  
  24  
  25  const getUID = prefix => {
  26    do {
  27      prefix += Math.floor(Math.random() * MAX_UID);
  28    } while (document.getElementById(prefix));
  29  
  30    return prefix;
  31  };
  32  
  33  const getSelector = element => {
  34    let selector = element.getAttribute('data-bs-target');
  35  
  36    if (!selector || selector === '#') {
  37      let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
  38      // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
  39      // `document.querySelector` will rightfully complain it is invalid.
  40      // See https://github.com/twbs/bootstrap/issues/32273
  41  
  42      if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
  43        return null;
  44      } // Just in case some CMS puts out a full URL with the anchor appended
  45  
  46  
  47      if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
  48        hrefAttr = `#$hrefAttr.split('#')[1]}`;
  49      }
  50  
  51      selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
  52    }
  53  
  54    return selector;
  55  };
  56  
  57  const getSelectorFromElement = element => {
  58    const selector = getSelector(element);
  59  
  60    if (selector) {
  61      return document.querySelector(selector) ? selector : null;
  62    }
  63  
  64    return null;
  65  };
  66  
  67  const getElementFromSelector = element => {
  68    const selector = getSelector(element);
  69    return selector ? document.querySelector(selector) : null;
  70  };
  71  
  72  const getTransitionDurationFromElement = element => {
  73    if (!element) {
  74      return 0;
  75    } // Get transition-duration of the element
  76  
  77  
  78    let {
  79      transitionDuration,
  80      transitionDelay
  81    } = window.getComputedStyle(element);
  82    const floatTransitionDuration = Number.parseFloat(transitionDuration);
  83    const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
  84  
  85    if (!floatTransitionDuration && !floatTransitionDelay) {
  86      return 0;
  87    } // If multiple durations are defined, take the first
  88  
  89  
  90    transitionDuration = transitionDuration.split(',')[0];
  91    transitionDelay = transitionDelay.split(',')[0];
  92    return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
  93  };
  94  
  95  const triggerTransitionEnd = element => {
  96    element.dispatchEvent(new Event(TRANSITION_END));
  97  };
  98  
  99  const isElement = obj => {
 100    if (!obj || typeof obj !== 'object') {
 101      return false;
 102    }
 103  
 104    if (typeof obj.jquery !== 'undefined') {
 105      obj = obj[0];
 106    }
 107  
 108    return typeof obj.nodeType !== 'undefined';
 109  };
 110  
 111  const getElement = obj => {
 112    if (isElement(obj)) {
 113      // it's a jQuery object or a node element
 114      return obj.jquery ? obj[0] : obj;
 115    }
 116  
 117    if (typeof obj === 'string' && obj.length > 0) {
 118      return document.querySelector(obj);
 119    }
 120  
 121    return null;
 122  };
 123  
 124  const typeCheckConfig = (componentName, config, configTypes) => {
 125    Object.keys(configTypes).forEach(property => {
 126      const expectedTypes = configTypes[property];
 127      const value = config[property];
 128      const valueType = value && isElement(value) ? 'element' : toType(value);
 129  
 130      if (!new RegExp(expectedTypes).test(valueType)) {
 131        throw new TypeError(`$componentName.toUpperCase()}: Option "$property}" provided type "$valueType}" but expected type "$expectedTypes}".`);
 132      }
 133    });
 134  };
 135  
 136  const isVisible = element => {
 137    if (!isElement(element) || element.getClientRects().length === 0) {
 138      return false;
 139    }
 140  
 141    return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
 142  };
 143  
 144  const isDisabled = element => {
 145    if (!element || element.nodeType !== Node.ELEMENT_NODE) {
 146      return true;
 147    }
 148  
 149    if (element.classList.contains('disabled')) {
 150      return true;
 151    }
 152  
 153    if (typeof element.disabled !== 'undefined') {
 154      return element.disabled;
 155    }
 156  
 157    return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
 158  };
 159  
 160  const findShadowRoot = element => {
 161    if (!document.documentElement.attachShadow) {
 162      return null;
 163    } // Can find the shadow root otherwise it'll return the document
 164  
 165  
 166    if (typeof element.getRootNode === 'function') {
 167      const root = element.getRootNode();
 168      return root instanceof ShadowRoot ? root : null;
 169    }
 170  
 171    if (element instanceof ShadowRoot) {
 172      return element;
 173    } // when we don't find a shadow root
 174  
 175  
 176    if (!element.parentNode) {
 177      return null;
 178    }
 179  
 180    return findShadowRoot(element.parentNode);
 181  };
 182  
 183  const noop = () => {};
 184  /**
 185   * Trick to restart an element's animation
 186   *
 187   * @param {HTMLElement} element
 188   * @return void
 189   *
 190   * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
 191   */
 192  
 193  
 194  const reflow = element => {
 195    // eslint-disable-next-line no-unused-expressions
 196    element.offsetHeight;
 197  };
 198  
 199  const getjQuery = () => {
 200    const {
 201      jQuery
 202    } = window;
 203  
 204    if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
 205      return jQuery;
 206    }
 207  
 208    return null;
 209  };
 210  
 211  const DOMContentLoadedCallbacks = [];
 212  
 213  const onDOMContentLoaded = callback => {
 214    if (document.readyState === 'loading') {
 215      // add listener on the first call when the document is in loading state
 216      if (!DOMContentLoadedCallbacks.length) {
 217        document.addEventListener('DOMContentLoaded', () => {
 218          DOMContentLoadedCallbacks.forEach(callback => callback());
 219        });
 220      }
 221  
 222      DOMContentLoadedCallbacks.push(callback);
 223    } else {
 224      callback();
 225    }
 226  };
 227  
 228  const isRTL = () => document.documentElement.dir === 'rtl';
 229  
 230  const defineJQueryPlugin = plugin => {
 231    onDOMContentLoaded(() => {
 232      const $ = getjQuery();
 233      /* istanbul ignore if */
 234  
 235      if ($) {
 236        const name = plugin.NAME;
 237        const JQUERY_NO_CONFLICT = $.fn[name];
 238        $.fn[name] = plugin.jQueryInterface;
 239        $.fn[name].Constructor = plugin;
 240  
 241        $.fn[name].noConflict = () => {
 242          $.fn[name] = JQUERY_NO_CONFLICT;
 243          return plugin.jQueryInterface;
 244        };
 245      }
 246    });
 247  };
 248  
 249  const execute = callback => {
 250    if (typeof callback === 'function') {
 251      callback();
 252    }
 253  };
 254  
 255  const executeAfterTransition = function (callback, transitionElement) {
 256    let waitForTransition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
 257  
 258    if (!waitForTransition) {
 259      execute(callback);
 260      return;
 261    }
 262  
 263    const durationPadding = 5;
 264    const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
 265    let called = false;
 266  
 267    const handler = _ref => {
 268      let {
 269        target
 270      } = _ref;
 271  
 272      if (target !== transitionElement) {
 273        return;
 274      }
 275  
 276      called = true;
 277      transitionElement.removeEventListener(TRANSITION_END, handler);
 278      execute(callback);
 279    };
 280  
 281    transitionElement.addEventListener(TRANSITION_END, handler);
 282    setTimeout(() => {
 283      if (!called) {
 284        triggerTransitionEnd(transitionElement);
 285      }
 286    }, emulatedDuration);
 287  };
 288  /**
 289   * Return the previous/next element of a list.
 290   *
 291   * @param {array} list    The list of elements
 292   * @param activeElement   The active element
 293   * @param shouldGetNext   Choose to get next or previous element
 294   * @param isCycleAllowed
 295   * @return {Element|elem} The proper element
 296   */
 297  
 298  
 299  const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
 300    let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
 301  
 302    if (index === -1) {
 303      return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
 304    }
 305  
 306    const listLength = list.length;
 307    index += shouldGetNext ? 1 : -1;
 308  
 309    if (isCycleAllowed) {
 310      index = (index + listLength) % listLength;
 311    }
 312  
 313    return list[Math.max(0, Math.min(index, listLength - 1))];
 314  };
 315  
 316  /**
 317   * --------------------------------------------------------------------------
 318   * Bootstrap (v5.1.3): dom/event-handler.js
 319   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 320   * --------------------------------------------------------------------------
 321   */
 322  /**
 323   * ------------------------------------------------------------------------
 324   * Constants
 325   * ------------------------------------------------------------------------
 326   */
 327  
 328  const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
 329  const stripNameRegex = /\..*/;
 330  const stripUidRegex = /::\d+$/;
 331  const eventRegistry = {}; // Events storage
 332  
 333  let uidEvent = 1;
 334  const customEvents = {
 335    mouseenter: 'mouseover',
 336    mouseleave: 'mouseout'
 337  };
 338  const customEventsRegex = /^(mouseenter|mouseleave)/i;
 339  const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);
 340  /**
 341   * ------------------------------------------------------------------------
 342   * Private methods
 343   * ------------------------------------------------------------------------
 344   */
 345  
 346  function getUidEvent(element, uid) {
 347    return uid && `$uid}::$uidEvent++}` || element.uidEvent || uidEvent++;
 348  }
 349  
 350  function getEvent(element) {
 351    const uid = getUidEvent(element);
 352    element.uidEvent = uid;
 353    eventRegistry[uid] = eventRegistry[uid] || {};
 354    return eventRegistry[uid];
 355  }
 356  
 357  function bootstrapHandler(element, fn) {
 358    return function handler(event) {
 359      event.delegateTarget = element;
 360  
 361      if (handler.oneOff) {
 362        EventHandler.off(element, event.type, fn);
 363      }
 364  
 365      return fn.apply(element, [event]);
 366    };
 367  }
 368  
 369  function bootstrapDelegationHandler(element, selector, fn) {
 370    return function handler(event) {
 371      const domElements = element.querySelectorAll(selector);
 372  
 373      for (let {
 374        target
 375      } = event; target && target !== this; target = target.parentNode) {
 376        for (let i = domElements.length; i--;) {
 377          if (domElements[i] === target) {
 378            event.delegateTarget = target;
 379  
 380            if (handler.oneOff) {
 381              EventHandler.off(element, event.type, selector, fn);
 382            }
 383  
 384            return fn.apply(target, [event]);
 385          }
 386        }
 387      } // To please ESLint
 388  
 389  
 390      return null;
 391    };
 392  }
 393  
 394  function findHandler(events, handler) {
 395    let delegationSelector = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
 396    const uidEventList = Object.keys(events);
 397  
 398    for (let i = 0, len = uidEventList.length; i < len; i++) {
 399      const event = events[uidEventList[i]];
 400  
 401      if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {
 402        return event;
 403      }
 404    }
 405  
 406    return null;
 407  }
 408  
 409  function normalizeParams(originalTypeEvent, handler, delegationFn) {
 410    const delegation = typeof handler === 'string';
 411    const originalHandler = delegation ? delegationFn : handler;
 412    let typeEvent = getTypeEvent(originalTypeEvent);
 413    const isNative = nativeEvents.has(typeEvent);
 414  
 415    if (!isNative) {
 416      typeEvent = originalTypeEvent;
 417    }
 418  
 419    return [delegation, originalHandler, typeEvent];
 420  }
 421  
 422  function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
 423    if (typeof originalTypeEvent !== 'string' || !element) {
 424      return;
 425    }
 426  
 427    if (!handler) {
 428      handler = delegationFn;
 429      delegationFn = null;
 430    } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
 431    // this prevents the handler from being dispatched the same way as mouseover or mouseout does
 432  
 433  
 434    if (customEventsRegex.test(originalTypeEvent)) {
 435      const wrapFn = fn => {
 436        return function (event) {
 437          if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
 438            return fn.call(this, event);
 439          }
 440        };
 441      };
 442  
 443      if (delegationFn) {
 444        delegationFn = wrapFn(delegationFn);
 445      } else {
 446        handler = wrapFn(handler);
 447      }
 448    }
 449  
 450    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
 451    const events = getEvent(element);
 452    const handlers = events[typeEvent] || (events[typeEvent] = {});
 453    const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);
 454  
 455    if (previousFn) {
 456      previousFn.oneOff = previousFn.oneOff && oneOff;
 457      return;
 458    }
 459  
 460    const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));
 461    const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);
 462    fn.delegationSelector = delegation ? handler : null;
 463    fn.originalHandler = originalHandler;
 464    fn.oneOff = oneOff;
 465    fn.uidEvent = uid;
 466    handlers[uid] = fn;
 467    element.addEventListener(typeEvent, fn, delegation);
 468  }
 469  
 470  function removeHandler(element, events, typeEvent, handler, delegationSelector) {
 471    const fn = findHandler(events[typeEvent], handler, delegationSelector);
 472  
 473    if (!fn) {
 474      return;
 475    }
 476  
 477    element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
 478    delete events[typeEvent][fn.uidEvent];
 479  }
 480  
 481  function removeNamespacedHandlers(element, events, typeEvent, namespace) {
 482    const storeElementEvent = events[typeEvent] || {};
 483    Object.keys(storeElementEvent).forEach(handlerKey => {
 484      if (handlerKey.includes(namespace)) {
 485        const event = storeElementEvent[handlerKey];
 486        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
 487      }
 488    });
 489  }
 490  
 491  function getTypeEvent(event) {
 492    // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
 493    event = event.replace(stripNameRegex, '');
 494    return customEvents[event] || event;
 495  }
 496  
 497  const EventHandler = {
 498    on(element, event, handler, delegationFn) {
 499      addHandler(element, event, handler, delegationFn, false);
 500    },
 501  
 502    one(element, event, handler, delegationFn) {
 503      addHandler(element, event, handler, delegationFn, true);
 504    },
 505  
 506    off(element, originalTypeEvent, handler, delegationFn) {
 507      if (typeof originalTypeEvent !== 'string' || !element) {
 508        return;
 509      }
 510  
 511      const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
 512      const inNamespace = typeEvent !== originalTypeEvent;
 513      const events = getEvent(element);
 514      const isNamespace = originalTypeEvent.startsWith('.');
 515  
 516      if (typeof originalHandler !== 'undefined') {
 517        // Simplest case: handler is passed, remove that listener ONLY.
 518        if (!events || !events[typeEvent]) {
 519          return;
 520        }
 521  
 522        removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);
 523        return;
 524      }
 525  
 526      if (isNamespace) {
 527        Object.keys(events).forEach(elementEvent => {
 528          removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
 529        });
 530      }
 531  
 532      const storeElementEvent = events[typeEvent] || {};
 533      Object.keys(storeElementEvent).forEach(keyHandlers => {
 534        const handlerKey = keyHandlers.replace(stripUidRegex, '');
 535  
 536        if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
 537          const event = storeElementEvent[keyHandlers];
 538          removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
 539        }
 540      });
 541    },
 542  
 543    trigger(element, event, args) {
 544      if (typeof event !== 'string' || !element) {
 545        return null;
 546      }
 547  
 548      const $ = getjQuery();
 549      const typeEvent = getTypeEvent(event);
 550      const inNamespace = event !== typeEvent;
 551      const isNative = nativeEvents.has(typeEvent);
 552      let jQueryEvent;
 553      let bubbles = true;
 554      let nativeDispatch = true;
 555      let defaultPrevented = false;
 556      let evt = null;
 557  
 558      if (inNamespace && $) {
 559        jQueryEvent = $.Event(event, args);
 560        $(element).trigger(jQueryEvent);
 561        bubbles = !jQueryEvent.isPropagationStopped();
 562        nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
 563        defaultPrevented = jQueryEvent.isDefaultPrevented();
 564      }
 565  
 566      if (isNative) {
 567        evt = document.createEvent('HTMLEvents');
 568        evt.initEvent(typeEvent, bubbles, true);
 569      } else {
 570        evt = new CustomEvent(event, {
 571          bubbles,
 572          cancelable: true
 573        });
 574      } // merge custom information in our event
 575  
 576  
 577      if (typeof args !== 'undefined') {
 578        Object.keys(args).forEach(key => {
 579          Object.defineProperty(evt, key, {
 580            get() {
 581              return args[key];
 582            }
 583  
 584          });
 585        });
 586      }
 587  
 588      if (defaultPrevented) {
 589        evt.preventDefault();
 590      }
 591  
 592      if (nativeDispatch) {
 593        element.dispatchEvent(evt);
 594      }
 595  
 596      if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {
 597        jQueryEvent.preventDefault();
 598      }
 599  
 600      return evt;
 601    }
 602  
 603  };
 604  
 605  /**
 606   * --------------------------------------------------------------------------
 607   * Bootstrap (v5.1.3): dom/data.js
 608   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 609   * --------------------------------------------------------------------------
 610   */
 611  
 612  /**
 613   * ------------------------------------------------------------------------
 614   * Constants
 615   * ------------------------------------------------------------------------
 616   */
 617  const elementMap = new Map();
 618  var Data = {
 619    set(element, key, instance) {
 620      if (!elementMap.has(element)) {
 621        elementMap.set(element, new Map());
 622      }
 623  
 624      const instanceMap = elementMap.get(element); // make it clear we only want one instance per element
 625      // can be removed later when multiple key/instances are fine to be used
 626  
 627      if (!instanceMap.has(key) && instanceMap.size !== 0) {
 628        // eslint-disable-next-line no-console
 629        console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: $Array.from(instanceMap.keys())[0]}.`);
 630        return;
 631      }
 632  
 633      instanceMap.set(key, instance);
 634    },
 635  
 636    get(element, key) {
 637      if (elementMap.has(element)) {
 638        return elementMap.get(element).get(key) || null;
 639      }
 640  
 641      return null;
 642    },
 643  
 644    remove(element, key) {
 645      if (!elementMap.has(element)) {
 646        return;
 647      }
 648  
 649      const instanceMap = elementMap.get(element);
 650      instanceMap.delete(key); // free up element references if there are no instances left for an element
 651  
 652      if (instanceMap.size === 0) {
 653        elementMap.delete(element);
 654      }
 655    }
 656  
 657  };
 658  
 659  /**
 660   * --------------------------------------------------------------------------
 661   * Bootstrap (v5.1.3): base-component.js
 662   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 663   * --------------------------------------------------------------------------
 664   */
 665  /**
 666   * ------------------------------------------------------------------------
 667   * Constants
 668   * ------------------------------------------------------------------------
 669   */
 670  
 671  const VERSION = '5.1.3';
 672  
 673  class BaseComponent {
 674    constructor(element) {
 675      element = getElement(element);
 676  
 677      if (!element) {
 678        return;
 679      }
 680  
 681      this._element = element;
 682      Data.set(this._element, this.constructor.DATA_KEY, this);
 683    }
 684  
 685    dispose() {
 686      Data.remove(this._element, this.constructor.DATA_KEY);
 687      EventHandler.off(this._element, this.constructor.EVENT_KEY);
 688      Object.getOwnPropertyNames(this).forEach(propertyName => {
 689        this[propertyName] = null;
 690      });
 691    }
 692  
 693    _queueCallback(callback, element) {
 694      let isAnimated = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
 695      executeAfterTransition(callback, element, isAnimated);
 696    }
 697    /** Static */
 698  
 699  
 700    static getInstance(element) {
 701      return Data.get(getElement(element), this.DATA_KEY);
 702    }
 703  
 704    static getOrCreateInstance(element) {
 705      let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 706      return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
 707    }
 708  
 709    static get VERSION() {
 710      return VERSION;
 711    }
 712  
 713    static get NAME() {
 714      throw new Error('You have to implement the static method "NAME", for each component!');
 715    }
 716  
 717    static get DATA_KEY() {
 718      return `bs.$this.NAME}`;
 719    }
 720  
 721    static get EVENT_KEY() {
 722      return `.$this.DATA_KEY}`;
 723    }
 724  
 725  }
 726  
 727  /**
 728   * --------------------------------------------------------------------------
 729   * Bootstrap (v5.1.3): util/component-functions.js
 730   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 731   * --------------------------------------------------------------------------
 732   */
 733  
 734  const enableDismissTrigger = function (component) {
 735    let method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'hide';
 736    const clickEvent = `click.dismiss$component.EVENT_KEY}`;
 737    const name = component.NAME;
 738    EventHandler.on(document, clickEvent, `[data-bs-dismiss="$name}"]`, function (event) {
 739      if (['A', 'AREA'].includes(this.tagName)) {
 740        event.preventDefault();
 741      }
 742  
 743      if (isDisabled(this)) {
 744        return;
 745      }
 746  
 747      const target = getElementFromSelector(this) || this.closest(`.$name}`);
 748      const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
 749  
 750      instance[method]();
 751    });
 752  };
 753  
 754  /**
 755   * --------------------------------------------------------------------------
 756   * Bootstrap (v5.1.3): dom/manipulator.js
 757   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 758   * --------------------------------------------------------------------------
 759   */
 760  function normalizeData(val) {
 761    if (val === 'true') {
 762      return true;
 763    }
 764  
 765    if (val === 'false') {
 766      return false;
 767    }
 768  
 769    if (val === Number(val).toString()) {
 770      return Number(val);
 771    }
 772  
 773    if (val === '' || val === 'null') {
 774      return null;
 775    }
 776  
 777    return val;
 778  }
 779  
 780  function normalizeDataKey(key) {
 781    return key.replace(/[A-Z]/g, chr => `-$chr.toLowerCase()}`);
 782  }
 783  
 784  const Manipulator = {
 785    setDataAttribute(element, key, value) {
 786      element.setAttribute(`data-bs-$normalizeDataKey(key)}`, value);
 787    },
 788  
 789    removeDataAttribute(element, key) {
 790      element.removeAttribute(`data-bs-$normalizeDataKey(key)}`);
 791    },
 792  
 793    getDataAttributes(element) {
 794      if (!element) {
 795        return {};
 796      }
 797  
 798      const attributes = {};
 799      Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {
 800        let pureKey = key.replace(/^bs/, '');
 801        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
 802        attributes[pureKey] = normalizeData(element.dataset[key]);
 803      });
 804      return attributes;
 805    },
 806  
 807    getDataAttribute(element, key) {
 808      return normalizeData(element.getAttribute(`data-bs-$normalizeDataKey(key)}`));
 809    },
 810  
 811    offset(element) {
 812      const rect = element.getBoundingClientRect();
 813      return {
 814        top: rect.top + window.pageYOffset,
 815        left: rect.left + window.pageXOffset
 816      };
 817    },
 818  
 819    position(element) {
 820      return {
 821        top: element.offsetTop,
 822        left: element.offsetLeft
 823      };
 824    }
 825  
 826  };
 827  
 828  /**
 829   * --------------------------------------------------------------------------
 830   * Bootstrap (v5.1.3): dom/selector-engine.js
 831   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 832   * --------------------------------------------------------------------------
 833   */
 834  const NODE_TEXT = 3;
 835  const SelectorEngine = {
 836    find(selector) {
 837      let element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.documentElement;
 838      return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
 839    },
 840  
 841    findOne(selector) {
 842      let element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.documentElement;
 843      return Element.prototype.querySelector.call(element, selector);
 844    },
 845  
 846    children(element, selector) {
 847      return [].concat(...element.children).filter(child => child.matches(selector));
 848    },
 849  
 850    parents(element, selector) {
 851      const parents = [];
 852      let ancestor = element.parentNode;
 853  
 854      while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
 855        if (ancestor.matches(selector)) {
 856          parents.push(ancestor);
 857        }
 858  
 859        ancestor = ancestor.parentNode;
 860      }
 861  
 862      return parents;
 863    },
 864  
 865    prev(element, selector) {
 866      let previous = element.previousElementSibling;
 867  
 868      while (previous) {
 869        if (previous.matches(selector)) {
 870          return [previous];
 871        }
 872  
 873        previous = previous.previousElementSibling;
 874      }
 875  
 876      return [];
 877    },
 878  
 879    next(element, selector) {
 880      let next = element.nextElementSibling;
 881  
 882      while (next) {
 883        if (next.matches(selector)) {
 884          return [next];
 885        }
 886  
 887        next = next.nextElementSibling;
 888      }
 889  
 890      return [];
 891    },
 892  
 893    focusableChildren(element) {
 894      const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `$selector}:not([tabindex^="-"])`).join(', ');
 895      return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
 896    }
 897  
 898  };
 899  
 900  /**
 901   * --------------------------------------------------------------------------
 902   * Bootstrap (v5.1.3): util/scrollBar.js
 903   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 904   * --------------------------------------------------------------------------
 905   */
 906  const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
 907  const SELECTOR_STICKY_CONTENT = '.sticky-top';
 908  
 909  class ScrollBarHelper {
 910    constructor() {
 911      this._element = document.body;
 912    }
 913  
 914    getWidth() {
 915      // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
 916      const documentWidth = document.documentElement.clientWidth;
 917      return Math.abs(window.innerWidth - documentWidth);
 918    }
 919  
 920    hide() {
 921      const width = this.getWidth();
 922  
 923      this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
 924  
 925  
 926      this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
 927  
 928  
 929      this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
 930  
 931      this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
 932    }
 933  
 934    _disableOverFlow() {
 935      this._saveInitialAttribute(this._element, 'overflow');
 936  
 937      this._element.style.overflow = 'hidden';
 938    }
 939  
 940    _setElementAttributes(selector, styleProp, callback) {
 941      const scrollbarWidth = this.getWidth();
 942  
 943      const manipulationCallBack = element => {
 944        if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
 945          return;
 946        }
 947  
 948        this._saveInitialAttribute(element, styleProp);
 949  
 950        const calculatedValue = window.getComputedStyle(element)[styleProp];
 951        element.style[styleProp] = `$callback(Number.parseFloat(calculatedValue))}px`;
 952      };
 953  
 954      this._applyManipulationCallback(selector, manipulationCallBack);
 955    }
 956  
 957    reset() {
 958      this._resetElementAttributes(this._element, 'overflow');
 959  
 960      this._resetElementAttributes(this._element, 'paddingRight');
 961  
 962      this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
 963  
 964      this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
 965    }
 966  
 967    _saveInitialAttribute(element, styleProp) {
 968      const actualValue = element.style[styleProp];
 969  
 970      if (actualValue) {
 971        Manipulator.setDataAttribute(element, styleProp, actualValue);
 972      }
 973    }
 974  
 975    _resetElementAttributes(selector, styleProp) {
 976      const manipulationCallBack = element => {
 977        const value = Manipulator.getDataAttribute(element, styleProp);
 978  
 979        if (typeof value === 'undefined') {
 980          element.style.removeProperty(styleProp);
 981        } else {
 982          Manipulator.removeDataAttribute(element, styleProp);
 983          element.style[styleProp] = value;
 984        }
 985      };
 986  
 987      this._applyManipulationCallback(selector, manipulationCallBack);
 988    }
 989  
 990    _applyManipulationCallback(selector, callBack) {
 991      if (isElement(selector)) {
 992        callBack(selector);
 993      } else {
 994        SelectorEngine.find(selector, this._element).forEach(callBack);
 995      }
 996    }
 997  
 998    isOverflowing() {
 999      return this.getWidth() > 0;
1000    }
1001  
1002  }
1003  
1004  /**
1005   * --------------------------------------------------------------------------
1006   * Bootstrap (v5.1.3): util/backdrop.js
1007   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1008   * --------------------------------------------------------------------------
1009   */
1010  const Default$1 = {
1011    className: 'modal-backdrop',
1012    isVisible: true,
1013    // if false, we use the backdrop helper without adding any element to the dom
1014    isAnimated: false,
1015    rootElement: 'body',
1016    // give the choice to place backdrop under different elements
1017    clickCallback: null
1018  };
1019  const DefaultType$1 = {
1020    className: 'string',
1021    isVisible: 'boolean',
1022    isAnimated: 'boolean',
1023    rootElement: '(element|string)',
1024    clickCallback: '(function|null)'
1025  };
1026  const NAME$1 = 'backdrop';
1027  const CLASS_NAME_FADE = 'fade';
1028  const CLASS_NAME_SHOW = 'show';
1029  const EVENT_MOUSEDOWN = `mousedown.bs.$NAME$1}`;
1030  
1031  class Backdrop {
1032    constructor(config) {
1033      this._config = this._getConfig(config);
1034      this._isAppended = false;
1035      this._element = null;
1036    }
1037  
1038    show(callback) {
1039      if (!this._config.isVisible) {
1040        execute(callback);
1041        return;
1042      }
1043  
1044      this._append();
1045  
1046      if (this._config.isAnimated) {
1047        reflow(this._getElement());
1048      }
1049  
1050      this._getElement().classList.add(CLASS_NAME_SHOW);
1051  
1052      this._emulateAnimation(() => {
1053        execute(callback);
1054      });
1055    }
1056  
1057    hide(callback) {
1058      if (!this._config.isVisible) {
1059        execute(callback);
1060        return;
1061      }
1062  
1063      this._getElement().classList.remove(CLASS_NAME_SHOW);
1064  
1065      this._emulateAnimation(() => {
1066        this.dispose();
1067        execute(callback);
1068      });
1069    } // Private
1070  
1071  
1072    _getElement() {
1073      if (!this._element) {
1074        const backdrop = document.createElement('div');
1075        backdrop.className = this._config.className;
1076  
1077        if (this._config.isAnimated) {
1078          backdrop.classList.add(CLASS_NAME_FADE);
1079        }
1080  
1081        this._element = backdrop;
1082      }
1083  
1084      return this._element;
1085    }
1086  
1087    _getConfig(config) {
1088      config = { ...Default$1,
1089        ...(typeof config === 'object' ? config : {})
1090      }; // use getElement() with the default "body" to get a fresh Element on each instantiation
1091  
1092      config.rootElement = getElement(config.rootElement);
1093      typeCheckConfig(NAME$1, config, DefaultType$1);
1094      return config;
1095    }
1096  
1097    _append() {
1098      if (this._isAppended) {
1099        return;
1100      }
1101  
1102      this._config.rootElement.append(this._getElement());
1103  
1104      EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
1105        execute(this._config.clickCallback);
1106      });
1107      this._isAppended = true;
1108    }
1109  
1110    dispose() {
1111      if (!this._isAppended) {
1112        return;
1113      }
1114  
1115      EventHandler.off(this._element, EVENT_MOUSEDOWN);
1116  
1117      this._element.remove();
1118  
1119      this._isAppended = false;
1120    }
1121  
1122    _emulateAnimation(callback) {
1123      executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
1124    }
1125  
1126  }
1127  
1128  /**
1129   * --------------------------------------------------------------------------
1130   * Bootstrap (v5.1.3): util/focustrap.js
1131   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1132   * --------------------------------------------------------------------------
1133   */
1134  const Default = {
1135    trapElement: null,
1136    // The element to trap focus inside of
1137    autofocus: true
1138  };
1139  const DefaultType = {
1140    trapElement: 'element',
1141    autofocus: 'boolean'
1142  };
1143  const NAME = 'focustrap';
1144  const DATA_KEY = 'bs.focustrap';
1145  const EVENT_KEY = `.$DATA_KEY}`;
1146  const EVENT_FOCUSIN = `focusin$EVENT_KEY}`;
1147  const EVENT_KEYDOWN_TAB = `keydown.tab$EVENT_KEY}`;
1148  const TAB_KEY = 'Tab';
1149  const TAB_NAV_FORWARD = 'forward';
1150  const TAB_NAV_BACKWARD = 'backward';
1151  
1152  class FocusTrap {
1153    constructor(config) {
1154      this._config = this._getConfig(config);
1155      this._isActive = false;
1156      this._lastTabNavDirection = null;
1157    }
1158  
1159    activate() {
1160      const {
1161        trapElement,
1162        autofocus
1163      } = this._config;
1164  
1165      if (this._isActive) {
1166        return;
1167      }
1168  
1169      if (autofocus) {
1170        trapElement.focus();
1171      }
1172  
1173      EventHandler.off(document, EVENT_KEY); // guard against infinite focus loop
1174  
1175      EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
1176      EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
1177      this._isActive = true;
1178    }
1179  
1180    deactivate() {
1181      if (!this._isActive) {
1182        return;
1183      }
1184  
1185      this._isActive = false;
1186      EventHandler.off(document, EVENT_KEY);
1187    } // Private
1188  
1189  
1190    _handleFocusin(event) {
1191      const {
1192        target
1193      } = event;
1194      const {
1195        trapElement
1196      } = this._config;
1197  
1198      if (target === document || target === trapElement || trapElement.contains(target)) {
1199        return;
1200      }
1201  
1202      const elements = SelectorEngine.focusableChildren(trapElement);
1203  
1204      if (elements.length === 0) {
1205        trapElement.focus();
1206      } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
1207        elements[elements.length - 1].focus();
1208      } else {
1209        elements[0].focus();
1210      }
1211    }
1212  
1213    _handleKeydown(event) {
1214      if (event.key !== TAB_KEY) {
1215        return;
1216      }
1217  
1218      this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
1219    }
1220  
1221    _getConfig(config) {
1222      config = { ...Default,
1223        ...(typeof config === 'object' ? config : {})
1224      };
1225      typeCheckConfig(NAME, config, DefaultType);
1226      return config;
1227    }
1228  
1229  }
1230  
1231  /**
1232   * --------------------------------------------------------------------------
1233   * Bootstrap (v5.1.3): util/sanitizer.js
1234   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1235   * --------------------------------------------------------------------------
1236   */
1237  const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
1238  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
1239  /**
1240   * A pattern that recognizes a commonly useful subset of URLs that are safe.
1241   *
1242   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
1243   */
1244  
1245  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
1246  /**
1247   * A pattern that matches safe data URLs. Only matches image, video and audio types.
1248   *
1249   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
1250   */
1251  
1252  const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
1253  
1254  const allowedAttribute = (attribute, allowedAttributeList) => {
1255    const attributeName = attribute.nodeName.toLowerCase();
1256  
1257    if (allowedAttributeList.includes(attributeName)) {
1258      if (uriAttributes.has(attributeName)) {
1259        return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));
1260      }
1261  
1262      return true;
1263    }
1264  
1265    const regExp = allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp); // Check if a regular expression validates the attribute.
1266  
1267    for (let i = 0, len = regExp.length; i < len; i++) {
1268      if (regExp[i].test(attributeName)) {
1269        return true;
1270      }
1271    }
1272  
1273    return false;
1274  };
1275  
1276  const DefaultAllowlist = {
1277    // Global attributes allowed on any supplied element below.
1278    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
1279    a: ['target', 'href', 'title', 'rel'],
1280    area: [],
1281    b: [],
1282    br: [],
1283    col: [],
1284    code: [],
1285    div: [],
1286    em: [],
1287    hr: [],
1288    h1: [],
1289    h2: [],
1290    h3: [],
1291    h4: [],
1292    h5: [],
1293    h6: [],
1294    i: [],
1295    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
1296    li: [],
1297    ol: [],
1298    p: [],
1299    pre: [],
1300    s: [],
1301    small: [],
1302    span: [],
1303    sub: [],
1304    sup: [],
1305    strong: [],
1306    u: [],
1307    ul: []
1308  };
1309  function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
1310    if (!unsafeHtml.length) {
1311      return unsafeHtml;
1312    }
1313  
1314    if (sanitizeFn && typeof sanitizeFn === 'function') {
1315      return sanitizeFn(unsafeHtml);
1316    }
1317  
1318    const domParser = new window.DOMParser();
1319    const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
1320    const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
1321  
1322    for (let i = 0, len = elements.length; i < len; i++) {
1323      const element = elements[i];
1324      const elementName = element.nodeName.toLowerCase();
1325  
1326      if (!Object.keys(allowList).includes(elementName)) {
1327        element.remove();
1328        continue;
1329      }
1330  
1331      const attributeList = [].concat(...element.attributes);
1332      const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
1333      attributeList.forEach(attribute => {
1334        if (!allowedAttribute(attribute, allowedAttributes)) {
1335          element.removeAttribute(attribute.nodeName);
1336        }
1337      });
1338    }
1339  
1340    return createdDocument.body.innerHTML;
1341  }
1342  
1343  export { BaseComponent as B, Data as D, EventHandler as E, FocusTrap as F, Manipulator as M, SelectorEngine as S, typeCheckConfig as a, isRTL as b, getElementFromSelector as c, defineJQueryPlugin as d, enableDismissTrigger as e, getSelectorFromElement as f, getNextActiveElement as g, getElement as h, isVisible as i, isDisabled as j, isElement as k, ScrollBarHelper as l, Backdrop as m, noop as n, findShadowRoot as o, getUID as p, DefaultAllowlist as q, reflow as r, sanitizeHtml as s, triggerTransitionEnd as t };


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer