<commit_before>import { 
    inBrowser,
    remove, 
    some, 
    find, 
    _,
    throttle,
    supportWebp,
    getDPR,
    scrollParent,
    getBestSelectionFromSrcset,
    assign,
    isObject
} from './util'

import ReactiveListener from './listener'

const DEFAULT_URL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const DEFAULT_EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']

export default function (Vue) {
    return class Lazy {
        constructor ({ preLoad, error, preLoadTop, dispatchEvent, loading, attempt, silent, scale, listenEvents, hasbind, filter, adapter }) {
            this.version = '__VUE_LAZYLOAD_VERSION__'
            this.ListenerQueue = []
            this.TargetIndex = 0
            this.TargetQueue = []
            this.options = {
                silent: silent || true,
                dispatchEvent: !!dispatchEvent,
                preLoad: preLoad || 1.3,
                preLoadTop: preLoadTop || 0,
                error: error || DEFAULT_URL,
                loading: loading || DEFAULT_URL,
                attempt: attempt || 3,
                scale: scale || getDPR(scale),
                ListenEvents: listenEvents || DEFAULT_EVENTS,
                hasbind: false,
                supportWebp: supportWebp(),
                filter: filter || {},
                adapter: adapter || {}
            }
            this._initEvent()

            this.lazyLoadHandler = throttle(() => {
                let catIn = false
                this.ListenerQueue.forEach(listener => {
                    if (listener.state.loaded) return
                    catIn = listener.checkInView()
                    catIn && listener.load()
                })
            }, 200)
        }

        /**
         * update config
         * @param  {Object} config params
         * @return
         */
        config (options = {}) {
            assign(this.options, options)
        }

        /**
         * output listener's load performance
         * @return {Array} 
         */
        performance () {
            let list = []

            this.ListenerQueue.map(item => {
                list.push(item.performance())
            })

            return list
        }

        /**
         * add lazy component to queue
         * @param  {Vue} vm lazy component instance
         * @return
         */
        addLazyBox (vm) {
            this.ListenerQueue.push(vm)
            if (inBrowser) {
                this._addListenerTarget(window)
                if (vm.$el && vm.$el.parentNode) {
                    this._addListenerTarget(vm.$el.parentNode)
                }
            }
        }

        /**
         * add image listener to queue
         * @param  {DOM} el 
         * @param  {object} binding vue directive binding
         * @param  {vnode} vnode vue directive vnode
         * @return
         */
        add (el, binding, vnode) {
            if (some(this.ListenerQueue, item => item.el === el)) {
                this.update(el, binding)
                return Vue.nextTick(this.lazyLoadHandler)
            }

            let { src, loading, error } = this._valueFormatter(binding.value)

            Vue.nextTick(() => {
                src = getBestSelectionFromSrcset(el, this.options.scale) || src

                const container = Object.keys(binding.modifiers)[0]
                let $parent

                if (container) {
                    $parent = vnode.context.$refs[container]
                    // if there is container passed in, try ref first, then fallback to getElementById to support the original usage
                    $parent = $parent ? $parent.$el || $parent : document.getElementById(container)
                }

                if (!$parent) {
                    $parent = scrollParent(el)
                }

                const newListener = new ReactiveListener({
                    bindType: binding.arg,
                    $parent,
                    el,
                    loading,
                    error,
                    src,
                    elRenderer: this._elRenderer.bind(this),
                    options: this.options
                })

                this.ListenerQueue.push(newListener)
                if (inBrowser) {
                    this._addListenerTarget(window)
                    this._addListenerTarget($parent)
                }

                this.lazyLoadHandler()
                Vue.nextTick(() => this.lazyLoadHandler())
            })
        }

         /**
         * update image src
         * @param  {DOM} el 
         * @param  {object} vue directive binding
         * @return
         */
        update (el, binding) {
            let { src, loading, error } = this._valueFormatter(binding.value)

            const exist = find(this.ListenerQueue, item => item.el === el)

            exist && exist.update({
                src,
                loading,
                error
            })
            this.lazyLoadHandler()
            Vue.nextTick(() => this.lazyLoadHandler())
        }

        /**
         * remove listener form list
         * @param  {DOM} el 
         * @return
         */
        remove (el) {
            if (!el) return
            const existItem = find(this.ListenerQueue, item => item.el === el)
            if (existItem) {
                this._removeListenerTarget(existItem.$parent)
                this._removeListenerTarget(window)
                remove(this.ListenerQueue, existItem) && existItem.destroy()
            }
        }

        /**
         * remove lazy components form list
         * @param  {Vue} vm Vue instance <commit_msg>set src to value from getBestSelectionFromSrcset if possible when in update hook<commit_after>import { 
    inBrowser,
    remove, 
    some, 
    find, 
    _,
    throttle,
    supportWebp,
    getDPR,
    scrollParent,
    getBestSelectionFromSrcset,
    assign,
    isObject
} from './util'

import ReactiveListener from './listener'

const DEFAULT_URL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const DEFAULT_EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']

export default function (Vue) {
    return class Lazy {
        constructor ({ preLoad, error, preLoadTop, dispatchEvent, loading, attempt, silent, scale, listenEvents, hasbind, filter, adapter }) {
            this.version = '__VUE_LAZYLOAD_VERSION__'
            this.ListenerQueue = []
            this.TargetIndex = 0
            this.TargetQueue = []
            this.options = {
                silent: silent || true,
                dispatchEvent: !!dispatchEvent,
                preLoad: preLoad || 1.3,
                preLoadTop: preLoadTop || 0,
                error: error || DEFAULT_URL,
                loading: loading || DEFAULT_URL,
                attempt: attempt || 3,
                scale: scale || getDPR(scale),
                ListenEvents: listenEvents || DEFAULT_EVENTS,
                hasbind: false,
                supportWebp: supportWebp(),
                filter: filter || {},
                adapter: adapter || {}
            }
            this._initEvent()

            this.lazyLoadHandler = throttle(() => {
                let catIn = false
                this.ListenerQueue.forEach(listener => {
                    if (listener.state.loaded) return
                    catIn = listener.checkInView()
                    catIn && listener.load()
                })
            }, 200)
        }

        /**
         * update config
         * @param  {Object} config params
         * @return
         */
        config (options = {}) {
            assign(this.options, options)
        }

        /**
         * output listener's load performance
         * @return {Array} 
         */
        performance () {
            let list = []

            this.ListenerQueue.map(item => {
                list.push(item.performance())
            })

            return list
        }

        /**
         * add lazy component to queue
         * @param  {Vue} vm lazy component instance
         * @return
         */
        addLazyBox (vm) {
            this.ListenerQueue.push(vm)
            if (inBrowser) {
                this._addListenerTarget(window)
                if (vm.$el && vm.$el.parentNode) {
                    this._addListenerTarget(vm.$el.parentNode)
                }
            }
        }

        /**
         * add image listener to queue
         * @param  {DOM} el 
         * @param  {object} binding vue directive binding
         * @param  {vnode} vnode vue directive vnode
         * @return
         */
        add (el, binding, vnode) {
            if (some(this.ListenerQueue, item => item.el === el)) {
                this.update(el, binding)
                return Vue.nextTick(this.lazyLoadHandler)
            }

            let { src, loading, error } = this._valueFormatter(binding.value)

            Vue.nextTick(() => {
                src = getBestSelectionFromSrcset(el, this.options.scale) || src

                const container = Object.keys(binding.modifiers)[0]
                let $parent

                if (container) {
                    $parent = vnode.context.$refs[container]
                    // if there is container passed in, try ref first, then fallback to getElementById to support the original usage
                    $parent = $parent ? $parent.$el || $parent : document.getElementById(container)
                }

                if (!$parent) {
                    $parent = scrollParent(el)
                }

                const newListener = new ReactiveListener({
                    bindType: binding.arg,
                    $parent,
                    el,
                    loading,
                    error,
                    src,
                    elRenderer: this._elRenderer.bind(this),
                    options: this.options
                })

                this.ListenerQueue.push(newListener)
                if (inBrowser) {
                    this._addListenerTarget(window)
                    this._addListenerTarget($parent)
                }

                this.lazyLoadHandler()
                Vue.nextTick(() => this.lazyLoadHandler())
            })
        }

         /**
         * update image src
         * @param  {DOM} el 
         * @param  {object} vue directive binding
         * @return
         */
        update (el, binding) {
            let { src, loading, error } = this._valueFormatter(binding.value)
            src = getBestSelectionFromSrcset(el, this.options.scale) || src

            const exist = find(this.ListenerQueue, item => item.el === el)

            exist && exist.update({
                src,
                loading,
                error
            })
            this.lazyLoadHandler()
            Vue.nextTick(() => this.lazyLoadHandler())
        }

        /**
         * remove listener form list
         * @param  {DOM} el 
         * @return
         */
        remove (el) {
            if (!el) return
            const existItem = find(this.ListenerQueue, item => item.el === el)
            if (existItem) {
                this._removeListenerTarget(existItem.$parent)
                this._removeListenerTarget(window)
                remove(this.ListenerQueue, existItem) && existItem.destroy()
            }
        }

        /**
         * remove lazy components form list
         * @param  {Vue} vm Vue instance 
{'fraction_non_alphanumeric': 0.10028333476431699, 'fraction_numerical': 0.002404052545719928, 'mean_word_length': 1.3212435233160622, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3890829', 'n_tokens_mistral': 3065, 'n_tokens_neox': 2862, 'n_words': 665}