]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Register only one `DOMContentLoaded` event listener in `onDOMContentLoaded` (#34158)
authoralpadev <2838324+alpadev@users.noreply.github.com>
Tue, 22 Jun 2021 17:19:55 +0000 (19:19 +0200)
committerGitHub <noreply@github.com>
Tue, 22 Jun 2021 17:19:55 +0000 (20:19 +0300)
* refactor: reuse one DOMContentLoaded event listener in onDOMContentLoaded function

Instead of adding an event listener everytime the utility function is called, cache the callbacks and execute them all at once.

* refactor: drop iife for onDOMContentLoaded

Co-authored-by: XhmikosR <xhmikosr@gmail.com>
js/src/util/index.js
js/tests/unit/util/index.spec.js

index 6edfaa580d4f42a51d5f3c11000c928dec709296..064b4e943113acedaa1835c4f4d1585f525772f5 100644 (file)
@@ -201,9 +201,18 @@ const getjQuery = () => {
   return null
 }
 
+const DOMContentLoadedCallbacks = []
+
 const onDOMContentLoaded = callback => {
   if (document.readyState === 'loading') {
-    document.addEventListener('DOMContentLoaded', callback)
+    // add listener on the first call when the document is in loading state
+    if (!DOMContentLoadedCallbacks.length) {
+      document.addEventListener('DOMContentLoaded', () => {
+        DOMContentLoadedCallbacks.forEach(callback => callback())
+      })
+    }
+
+    DOMContentLoadedCallbacks.push(callback)
   } else {
     callback()
   }
index 04ad6bf4323dbc13513c18fa4090d518d85d14b0..9b5d7b70e22a27f43ce65a9f82212acf4f61026c 100644 (file)
@@ -582,15 +582,24 @@ describe('Util', () => {
   })
 
   describe('onDOMContentLoaded', () => {
-    it('should execute callback when DOMContentLoaded is fired', () => {
+    it('should execute callbacks when DOMContentLoaded is fired and should not add more than one listener', () => {
       const spy = jasmine.createSpy()
+      const spy2 = jasmine.createSpy()
+
+      spyOn(document, 'addEventListener').and.callThrough()
       spyOnProperty(document, 'readyState').and.returnValue('loading')
+
       Util.onDOMContentLoaded(spy)
-      window.document.dispatchEvent(new Event('DOMContentLoaded', {
+      Util.onDOMContentLoaded(spy2)
+
+      document.dispatchEvent(new Event('DOMContentLoaded', {
         bubbles: true,
         cancelable: true
       }))
+
       expect(spy).toHaveBeenCalled()
+      expect(spy2).toHaveBeenCalled()
+      expect(document.addEventListener).toHaveBeenCalledTimes(1)
     })
 
     it('should execute callback if readyState is not "loading"', () => {