globalAttributes.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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.82
  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. export function watchGlobalAttributes(component, attributeFilter) {
  38. const { el } = component;
  39. const observerOptions = { attributeFilter };
  40. elementToComponentAndObserverOptionsMap.set(el, [component, observerOptions]);
  41. updateGlobalAttributes(component, attributeFilter);
  42. if (!mutationObserver) {
  43. mutationObserver = createObserver("mutation", processMutations);
  44. }
  45. mutationObserver.observe(el, observerOptions);
  46. }
  47. /**
  48. * Helper remove listening for changes to inherited attributes.
  49. */
  50. export function unwatchGlobalAttributes(component) {
  51. elementToComponentAndObserverOptionsMap.delete(component.el);
  52. // we explicitly process queued mutations and disconnect and reconnect
  53. // the observer until MutationObserver gets an `unobserve` method
  54. // see https://github.com/whatwg/dom/issues/126
  55. processMutations(mutationObserver.takeRecords());
  56. mutationObserver.disconnect();
  57. for (const [element, [, observerOptions]] of elementToComponentAndObserverOptionsMap.entries()) {
  58. mutationObserver.observe(element, observerOptions);
  59. }
  60. }