This commit is contained in:
2023-08-11 10:45:20 +08:00
commit 161ca982f3
31850 changed files with 2706500 additions and 0 deletions

13
node_modules/vue-lazyload/.babelrc generated vendored Normal file
View File

@ -0,0 +1,13 @@
{
"presets": [
[
"env",
{
"modules": false
}
]
],
"plugins": [
"external-helpers"
]
}

42
node_modules/vue-lazyload/.circleci/config.yml generated vendored Normal file
View File

@ -0,0 +1,42 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:8.9.4
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: Workaround for GoogleChrome/puppeteer#290
command: 'sh .circleci/setup_puppeteer.sh'
- run: yarn install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
# run tests!
- run: yarn lint
- run: yarn test

View File

@ -0,0 +1,8 @@
#!/bin/bash
sudo apt-get update
sudo apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

10
node_modules/vue-lazyload/.editorconfig generated vendored Normal file
View File

@ -0,0 +1,10 @@
root = true
[*]
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

8
node_modules/vue-lazyload/.eslintrc generated vendored Normal file
View File

@ -0,0 +1,8 @@
{
"extends": "standard",
"env": {
"browser": true,
"es6": true,
"mocha": true
}
}

21
node_modules/vue-lazyload/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Awe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

447
node_modules/vue-lazyload/README.md generated vendored Normal file
View File

@ -0,0 +1,447 @@
# Vue-Lazyload
[![Build Status](https://img.shields.io/circleci/project/hilongjw/vue-lazyload/master.svg?style=flat-square)](https://circleci.com/gh/hilongjw/vue-lazyload)
[![npm version](https://img.shields.io/npm/v/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)
[![npm downloads](https://img.shields.io/npm/dm/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)
[![npm license](https://img.shields.io/npm/l/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![CDNJS version](https://img.shields.io/cdnjs/v/vue-lazyload.svg)](https://cdnjs.com/libraries/vue-lazyload)
Vue module for lazyloading images in your applications. Some of goals of this project worth noting include:
* Be lightweight, powerful and easy to use
* Work on any image type
* Add loading class while image is loading
* Supports both of Vue 1.0 and Vue 2.0
# Table of Contents
* [___Demo___](#demo)
* [___Requirements___](#requirements)
* [___Installation___](#installation)
* [___Usage___](#usage)
* [___Constructor Options___](#constructor-options)
* [___Implementation___](#implementation)
* [___Basic___](#basic)
* [___Css state___](#css-state)
* [___Methods___](#methods)
* [__Event hook__](#event-hook)
* [__LazyLoadHandler__](#lazyloadhandler)
* [__Performance__](#performance)
* [___Authors && Contributors___](#authors-&&-Contributors)
* [___License___](#license)
# Demo
[___Demo___](http://hilongjw.github.io/vue-lazyload/)
# Requirements
- [Vue.js](https://github.com/vuejs/vue) `1.x` or `2.x`
# Installation
## npm
```bash
$ npm install vue-lazyload -D
```
## CDN
CDN: [https://unpkg.com/vue-lazyload/vue-lazyload.js](https://unpkg.com/vue-lazyload/vue-lazyload.js)
```html
<script src="https://unpkg.com/vue-lazyload/vue-lazyload.js"></script>
<script>
Vue.use(VueLazyload)
...
</script>
```
# Usage
main.js:
```javascript
import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)
// or with options
Vue.use(VueLazyload, {
preLoad: 1.3,
error: 'dist/error.png',
loading: 'dist/loading.gif',
attempt: 1
})
new Vue({
el: 'body',
components: {
App
}
})
```
template:
```html
<ul>
<li v-for="img in list">
<img v-lazy="img.src" >
</li>
</ul>
```
use `v-lazy-container` work with raw HTML
```html
<div v-lazy-container="{ selector: 'img' }">
<img data-src="//domain.com/img1.jpg">
<img data-src="//domain.com/img2.jpg">
<img data-src="//domain.com/img3.jpg">
</div>
```
custom `error` and `loading` placeholder image
```html
<div v-lazy-container="{ selector: 'img', error: 'xxx.jpg', loading: 'xxx.jpg' }">
<img data-src="//domain.com/img1.jpg">
<img data-src="//domain.com/img2.jpg">
<img data-src="//domain.com/img3.jpg">
</div>
```
```html
<div v-lazy-container="{ selector: 'img' }">
<img data-src="//domain.com/img1.jpg" data-error="xxx.jpg">
<img data-src="//domain.com/img2.jpg" data-loading="xxx.jpg">
<img data-src="//domain.com/img3.jpg">
</div>
```
## Constructor Options
|key|description|default|options|
|:---|---|---|---|
| `preLoad`|proportion of pre-loading height|`1.3`|`Number`|
|`error`|src of the image upon load fail|`'data-src'`|`String`
|`loading`|src of the image while loading|`'data-src'`|`String`|
|`attempt`|attempts count|`3`|`Number`|
|`listenEvents`|events that you want vue listen for|`['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']`| [Desired Listen Events](#desired-listen-events) |
|`adapter`| dynamically modify the attribute of element |`{ }`| [Element Adapter](#element-adapter) |
|`filter`| the image's listener filter |`{ }`| [Image listener filter](#image-listener-filter) |
|`lazyComponent`| lazyload component | `false` | [Lazy Component](#lazy-component)
| `dispatchEvent`|trigger the dom event|`false`|`Boolean`|
| `throttleWait`|throttle wait|`200`|`Number`|
| `observer`|use IntersectionObserver|`false`|`Boolean`|
| `observerOptions`|IntersectionObserver options|{ rootMargin: '0px', threshold: 0.1 }|[IntersectionObserver](#intersectionobserver)|
| `silent`|do not print debug info|`true`|`Boolean`|
### Desired Listen Events
You can configure which events you want vue-lazyload by passing in an array
of listener names.
```javascript
Vue.use(VueLazyload, {
preLoad: 1.3,
error: 'dist/error.png',
loading: 'dist/loading.gif',
attempt: 1,
// the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend']
listenEvents: [ 'scroll' ]
})
```
This is useful if you are having trouble with this plugin resetting itself to loading
when you have certain animations and transitions taking place
### Image listener filter
dynamically modify the src of image
```javascript
Vue.use(vueLazy, {
filter: {
progressive (listener, options) {
const isCDN = /qiniudn.com/
if (isCDN.test(listener.src)) {
listener.el.setAttribute('lazy-progressive', 'true')
listener.loading = listener.src + '?imageView2/1/w/10/h/10'
}
},
webp (listener, options) {
if (!options.supportWebp) return
const isCDN = /qiniudn.com/
if (isCDN.test(listener.src)) {
listener.src += '?imageView2/2/format/webp'
}
}
}
})
```
### Element Adapter
```javascript
Vue.use(vueLazy, {
adapter: {
loaded ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error, Init }) {
// do something here
// example for call LoadedHandler
LoadedHandler(el)
},
loading (listender, Init) {
console.log('loading')
},
error (listender, Init) {
console.log('error')
}
}
})
```
### IntersectionObserver
use [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to to improve performance of a large number of nodes.
```javascript
Vue.use(vueLazy, {
// set observer to true
observer: true,
// optional
observerOptions: {
rootMargin: '0px',
threshold: 0.1
}
})
```
### Lazy Component
```javascript
Vue.use(VueLazyload, {
lazyComponent: true
});
```
```html
<lazy-component @show="handler">
<img class="mini-cover" :src="img.src" width="100%" height="400">
</lazy-component>
<script>
{
...
methods: {
handler (component) {
console.log('this component is showing')
}
}
}
</script>
```
## Implementation
### Basic
vue-lazyload will set this img element's `src` with `imgUrl` string
```html
<script>
export default {
data () {
return {
imgObj: {
src: 'http://xx.com/logo.png',
error: 'http://xx.com/error.png',
loading: 'http://xx.com/loading-spin.svg'
},
imgUrl: 'http://xx.com/logo.png' // String
}
}
}
</script>
<template>
<div ref="container">
<img v-lazy="imgUrl"/>
<div v-lazy:background-image="imgUrl"></div>
<!-- with customer error and loading -->
<img v-lazy="imgObj"/>
<div v-lazy:background-image="imgObj"></div>
<!-- Customer scrollable element -->
<img v-lazy.container ="imgUrl"/>
<div v-lazy:background-image.container="img"></div>
<!-- srcset -->
<img v-lazy="'img.400px.jpg'" data-srcset="img.400px.jpg 400w, img.800px.jpg 800w, img.1200px.jpg 1200w">
<img v-lazy="imgUrl" :data-srcset="imgUrl' + '?size=400 400w, ' + imgUrl + ' ?size=800 800w, ' + imgUrl +'/1200.jpg 1200w'" />
</div>
</template>
```
### CSS state
There are three states while img loading
`loading` `loaded` `error`
```html
<img src="imgUrl" lazy="loading">
<img src="imgUrl" lazy="loaded">
<img src="imgUrl" lazy="error">
```
```html
<style>
img[lazy=loading] {
/*your style here*/
}
img[lazy=error] {
/*your style here*/
}
img[lazy=loaded] {
/*your style here*/
}
/*
or background-image
*/
.yourclass[lazy=loading] {
/*your style here*/
}
.yourclass[lazy=error] {
/*your style here*/
}
.yourclass[lazy=loaded] {
/*your style here*/
}
</style>
```
## Methods
### Event Hook
`vm.$Lazyload.$on(event, callback)`
`vm.$Lazyload.$off(event, callback)`
`vm.$Lazyload.$once(event, callback)`
- `$on` Listen for a custom events `loading`, `loaded`, `error`
- `$once` Listen for a custom event, but only once. The listener will be removed once it triggers for the first time.
- `$off` Remove event listener(s).
#### `vm.$Lazyload.$on`
#### Arguments:
* `{string} event`
* `{Function} callback`
#### Example
```javascript
vm.$Lazyload.$on('loaded', function ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error }, formCache) {
console.log(el, src)
})
```
#### `vm.$Lazyload.$once`
#### Arguments:
* `{string} event`
* `{Function} callback`
#### Example
```javascript
vm.$Lazyload.$once('loaded', function ({ el, src }) {
console.log(el, src)
})
```
#### `vm.$Lazyload.$off`
If only the event is provided, remove all listeners for that event
#### Arguments:
* `{string} event`
* `{Function} callback`
#### Example
```javascript
function handler ({ el, src }, formCache) {
console.log(el, src)
}
vm.$Lazyload.$on('loaded', handler)
vm.$Lazyload.$off('loaded', handler)
vm.$Lazyload.$off('loaded')
```
### LazyLoadHandler
`vm.$Lazyload.lazyLoadHandler`
Manually trigger lazy loading position calculation
#### Example
```javascript
this.$Lazyload.lazyLoadHandler()
```
### Performance
```javascript
this.$Lazyload.$on('loaded', function (listener) {
console.table(this.$Lazyload.performance())
})
```
![performance-demo](http://ww1.sinaimg.cn/large/69402bf8gw1fbo62ocvlaj213k09w78w.jpg)
# Authors && Contributors
- [hilongjw](https://github.com/hilongjw)
- [imcvampire](https://github.com/imcvampire)
- [darrynten](https://github.com/darrynten)
- [biluochun](https://github.com/biluochun)
- [whwnow](https://github.com/whwnow)
- [Leopoldthecoder](https://github.com/Leopoldthecoder)
- [michalbcz](https://github.com/michalbcz)
- [blue0728](https://github.com/blue0728)
- [JounQin](https://github.com/JounQin)
- [llissery](https://github.com/llissery)
- [mega667](https://github.com/mega667)
- [RobinCK](https://github.com/RobinCK)
- [GallenHu](https://github.com/GallenHu)
# License
[The MIT License](http://opensource.org/licenses/MIT)

67
node_modules/vue-lazyload/build.js generated vendored Normal file
View File

@ -0,0 +1,67 @@
const fs = require('fs')
const path = require('path')
const rollup = require('rollup')
const babel = require('rollup-plugin-babel')
const uglify = require('rollup-plugin-uglify')
const resolve = require('rollup-plugin-node-resolve')
const commonjs = require('rollup-plugin-commonjs')
const version = process.env.VERSION || require('./package.json').version
const banner =
'/*!\n' +
' * Vue-Lazyload.js v' + version + '\n' +
' * (c) ' + new Date().getFullYear() + ' Awe <hilongjw@gmail.com>\n' +
' * Released under the MIT License.\n' +
' */\n'
async function build () {
try {
const bundle = await rollup.rollup({
input: path.resolve(__dirname, 'src/index.js'),
plugins: [
resolve(),
commonjs(),
babel({ runtimeHelpers: true }),
uglify()
]
})
let { code } = await bundle.generate({
format: 'umd',
name: 'VueLazyload'
})
code = rewriteVersion(code)
await write(path.resolve(__dirname, 'vue-lazyload.js'), code)
console.log('Vue-Lazyload.js v' + version + ' builded')
} catch (e) {
console.log(e)
}
}
function rewriteVersion (code) {
return code.replace('__VUE_LAZYLOAD_VERSION__', version)
}
function getSize (code) {
return (code.length / 1024).toFixed(2) + 'kb'
}
function blue (str) {
return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m'
}
function write (dest, code) {
return new Promise(function (resolve, reject) {
code = banner + code
fs.writeFile(dest, code, function (err) {
if (err) return reject(err)
console.log(blue(dest) + ' ' + getSize(code))
resolve()
})
})
}
build()

51
node_modules/vue-lazyload/karma.conf.js generated vendored Normal file
View File

@ -0,0 +1,51 @@
const DEBUG = !!process.env.DEBUG
if (!DEBUG) process.env.CHROME_BIN = require('puppeteer').executablePath()
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['mocha', 'chai'],
plugins: [
require('karma-mocha'),
require('karma-chai'),
require('karma-chrome-launcher'),
require('karma-rollup-preprocessor')
// require('karma-coverage')
],
files: [
{ pattern: 'test/*-spec.js', watched: false }
],
exclude: [],
preprocessors: {
'test/*-spec.js': ['rollup']
},
// coverageReporter: {
// type: 'html',
// dir: 'coverage/'
// },
rollupPreprocessor: {
plugins: [
require('rollup-plugin-node-resolve')({
jsnext: true,
browser: true
}),
require('rollup-plugin-commonjs')(),
require('rollup-plugin-babel')(),
require('rollup-plugin-replace')({
'process.env.NODE_ENV': JSON.stringify('production')
})
],
format: 'iife', // Helps prevent naming collisions.
name: 'lib', // Required for 'iife' format.
sourcemap: 'inline' // Sensible for testing.
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: DEBUG ? ['Chrome'] : ['ChromeHeadless'],
singleRun: !DEBUG,
concurrency: Infinity
})
}

96
node_modules/vue-lazyload/package.json generated vendored Normal file
View File

@ -0,0 +1,96 @@
{
"_from": "vue-lazyload@1.2.3",
"_id": "vue-lazyload@1.2.3",
"_inBundle": false,
"_integrity": "sha512-DC0ZwxanbRhx79tlA3zY5OYJkH8FYp3WBAnAJbrcuoS8eye1P73rcgAZhyxFSPUluJUTelMB+i/+VkNU/qVm7g==",
"_location": "/vue-lazyload",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "vue-lazyload@1.2.3",
"name": "vue-lazyload",
"escapedName": "vue-lazyload",
"rawSpec": "1.2.3",
"saveSpec": null,
"fetchSpec": "1.2.3"
},
"_requiredBy": [
"/vant"
],
"_resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.2.3.tgz",
"_shasum": "901f9ec15c7e6ca78781a2bae4a343686bdedb2c",
"_spec": "vue-lazyload@1.2.3",
"_where": "C:\\Users\\zhouxueli\\Desktop\\scheduling-app\\node_modules\\vant",
"author": {
"name": "Awe",
"email": "hilongjw@gmail.com"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"bugs": {
"url": "https://github.com/hilongjw/vue-lazyload/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "Vue module for lazy-loading images in your vue.js applications.",
"devDependencies": {
"assign-deep": "^0.4.7",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"chai": "^4.1.2",
"eslint": "^4.13.1",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"karma": "^1.7.1",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-expect": "^1.1.3",
"karma-mocha": "^1.3.0",
"karma-rollup-preprocessor": "^5.0.2",
"mocha": "^4.0.1",
"puppeteer": "^0.13.0",
"rollup": "^0.51.1",
"rollup-plugin-babel": "^2.6.1",
"rollup-plugin-commonjs": "^8.4.1",
"rollup-plugin-node-resolve": "^3.2.0",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^1.0.1",
"vue": "^2.5.13"
},
"homepage": "https://github.com/hilongjw/vue-lazyload#readme",
"keywords": [
"vue-lazyload",
"vue",
"lazyload",
"vue-directive"
],
"license": "MIT",
"main": "vue-lazyload.js",
"name": "vue-lazyload",
"repository": {
"type": "git",
"url": "git+https://github.com/hilongjw/vue-lazyload.git"
},
"scripts": {
"build": "node build",
"lint": "eslint ./src",
"test": "karma start",
"test:debug": "cross-env DEBUG=true karma start"
},
"unpkg": "vue-lazyload.js",
"version": "1.2.3"
}

73
node_modules/vue-lazyload/src/index.js generated vendored Normal file
View File

@ -0,0 +1,73 @@
import Lazy from './lazy'
import LazyComponent from './lazy-component'
import LazyContainer from './lazy-container'
import { assign } from './util'
export default {
/*
* install function
* @param {Vue} Vue
* @param {object} options lazyload options
*/
install (Vue, options = {}) {
const LazyClass = Lazy(Vue)
const lazy = new LazyClass(options)
const lazyContainer = new LazyContainer({ lazy })
const isVue2 = Vue.version.split('.')[0] === '2'
Vue.prototype.$Lazyload = lazy
if (options.lazyComponent) {
Vue.component('lazy-component', LazyComponent(lazy))
}
if (isVue2) {
Vue.directive('lazy', {
bind: lazy.add.bind(lazy),
update: lazy.update.bind(lazy),
componentUpdated: lazy.lazyLoadHandler.bind(lazy),
unbind: lazy.remove.bind(lazy)
})
Vue.directive('lazy-container', {
bind: lazyContainer.bind.bind(lazyContainer),
update: lazyContainer.update.bind(lazyContainer),
unbind: lazyContainer.unbind.bind(lazyContainer)
})
} else {
Vue.directive('lazy', {
bind: lazy.lazyLoadHandler.bind(lazy),
update (newValue, oldValue) {
assign(this.vm.$refs, this.vm.$els)
lazy.add(this.el, {
modifiers: this.modifiers || {},
arg: this.arg,
value: newValue,
oldValue: oldValue
}, {
context: this.vm
})
},
unbind () {
lazy.remove(this.el)
}
})
Vue.directive('lazy-container', {
update (newValue, oldValue) {
lazyContainer.update(this.el, {
modifiers: this.modifiers || {},
arg: this.arg,
value: newValue,
oldValue: oldValue
}, {
context: this.vm
})
},
unbind () {
lazyContainer.unbind(this.el)
}
})
}
}
}

52
node_modules/vue-lazyload/src/lazy-component.js generated vendored Normal file
View File

@ -0,0 +1,52 @@
import { inBrowser } from './util'
export default (lazy) => {
return {
props: {
tag: {
type: String,
default: 'div'
}
},
render (h) {
if (this.show === false) {
return h(this.tag)
}
return h(this.tag, null, this.$slots.default)
},
data () {
return {
el: null,
state: {
loaded: false
},
rect: {},
show: false
}
},
mounted () {
this.el = this.$el
lazy.addLazyBox(this)
lazy.lazyLoadHandler()
},
beforeDestroy () {
lazy.removeComponent(this)
},
methods: {
getRect () {
this.rect = this.$el.getBoundingClientRect()
},
checkInView () {
this.getRect()
return inBrowser &&
(this.rect.top < window.innerHeight * lazy.options.preLoad && this.rect.bottom > 0) &&
(this.rect.left < window.innerWidth * lazy.options.preLoad && this.rect.right > 0)
},
load () {
this.show = true
this.state.loaded = true
this.$emit('show', this)
}
}
}
}

78
node_modules/vue-lazyload/src/lazy-container.js generated vendored Normal file
View File

@ -0,0 +1,78 @@
import {
find,
remove,
assign,
ArrayFrom
} from './util'
export default class LazyContainerMananger {
constructor ({ lazy }) {
this.lazy = lazy
lazy.lazyContainerMananger = this
this._queue = []
}
bind (el, binding, vnode) {
const container = new LazyContainer({ el, binding, vnode, lazy: this.lazy })
this._queue.push(container)
}
update (el, binding, vnode) {
const container = find(this._queue, item => item.el === el)
if (!container) return
container.update({ el, binding, vnode })
}
unbind (el, binding, vnode) {
const container = find(this._queue, item => item.el === el)
if (!container) return
container.clear()
remove(this._queue, container)
}
}
const defaultOptions = {
selector: 'img'
}
class LazyContainer {
constructor ({ el, binding, vnode, lazy }) {
this.el = null
this.vnode = vnode
this.binding = binding
this.options = {}
this.lazy = lazy
this._queue = []
this.update({ el, binding })
}
update ({ el, binding }) {
this.el = el
this.options = assign({}, defaultOptions, binding.value)
const imgs = this.getImgs()
imgs.forEach(el => {
this.lazy.add(el, assign({}, this.binding, {
value: {
src: el.dataset.src,
error: el.dataset.error,
loading: el.dataset.loading
}
}), this.vnode)
})
}
getImgs () {
return ArrayFrom(this.el.querySelectorAll(this.options.selector))
}
clear () {
const imgs = this.getImgs()
imgs.forEach(el => this.lazy.remove(el))
this.vnode = null
this.binding = null
this.lazy = null
}
}

443
node_modules/vue-lazyload/src/lazy.js generated vendored Normal file
View File

@ -0,0 +1,443 @@
import {
inBrowser,
CustomEvent,
remove,
some,
find,
_,
throttle,
supportWebp,
getDPR,
scrollParent,
getBestSelectionFromSrcset,
assign,
isObject,
hasIntersectionObserver,
modeType
} 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']
const DEFAULT_OBSERVER_OPTIONS = {
rootMargin: '0px',
threshold: 0
}
export default function (Vue) {
return class Lazy {
constructor ({ preLoad, error, throttleWait, preLoadTop, dispatchEvent, loading, attempt, silent = true, scale, listenEvents, hasbind, filter, adapter, observer, observerOptions }) {
this.version = '__VUE_LAZYLOAD_VERSION__'
this.mode = modeType.event
this.ListenerQueue = []
this.TargetIndex = 0
this.TargetQueue = []
this.options = {
silent: silent,
dispatchEvent: !!dispatchEvent,
throttleWait: throttleWait || 200,
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 || {},
observer: !!observer,
observerOptions: observerOptions || DEFAULT_OBSERVER_OPTIONS
}
this._initEvent()
this.lazyLoadHandler = throttle(this._lazyLoadHandler.bind(this), this.options.throttleWait)
this.setMode(this.options.observer ? modeType.observer : modeType.event)
}
/**
* 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)
this._observer && this._observer.observe(vm.el)
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
this._observer && this._observer.observe(el)
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
})
if(this._observer){
this._observer.unobserve(el)
this._observer.observe(el)
}
this.lazyLoadHandler()
Vue.nextTick(() => this.lazyLoadHandler())
}
/**
* remove listener form list
* @param {DOM} el
* @return
*/
remove (el) {
if (!el) return
this._observer && this._observer.unobserve(el)
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
* @return
*/
removeComponent (vm) {
if (!vm) return
remove(this.ListenerQueue, vm)
this._observer && this._observer.unobserve(vm.el)
if (vm.$parent && vm.$el.parentNode) {
this._removeListenerTarget(vm.$el.parentNode)
}
this._removeListenerTarget(window)
}
setMode (mode) {
if (!hasIntersectionObserver && mode === modeType.observer) {
mode = modeType.event
}
this.mode = mode // event or observer
if (mode === modeType.event) {
if (this._observer) {
this.ListenerQueue.forEach(listener => {
this._observer.unobserve(listener.el)
})
this._observer = null
}
this.TargetQueue.forEach(target => {
this._initListen(target.el, true)
})
} else {
this.TargetQueue.forEach(target => {
this._initListen(target.el, false)
})
this._initIntersectionObserver()
}
}
/*
*** Private functions ***
*/
/*
* add listener target
* @param {DOM} el listener target
* @return
*/
_addListenerTarget (el) {
if (!el) return
let target = find(this.TargetQueue, target => target.el === el)
if (!target) {
target = {
el: el,
id: ++this.TargetIndex,
childrenCount: 1,
listened: true
}
this.mode === modeType.event && this._initListen(target.el, true)
this.TargetQueue.push(target)
} else {
target.childrenCount++
}
return this.TargetIndex
}
/*
* remove listener target or reduce target childrenCount
* @param {DOM} el or window
* @return
*/
_removeListenerTarget (el) {
this.TargetQueue.forEach((target, index) => {
if (target.el === el) {
target.childrenCount--
if (!target.childrenCount) {
this._initListen(target.el, false)
this.TargetQueue.splice(index, 1)
target = null
}
}
})
}
/*
* add or remove eventlistener
* @param {DOM} el DOM or Window
* @param {boolean} start flag
* @return
*/
_initListen (el, start) {
this.options.ListenEvents.forEach((evt) => _[start ? 'on' : 'off'](el, evt, this.lazyLoadHandler))
}
_initEvent () {
this.Event = {
listeners: {
loading: [],
loaded: [],
error: []
}
}
this.$on = (event, func) => {
this.Event.listeners[event].push(func)
}
this.$once = (event, func) => {
const vm = this
function on () {
vm.$off(event, on)
func.apply(vm, arguments)
}
this.$on(event, on)
}
this.$off = (event, func) => {
if (!func) {
this.Event.listeners[event] = []
return
}
remove(this.Event.listeners[event], func)
}
this.$emit = (event, context, inCache) => {
this.Event.listeners[event].forEach(func => func(context, inCache))
}
}
/**
* find nodes which in viewport and trigger load
* @return
*/
_lazyLoadHandler () {
let catIn = false
this.ListenerQueue.forEach((listener, index) => {
if (listener.state.loaded) return
catIn = listener.checkInView()
if (!catIn) return
listener.load(() => {
if (!listener.error && listener.loaded) {
this.ListenerQueue.splice(index, 1)
}
})
})
}
/**
* init IntersectionObserver
* set mode to observer
* @return
*/
_initIntersectionObserver () {
if (!hasIntersectionObserver) return
this._observer = new IntersectionObserver(this._observerHandler.bind(this), this.options.observerOptions)
if (this.ListenerQueue.length) {
this.ListenerQueue.forEach(listener => {
this._observer.observe(listener.el)
})
}
}
/**
* init IntersectionObserver
* @return
*/
_observerHandler (entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.ListenerQueue.forEach(listener => {
if (listener.el === entry.target) {
if (listener.state.loaded) return this._observer.unobserve(listener.el)
listener.load()
}
})
}
})
}
/**
* set element attribute with image'url and state
* @param {object} lazyload listener object
* @param {string} state will be rendered
* @param {bool} inCache is rendered from cache
* @return
*/
_elRenderer (listener, state, cache) {
if (!listener.el) return
const { el, bindType } = listener
let src
switch (state) {
case 'loading':
src = listener.loading
break
case 'error':
src = listener.error
break
default:
src = listener.src
break
}
if (bindType) {
el.style[bindType] = 'url("' + src + '")'
} else if (el.getAttribute('src') !== src) {
el.setAttribute('src', src)
}
el.setAttribute('lazy', state)
this.$emit(state, listener, cache)
this.options.adapter[state] && this.options.adapter[state](listener, this.options)
if (this.options.dispatchEvent) {
const event = new CustomEvent(state, {
detail: listener
})
el.dispatchEvent(event)
}
}
/**
* generate loading loaded error image url
* @param {string} image's src
* @return {object} image's loading, loaded, error url
*/
_valueFormatter (value) {
let src = value
let loading = this.options.loading
let error = this.options.error
// value is object
if (isObject(value)) {
if (!value.src && !this.options.silent) console.error('Vue Lazyload warning: miss src with ' + value)
src = value.src
loading = value.loading || this.options.loading
error = value.error || this.options.error
}
return {
src,
loading,
error
}
}
}
}

217
node_modules/vue-lazyload/src/listener.js generated vendored Normal file
View File

@ -0,0 +1,217 @@
import {
loadImageAsync,
ObjectKeys,
noop
} from './util'
let imageCache = {}
// el: {
// state,
// src,
// error,
// loading
// }
export default class ReactiveListener {
constructor ({ el, src, error, loading, bindType, $parent, options, elRenderer }) {
this.el = el
this.src = src
this.error = error
this.loading = loading
this.bindType = bindType
this.attempt = 0
this.naturalHeight = 0
this.naturalWidth = 0
this.options = options
this.rect = null
this.$parent = $parent
this.elRenderer = elRenderer
this.performanceData = {
init: Date.now(),
loadStart: 0,
loadEnd: 0
}
this.filter()
this.initState()
this.render('loading', false)
}
/*
* init listener state
* @return
*/
initState () {
this.el.dataset.src = this.src
this.state = {
error: false,
loaded: false,
rendered: false
}
}
/*
* record performance
* @return
*/
record (event) {
this.performanceData[event] = Date.now()
}
/*
* update image listener data
* @param {String} image uri
* @param {String} loading image uri
* @param {String} error image uri
* @return
*/
update ({ src, loading, error }) {
const oldSrc = this.src
this.src = src
this.loading = loading
this.error = error
this.filter()
if (oldSrc !== this.src) {
this.attempt = 0
this.initState()
}
}
/*
* get el node rect
* @return
*/
getRect () {
this.rect = this.el.getBoundingClientRect()
}
/*
* check el is in view
* @return {Boolean} el is in view
*/
checkInView () {
this.getRect()
return (this.rect.top < window.innerHeight * this.options.preLoad && this.rect.bottom > this.options.preLoadTop) &&
(this.rect.left < window.innerWidth * this.options.preLoad && this.rect.right > 0)
}
/*
* listener filter
*/
filter () {
ObjectKeys(this.options.filter).map(key => {
this.options.filter[key](this, this.options)
})
}
/*
* render loading first
* @params cb:Function
* @return
*/
renderLoading (cb) {
loadImageAsync({
src: this.loading
}, data => {
this.render('loading', false)
cb()
}, () => {
// handler `loading image` load failed
cb()
if (!this.options.silent) console.warn(`VueLazyload log: load failed with loading image(${this.loading})`)
})
}
/*
* try load image and render it
* @return
*/
load (onFinish = noop) {
if ((this.attempt > this.options.attempt - 1) && this.state.error) {
if (!this.options.silent) console.log(`VueLazyload log: ${this.src} tried too more than ${this.options.attempt} times`)
onFinish()
return
}
if (this.state.loaded || imageCache[this.src]) {
this.state.loaded = true
onFinish()
return this.render('loaded', true)
}
this.renderLoading(() => {
this.attempt++
this.record('loadStart')
loadImageAsync({
src: this.src
}, data => {
this.naturalHeight = data.naturalHeight
this.naturalWidth = data.naturalWidth
this.state.loaded = true
this.state.error = false
this.record('loadEnd')
this.render('loaded', false)
imageCache[this.src] = 1
onFinish()
}, err => {
!this.options.silent && console.error(err)
this.state.error = true
this.state.loaded = false
this.render('error', false)
})
})
}
/*
* render image
* @param {String} state to render // ['loading', 'src', 'error']
* @param {String} is form cache
* @return
*/
render (state, cache) {
this.elRenderer(this, state, cache)
}
/*
* output performance data
* @return {Object} performance data
*/
performance () {
let state = 'loading'
let time = 0
if (this.state.loaded) {
state = 'loaded'
time = (this.performanceData.loadEnd - this.performanceData.loadStart) / 1000
}
if (this.state.error) state = 'error'
return {
src: this.src,
state,
time
}
}
/*
* destroy
* @return
*/
destroy () {
this.el = null
this.src = null
this.error = null
this.loading = null
this.bindType = null
this.attempt = 0
}
}

292
node_modules/vue-lazyload/src/util.js generated vendored Normal file
View File

@ -0,0 +1,292 @@
import assign from 'assign-deep'
const inBrowser = typeof window !== 'undefined'
export const hasIntersectionObserver = inBrowser && 'IntersectionObserver' in window
export const modeType = {
event: 'event',
observer: 'observer'
}
// CustomEvent polyfill
const CustomEvent = (function () {
if (!inBrowser) return
if (typeof window.CustomEvent === 'function') return window.CustomEvent
function CustomEvent (event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined }
var evt = document.createEvent('CustomEvent')
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
return evt
}
CustomEvent.prototype = window.Event.prototype
return CustomEvent
})()
function remove (arr, item) {
if (!arr.length) return
const index = arr.indexOf(item)
if (index > -1) return arr.splice(index, 1)
}
function some (arr, fn) {
let has = false
for (let i = 0, len = arr.length; i < len; i++) {
if (fn(arr[i])) {
has = true
break
}
}
return has
}
function getBestSelectionFromSrcset (el, scale) {
if (el.tagName !== 'IMG' || !el.getAttribute('data-srcset')) return
let options = el.getAttribute('data-srcset')
const result = []
const container = el.parentNode
const containerWidth = container.offsetWidth * scale
let spaceIndex
let tmpSrc
let tmpWidth
options = options.trim().split(',')
options.map(item => {
item = item.trim()
spaceIndex = item.lastIndexOf(' ')
if (spaceIndex === -1) {
tmpSrc = item
tmpWidth = 999998
} else {
tmpSrc = item.substr(0, spaceIndex)
tmpWidth = parseInt(item.substr(spaceIndex + 1, item.length - spaceIndex - 2), 10)
}
result.push([tmpWidth, tmpSrc])
})
result.sort(function (a, b) {
if (a[0] < b[0]) {
return -1
}
if (a[0] > b[0]) {
return 1
}
if (a[0] === b[0]) {
if (b[1].indexOf('.webp', b[1].length - 5) !== -1) {
return 1
}
if (a[1].indexOf('.webp', a[1].length - 5) !== -1) {
return -1
}
}
return 0
})
let bestSelectedSrc = ''
let tmpOption
const resultCount = result.length
for (let i = 0; i < resultCount; i++) {
tmpOption = result[i]
if (tmpOption[0] >= containerWidth) {
bestSelectedSrc = tmpOption[1]
break
}
}
return bestSelectedSrc
}
function find (arr, fn) {
let item
for (let i = 0, len = arr.length; i < len; i++) {
if (fn(arr[i])) {
item = arr[i]
break
}
}
return item
}
const getDPR = (scale = 1) => inBrowser ? (window.devicePixelRatio || scale) : scale
function supportWebp () {
if (!inBrowser) return false
let support = true
const d = document
try {
let el = d.createElement('object')
el.type = 'image/webp'
el.style.visibility = 'hidden'
el.innerHTML = '!'
d.body.appendChild(el)
support = !el.offsetWidth
d.body.removeChild(el)
} catch (err) {
support = false
}
return support
}
function throttle (action, delay) {
let timeout = null
let lastRun = 0
return function () {
if (timeout) {
return
}
let elapsed = Date.now() - lastRun
let context = this
let args = arguments
let runCallback = function () {
lastRun = Date.now()
timeout = false
action.apply(context, args)
}
if (elapsed >= delay) {
runCallback()
} else {
timeout = setTimeout(runCallback, delay)
}
}
}
function testSupportsPassive () {
if (!inBrowser) return
let support = false
try {
let opts = Object.defineProperty({}, 'passive', {
get: function () {
support = true
}
})
window.addEventListener('test', null, opts)
} catch (e) {}
return support
}
const supportsPassive = testSupportsPassive()
const _ = {
on (el, type, func, capture = false) {
if (supportsPassive) {
el.addEventListener(type, func, {
capture: capture,
passive: true
})
} else {
el.addEventListener(type, func, capture)
}
},
off (el, type, func, capture = false) {
el.removeEventListener(type, func, capture)
}
}
const loadImageAsync = (item, resolve, reject) => {
let image = new Image()
image.src = item.src
image.onload = function () {
resolve({
naturalHeight: image.naturalHeight,
naturalWidth: image.naturalWidth,
src: image.src
})
}
image.onerror = function (e) {
reject(e)
}
}
const style = (el, prop) => {
return typeof getComputedStyle !== 'undefined'
? getComputedStyle(el, null).getPropertyValue(prop)
: el.style[prop]
}
const overflow = (el) => {
return style(el, 'overflow') + style(el, 'overflow-y') + style(el, 'overflow-x')
}
const scrollParent = (el) => {
if (!inBrowser) return
if (!(el instanceof HTMLElement)) {
return window
}
let parent = el
while (parent) {
if (parent === document.body || parent === document.documentElement) {
break
}
if (!parent.parentNode) {
break
}
if (/(scroll|auto)/.test(overflow(parent))) {
return parent
}
parent = parent.parentNode
}
return window
}
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
function ObjectKeys (obj) {
if (!(obj instanceof Object)) return []
if (Object.keys) {
return Object.keys(obj)
} else {
let keys = []
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key)
}
}
return keys
}
}
function ArrayFrom (arrLike) {
let len = arrLike.length
const list = []
for (let i = 0; i < len; i++) {
list.push(arrLike[i])
}
return list
}
function noop () {}
export {
inBrowser,
CustomEvent,
remove,
some,
find,
assign,
noop,
ArrayFrom,
_,
isObject,
throttle,
supportWebp,
getDPR,
scrollParent,
loadImageAsync,
getBestSelectionFromSrcset,
ObjectKeys
}

42
node_modules/vue-lazyload/test/test-spec.js generated vendored Normal file
View File

@ -0,0 +1,42 @@
import Vue from 'vue'
import VueLazyload from '../src'
import genLazyCore from '../src/lazy'
describe('VueLazyload.js Test Suite', function () {
it('install', function () {
Vue.use(VueLazyload)
const vm = new Vue()
assert(vm.$Lazyload, 'has $Lazyload')
})
it('_valueFormatter', function () {
const LazyCore = genLazyCore(Vue)
const lazyload = new LazyCore({
error: 'error',
loading: 'loading'
})
expect(lazyload._valueFormatter('src').src).to.equal('src')
expect(lazyload._valueFormatter('src').error).to.equal('error')
expect(lazyload._valueFormatter('src').loading).to.equal('loading')
expect(lazyload._valueFormatter({
src: 'src',
error: 'error',
loading: 'loading'
}).src).to.equal('src')
expect(lazyload._valueFormatter({
src: 'src',
error: 'error',
loading: 'loading'
}).error).to.equal('error')
expect(lazyload._valueFormatter({
src: 'src',
error: 'error',
loading: 'loading'
}).loading).to.equal('loading')
})
})

6
node_modules/vue-lazyload/vue-lazyload.js generated vendored Normal file

File diff suppressed because one or more lines are too long