import ResizeObserver from 'resize-observer-polyfill';
import nullthrows from 'nullthrows';

// flow type copied from
// https://github.com/que-etc/resize-observer-polyfill/blob/master/src/index.js.flow
var bpfrpt_proptype_ResizeObserverEntry = {
  "target": function target() {
    return (typeof Element === "function" ? PropTypes.instanceOf(Element).isRequired : PropTypes.any.isRequired).apply(this, arguments);
  },
  "contentRect": PropTypes.shape({
    x: PropTypes.number.isRequired,
    y: PropTypes.number.isRequired,
    width: PropTypes.number.isRequired,
    height: PropTypes.number.isRequired,
    top: PropTypes.number.isRequired,
    right: PropTypes.number.isRequired,
    bottom: PropTypes.number.isRequired,
    left: PropTypes.number.isRequired
  }).isRequired
}; // Lightweight utilities to make observing resize of DOM element easier
// with `ResizeObserver`.
// See https://developers.google.com/web/updates/2016/10/resizeobserver
// Usage:
//   `ResizeObserver.observe(element, (entry) => console.log(entry))`
//   `ResizeObserver.unobserve(element)`
var instance = null;
var nodesObserving = new Map();
function onResizeObserve(entries) {
  entries.forEach(handleResizeObserverEntry);
}
function handleResizeObserverEntry(entry) {
  var node = entry.target;
  var callbacks = nodesObserving.get(node);
  var executeCallback = function executeCallback(cb) {
    return cb(entry);
  };
  callbacks && callbacks.forEach(executeCallback);
}
export function observe(node, callback) {
  var el = node;
  var observer = instance || (instance = new ResizeObserver(onResizeObserve));
  if (nodesObserving.has(el)) {
    // Already observing node.
    var callbacks = nullthrows(nodesObserving.get(el));
    callbacks.push(callback);
  } else {
    var _callbacks = [callback];
    nodesObserving.set(el, _callbacks);
    observer.observe(el);
  }
}
export function unobserve(node, callback) {
  var observer = instance;
  if (!observer) {
    return;
  }
  var el = node;
  observer.unobserve(el);
  if (callback) {
    // Remove the passed in callback from the callbacks of the observed node
    // And, if no more callbacks then stop observing the node
    var callbacks = nodesObserving.has(el) ? nullthrows(nodesObserving.get(el)).filter(function (cb) {
      return cb !== callback;
    }) : null;
    if (callbacks && callbacks.length) {
      nodesObserving.set(el, callbacks);
    } else {
      nodesObserving["delete"](el);
    }
  } else {
    // Delete all callbacks for the node.
    nodesObserving["delete"](el);
  }
  if (!nodesObserving.size) {
    // We have nothing to observe. Stop observing, which stops the
    // ResizeObserver instance from receiving notifications of
    // DOM resizing. Until the observe() method is used again.
    // According to specification a ResizeObserver is deleted by the garbage
    // collector if the target element is deleted.
    observer.disconnect();
    instance = null;
  }
}
export default {
  observe: observe,
  unobserve: unobserve
};
import PropTypes from "prop-types";
export { bpfrpt_proptype_ResizeObserverEntry };