import { getWindow } from 'ssr-window';
import { bindModuleMethods } from '../../../shared/utils.js';

const Observer = {
  attach(target, options = {}) {
    const window = getWindow();
    const swiper = this;

    const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
    const observer = new ObserverFunc((mutations) => {
      // The observerUpdate event should only be triggered
      // once despite the number of mutations.  Additional
      // triggers are redundant and are very costly
      if (mutations.length === 1) {
        swiper.emit('observerUpdate', mutations[0]);
        return;
      }
      const observerUpdate = function observerUpdate() {
        swiper.emit('observerUpdate', mutations[0]);
      };

      if (window.requestAnimationFrame) {
        window.requestAnimationFrame(observerUpdate);
      } else {
        window.setTimeout(observerUpdate, 0);
      }
    });

    observer.observe(target, {
      attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
      childList: typeof options.childList === 'undefined' ? true : options.childList,
      characterData: typeof options.characterData === 'undefined' ? true : options.characterData,
    });

    swiper.observer.observers.push(observer);
  },
  init() {
    const swiper = this;
    if (!swiper.support.observer || !swiper.params.observer) return;
    if (swiper.params.observeParents) {
      const containerParents = swiper.$el.parents();
      for (let i = 0; i < containerParents.length; i += 1) {
        swiper.observer.attach(containerParents[i]);
      }
    }
    // Observe container
    swiper.observer.attach(swiper.$el[0], {
      childList: swiper.params.observeSlideChildren,
    });

    // Observe wrapper
    swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false });
  },
  destroy() {
    const swiper = this;
    swiper.observer.observers.forEach((observer) => {
      observer.disconnect();
    });
    swiper.observer.observers = [];
  },
};

export default {
  name: 'observer',
  params: {
    observer: false,
    observeParents: false,
    observeSlideChildren: false,
  },
  create() {
    const swiper = this;
    bindModuleMethods(swiper, {
      observer: {
        ...Observer,
        observers: [],
      },
    });
  },
  on: {
    init(swiper) {
      swiper.observer.init();
    },
    destroy(swiper) {
      swiper.observer.destroy();
    },
  },
};

@@ -37,125 +37,104 @@
 w';%0A
-im
+%0Aex
 port 
-%7B bindModuleMethods %7D from '../../../shared/utils.js';%0A%0Aconst Observer = %7B%0A  attach(target, options = %7B%7D) %7B%0A  
+default function Observer(%7B swiper, extendParams, on, emit %7D) %7B%0A  const observers = %5B%5D;%0A
   co
@@ -159,26 +159,24 @@
 ndow();%0A
-  
   const 
 swiper =
@@ -167,31 +167,52 @@
   const 
-swiper = this;%0A
+attach = (target, options = %7B%7D) =%3E %7B
 %0A    con
@@ -548,39 +548,32 @@
 == 1) %7B%0A        
-swiper.
 emit('observerUp
@@ -683,23 +683,16 @@
         
-swiper.
 emit('ob
@@ -1222,32 +1222,16 @@
 );%0A%0A    
-swiper.observer.
 observer
@@ -1255,45 +1255,32 @@
 %0A  %7D
-,%0A  init() %7B%0A    const swiper = this;
+;%0A  const init = () =%3E %7B
 %0A   
@@ -1507,32 +1507,16 @@
         
-swiper.observer.
 attach(c
@@ -1579,32 +1579,16 @@
 ner%0A    
-swiper.observer.
 attach(s
@@ -1692,32 +1692,16 @@
 per%0A    
-swiper.observer.
 attach(s
@@ -1752,69 +1752,40 @@
 %0A  %7D
-,
+;
 %0A  
+const 
 destroy
-() %7B%0A    const swiper = this;%0A    swiper.observer.
+ = () =%3E %7B%0A    
 obse
@@ -1855,31 +1855,24 @@
 %7D);%0A    
-swiper.
 observer
 .observe
@@ -1867,81 +1867,60 @@
 rver
-.observers = %5B%5D;%0A  %7D,%0A%7D;%0A%0Aexport default %7B%0A  name: 'observer',%0A  p
+s.splice(0, observers.length);%0A  %7D;%0A%0A  extendP
 arams
-: 
+(
 %7B%0A  
@@ -2005,294 +2005,55 @@
 %0A  %7D
-,%0A  create() %7B%0A    const swiper = this;%0A    bindModuleMethods(swiper, %7B%0A      observer: %7B%0A        ...Observer,%0A        observers: %5B%5D,%0A      %7D,%0A    %7D);%0A  %7D,%0A  on: %7B%0A    init(swiper) %7B%0A      swiper.observer.init();%0A    %7D,%0A    destroy(swiper) %7B%0A      swiper.observer.
+);%0A  on('init', init);%0A  on('destroy', 
 destroy
-(
 );%0A
-    %7D,%0A  %7D,%0A%7D;
+%7D
 %0A

convert Observer to functional module