index.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import Component from './component'
  2. import { domReady, isTesting } from './utils'
  3. const Alpine = {
  4. start: async function () {
  5. if (! isTesting()) {
  6. await domReady()
  7. }
  8. this.discoverComponents(el => {
  9. this.initializeComponent(el)
  10. })
  11. // It's easier and more performant to just support Turbolinks than listen
  12. // to MutationOberserver mutations at the document level.
  13. document.addEventListener("turbolinks:load", () => {
  14. this.discoverUninitializedComponents(el => {
  15. this.initializeComponent(el)
  16. })
  17. })
  18. this.listenForNewUninitializedComponentsAtRunTime(el => {
  19. this.initializeComponent(el)
  20. })
  21. },
  22. discoverComponents: function (callback) {
  23. const rootEls = document.querySelectorAll('[x-data]');
  24. rootEls.forEach(rootEl => {
  25. callback(rootEl)
  26. })
  27. },
  28. discoverUninitializedComponents: function (callback) {
  29. const rootEls = document.querySelectorAll('[x-data]');
  30. Array.from(rootEls)
  31. .filter(el => el.__x === undefined)
  32. .forEach(rootEl => {
  33. callback(rootEl)
  34. })
  35. },
  36. listenForNewUninitializedComponentsAtRunTime: function (callback) {
  37. const targetNode = document.querySelector('body');
  38. const observerOptions = {
  39. childList: true,
  40. attributes: true,
  41. subtree: true,
  42. }
  43. const observer = new MutationObserver((mutations) => {
  44. for (let i=0; i < mutations.length; i++){
  45. if (mutations[i].addedNodes.length > 0) {
  46. mutations[i].addedNodes.forEach(node => {
  47. if (node.nodeType !== 1) return
  48. if (node.matches('[x-data]')) callback(node)
  49. })
  50. }
  51. }
  52. })
  53. observer.observe(targetNode, observerOptions)
  54. },
  55. initializeComponent: function (el) {
  56. el.__x = new Component(el)
  57. }
  58. }
  59. if (! window.Alpine && ! isTesting()) {
  60. window.Alpine = Alpine
  61. window.Alpine.start()
  62. }
  63. export default Alpine