watch-options-f5f3e158.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. 'use strict';
  5. const watchForOptions = (containerEl, tagName, onChange) => {
  6. if (typeof MutationObserver === 'undefined') {
  7. return;
  8. }
  9. const mutation = new MutationObserver((mutationList) => {
  10. onChange(getSelectedOption(mutationList, tagName));
  11. });
  12. mutation.observe(containerEl, {
  13. childList: true,
  14. subtree: true,
  15. });
  16. return mutation;
  17. };
  18. const getSelectedOption = (mutationList, tagName) => {
  19. let newOption;
  20. mutationList.forEach((mut) => {
  21. // eslint-disable-next-line @typescript-eslint/prefer-for-of
  22. for (let i = 0; i < mut.addedNodes.length; i++) {
  23. newOption = findCheckedOption(mut.addedNodes[i], tagName) || newOption;
  24. }
  25. });
  26. return newOption;
  27. };
  28. /**
  29. * The "value" key is only set on some components such as ion-select-option.
  30. * As a result, we create a default union type of HTMLElement and the "value" key.
  31. * However, implementers are required to provide the appropriate component type
  32. * such as HTMLIonSelectOptionElement.
  33. */
  34. const findCheckedOption = (node, tagName) => {
  35. /**
  36. * https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
  37. * The above check ensures "node" is an Element (nodeType 1).
  38. */
  39. if (node.nodeType !== 1) {
  40. return undefined;
  41. }
  42. // HTMLElement inherits from Element, so we cast "el" as T.
  43. const el = node;
  44. const options = el.tagName === tagName.toUpperCase() ? [el] : Array.from(el.querySelectorAll(tagName));
  45. return options.find((o) => o.value === el.value);
  46. };
  47. exports.watchForOptions = watchForOptions;