/**
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
import"./boot.js";import{calculateSplices as e}from"./array-splice.js";import{microTask as t}from"./async.js";import{wrap as s}from"./wrap.js";function isSlot(e){return"slot"===e.localName}export let FlattenedNodesObserver=class{static getFlattenedNodes(e){const t=s(e);return isSlot(e)?t.assignedNodes({flatten:!0}):Array.from(t.childNodes).map((e=>isSlot(e)?s(e).assignedNodes({flatten:!0}):[e])).reduce(((e,t)=>e.concat(t)),[])}constructor(e,t){this._shadyChildrenObserver=null,this._nativeChildrenObserver=null,this._connected=!1,this._target=e,this.callback=t,this._effectiveNodes=[],this._observer=null,this._scheduled=!1,this._boundSchedule=()=>{this._schedule()},this.connect(),this._schedule()}connect(){isSlot(this._target)?this._listenSlots([this._target]):s(this._target).children&&(this._listenSlots(s(this._target).children),window.ShadyDOM?this._shadyChildrenObserver=window.ShadyDOM.observeChildren(this._target,(e=>{this._processMutations(e)})):(this._nativeChildrenObserver=new MutationObserver((e=>{this._processMutations(e)})),this._nativeChildrenObserver.observe(this._target,{childList:!0}))),this._connected=!0}disconnect(){isSlot(this._target)?this._unlistenSlots([this._target]):s(this._target).children&&(this._unlistenSlots(s(this._target).children),window.ShadyDOM&&this._shadyChildrenObserver?(window.ShadyDOM.unobserveChildren(this._shadyChildrenObserver),this._shadyChildrenObserver=null):this._nativeChildrenObserver&&(this._nativeChildrenObserver.disconnect(),this._nativeChildrenObserver=null)),this._connected=!1}_schedule(){this._scheduled||(this._scheduled=!0,t.run((()=>this.flush())))}_processMutations(e){this._processSlotMutations(e),this.flush()}_processSlotMutations(e){if(e)for(let t=0;t<e.length;t++){let s=e[t];s.addedNodes&&this._listenSlots(s.addedNodes),s.removedNodes&&this._unlistenSlots(s.removedNodes)}}flush(){if(!this._connected)return!1;window.ShadyDOM&&ShadyDOM.flush(),this._nativeChildrenObserver?this._processSlotMutations(this._nativeChildrenObserver.takeRecords()):this._shadyChildrenObserver&&this._processSlotMutations(this._shadyChildrenObserver.takeRecords()),this._scheduled=!1;let t={target:this._target,addedNodes:[],removedNodes:[]},s=this.constructor.getFlattenedNodes(this._target),i=e(s,this._effectiveNodes);for(let e,s=0;s<i.length&&(e=i[s]);s++)for(let s,i=0;i<e.removed.length&&(s=e.removed[i]);i++)t.removedNodes.push(s);for(let e,r=0;r<i.length&&(e=i[r]);r++)for(let i=e.index;i<e.index+e.addedCount;i++)t.addedNodes.push(s[i]);this._effectiveNodes=s;let r=!1;return(t.addedNodes.length||t.removedNodes.length)&&(r=!0,this.callback.call(this._target,t)),r}_listenSlots(e){for(let t=0;t<e.length;t++){let s=e[t];isSlot(s)&&s.addEventListener("slotchange",this._boundSchedule)}}_unlistenSlots(e){for(let t=0;t<e.length;t++){let s=e[t];isSlot(s)&&s.removeEventListener("slotchange",this._boundSchedule)}}};