globalAttributes.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. import { createObserver } from "./observers";
  7. const allowedGlobalAttributes = ["lang"];
  8. const elementToComponentAndObserverOptionsMap = new Map();
  9. let mutationObserver;
  10. function updateGlobalAttributes(component, attributeFilter) {
  11. const { el } = component;
  12. const updatedAttributes = {};
  13. attributeFilter
  14. .filter((attr) => !!allowedGlobalAttributes.includes(attr) && !!el.hasAttribute(attr))
  15. .forEach((attr) => {
  16. const value = el.getAttribute(attr);
  17. if (value !== null) {
  18. updatedAttributes[attr] = value;
  19. }
  20. });
  21. component.globalAttributes = updatedAttributes;
  22. }
  23. function processMutations(mutations) {
  24. mutations.forEach(({ target }) => {
  25. const [component, options] = elementToComponentAndObserverOptionsMap.get(target);
  26. updateGlobalAttributes(component, options.attributeFilter);
  27. });
  28. }
  29. /**
  30. * Helper to set up listening for changes to global attributes.
  31. *
  32. * render(): VNode {
  33. * const lang = this.inheritedAttributes['lang'] ?? 'en';
  34. * return <div>My lang is {lang}</div>;
  35. * }
  36. *
  37. * @param component
  38. * @param attributeFilter
  39. */
  40. export function watchGlobalAttributes(component, attributeFilter) {
  41. const { el } = component;
  42. const observerOptions = { attributeFilter };
  43. elementToComponentAndObserverOptionsMap.set(el, [component, observerOptions]);
  44. updateGlobalAttributes(component, attributeFilter);
  45. if (!mutationObserver) {
  46. mutationObserver = createObserver("mutation", processMutations);
  47. }
  48. mutationObserver.observe(el, observerOptions);
  49. }
  50. /**
  51. * Helper remove listening for changes to inherited attributes.
  52. *
  53. * @param component
  54. */
  55. export function unwatchGlobalAttributes(component) {
  56. elementToComponentAndObserverOptionsMap.delete(component.el);
  57. // we explicitly process queued mutations and disconnect and reconnect
  58. // the observer until MutationObserver gets an `unobserve` method
  59. // see https://github.com/whatwg/dom/issues/126
  60. processMutations(mutationObserver.takeRecords());
  61. mutationObserver.disconnect();
  62. for (const [element, [, observerOptions]] of elementToComponentAndObserverOptionsMap.entries()) {
  63. mutationObserver.observe(element, observerOptions);
  64. }
  65. }