ocr scan
This commit is contained in:
parent
8f5e577cca
commit
1146dddac2
21
express-server/node_modules/vue/LICENSE
generated
vendored
Normal file
21
express-server/node_modules/vue/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-present, Yuxi (Evan) You
|
||||
|
||||
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.
|
327
express-server/node_modules/vue/README.md
generated
vendored
Normal file
327
express-server/node_modules/vue/README.md
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
<p align="center"><a href="https://vuejs.org" target="_blank" rel="noopener noreferrer"><img width="100" src="https://vuejs.org/images/logo.png" alt="Vue logo"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://circleci.com/gh/vuejs/vue/tree/dev"><img src="https://img.shields.io/circleci/project/github/vuejs/vue/dev.svg" alt="Build Status"></a>
|
||||
<a href="https://codecov.io/github/vuejs/vue?branch=dev"><img src="https://img.shields.io/codecov/c/github/vuejs/vue/dev.svg" alt="Coverage Status"></a>
|
||||
<a href="https://npmcharts.com/compare/vue?minimal=true"><img src="https://img.shields.io/npm/dm/vue.svg" alt="Downloads"></a>
|
||||
<a href="https://www.npmjs.com/package/vue"><img src="https://img.shields.io/npm/v/vue.svg" alt="Version"></a>
|
||||
<a href="https://www.npmjs.com/package/vue"><img src="https://img.shields.io/npm/l/vue.svg" alt="License"></a>
|
||||
<a href="https://chat.vuejs.org/"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
|
||||
<br>
|
||||
<a href="https://app.saucelabs.com/builds/50f8372d79f743a3b25fb6ca4851ca4c"><img src="https://app.saucelabs.com/buildstatus/vuejs" alt="Build Status"></a>
|
||||
</p>
|
||||
|
||||
<h2 align="center">Supporting Vue.js</h2>
|
||||
|
||||
Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [backers](https://github.com/vuejs/vue/blob/dev/BACKERS.md). If you'd like to join them, please consider:
|
||||
|
||||
- [Become a backer or sponsor on Patreon](https://www.patreon.com/evanyou).
|
||||
- [Become a backer or sponsor on Open Collective](https://opencollective.com/vuejs).
|
||||
- [One-time donation via PayPal or crypto-currencies.](https://vuejs.org/support-vuejs/#One-time-Donations)
|
||||
|
||||
#### What's the difference between Patreon and OpenCollective?
|
||||
|
||||
Funds donated via Patreon go directly to support Evan You's full-time work on Vue.js. Funds donated via OpenCollective are managed with transparent expenses and will be used for compensating work and expenses for core team members or sponsoring community events. Your name/logo will receive proper recognition and exposure by donating on either platform.
|
||||
|
||||
<h3 align="center">Special Sponsors</h3>
|
||||
<!--special start-->
|
||||
|
||||
<p align="center">
|
||||
<a href="https://stdlib.com/" target="_blank">
|
||||
<img width="260px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/stdlib.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<!--special end-->
|
||||
|
||||
<h3 align="center">Platinum Sponsors</h3>
|
||||
|
||||
<!--platinum start-->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://moduscreate.com/?utm_source=Vue&utm_medium=Partnership&utm_campaign=VueShip" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/modus.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.bitsrc.io/?utm_source=vue&utm_medium=vue&utm_campaign=vue&utm_term=vue&utm_content=vue" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/bit.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://tooltwist.com/" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/tooltwist.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://vueschool.io/?utm_source=Vuejs.org&utm_medium=Banner&utm_campaign=Sponsored%20Banner&utm_content=V1" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vueschool.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://vehikl.com/" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vehikl.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.nativescript.org/vue?utm_source=vue-js-org&utm_medium=website&utm_campaign=nativescript-awareness" target="_blank">
|
||||
<img width="222px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/nativescript.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--platinum end-->
|
||||
|
||||
<!--special-china start-->
|
||||
<h3 align="center">Platinum Sponsors (China)</h3>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://www.dcloud.io/?hmsr=vuejsorg&hmpl=&hmcu=&hmkw=&hmci=" target="_blank">
|
||||
<img width="177px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/dcloud.gif">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--special-china end-->
|
||||
|
||||
<h3 align="center">Gold Sponsors</h4>
|
||||
|
||||
<!--gold start-->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.vuemastery.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vuemastery.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://laravel.com" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/laravel.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://chaitin.cn/en/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/chaitin.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://htmlburger.com" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/html_burger.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.frontenddeveloperlove.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/frontend_love.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://onsen.io/vue/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/onsen_ui.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://vuetifyjs.com" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vuetify.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://neds.com.au/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/neds.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://icons8.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/icons_8.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://vuejobs.com/?ref=vuejs" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/vuejobs.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://tidelift.com/subscription/npm/vue" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/tidelift.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://www.syncfusion.com/?utm_source=vuejs&utm_medium=list&utm_campaign=vuejsjslistcy19" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/syncfusion.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://opteo.com/vue" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/opteo.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://devsquad.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/devsquad.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.inkoop.in/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/inkoop.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.firesticktricks.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/firestick_tricks.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://github.com/marcus-hiles" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/marcus_hiles.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://intygrate.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/intygrate.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://isleofcode.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/isle_of_code.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://yakaz.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/yakaz.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://passionatepeople.io/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/passionate_people.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.bestvpn.co/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/bestvpn_co.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://en.shopware.com/" target="_blank">
|
||||
<img width="148px" src="https://raw.githubusercontent.com/vuejs/vuejs.org/master/themes/vue/source/images/shopware_ag.svg">
|
||||
</a>
|
||||
</td>
|
||||
</tr><tr></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--gold end-->
|
||||
|
||||
<h3 align="center">Sponsors via <a href="https://opencollective.com/vuejs">Open Collective</a></h3>
|
||||
|
||||
<h4 align="center">Platinum</h4>
|
||||
|
||||
<a href="https://opencollective.com/vuejs/tiers/platinum-sponsors/0/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/platinum-sponsors/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/vuejs/tiers/platinum-sponsors/1/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/platinum-sponsors/1/avatar.svg"></a>
|
||||
|
||||
<h4 align="center">Gold</h4>
|
||||
|
||||
<a href="https://opencollective.com/vuejs/tiers/gold-sponsors/0/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/gold-sponsors/0/avatar.svg" height="60px"></a>
|
||||
<a href="https://opencollective.com/vuejs/tiers/gold-sponsors/1/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/gold-sponsors/1/avatar.svg" height="60px"></a>
|
||||
<a href="https://opencollective.com/vuejs/tiers/gold-sponsors/2/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/gold-sponsors/2/avatar.svg" height="60px"></a>
|
||||
<a href="https://opencollective.com/vuejs/tiers/gold-sponsors/3/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/gold-sponsors/3/avatar.svg" height="60px"></a>
|
||||
<a href="https://opencollective.com/vuejs/tiers/gold-sponsors/4/website" target="_blank" rel="noopener noreferrer"><img src="https://opencollective.com/vuejs/tiers/gold-sponsors/4/avatar.svg" height="60px"></a>
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Vue (pronounced `/vjuː/`, like view) is a **progressive framework** for building user interfaces. It is designed from the ground up to be incrementally adoptable, and can easily scale between a library and a framework depending on different use cases. It consists of an approachable core library that focuses on the view layer only, and an ecosystem of supporting libraries that helps you tackle complexity in large Single-Page Applications.
|
||||
|
||||
#### Browser Compatibility
|
||||
|
||||
Vue.js supports all browsers that are [ES5-compliant](http://kangax.github.io/compat-table/es5/) (IE8 and below are not supported).
|
||||
|
||||
## Ecosystem
|
||||
|
||||
| Project | Status | Description |
|
||||
|---------|--------|-------------|
|
||||
| [vue-router] | [![vue-router-status]][vue-router-package] | Single-page application routing |
|
||||
| [vuex] | [![vuex-status]][vuex-package] | Large-scale state management |
|
||||
| [vue-cli] | [![vue-cli-status]][vue-cli-package] | Project scaffolding |
|
||||
| [vue-loader] | [![vue-loader-status]][vue-loader-package] | Single File Component (`*.vue` file) loader for webpack |
|
||||
| [vue-server-renderer] | [![vue-server-renderer-status]][vue-server-renderer-package] | Server-side rendering support |
|
||||
| [vue-class-component] | [![vue-class-component-status]][vue-class-component-package] | TypeScript decorator for a class-based API |
|
||||
| [vue-rx] | [![vue-rx-status]][vue-rx-package] | RxJS integration |
|
||||
| [vue-devtools] | [![vue-devtools-status]][vue-devtools-package] | Browser DevTools extension |
|
||||
|
||||
[vue-router]: https://github.com/vuejs/vue-router
|
||||
[vuex]: https://github.com/vuejs/vuex
|
||||
[vue-cli]: https://github.com/vuejs/vue-cli
|
||||
[vue-loader]: https://github.com/vuejs/vue-loader
|
||||
[vue-server-renderer]: https://github.com/vuejs/vue/tree/dev/packages/vue-server-renderer
|
||||
[vue-class-component]: https://github.com/vuejs/vue-class-component
|
||||
[vue-rx]: https://github.com/vuejs/vue-rx
|
||||
[vue-devtools]: https://github.com/vuejs/vue-devtools
|
||||
|
||||
[vue-router-status]: https://img.shields.io/npm/v/vue-router.svg
|
||||
[vuex-status]: https://img.shields.io/npm/v/vuex.svg
|
||||
[vue-cli-status]: https://img.shields.io/npm/v/@vue/cli.svg
|
||||
[vue-loader-status]: https://img.shields.io/npm/v/vue-loader.svg
|
||||
[vue-server-renderer-status]: https://img.shields.io/npm/v/vue-server-renderer.svg
|
||||
[vue-class-component-status]: https://img.shields.io/npm/v/vue-class-component.svg
|
||||
[vue-rx-status]: https://img.shields.io/npm/v/vue-rx.svg
|
||||
[vue-devtools-status]: https://img.shields.io/chrome-web-store/v/nhdogjmejiglipccpnnnanhbledajbpd.svg
|
||||
|
||||
[vue-router-package]: https://npmjs.com/package/vue-router
|
||||
[vuex-package]: https://npmjs.com/package/vuex
|
||||
[vue-cli-package]: https://npmjs.com/package/@vue/cli
|
||||
[vue-loader-package]: https://npmjs.com/package/vue-loader
|
||||
[vue-server-renderer-package]: https://npmjs.com/package/vue-server-renderer
|
||||
[vue-class-component-package]: https://npmjs.com/package/vue-class-component
|
||||
[vue-rx-package]: https://npmjs.com/package/vue-rx
|
||||
[vue-devtools-package]: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
|
||||
|
||||
## Documentation
|
||||
|
||||
To check out [live examples](https://vuejs.org/v2/examples/) and docs, visit [vuejs.org](https://vuejs.org).
|
||||
|
||||
## Questions
|
||||
|
||||
For questions and support please use [the official forum](http://forum.vuejs.org) or [community chat](https://chat.vuejs.org/). The issue list of this repo is **exclusively** for bug reports and feature requests.
|
||||
|
||||
## Issues
|
||||
|
||||
Please make sure to read the [Issue Reporting Checklist](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#issue-reporting-guidelines) before opening an issue. Issues not conforming to the guidelines may be closed immediately.
|
||||
|
||||
## Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [release notes](https://github.com/vuejs/vue/releases).
|
||||
|
||||
## Stay In Touch
|
||||
|
||||
- [Twitter](https://twitter.com/vuejs)
|
||||
- [Blog](https://medium.com/the-vue-point)
|
||||
- [Job Board](https://vuejobs.com/?ref=vuejs)
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md) before making a pull request. If you have a Vue-related project/component/tool, add it with a pull request to [this curated list](https://github.com/vuejs/awesome-vue)!
|
||||
|
||||
Thank you to all the people who already contributed to Vue!
|
||||
|
||||
<a href="https://github.com/vuejs/vue/graphs/contributors"><img src="https://opencollective.com/vuejs/contributors.svg?width=890" /></a>
|
||||
|
||||
|
||||
## License
|
||||
|
||||
[MIT](http://opensource.org/licenses/MIT)
|
||||
|
||||
Copyright (c) 2013-present, Yuxi (Evan) You
|
124
express-server/node_modules/vue/dist/README.md
generated
vendored
Normal file
124
express-server/node_modules/vue/dist/README.md
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
## Explanation of Build Files
|
||||
|
||||
| | UMD | CommonJS | ES Module |
|
||||
| --- | --- | --- | --- |
|
||||
| **Full** | vue.js | vue.common.js | vue.esm.js |
|
||||
| **Runtime-only** | vue.runtime.js | vue.runtime.common.js | vue.runtime.esm.js |
|
||||
| **Full (production)** | vue.min.js | | |
|
||||
| **Runtime-only (production)** | vue.runtime.min.js | | |
|
||||
|
||||
### Terms
|
||||
|
||||
- **Full**: builds that contains both the compiler and the runtime.
|
||||
|
||||
- **Compiler**: code that is responsible for compiling template strings into JavaScript render functions.
|
||||
|
||||
- **Runtime**: code that is responsible for creating Vue instances, rendering and patching virtual DOM, etc. Basically everything minus the compiler.
|
||||
|
||||
- **[UMD](https://github.com/umdjs/umd)**: UMD builds can be used directly in the browser via a `<script>` tag. The default file from Unpkg CDN at [https://unpkg.com/vue](https://unpkg.com/vue) is the Runtime + Compiler UMD build (`vue.js`).
|
||||
|
||||
- **[CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1)**: CommonJS builds are intended for use with older bundlers like [browserify](http://browserify.org/) or [webpack 1](https://webpack.github.io). The default file for these bundlers (`pkg.main`) is the Runtime only CommonJS build (`vue.runtime.common.js`).
|
||||
|
||||
- **[ES Module](http://exploringjs.com/es6/ch_modules.html)**: ES module builds are intended for use with modern bundlers like [webpack 2](https://webpack.js.org) or [rollup](http://rollupjs.org/). The default file for these bundlers (`pkg.module`) is the Runtime only ES Module build (`vue.runtime.esm.js`).
|
||||
|
||||
### Runtime + Compiler vs. Runtime-only
|
||||
|
||||
If you need to compile templates on the fly (e.g. passing a string to the `template` option, or mounting to an element using its in-DOM HTML as the template), you will need the compiler and thus the full build.
|
||||
|
||||
When using `vue-loader` or `vueify`, templates inside `*.vue` files are compiled into JavaScript at build time. You don't really need the compiler in the final bundle, and can therefore, use the runtime-only build.
|
||||
|
||||
Since the runtime-only builds are roughly 30% lighter-weight than their full-build counterparts, you should use it whenever you can. If you wish to use the full build instead, you need to configure an alias in your bundler.
|
||||
|
||||
#### Webpack
|
||||
|
||||
``` js
|
||||
module.exports = {
|
||||
// ...
|
||||
resolve: {
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Rollup
|
||||
|
||||
``` js
|
||||
const alias = require('rollup-plugin-alias')
|
||||
|
||||
rollup({
|
||||
// ...
|
||||
plugins: [
|
||||
alias({
|
||||
'vue': 'vue/dist/vue.esm.js'
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
#### Browserify
|
||||
|
||||
Add to your project's `package.json`:
|
||||
|
||||
``` js
|
||||
{
|
||||
// ...
|
||||
"browser": {
|
||||
"vue": "vue/dist/vue.common.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Development vs. Production Mode
|
||||
|
||||
Development/production modes are hard-coded for the UMD builds: the un-minified files are for development, and the minified files are for production.
|
||||
|
||||
CommonJS and ES Module builds are intended for bundlers, therefore we don't provide minified versions for them. You will be responsible for minifying the final bundle yourself.
|
||||
|
||||
CommonJS and ES Module builds also preserve raw checks for `process.env.NODE_ENV` to determine the mode they should run in. You should use appropriate bundler configurations to replace these environment variables in order to control which mode Vue will run in. Replacing `process.env.NODE_ENV` with string literals also allows minifiers like UglifyJS to completely drop the development-only code blocks, reducing final file size.
|
||||
|
||||
#### Webpack
|
||||
|
||||
Use Webpack's [DefinePlugin](https://webpack.js.org/plugins/define-plugin/):
|
||||
|
||||
``` js
|
||||
var webpack = require('webpack')
|
||||
|
||||
module.exports = {
|
||||
// ...
|
||||
plugins: [
|
||||
// ...
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('production')
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Rollup
|
||||
|
||||
Use [rollup-plugin-replace](https://github.com/rollup/rollup-plugin-replace):
|
||||
|
||||
``` js
|
||||
const replace = require('rollup-plugin-replace')
|
||||
|
||||
rollup({
|
||||
// ...
|
||||
plugins: [
|
||||
replace({
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
})
|
||||
]
|
||||
}).then(...)
|
||||
```
|
||||
|
||||
#### Browserify
|
||||
|
||||
Apply a global [envify](https://github.com/hughsk/envify) transform to your bundle.
|
||||
|
||||
``` bash
|
||||
NODE_ENV=production browserify -g envify -e main.js | uglifyjs -c -m > build.js
|
||||
```
|
11920
express-server/node_modules/vue/dist/vue.common.dev.js
generated
vendored
Normal file
11920
express-server/node_modules/vue/dist/vue.common.dev.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
express-server/node_modules/vue/dist/vue.common.js
generated
vendored
Normal file
5
express-server/node_modules/vue/dist/vue.common.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./vue.common.prod.js')
|
||||
} else {
|
||||
module.exports = require('./vue.common.dev.js')
|
||||
}
|
6
express-server/node_modules/vue/dist/vue.common.prod.js
generated
vendored
Normal file
6
express-server/node_modules/vue/dist/vue.common.prod.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
11977
express-server/node_modules/vue/dist/vue.esm.browser.js
generated
vendored
Normal file
11977
express-server/node_modules/vue/dist/vue.esm.browser.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
express-server/node_modules/vue/dist/vue.esm.browser.min.js
generated
vendored
Normal file
6
express-server/node_modules/vue/dist/vue.esm.browser.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
11954
express-server/node_modules/vue/dist/vue.esm.js
generated
vendored
Normal file
11954
express-server/node_modules/vue/dist/vue.esm.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11926
express-server/node_modules/vue/dist/vue.js
generated
vendored
Normal file
11926
express-server/node_modules/vue/dist/vue.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
express-server/node_modules/vue/dist/vue.min.js
generated
vendored
Normal file
6
express-server/node_modules/vue/dist/vue.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
8399
express-server/node_modules/vue/dist/vue.runtime.common.dev.js
generated
vendored
Normal file
8399
express-server/node_modules/vue/dist/vue.runtime.common.dev.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
express-server/node_modules/vue/dist/vue.runtime.common.js
generated
vendored
Normal file
5
express-server/node_modules/vue/dist/vue.runtime.common.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./vue.runtime.common.prod.js')
|
||||
} else {
|
||||
module.exports = require('./vue.runtime.common.dev.js')
|
||||
}
|
6
express-server/node_modules/vue/dist/vue.runtime.common.prod.js
generated
vendored
Normal file
6
express-server/node_modules/vue/dist/vue.runtime.common.prod.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
8427
express-server/node_modules/vue/dist/vue.runtime.esm.js
generated
vendored
Normal file
8427
express-server/node_modules/vue/dist/vue.runtime.esm.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8405
express-server/node_modules/vue/dist/vue.runtime.js
generated
vendored
Normal file
8405
express-server/node_modules/vue/dist/vue.runtime.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
express-server/node_modules/vue/dist/vue.runtime.min.js
generated
vendored
Normal file
6
express-server/node_modules/vue/dist/vue.runtime.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
178
express-server/node_modules/vue/package.json
generated
vendored
Normal file
178
express-server/node_modules/vue/package.json
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
{
|
||||
"_from": "vue",
|
||||
"_id": "vue@2.6.9",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-t1+tvH8hybPM86oNne3ZozCD02zj/VoZIiojOBPJLjwBn7hxYU5e1gBObFpq8ts1NEn1VhPf/hVXBDAJ3X5ljg==",
|
||||
"_location": "/vue",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "vue",
|
||||
"name": "vue",
|
||||
"escapedName": "vue",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/vue/-/vue-2.6.9.tgz",
|
||||
"_shasum": "415c1cc1a5ed00c8f0acdd0a948139d12b7ea6b3",
|
||||
"_spec": "vue",
|
||||
"_where": "D:\\5CHITM\\Diplomarbeit\\repos\\SmartShopper\\express-server",
|
||||
"author": {
|
||||
"name": "Evan You"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vuejs/vue/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Reactive, component-oriented view layer for modern web interfaces.",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-jsx": "^7.0.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/register": "^7.0.0",
|
||||
"@types/node": "^10.12.18",
|
||||
"@types/webpack": "^4.4.22",
|
||||
"acorn": "^5.2.1",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
"babel-loader": "^8.0.4",
|
||||
"babel-plugin-istanbul": "^5.1.0",
|
||||
"babel-plugin-transform-vue-jsx": "^4.0.1",
|
||||
"babel-preset-flow-vue": "^1.0.0",
|
||||
"buble": "^0.19.3",
|
||||
"chalk": "^2.3.0",
|
||||
"chromedriver": "^2.45.0",
|
||||
"codecov": "^3.0.0",
|
||||
"commitizen": "^2.9.6",
|
||||
"conventional-changelog": "^1.1.3",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"cz-conventional-changelog": "^2.0.0",
|
||||
"de-indent": "^1.0.2",
|
||||
"es6-promise": "^4.1.0",
|
||||
"escodegen": "^1.8.1",
|
||||
"eslint": "^5.7.0",
|
||||
"eslint-plugin-flowtype": "^2.34.0",
|
||||
"eslint-plugin-jasmine": "^2.8.4",
|
||||
"file-loader": "^3.0.1",
|
||||
"flow-bin": "^0.61.0",
|
||||
"hash-sum": "^1.0.2",
|
||||
"he": "^1.1.1",
|
||||
"http-server": "^0.11.1",
|
||||
"jasmine": "^2.99.0",
|
||||
"jasmine-core": "^2.99.0",
|
||||
"karma": "^3.1.1",
|
||||
"karma-chrome-launcher": "^2.1.1",
|
||||
"karma-coverage": "^1.1.1",
|
||||
"karma-firefox-launcher": "^1.0.1",
|
||||
"karma-jasmine": "^1.1.0",
|
||||
"karma-mocha-reporter": "^2.2.3",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"karma-safari-launcher": "^1.0.0",
|
||||
"karma-sauce-launcher": "^2.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^4.0.0-rc.2",
|
||||
"lint-staged": "^8.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"lodash.template": "^4.4.0",
|
||||
"lodash.uniq": "^4.5.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"nightwatch": "^0.9.16",
|
||||
"nightwatch-helpers": "^1.2.0",
|
||||
"phantomjs-prebuilt": "^2.1.14",
|
||||
"puppeteer": "^1.11.0",
|
||||
"resolve": "^1.3.3",
|
||||
"rollup": "^1.0.0",
|
||||
"rollup-plugin-alias": "^1.3.1",
|
||||
"rollup-plugin-buble": "^0.19.6",
|
||||
"rollup-plugin-commonjs": "^9.2.0",
|
||||
"rollup-plugin-flow-no-whitespace": "^1.0.0",
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"selenium-server": "^2.53.1",
|
||||
"serialize-javascript": "^1.3.0",
|
||||
"shelljs": "^0.8.1",
|
||||
"terser": "^3.10.2",
|
||||
"typescript": "^3.1.3",
|
||||
"webpack": "~4.28.4",
|
||||
"weex-js-runtime": "^0.23.6",
|
||||
"weex-styler": "^0.3.0",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist/*.js",
|
||||
"types/*.d.ts"
|
||||
],
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"commit-msg": "node scripts/verify-commit-msg.js"
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue#readme",
|
||||
"jsdelivr": "dist/vue.js",
|
||||
"keywords": [
|
||||
"vue"
|
||||
],
|
||||
"license": "MIT",
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"main": "dist/vue.runtime.common.js",
|
||||
"module": "dist/vue.runtime.esm.js",
|
||||
"name": "vue",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue.git"
|
||||
},
|
||||
"scripts": {
|
||||
"bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js",
|
||||
"build": "node scripts/build.js",
|
||||
"build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
|
||||
"build:weex": "npm run build -- weex",
|
||||
"commit": "git-cz",
|
||||
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
|
||||
"dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",
|
||||
"dev:compiler": "rollup -w -c scripts/config.js --environment TARGET:web-compiler ",
|
||||
"dev:esm": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-esm",
|
||||
"dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer",
|
||||
"dev:test": "karma start test/unit/karma.dev.config.js",
|
||||
"dev:weex": "rollup -w -c scripts/config.js --environment TARGET:weex-framework",
|
||||
"dev:weex:compiler": "rollup -w -c scripts/config.js --environment TARGET:weex-compiler ",
|
||||
"dev:weex:factory": "rollup -w -c scripts/config.js --environment TARGET:weex-factory",
|
||||
"flow": "flow check",
|
||||
"lint": "eslint src scripts test",
|
||||
"release": "bash scripts/release.sh",
|
||||
"release:note": "node scripts/gen-release-note.js",
|
||||
"release:weex": "bash scripts/release-weex.sh",
|
||||
"sauce": "karma start test/unit/karma.sauce.config.js",
|
||||
"test": "npm run lint && flow check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex",
|
||||
"test:cover": "karma start test/unit/karma.cover.config.js",
|
||||
"test:e2e": "npm run build -- web-full-prod,web-server-basic-renderer && node test/e2e/runner.js",
|
||||
"test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2",
|
||||
"test:ssr": "npm run build:ssr && jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.js",
|
||||
"test:types": "tsc -p ./types/test/tsconfig.json",
|
||||
"test:unit": "karma start test/unit/karma.unit.config.js",
|
||||
"test:weex": "npm run build:weex && jasmine JASMINE_CONFIG_PATH=test/weex/jasmine.js"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"typings": "types/index.d.ts",
|
||||
"unpkg": "dist/vue.js",
|
||||
"version": "2.6.9"
|
||||
}
|
BIN
express-server/node_modules/vue/src/.DS_Store
generated
vendored
Normal file
BIN
express-server/node_modules/vue/src/.DS_Store
generated
vendored
Normal file
Binary file not shown.
BIN
express-server/node_modules/vue/src/compiler/.DS_Store
generated
vendored
Normal file
BIN
express-server/node_modules/vue/src/compiler/.DS_Store
generated
vendored
Normal file
Binary file not shown.
50
express-server/node_modules/vue/src/compiler/codeframe.js
generated
vendored
Normal file
50
express-server/node_modules/vue/src/compiler/codeframe.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* @flow */
|
||||
|
||||
const range = 2
|
||||
|
||||
export function generateCodeFrame (
|
||||
source: string,
|
||||
start: number = 0,
|
||||
end: number = source.length
|
||||
): string {
|
||||
const lines = source.split(/\r?\n/)
|
||||
let count = 0
|
||||
const res = []
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
count += lines[i].length + 1
|
||||
if (count >= start) {
|
||||
for (let j = i - range; j <= i + range || end > count; j++) {
|
||||
if (j < 0 || j >= lines.length) continue
|
||||
res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}| ${lines[j]}`)
|
||||
const lineLength = lines[j].length
|
||||
if (j === i) {
|
||||
// push underline
|
||||
const pad = start - (count - lineLength) + 1
|
||||
const length = end > count ? lineLength - pad : end - start
|
||||
res.push(` | ` + repeat(` `, pad) + repeat(`^`, length))
|
||||
} else if (j > i) {
|
||||
if (end > count) {
|
||||
const length = Math.min(end - count, lineLength)
|
||||
res.push(` | ` + repeat(`^`, length))
|
||||
}
|
||||
count += lineLength + 1
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return res.join('\n')
|
||||
}
|
||||
|
||||
function repeat (str, n) {
|
||||
let result = ''
|
||||
if (n > 0) {
|
||||
while (true) { // eslint-disable-line
|
||||
if (n & 1) result += str
|
||||
n >>>= 1
|
||||
if (n <= 0) break
|
||||
str += str
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
190
express-server/node_modules/vue/src/compiler/codegen/events.js
generated
vendored
Normal file
190
express-server/node_modules/vue/src/compiler/codegen/events.js
generated
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
/* @flow */
|
||||
|
||||
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
|
||||
const fnInvokeRE = /\([^)]*?\);*$/
|
||||
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
|
||||
|
||||
// KeyboardEvent.keyCode aliases
|
||||
const keyCodes: { [key: string]: number | Array<number> } = {
|
||||
esc: 27,
|
||||
tab: 9,
|
||||
enter: 13,
|
||||
space: 32,
|
||||
up: 38,
|
||||
left: 37,
|
||||
right: 39,
|
||||
down: 40,
|
||||
'delete': [8, 46]
|
||||
}
|
||||
|
||||
// KeyboardEvent.key aliases
|
||||
const keyNames: { [key: string]: string | Array<string> } = {
|
||||
// #7880: IE11 and Edge use `Esc` for Escape key name.
|
||||
esc: ['Esc', 'Escape'],
|
||||
tab: 'Tab',
|
||||
enter: 'Enter',
|
||||
// #9112: IE11 uses `Spacebar` for Space key name.
|
||||
space: [' ', 'Spacebar'],
|
||||
// #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
|
||||
up: ['Up', 'ArrowUp'],
|
||||
left: ['Left', 'ArrowLeft'],
|
||||
right: ['Right', 'ArrowRight'],
|
||||
down: ['Down', 'ArrowDown'],
|
||||
// #9112: IE11 uses `Del` for Delete key name.
|
||||
'delete': ['Backspace', 'Delete', 'Del']
|
||||
}
|
||||
|
||||
// #4868: modifiers that prevent the execution of the listener
|
||||
// need to explicitly return null so that we can determine whether to remove
|
||||
// the listener for .once
|
||||
const genGuard = condition => `if(${condition})return null;`
|
||||
|
||||
const modifierCode: { [key: string]: string } = {
|
||||
stop: '$event.stopPropagation();',
|
||||
prevent: '$event.preventDefault();',
|
||||
self: genGuard(`$event.target !== $event.currentTarget`),
|
||||
ctrl: genGuard(`!$event.ctrlKey`),
|
||||
shift: genGuard(`!$event.shiftKey`),
|
||||
alt: genGuard(`!$event.altKey`),
|
||||
meta: genGuard(`!$event.metaKey`),
|
||||
left: genGuard(`'button' in $event && $event.button !== 0`),
|
||||
middle: genGuard(`'button' in $event && $event.button !== 1`),
|
||||
right: genGuard(`'button' in $event && $event.button !== 2`)
|
||||
}
|
||||
|
||||
export function genHandlers (
|
||||
events: ASTElementHandlers,
|
||||
isNative: boolean
|
||||
): string {
|
||||
const prefix = isNative ? 'nativeOn:' : 'on:'
|
||||
let staticHandlers = ``
|
||||
let dynamicHandlers = ``
|
||||
for (const name in events) {
|
||||
const handlerCode = genHandler(events[name])
|
||||
if (events[name] && events[name].dynamic) {
|
||||
dynamicHandlers += `${name},${handlerCode},`
|
||||
} else {
|
||||
staticHandlers += `"${name}":${handlerCode},`
|
||||
}
|
||||
}
|
||||
staticHandlers = `{${staticHandlers.slice(0, -1)}}`
|
||||
if (dynamicHandlers) {
|
||||
return prefix + `_d(${staticHandlers},[${dynamicHandlers.slice(0, -1)}])`
|
||||
} else {
|
||||
return prefix + staticHandlers
|
||||
}
|
||||
}
|
||||
|
||||
// Generate handler code with binding params on Weex
|
||||
/* istanbul ignore next */
|
||||
function genWeexHandler (params: Array<any>, handlerCode: string) {
|
||||
let innerHandlerCode = handlerCode
|
||||
const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
|
||||
const bindings = exps.map(exp => ({ '@binding': exp }))
|
||||
const args = exps.map((exp, i) => {
|
||||
const key = `$_${i + 1}`
|
||||
innerHandlerCode = innerHandlerCode.replace(exp, key)
|
||||
return key
|
||||
})
|
||||
args.push('$event')
|
||||
return '{\n' +
|
||||
`handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
|
||||
`params:${JSON.stringify(bindings)}\n` +
|
||||
'}'
|
||||
}
|
||||
|
||||
function genHandler (handler: ASTElementHandler | Array<ASTElementHandler>): string {
|
||||
if (!handler) {
|
||||
return 'function(){}'
|
||||
}
|
||||
|
||||
if (Array.isArray(handler)) {
|
||||
return `[${handler.map(handler => genHandler(handler)).join(',')}]`
|
||||
}
|
||||
|
||||
const isMethodPath = simplePathRE.test(handler.value)
|
||||
const isFunctionExpression = fnExpRE.test(handler.value)
|
||||
const isFunctionInvocation = simplePathRE.test(handler.value.replace(fnInvokeRE, ''))
|
||||
|
||||
if (!handler.modifiers) {
|
||||
if (isMethodPath || isFunctionExpression) {
|
||||
return handler.value
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && handler.params) {
|
||||
return genWeexHandler(handler.params, handler.value)
|
||||
}
|
||||
return `function($event){${
|
||||
isFunctionInvocation ? `return ${handler.value}` : handler.value
|
||||
}}` // inline statement
|
||||
} else {
|
||||
let code = ''
|
||||
let genModifierCode = ''
|
||||
const keys = []
|
||||
for (const key in handler.modifiers) {
|
||||
if (modifierCode[key]) {
|
||||
genModifierCode += modifierCode[key]
|
||||
// left/right
|
||||
if (keyCodes[key]) {
|
||||
keys.push(key)
|
||||
}
|
||||
} else if (key === 'exact') {
|
||||
const modifiers: ASTModifiers = (handler.modifiers: any)
|
||||
genModifierCode += genGuard(
|
||||
['ctrl', 'shift', 'alt', 'meta']
|
||||
.filter(keyModifier => !modifiers[keyModifier])
|
||||
.map(keyModifier => `$event.${keyModifier}Key`)
|
||||
.join('||')
|
||||
)
|
||||
} else {
|
||||
keys.push(key)
|
||||
}
|
||||
}
|
||||
if (keys.length) {
|
||||
code += genKeyFilter(keys)
|
||||
}
|
||||
// Make sure modifiers like prevent and stop get executed after key filtering
|
||||
if (genModifierCode) {
|
||||
code += genModifierCode
|
||||
}
|
||||
const handlerCode = isMethodPath
|
||||
? `return ${handler.value}($event)`
|
||||
: isFunctionExpression
|
||||
? `return (${handler.value})($event)`
|
||||
: isFunctionInvocation
|
||||
? `return ${handler.value}`
|
||||
: handler.value
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && handler.params) {
|
||||
return genWeexHandler(handler.params, code + handlerCode)
|
||||
}
|
||||
return `function($event){${code}${handlerCode}}`
|
||||
}
|
||||
}
|
||||
|
||||
function genKeyFilter (keys: Array<string>): string {
|
||||
return (
|
||||
// make sure the key filters only apply to KeyboardEvents
|
||||
// #9441: can't use 'keyCode' in $event because Chrome autofill fires fake
|
||||
// key events that do not have keyCode property...
|
||||
`if(!$event.type.indexOf('key')&&` +
|
||||
`${keys.map(genFilterCode).join('&&')})return null;`
|
||||
)
|
||||
}
|
||||
|
||||
function genFilterCode (key: string): string {
|
||||
const keyVal = parseInt(key, 10)
|
||||
if (keyVal) {
|
||||
return `$event.keyCode!==${keyVal}`
|
||||
}
|
||||
const keyCode = keyCodes[key]
|
||||
const keyName = keyNames[key]
|
||||
return (
|
||||
`_k($event.keyCode,` +
|
||||
`${JSON.stringify(key)},` +
|
||||
`${JSON.stringify(keyCode)},` +
|
||||
`$event.key,` +
|
||||
`${JSON.stringify(keyName)}` +
|
||||
`)`
|
||||
)
|
||||
}
|
618
express-server/node_modules/vue/src/compiler/codegen/index.js
generated
vendored
Normal file
618
express-server/node_modules/vue/src/compiler/codegen/index.js
generated
vendored
Normal file
@ -0,0 +1,618 @@
|
||||
/* @flow */
|
||||
|
||||
import { genHandlers } from './events'
|
||||
import baseDirectives from '../directives/index'
|
||||
import { camelize, no, extend } from 'shared/util'
|
||||
import { baseWarn, pluckModuleFunction } from '../helpers'
|
||||
import { emptySlotScopeToken } from '../parser/index'
|
||||
|
||||
type TransformFunction = (el: ASTElement, code: string) => string;
|
||||
type DataGenFunction = (el: ASTElement) => string;
|
||||
type DirectiveFunction = (el: ASTElement, dir: ASTDirective, warn: Function) => boolean;
|
||||
|
||||
export class CodegenState {
|
||||
options: CompilerOptions;
|
||||
warn: Function;
|
||||
transforms: Array<TransformFunction>;
|
||||
dataGenFns: Array<DataGenFunction>;
|
||||
directives: { [key: string]: DirectiveFunction };
|
||||
maybeComponent: (el: ASTElement) => boolean;
|
||||
onceId: number;
|
||||
staticRenderFns: Array<string>;
|
||||
pre: boolean;
|
||||
|
||||
constructor (options: CompilerOptions) {
|
||||
this.options = options
|
||||
this.warn = options.warn || baseWarn
|
||||
this.transforms = pluckModuleFunction(options.modules, 'transformCode')
|
||||
this.dataGenFns = pluckModuleFunction(options.modules, 'genData')
|
||||
this.directives = extend(extend({}, baseDirectives), options.directives)
|
||||
const isReservedTag = options.isReservedTag || no
|
||||
this.maybeComponent = (el: ASTElement) => !!el.component || !isReservedTag(el.tag)
|
||||
this.onceId = 0
|
||||
this.staticRenderFns = []
|
||||
this.pre = false
|
||||
}
|
||||
}
|
||||
|
||||
export type CodegenResult = {
|
||||
render: string,
|
||||
staticRenderFns: Array<string>
|
||||
};
|
||||
|
||||
export function generate (
|
||||
ast: ASTElement | void,
|
||||
options: CompilerOptions
|
||||
): CodegenResult {
|
||||
const state = new CodegenState(options)
|
||||
const code = ast ? genElement(ast, state) : '_c("div")'
|
||||
return {
|
||||
render: `with(this){return ${code}}`,
|
||||
staticRenderFns: state.staticRenderFns
|
||||
}
|
||||
}
|
||||
|
||||
export function genElement (el: ASTElement, state: CodegenState): string {
|
||||
if (el.parent) {
|
||||
el.pre = el.pre || el.parent.pre
|
||||
}
|
||||
|
||||
if (el.staticRoot && !el.staticProcessed) {
|
||||
return genStatic(el, state)
|
||||
} else if (el.once && !el.onceProcessed) {
|
||||
return genOnce(el, state)
|
||||
} else if (el.for && !el.forProcessed) {
|
||||
return genFor(el, state)
|
||||
} else if (el.if && !el.ifProcessed) {
|
||||
return genIf(el, state)
|
||||
} else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
|
||||
return genChildren(el, state) || 'void 0'
|
||||
} else if (el.tag === 'slot') {
|
||||
return genSlot(el, state)
|
||||
} else {
|
||||
// component or element
|
||||
let code
|
||||
if (el.component) {
|
||||
code = genComponent(el.component, el, state)
|
||||
} else {
|
||||
let data
|
||||
if (!el.plain || (el.pre && state.maybeComponent(el))) {
|
||||
data = genData(el, state)
|
||||
}
|
||||
|
||||
const children = el.inlineTemplate ? null : genChildren(el, state, true)
|
||||
code = `_c('${el.tag}'${
|
||||
data ? `,${data}` : '' // data
|
||||
}${
|
||||
children ? `,${children}` : '' // children
|
||||
})`
|
||||
}
|
||||
// module transforms
|
||||
for (let i = 0; i < state.transforms.length; i++) {
|
||||
code = state.transforms[i](el, code)
|
||||
}
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
||||
// hoist static sub-trees out
|
||||
function genStatic (el: ASTElement, state: CodegenState): string {
|
||||
el.staticProcessed = true
|
||||
// Some elements (templates) need to behave differently inside of a v-pre
|
||||
// node. All pre nodes are static roots, so we can use this as a location to
|
||||
// wrap a state change and reset it upon exiting the pre node.
|
||||
const originalPreState = state.pre
|
||||
if (el.pre) {
|
||||
state.pre = el.pre
|
||||
}
|
||||
state.staticRenderFns.push(`with(this){return ${genElement(el, state)}}`)
|
||||
state.pre = originalPreState
|
||||
return `_m(${
|
||||
state.staticRenderFns.length - 1
|
||||
}${
|
||||
el.staticInFor ? ',true' : ''
|
||||
})`
|
||||
}
|
||||
|
||||
// v-once
|
||||
function genOnce (el: ASTElement, state: CodegenState): string {
|
||||
el.onceProcessed = true
|
||||
if (el.if && !el.ifProcessed) {
|
||||
return genIf(el, state)
|
||||
} else if (el.staticInFor) {
|
||||
let key = ''
|
||||
let parent = el.parent
|
||||
while (parent) {
|
||||
if (parent.for) {
|
||||
key = parent.key
|
||||
break
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
if (!key) {
|
||||
process.env.NODE_ENV !== 'production' && state.warn(
|
||||
`v-once can only be used inside v-for that is keyed. `,
|
||||
el.rawAttrsMap['v-once']
|
||||
)
|
||||
return genElement(el, state)
|
||||
}
|
||||
return `_o(${genElement(el, state)},${state.onceId++},${key})`
|
||||
} else {
|
||||
return genStatic(el, state)
|
||||
}
|
||||
}
|
||||
|
||||
export function genIf (
|
||||
el: any,
|
||||
state: CodegenState,
|
||||
altGen?: Function,
|
||||
altEmpty?: string
|
||||
): string {
|
||||
el.ifProcessed = true // avoid recursion
|
||||
return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
|
||||
}
|
||||
|
||||
function genIfConditions (
|
||||
conditions: ASTIfConditions,
|
||||
state: CodegenState,
|
||||
altGen?: Function,
|
||||
altEmpty?: string
|
||||
): string {
|
||||
if (!conditions.length) {
|
||||
return altEmpty || '_e()'
|
||||
}
|
||||
|
||||
const condition = conditions.shift()
|
||||
if (condition.exp) {
|
||||
return `(${condition.exp})?${
|
||||
genTernaryExp(condition.block)
|
||||
}:${
|
||||
genIfConditions(conditions, state, altGen, altEmpty)
|
||||
}`
|
||||
} else {
|
||||
return `${genTernaryExp(condition.block)}`
|
||||
}
|
||||
|
||||
// v-if with v-once should generate code like (a)?_m(0):_m(1)
|
||||
function genTernaryExp (el) {
|
||||
return altGen
|
||||
? altGen(el, state)
|
||||
: el.once
|
||||
? genOnce(el, state)
|
||||
: genElement(el, state)
|
||||
}
|
||||
}
|
||||
|
||||
export function genFor (
|
||||
el: any,
|
||||
state: CodegenState,
|
||||
altGen?: Function,
|
||||
altHelper?: string
|
||||
): string {
|
||||
const exp = el.for
|
||||
const alias = el.alias
|
||||
const iterator1 = el.iterator1 ? `,${el.iterator1}` : ''
|
||||
const iterator2 = el.iterator2 ? `,${el.iterator2}` : ''
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
state.maybeComponent(el) &&
|
||||
el.tag !== 'slot' &&
|
||||
el.tag !== 'template' &&
|
||||
!el.key
|
||||
) {
|
||||
state.warn(
|
||||
`<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` +
|
||||
`v-for should have explicit keys. ` +
|
||||
`See https://vuejs.org/guide/list.html#key for more info.`,
|
||||
el.rawAttrsMap['v-for'],
|
||||
true /* tip */
|
||||
)
|
||||
}
|
||||
|
||||
el.forProcessed = true // avoid recursion
|
||||
return `${altHelper || '_l'}((${exp}),` +
|
||||
`function(${alias}${iterator1}${iterator2}){` +
|
||||
`return ${(altGen || genElement)(el, state)}` +
|
||||
'})'
|
||||
}
|
||||
|
||||
export function genData (el: ASTElement, state: CodegenState): string {
|
||||
let data = '{'
|
||||
|
||||
// directives first.
|
||||
// directives may mutate the el's other properties before they are generated.
|
||||
const dirs = genDirectives(el, state)
|
||||
if (dirs) data += dirs + ','
|
||||
|
||||
// key
|
||||
if (el.key) {
|
||||
data += `key:${el.key},`
|
||||
}
|
||||
// ref
|
||||
if (el.ref) {
|
||||
data += `ref:${el.ref},`
|
||||
}
|
||||
if (el.refInFor) {
|
||||
data += `refInFor:true,`
|
||||
}
|
||||
// pre
|
||||
if (el.pre) {
|
||||
data += `pre:true,`
|
||||
}
|
||||
// record original tag name for components using "is" attribute
|
||||
if (el.component) {
|
||||
data += `tag:"${el.tag}",`
|
||||
}
|
||||
// module data generation functions
|
||||
for (let i = 0; i < state.dataGenFns.length; i++) {
|
||||
data += state.dataGenFns[i](el)
|
||||
}
|
||||
// attributes
|
||||
if (el.attrs) {
|
||||
data += `attrs:${genProps(el.attrs)},`
|
||||
}
|
||||
// DOM props
|
||||
if (el.props) {
|
||||
data += `domProps:${genProps(el.props)},`
|
||||
}
|
||||
// event handlers
|
||||
if (el.events) {
|
||||
data += `${genHandlers(el.events, false)},`
|
||||
}
|
||||
if (el.nativeEvents) {
|
||||
data += `${genHandlers(el.nativeEvents, true)},`
|
||||
}
|
||||
// slot target
|
||||
// only for non-scoped slots
|
||||
if (el.slotTarget && !el.slotScope) {
|
||||
data += `slot:${el.slotTarget},`
|
||||
}
|
||||
// scoped slots
|
||||
if (el.scopedSlots) {
|
||||
data += `${genScopedSlots(el, el.scopedSlots, state)},`
|
||||
}
|
||||
// component v-model
|
||||
if (el.model) {
|
||||
data += `model:{value:${
|
||||
el.model.value
|
||||
},callback:${
|
||||
el.model.callback
|
||||
},expression:${
|
||||
el.model.expression
|
||||
}},`
|
||||
}
|
||||
// inline-template
|
||||
if (el.inlineTemplate) {
|
||||
const inlineTemplate = genInlineTemplate(el, state)
|
||||
if (inlineTemplate) {
|
||||
data += `${inlineTemplate},`
|
||||
}
|
||||
}
|
||||
data = data.replace(/,$/, '') + '}'
|
||||
// v-bind dynamic argument wrap
|
||||
// v-bind with dynamic arguments must be applied using the same v-bind object
|
||||
// merge helper so that class/style/mustUseProp attrs are handled correctly.
|
||||
if (el.dynamicAttrs) {
|
||||
data = `_b(${data},"${el.tag}",${genProps(el.dynamicAttrs)})`
|
||||
}
|
||||
// v-bind data wrap
|
||||
if (el.wrapData) {
|
||||
data = el.wrapData(data)
|
||||
}
|
||||
// v-on data wrap
|
||||
if (el.wrapListeners) {
|
||||
data = el.wrapListeners(data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
function genDirectives (el: ASTElement, state: CodegenState): string | void {
|
||||
const dirs = el.directives
|
||||
if (!dirs) return
|
||||
let res = 'directives:['
|
||||
let hasRuntime = false
|
||||
let i, l, dir, needRuntime
|
||||
for (i = 0, l = dirs.length; i < l; i++) {
|
||||
dir = dirs[i]
|
||||
needRuntime = true
|
||||
const gen: DirectiveFunction = state.directives[dir.name]
|
||||
if (gen) {
|
||||
// compile-time directive that manipulates AST.
|
||||
// returns true if it also needs a runtime counterpart.
|
||||
needRuntime = !!gen(el, dir, state.warn)
|
||||
}
|
||||
if (needRuntime) {
|
||||
hasRuntime = true
|
||||
res += `{name:"${dir.name}",rawName:"${dir.rawName}"${
|
||||
dir.value ? `,value:(${dir.value}),expression:${JSON.stringify(dir.value)}` : ''
|
||||
}${
|
||||
dir.arg ? `,arg:${dir.isDynamicArg ? dir.arg : `"${dir.arg}"`}` : ''
|
||||
}${
|
||||
dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
|
||||
}},`
|
||||
}
|
||||
}
|
||||
if (hasRuntime) {
|
||||
return res.slice(0, -1) + ']'
|
||||
}
|
||||
}
|
||||
|
||||
function genInlineTemplate (el: ASTElement, state: CodegenState): ?string {
|
||||
const ast = el.children[0]
|
||||
if (process.env.NODE_ENV !== 'production' && (
|
||||
el.children.length !== 1 || ast.type !== 1
|
||||
)) {
|
||||
state.warn(
|
||||
'Inline-template components must have exactly one child element.',
|
||||
{ start: el.start }
|
||||
)
|
||||
}
|
||||
if (ast && ast.type === 1) {
|
||||
const inlineRenderFns = generate(ast, state.options)
|
||||
return `inlineTemplate:{render:function(){${
|
||||
inlineRenderFns.render
|
||||
}},staticRenderFns:[${
|
||||
inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
|
||||
}]}`
|
||||
}
|
||||
}
|
||||
|
||||
function genScopedSlots (
|
||||
el: ASTElement,
|
||||
slots: { [key: string]: ASTElement },
|
||||
state: CodegenState
|
||||
): string {
|
||||
// by default scoped slots are considered "stable", this allows child
|
||||
// components with only scoped slots to skip forced updates from parent.
|
||||
// but in some cases we have to bail-out of this optimization
|
||||
// for example if the slot contains dynamic names, has v-if or v-for on them...
|
||||
let needsForceUpdate = el.for || Object.keys(slots).some(key => {
|
||||
const slot = slots[key]
|
||||
return (
|
||||
slot.slotTargetDynamic ||
|
||||
slot.if ||
|
||||
slot.for ||
|
||||
containsSlotChild(slot) // is passing down slot from parent which may be dynamic
|
||||
)
|
||||
})
|
||||
|
||||
// #9534: if a component with scoped slots is inside a conditional branch,
|
||||
// it's possible for the same component to be reused but with different
|
||||
// compiled slot content. To avoid that, we generate a unique key based on
|
||||
// the generated code of all the slot contents.
|
||||
let needsKey = !!el.if
|
||||
|
||||
// OR when it is inside another scoped slot or v-for (the reactivity may be
|
||||
// disconnected due to the intermediate scope variable)
|
||||
// #9438, #9506
|
||||
// TODO: this can be further optimized by properly analyzing in-scope bindings
|
||||
// and skip force updating ones that do not actually use scope variables.
|
||||
if (!needsForceUpdate) {
|
||||
let parent = el.parent
|
||||
while (parent) {
|
||||
if (
|
||||
(parent.slotScope && parent.slotScope !== emptySlotScopeToken) ||
|
||||
parent.for
|
||||
) {
|
||||
needsForceUpdate = true
|
||||
break
|
||||
}
|
||||
if (parent.if) {
|
||||
needsKey = true
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
}
|
||||
|
||||
const generatedSlots = Object.keys(slots)
|
||||
.map(key => genScopedSlot(slots[key], state))
|
||||
.join(',')
|
||||
|
||||
return `scopedSlots:_u([${generatedSlots}]${
|
||||
needsForceUpdate ? `,null,true` : ``
|
||||
}${
|
||||
!needsForceUpdate && needsKey ? `,null,false,${hash(generatedSlots)}` : ``
|
||||
})`
|
||||
}
|
||||
|
||||
function hash(str) {
|
||||
let hash = 5381
|
||||
let i = str.length
|
||||
while(i) {
|
||||
hash = (hash * 33) ^ str.charCodeAt(--i)
|
||||
}
|
||||
return hash >>> 0
|
||||
}
|
||||
|
||||
function containsSlotChild (el: ASTNode): boolean {
|
||||
if (el.type === 1) {
|
||||
if (el.tag === 'slot') {
|
||||
return true
|
||||
}
|
||||
return el.children.some(containsSlotChild)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function genScopedSlot (
|
||||
el: ASTElement,
|
||||
state: CodegenState
|
||||
): string {
|
||||
const isLegacySyntax = el.attrsMap['slot-scope']
|
||||
if (el.if && !el.ifProcessed && !isLegacySyntax) {
|
||||
return genIf(el, state, genScopedSlot, `null`)
|
||||
}
|
||||
if (el.for && !el.forProcessed) {
|
||||
return genFor(el, state, genScopedSlot)
|
||||
}
|
||||
const slotScope = el.slotScope === emptySlotScopeToken
|
||||
? ``
|
||||
: String(el.slotScope)
|
||||
const fn = `function(${slotScope}){` +
|
||||
`return ${el.tag === 'template'
|
||||
? el.if && isLegacySyntax
|
||||
? `(${el.if})?${genChildren(el, state) || 'undefined'}:undefined`
|
||||
: genChildren(el, state) || 'undefined'
|
||||
: genElement(el, state)
|
||||
}}`
|
||||
// reverse proxy v-slot without scope on this.$slots
|
||||
const reverseProxy = slotScope ? `` : `,proxy:true`
|
||||
return `{key:${el.slotTarget || `"default"`},fn:${fn}${reverseProxy}}`
|
||||
}
|
||||
|
||||
export function genChildren (
|
||||
el: ASTElement,
|
||||
state: CodegenState,
|
||||
checkSkip?: boolean,
|
||||
altGenElement?: Function,
|
||||
altGenNode?: Function
|
||||
): string | void {
|
||||
const children = el.children
|
||||
if (children.length) {
|
||||
const el: any = children[0]
|
||||
// optimize single v-for
|
||||
if (children.length === 1 &&
|
||||
el.for &&
|
||||
el.tag !== 'template' &&
|
||||
el.tag !== 'slot'
|
||||
) {
|
||||
const normalizationType = checkSkip
|
||||
? state.maybeComponent(el) ? `,1` : `,0`
|
||||
: ``
|
||||
return `${(altGenElement || genElement)(el, state)}${normalizationType}`
|
||||
}
|
||||
const normalizationType = checkSkip
|
||||
? getNormalizationType(children, state.maybeComponent)
|
||||
: 0
|
||||
const gen = altGenNode || genNode
|
||||
return `[${children.map(c => gen(c, state)).join(',')}]${
|
||||
normalizationType ? `,${normalizationType}` : ''
|
||||
}`
|
||||
}
|
||||
}
|
||||
|
||||
// determine the normalization needed for the children array.
|
||||
// 0: no normalization needed
|
||||
// 1: simple normalization needed (possible 1-level deep nested array)
|
||||
// 2: full normalization needed
|
||||
function getNormalizationType (
|
||||
children: Array<ASTNode>,
|
||||
maybeComponent: (el: ASTElement) => boolean
|
||||
): number {
|
||||
let res = 0
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const el: ASTNode = children[i]
|
||||
if (el.type !== 1) {
|
||||
continue
|
||||
}
|
||||
if (needsNormalization(el) ||
|
||||
(el.ifConditions && el.ifConditions.some(c => needsNormalization(c.block)))) {
|
||||
res = 2
|
||||
break
|
||||
}
|
||||
if (maybeComponent(el) ||
|
||||
(el.ifConditions && el.ifConditions.some(c => maybeComponent(c.block)))) {
|
||||
res = 1
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function needsNormalization (el: ASTElement): boolean {
|
||||
return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'
|
||||
}
|
||||
|
||||
function genNode (node: ASTNode, state: CodegenState): string {
|
||||
if (node.type === 1) {
|
||||
return genElement(node, state)
|
||||
} else if (node.type === 3 && node.isComment) {
|
||||
return genComment(node)
|
||||
} else {
|
||||
return genText(node)
|
||||
}
|
||||
}
|
||||
|
||||
export function genText (text: ASTText | ASTExpression): string {
|
||||
return `_v(${text.type === 2
|
||||
? text.expression // no need for () because already wrapped in _s()
|
||||
: transformSpecialNewlines(JSON.stringify(text.text))
|
||||
})`
|
||||
}
|
||||
|
||||
export function genComment (comment: ASTText): string {
|
||||
return `_e(${JSON.stringify(comment.text)})`
|
||||
}
|
||||
|
||||
function genSlot (el: ASTElement, state: CodegenState): string {
|
||||
const slotName = el.slotName || '"default"'
|
||||
const children = genChildren(el, state)
|
||||
let res = `_t(${slotName}${children ? `,${children}` : ''}`
|
||||
const attrs = el.attrs || el.dynamicAttrs
|
||||
? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
|
||||
// slot props are camelized
|
||||
name: camelize(attr.name),
|
||||
value: attr.value,
|
||||
dynamic: attr.dynamic
|
||||
})))
|
||||
: null
|
||||
const bind = el.attrsMap['v-bind']
|
||||
if ((attrs || bind) && !children) {
|
||||
res += `,null`
|
||||
}
|
||||
if (attrs) {
|
||||
res += `,${attrs}`
|
||||
}
|
||||
if (bind) {
|
||||
res += `${attrs ? '' : ',null'},${bind}`
|
||||
}
|
||||
return res + ')'
|
||||
}
|
||||
|
||||
// componentName is el.component, take it as argument to shun flow's pessimistic refinement
|
||||
function genComponent (
|
||||
componentName: string,
|
||||
el: ASTElement,
|
||||
state: CodegenState
|
||||
): string {
|
||||
const children = el.inlineTemplate ? null : genChildren(el, state, true)
|
||||
return `_c(${componentName},${genData(el, state)}${
|
||||
children ? `,${children}` : ''
|
||||
})`
|
||||
}
|
||||
|
||||
function genProps (props: Array<ASTAttr>): string {
|
||||
let staticProps = ``
|
||||
let dynamicProps = ``
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
const prop = props[i]
|
||||
const value = __WEEX__
|
||||
? generateValue(prop.value)
|
||||
: transformSpecialNewlines(prop.value)
|
||||
if (prop.dynamic) {
|
||||
dynamicProps += `${prop.name},${value},`
|
||||
} else {
|
||||
staticProps += `"${prop.name}":${value},`
|
||||
}
|
||||
}
|
||||
staticProps = `{${staticProps.slice(0, -1)}}`
|
||||
if (dynamicProps) {
|
||||
return `_d(${staticProps},[${dynamicProps.slice(0, -1)}])`
|
||||
} else {
|
||||
return staticProps
|
||||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
function generateValue (value) {
|
||||
if (typeof value === 'string') {
|
||||
return transformSpecialNewlines(value)
|
||||
}
|
||||
return JSON.stringify(value)
|
||||
}
|
||||
|
||||
// #3895, #4268
|
||||
function transformSpecialNewlines (text: string): string {
|
||||
return text
|
||||
.replace(/\u2028/g, '\\u2028')
|
||||
.replace(/\u2029/g, '\\u2029')
|
||||
}
|
75
express-server/node_modules/vue/src/compiler/create-compiler.js
generated
vendored
Normal file
75
express-server/node_modules/vue/src/compiler/create-compiler.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/* @flow */
|
||||
|
||||
import { extend } from 'shared/util'
|
||||
import { detectErrors } from './error-detector'
|
||||
import { createCompileToFunctionFn } from './to-function'
|
||||
|
||||
export function createCompilerCreator (baseCompile: Function): Function {
|
||||
return function createCompiler (baseOptions: CompilerOptions) {
|
||||
function compile (
|
||||
template: string,
|
||||
options?: CompilerOptions
|
||||
): CompiledResult {
|
||||
const finalOptions = Object.create(baseOptions)
|
||||
const errors = []
|
||||
const tips = []
|
||||
|
||||
let warn = (msg, range, tip) => {
|
||||
(tip ? tips : errors).push(msg)
|
||||
}
|
||||
|
||||
if (options) {
|
||||
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
|
||||
// $flow-disable-line
|
||||
const leadingSpaceLength = template.match(/^\s*/)[0].length
|
||||
|
||||
warn = (msg, range, tip) => {
|
||||
const data: WarningMessage = { msg }
|
||||
if (range) {
|
||||
if (range.start != null) {
|
||||
data.start = range.start + leadingSpaceLength
|
||||
}
|
||||
if (range.end != null) {
|
||||
data.end = range.end + leadingSpaceLength
|
||||
}
|
||||
}
|
||||
(tip ? tips : errors).push(data)
|
||||
}
|
||||
}
|
||||
// merge custom modules
|
||||
if (options.modules) {
|
||||
finalOptions.modules =
|
||||
(baseOptions.modules || []).concat(options.modules)
|
||||
}
|
||||
// merge custom directives
|
||||
if (options.directives) {
|
||||
finalOptions.directives = extend(
|
||||
Object.create(baseOptions.directives || null),
|
||||
options.directives
|
||||
)
|
||||
}
|
||||
// copy other options
|
||||
for (const key in options) {
|
||||
if (key !== 'modules' && key !== 'directives') {
|
||||
finalOptions[key] = options[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalOptions.warn = warn
|
||||
|
||||
const compiled = baseCompile(template.trim(), finalOptions)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
detectErrors(compiled.ast, warn)
|
||||
}
|
||||
compiled.errors = errors
|
||||
compiled.tips = tips
|
||||
return compiled
|
||||
}
|
||||
|
||||
return {
|
||||
compile,
|
||||
compileToFunctions: createCompileToFunctionFn(compile)
|
||||
}
|
||||
}
|
||||
}
|
11
express-server/node_modules/vue/src/compiler/directives/bind.js
generated
vendored
Normal file
11
express-server/node_modules/vue/src/compiler/directives/bind.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
export default function bind (el: ASTElement, dir: ASTDirective) {
|
||||
el.wrapData = (code: string) => {
|
||||
return `_b(${code},'${el.tag}',${dir.value},${
|
||||
dir.modifiers && dir.modifiers.prop ? 'true' : 'false'
|
||||
}${
|
||||
dir.modifiers && dir.modifiers.sync ? ',true' : ''
|
||||
})`
|
||||
}
|
||||
}
|
11
express-server/node_modules/vue/src/compiler/directives/index.js
generated
vendored
Normal file
11
express-server/node_modules/vue/src/compiler/directives/index.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
import on from './on'
|
||||
import bind from './bind'
|
||||
import { noop } from 'shared/util'
|
||||
|
||||
export default {
|
||||
on,
|
||||
bind,
|
||||
cloak: noop
|
||||
}
|
148
express-server/node_modules/vue/src/compiler/directives/model.js
generated
vendored
Normal file
148
express-server/node_modules/vue/src/compiler/directives/model.js
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
/* @flow */
|
||||
|
||||
/**
|
||||
* Cross-platform code generation for component v-model
|
||||
*/
|
||||
export function genComponentModel (
|
||||
el: ASTElement,
|
||||
value: string,
|
||||
modifiers: ?ASTModifiers
|
||||
): ?boolean {
|
||||
const { number, trim } = modifiers || {}
|
||||
|
||||
const baseValueExpression = '$$v'
|
||||
let valueExpression = baseValueExpression
|
||||
if (trim) {
|
||||
valueExpression =
|
||||
`(typeof ${baseValueExpression} === 'string'` +
|
||||
`? ${baseValueExpression}.trim()` +
|
||||
`: ${baseValueExpression})`
|
||||
}
|
||||
if (number) {
|
||||
valueExpression = `_n(${valueExpression})`
|
||||
}
|
||||
const assignment = genAssignmentCode(value, valueExpression)
|
||||
|
||||
el.model = {
|
||||
value: `(${value})`,
|
||||
expression: JSON.stringify(value),
|
||||
callback: `function (${baseValueExpression}) {${assignment}}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-platform codegen helper for generating v-model value assignment code.
|
||||
*/
|
||||
export function genAssignmentCode (
|
||||
value: string,
|
||||
assignment: string
|
||||
): string {
|
||||
const res = parseModel(value)
|
||||
if (res.key === null) {
|
||||
return `${value}=${assignment}`
|
||||
} else {
|
||||
return `$set(${res.exp}, ${res.key}, ${assignment})`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a v-model expression into a base path and a final key segment.
|
||||
* Handles both dot-path and possible square brackets.
|
||||
*
|
||||
* Possible cases:
|
||||
*
|
||||
* - test
|
||||
* - test[key]
|
||||
* - test[test1[key]]
|
||||
* - test["a"][key]
|
||||
* - xxx.test[a[a].test1[key]]
|
||||
* - test.xxx.a["asa"][test1[key]]
|
||||
*
|
||||
*/
|
||||
|
||||
let len, str, chr, index, expressionPos, expressionEndPos
|
||||
|
||||
type ModelParseResult = {
|
||||
exp: string,
|
||||
key: string | null
|
||||
}
|
||||
|
||||
export function parseModel (val: string): ModelParseResult {
|
||||
// Fix https://github.com/vuejs/vue/pull/7730
|
||||
// allow v-model="obj.val " (trailing whitespace)
|
||||
val = val.trim()
|
||||
len = val.length
|
||||
|
||||
if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
|
||||
index = val.lastIndexOf('.')
|
||||
if (index > -1) {
|
||||
return {
|
||||
exp: val.slice(0, index),
|
||||
key: '"' + val.slice(index + 1) + '"'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
exp: val,
|
||||
key: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
str = val
|
||||
index = expressionPos = expressionEndPos = 0
|
||||
|
||||
while (!eof()) {
|
||||
chr = next()
|
||||
/* istanbul ignore if */
|
||||
if (isStringStart(chr)) {
|
||||
parseString(chr)
|
||||
} else if (chr === 0x5B) {
|
||||
parseBracket(chr)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
exp: val.slice(0, expressionPos),
|
||||
key: val.slice(expressionPos + 1, expressionEndPos)
|
||||
}
|
||||
}
|
||||
|
||||
function next (): number {
|
||||
return str.charCodeAt(++index)
|
||||
}
|
||||
|
||||
function eof (): boolean {
|
||||
return index >= len
|
||||
}
|
||||
|
||||
function isStringStart (chr: number): boolean {
|
||||
return chr === 0x22 || chr === 0x27
|
||||
}
|
||||
|
||||
function parseBracket (chr: number): void {
|
||||
let inBracket = 1
|
||||
expressionPos = index
|
||||
while (!eof()) {
|
||||
chr = next()
|
||||
if (isStringStart(chr)) {
|
||||
parseString(chr)
|
||||
continue
|
||||
}
|
||||
if (chr === 0x5B) inBracket++
|
||||
if (chr === 0x5D) inBracket--
|
||||
if (inBracket === 0) {
|
||||
expressionEndPos = index
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseString (chr: number): void {
|
||||
const stringQuote = chr
|
||||
while (!eof()) {
|
||||
chr = next()
|
||||
if (chr === stringQuote) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
10
express-server/node_modules/vue/src/compiler/directives/on.js
generated
vendored
Normal file
10
express-server/node_modules/vue/src/compiler/directives/on.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import { warn } from 'core/util/index'
|
||||
|
||||
export default function on (el: ASTElement, dir: ASTDirective) {
|
||||
if (process.env.NODE_ENV !== 'production' && dir.modifiers) {
|
||||
warn(`v-on without argument does not support modifiers.`)
|
||||
}
|
||||
el.wrapListeners = (code: string) => `_g(${code},${dir.value})`
|
||||
}
|
113
express-server/node_modules/vue/src/compiler/error-detector.js
generated
vendored
Normal file
113
express-server/node_modules/vue/src/compiler/error-detector.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/* @flow */
|
||||
|
||||
import { dirRE, onRE } from './parser/index'
|
||||
|
||||
type Range = { start?: number, end?: number };
|
||||
|
||||
// these keywords should not appear inside expressions, but operators like
|
||||
// typeof, instanceof and in are allowed
|
||||
const prohibitedKeywordRE = new RegExp('\\b' + (
|
||||
'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
|
||||
'super,throw,while,yield,delete,export,import,return,switch,default,' +
|
||||
'extends,finally,continue,debugger,function,arguments'
|
||||
).split(',').join('\\b|\\b') + '\\b')
|
||||
|
||||
// these unary operators should not be used as property/method names
|
||||
const unaryOperatorsRE = new RegExp('\\b' + (
|
||||
'delete,typeof,void'
|
||||
).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)')
|
||||
|
||||
// strip strings in expressions
|
||||
const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g
|
||||
|
||||
// detect problematic expressions in a template
|
||||
export function detectErrors (ast: ?ASTNode, warn: Function) {
|
||||
if (ast) {
|
||||
checkNode(ast, warn)
|
||||
}
|
||||
}
|
||||
|
||||
function checkNode (node: ASTNode, warn: Function) {
|
||||
if (node.type === 1) {
|
||||
for (const name in node.attrsMap) {
|
||||
if (dirRE.test(name)) {
|
||||
const value = node.attrsMap[name]
|
||||
if (value) {
|
||||
const range = node.rawAttrsMap[name]
|
||||
if (name === 'v-for') {
|
||||
checkFor(node, `v-for="${value}"`, warn, range)
|
||||
} else if (onRE.test(name)) {
|
||||
checkEvent(value, `${name}="${value}"`, warn, range)
|
||||
} else {
|
||||
checkExpression(value, `${name}="${value}"`, warn, range)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.children) {
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
checkNode(node.children[i], warn)
|
||||
}
|
||||
}
|
||||
} else if (node.type === 2) {
|
||||
checkExpression(node.expression, node.text, warn, node)
|
||||
}
|
||||
}
|
||||
|
||||
function checkEvent (exp: string, text: string, warn: Function, range?: Range) {
|
||||
const stipped = exp.replace(stripStringRE, '')
|
||||
const keywordMatch: any = stipped.match(unaryOperatorsRE)
|
||||
if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {
|
||||
warn(
|
||||
`avoid using JavaScript unary operator as property name: ` +
|
||||
`"${keywordMatch[0]}" in expression ${text.trim()}`,
|
||||
range
|
||||
)
|
||||
}
|
||||
checkExpression(exp, text, warn, range)
|
||||
}
|
||||
|
||||
function checkFor (node: ASTElement, text: string, warn: Function, range?: Range) {
|
||||
checkExpression(node.for || '', text, warn, range)
|
||||
checkIdentifier(node.alias, 'v-for alias', text, warn, range)
|
||||
checkIdentifier(node.iterator1, 'v-for iterator', text, warn, range)
|
||||
checkIdentifier(node.iterator2, 'v-for iterator', text, warn, range)
|
||||
}
|
||||
|
||||
function checkIdentifier (
|
||||
ident: ?string,
|
||||
type: string,
|
||||
text: string,
|
||||
warn: Function,
|
||||
range?: Range
|
||||
) {
|
||||
if (typeof ident === 'string') {
|
||||
try {
|
||||
new Function(`var ${ident}=_`)
|
||||
} catch (e) {
|
||||
warn(`invalid ${type} "${ident}" in expression: ${text.trim()}`, range)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkExpression (exp: string, text: string, warn: Function, range?: Range) {
|
||||
try {
|
||||
new Function(`return ${exp}`)
|
||||
} catch (e) {
|
||||
const keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE)
|
||||
if (keywordMatch) {
|
||||
warn(
|
||||
`avoid using JavaScript keyword as property name: ` +
|
||||
`"${keywordMatch[0]}"\n Raw expression: ${text.trim()}`,
|
||||
range
|
||||
)
|
||||
} else {
|
||||
warn(
|
||||
`invalid expression: ${e.message} in\n\n` +
|
||||
` ${exp}\n\n` +
|
||||
` Raw expression: ${text.trim()}\n`,
|
||||
range
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
231
express-server/node_modules/vue/src/compiler/helpers.js
generated
vendored
Normal file
231
express-server/node_modules/vue/src/compiler/helpers.js
generated
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/* @flow */
|
||||
|
||||
import { emptyObject } from 'shared/util'
|
||||
import { parseFilters } from './parser/filter-parser'
|
||||
|
||||
type Range = { start?: number, end?: number };
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
export function baseWarn (msg: string, range?: Range) {
|
||||
console.error(`[Vue compiler]: ${msg}`)
|
||||
}
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
export function pluckModuleFunction<F: Function> (
|
||||
modules: ?Array<Object>,
|
||||
key: string
|
||||
): Array<F> {
|
||||
return modules
|
||||
? modules.map(m => m[key]).filter(_ => _)
|
||||
: []
|
||||
}
|
||||
|
||||
export function addProp (el: ASTElement, name: string, value: string, range?: Range, dynamic?: boolean) {
|
||||
(el.props || (el.props = [])).push(rangeSetItem({ name, value, dynamic }, range))
|
||||
el.plain = false
|
||||
}
|
||||
|
||||
export function addAttr (el: ASTElement, name: string, value: any, range?: Range, dynamic?: boolean) {
|
||||
const attrs = dynamic
|
||||
? (el.dynamicAttrs || (el.dynamicAttrs = []))
|
||||
: (el.attrs || (el.attrs = []))
|
||||
attrs.push(rangeSetItem({ name, value, dynamic }, range))
|
||||
el.plain = false
|
||||
}
|
||||
|
||||
// add a raw attr (use this in preTransforms)
|
||||
export function addRawAttr (el: ASTElement, name: string, value: any, range?: Range) {
|
||||
el.attrsMap[name] = value
|
||||
el.attrsList.push(rangeSetItem({ name, value }, range))
|
||||
}
|
||||
|
||||
export function addDirective (
|
||||
el: ASTElement,
|
||||
name: string,
|
||||
rawName: string,
|
||||
value: string,
|
||||
arg: ?string,
|
||||
isDynamicArg: boolean,
|
||||
modifiers: ?ASTModifiers,
|
||||
range?: Range
|
||||
) {
|
||||
(el.directives || (el.directives = [])).push(rangeSetItem({
|
||||
name,
|
||||
rawName,
|
||||
value,
|
||||
arg,
|
||||
isDynamicArg,
|
||||
modifiers
|
||||
}, range))
|
||||
el.plain = false
|
||||
}
|
||||
|
||||
function prependModifierMarker (symbol: string, name: string, dynamic?: boolean): string {
|
||||
return dynamic
|
||||
? `_p(${name},"${symbol}")`
|
||||
: symbol + name // mark the event as captured
|
||||
}
|
||||
|
||||
export function addHandler (
|
||||
el: ASTElement,
|
||||
name: string,
|
||||
value: string,
|
||||
modifiers: ?ASTModifiers,
|
||||
important?: boolean,
|
||||
warn?: ?Function,
|
||||
range?: Range,
|
||||
dynamic?: boolean
|
||||
) {
|
||||
modifiers = modifiers || emptyObject
|
||||
// warn prevent and passive modifier
|
||||
/* istanbul ignore if */
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' && warn &&
|
||||
modifiers.prevent && modifiers.passive
|
||||
) {
|
||||
warn(
|
||||
'passive and prevent can\'t be used together. ' +
|
||||
'Passive handler can\'t prevent default event.',
|
||||
range
|
||||
)
|
||||
}
|
||||
|
||||
// normalize click.right and click.middle since they don't actually fire
|
||||
// this is technically browser-specific, but at least for now browsers are
|
||||
// the only target envs that have right/middle clicks.
|
||||
if (modifiers.right) {
|
||||
if (dynamic) {
|
||||
name = `(${name})==='click'?'contextmenu':(${name})`
|
||||
} else if (name === 'click') {
|
||||
name = 'contextmenu'
|
||||
delete modifiers.right
|
||||
}
|
||||
} else if (modifiers.middle) {
|
||||
if (dynamic) {
|
||||
name = `(${name})==='click'?'mouseup':(${name})`
|
||||
} else if (name === 'click') {
|
||||
name = 'mouseup'
|
||||
}
|
||||
}
|
||||
|
||||
// check capture modifier
|
||||
if (modifiers.capture) {
|
||||
delete modifiers.capture
|
||||
name = prependModifierMarker('!', name, dynamic)
|
||||
}
|
||||
if (modifiers.once) {
|
||||
delete modifiers.once
|
||||
name = prependModifierMarker('~', name, dynamic)
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (modifiers.passive) {
|
||||
delete modifiers.passive
|
||||
name = prependModifierMarker('&', name, dynamic)
|
||||
}
|
||||
|
||||
let events
|
||||
if (modifiers.native) {
|
||||
delete modifiers.native
|
||||
events = el.nativeEvents || (el.nativeEvents = {})
|
||||
} else {
|
||||
events = el.events || (el.events = {})
|
||||
}
|
||||
|
||||
const newHandler: any = rangeSetItem({ value: value.trim(), dynamic }, range)
|
||||
if (modifiers !== emptyObject) {
|
||||
newHandler.modifiers = modifiers
|
||||
}
|
||||
|
||||
const handlers = events[name]
|
||||
/* istanbul ignore if */
|
||||
if (Array.isArray(handlers)) {
|
||||
important ? handlers.unshift(newHandler) : handlers.push(newHandler)
|
||||
} else if (handlers) {
|
||||
events[name] = important ? [newHandler, handlers] : [handlers, newHandler]
|
||||
} else {
|
||||
events[name] = newHandler
|
||||
}
|
||||
|
||||
el.plain = false
|
||||
}
|
||||
|
||||
export function getRawBindingAttr (
|
||||
el: ASTElement,
|
||||
name: string
|
||||
) {
|
||||
return el.rawAttrsMap[':' + name] ||
|
||||
el.rawAttrsMap['v-bind:' + name] ||
|
||||
el.rawAttrsMap[name]
|
||||
}
|
||||
|
||||
export function getBindingAttr (
|
||||
el: ASTElement,
|
||||
name: string,
|
||||
getStatic?: boolean
|
||||
): ?string {
|
||||
const dynamicValue =
|
||||
getAndRemoveAttr(el, ':' + name) ||
|
||||
getAndRemoveAttr(el, 'v-bind:' + name)
|
||||
if (dynamicValue != null) {
|
||||
return parseFilters(dynamicValue)
|
||||
} else if (getStatic !== false) {
|
||||
const staticValue = getAndRemoveAttr(el, name)
|
||||
if (staticValue != null) {
|
||||
return JSON.stringify(staticValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note: this only removes the attr from the Array (attrsList) so that it
|
||||
// doesn't get processed by processAttrs.
|
||||
// By default it does NOT remove it from the map (attrsMap) because the map is
|
||||
// needed during codegen.
|
||||
export function getAndRemoveAttr (
|
||||
el: ASTElement,
|
||||
name: string,
|
||||
removeFromMap?: boolean
|
||||
): ?string {
|
||||
let val
|
||||
if ((val = el.attrsMap[name]) != null) {
|
||||
const list = el.attrsList
|
||||
for (let i = 0, l = list.length; i < l; i++) {
|
||||
if (list[i].name === name) {
|
||||
list.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeFromMap) {
|
||||
delete el.attrsMap[name]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
export function getAndRemoveAttrByRegex (
|
||||
el: ASTElement,
|
||||
name: RegExp
|
||||
) {
|
||||
const list = el.attrsList
|
||||
for (let i = 0, l = list.length; i < l; i++) {
|
||||
const attr = list[i]
|
||||
if (name.test(attr.name)) {
|
||||
list.splice(i, 1)
|
||||
return attr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rangeSetItem (
|
||||
item: any,
|
||||
range?: { start?: number, end?: number }
|
||||
) {
|
||||
if (range) {
|
||||
if (range.start != null) {
|
||||
item.start = range.start
|
||||
}
|
||||
if (range.end != null) {
|
||||
item.end = range.end
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
25
express-server/node_modules/vue/src/compiler/index.js
generated
vendored
Normal file
25
express-server/node_modules/vue/src/compiler/index.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/* @flow */
|
||||
|
||||
import { parse } from './parser/index'
|
||||
import { optimize } from './optimizer'
|
||||
import { generate } from './codegen/index'
|
||||
import { createCompilerCreator } from './create-compiler'
|
||||
|
||||
// `createCompilerCreator` allows creating compilers that use alternative
|
||||
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
|
||||
// Here we just export a default compiler using the default parts.
|
||||
export const createCompiler = createCompilerCreator(function baseCompile (
|
||||
template: string,
|
||||
options: CompilerOptions
|
||||
): CompiledResult {
|
||||
const ast = parse(template.trim(), options)
|
||||
if (options.optimize !== false) {
|
||||
optimize(ast, options)
|
||||
}
|
||||
const code = generate(ast, options)
|
||||
return {
|
||||
ast,
|
||||
render: code.render,
|
||||
staticRenderFns: code.staticRenderFns
|
||||
}
|
||||
})
|
128
express-server/node_modules/vue/src/compiler/optimizer.js
generated
vendored
Normal file
128
express-server/node_modules/vue/src/compiler/optimizer.js
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/* @flow */
|
||||
|
||||
import { makeMap, isBuiltInTag, cached, no } from 'shared/util'
|
||||
|
||||
let isStaticKey
|
||||
let isPlatformReservedTag
|
||||
|
||||
const genStaticKeysCached = cached(genStaticKeys)
|
||||
|
||||
/**
|
||||
* Goal of the optimizer: walk the generated template AST tree
|
||||
* and detect sub-trees that are purely static, i.e. parts of
|
||||
* the DOM that never needs to change.
|
||||
*
|
||||
* Once we detect these sub-trees, we can:
|
||||
*
|
||||
* 1. Hoist them into constants, so that we no longer need to
|
||||
* create fresh nodes for them on each re-render;
|
||||
* 2. Completely skip them in the patching process.
|
||||
*/
|
||||
export function optimize (root: ?ASTElement, options: CompilerOptions) {
|
||||
if (!root) return
|
||||
isStaticKey = genStaticKeysCached(options.staticKeys || '')
|
||||
isPlatformReservedTag = options.isReservedTag || no
|
||||
// first pass: mark all non-static nodes.
|
||||
markStatic(root)
|
||||
// second pass: mark static roots.
|
||||
markStaticRoots(root, false)
|
||||
}
|
||||
|
||||
function genStaticKeys (keys: string): Function {
|
||||
return makeMap(
|
||||
'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
|
||||
(keys ? ',' + keys : '')
|
||||
)
|
||||
}
|
||||
|
||||
function markStatic (node: ASTNode) {
|
||||
node.static = isStatic(node)
|
||||
if (node.type === 1) {
|
||||
// do not make component slot content static. this avoids
|
||||
// 1. components not able to mutate slot nodes
|
||||
// 2. static slot content fails for hot-reloading
|
||||
if (
|
||||
!isPlatformReservedTag(node.tag) &&
|
||||
node.tag !== 'slot' &&
|
||||
node.attrsMap['inline-template'] == null
|
||||
) {
|
||||
return
|
||||
}
|
||||
for (let i = 0, l = node.children.length; i < l; i++) {
|
||||
const child = node.children[i]
|
||||
markStatic(child)
|
||||
if (!child.static) {
|
||||
node.static = false
|
||||
}
|
||||
}
|
||||
if (node.ifConditions) {
|
||||
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
|
||||
const block = node.ifConditions[i].block
|
||||
markStatic(block)
|
||||
if (!block.static) {
|
||||
node.static = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function markStaticRoots (node: ASTNode, isInFor: boolean) {
|
||||
if (node.type === 1) {
|
||||
if (node.static || node.once) {
|
||||
node.staticInFor = isInFor
|
||||
}
|
||||
// For a node to qualify as a static root, it should have children that
|
||||
// are not just static text. Otherwise the cost of hoisting out will
|
||||
// outweigh the benefits and it's better off to just always render it fresh.
|
||||
if (node.static && node.children.length && !(
|
||||
node.children.length === 1 &&
|
||||
node.children[0].type === 3
|
||||
)) {
|
||||
node.staticRoot = true
|
||||
return
|
||||
} else {
|
||||
node.staticRoot = false
|
||||
}
|
||||
if (node.children) {
|
||||
for (let i = 0, l = node.children.length; i < l; i++) {
|
||||
markStaticRoots(node.children[i], isInFor || !!node.for)
|
||||
}
|
||||
}
|
||||
if (node.ifConditions) {
|
||||
for (let i = 1, l = node.ifConditions.length; i < l; i++) {
|
||||
markStaticRoots(node.ifConditions[i].block, isInFor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isStatic (node: ASTNode): boolean {
|
||||
if (node.type === 2) { // expression
|
||||
return false
|
||||
}
|
||||
if (node.type === 3) { // text
|
||||
return true
|
||||
}
|
||||
return !!(node.pre || (
|
||||
!node.hasBindings && // no dynamic bindings
|
||||
!node.if && !node.for && // not v-if or v-for or v-else
|
||||
!isBuiltInTag(node.tag) && // not a built-in
|
||||
isPlatformReservedTag(node.tag) && // not a component
|
||||
!isDirectChildOfTemplateFor(node) &&
|
||||
Object.keys(node).every(isStaticKey)
|
||||
))
|
||||
}
|
||||
|
||||
function isDirectChildOfTemplateFor (node: ASTElement): boolean {
|
||||
while (node.parent) {
|
||||
node = node.parent
|
||||
if (node.tag !== 'template') {
|
||||
return false
|
||||
}
|
||||
if (node.for) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
11
express-server/node_modules/vue/src/compiler/parser/entity-decoder.js
generated
vendored
Normal file
11
express-server/node_modules/vue/src/compiler/parser/entity-decoder.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
let decoder
|
||||
|
||||
export default {
|
||||
decode (html: string): string {
|
||||
decoder = decoder || document.createElement('div')
|
||||
decoder.innerHTML = html
|
||||
return decoder.textContent
|
||||
}
|
||||
}
|
97
express-server/node_modules/vue/src/compiler/parser/filter-parser.js
generated
vendored
Normal file
97
express-server/node_modules/vue/src/compiler/parser/filter-parser.js
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/* @flow */
|
||||
|
||||
const validDivisionCharRE = /[\w).+\-_$\]]/
|
||||
|
||||
export function parseFilters (exp: string): string {
|
||||
let inSingle = false
|
||||
let inDouble = false
|
||||
let inTemplateString = false
|
||||
let inRegex = false
|
||||
let curly = 0
|
||||
let square = 0
|
||||
let paren = 0
|
||||
let lastFilterIndex = 0
|
||||
let c, prev, i, expression, filters
|
||||
|
||||
for (i = 0; i < exp.length; i++) {
|
||||
prev = c
|
||||
c = exp.charCodeAt(i)
|
||||
if (inSingle) {
|
||||
if (c === 0x27 && prev !== 0x5C) inSingle = false
|
||||
} else if (inDouble) {
|
||||
if (c === 0x22 && prev !== 0x5C) inDouble = false
|
||||
} else if (inTemplateString) {
|
||||
if (c === 0x60 && prev !== 0x5C) inTemplateString = false
|
||||
} else if (inRegex) {
|
||||
if (c === 0x2f && prev !== 0x5C) inRegex = false
|
||||
} else if (
|
||||
c === 0x7C && // pipe
|
||||
exp.charCodeAt(i + 1) !== 0x7C &&
|
||||
exp.charCodeAt(i - 1) !== 0x7C &&
|
||||
!curly && !square && !paren
|
||||
) {
|
||||
if (expression === undefined) {
|
||||
// first filter, end of expression
|
||||
lastFilterIndex = i + 1
|
||||
expression = exp.slice(0, i).trim()
|
||||
} else {
|
||||
pushFilter()
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case 0x22: inDouble = true; break // "
|
||||
case 0x27: inSingle = true; break // '
|
||||
case 0x60: inTemplateString = true; break // `
|
||||
case 0x28: paren++; break // (
|
||||
case 0x29: paren--; break // )
|
||||
case 0x5B: square++; break // [
|
||||
case 0x5D: square--; break // ]
|
||||
case 0x7B: curly++; break // {
|
||||
case 0x7D: curly--; break // }
|
||||
}
|
||||
if (c === 0x2f) { // /
|
||||
let j = i - 1
|
||||
let p
|
||||
// find first non-whitespace prev char
|
||||
for (; j >= 0; j--) {
|
||||
p = exp.charAt(j)
|
||||
if (p !== ' ') break
|
||||
}
|
||||
if (!p || !validDivisionCharRE.test(p)) {
|
||||
inRegex = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expression === undefined) {
|
||||
expression = exp.slice(0, i).trim()
|
||||
} else if (lastFilterIndex !== 0) {
|
||||
pushFilter()
|
||||
}
|
||||
|
||||
function pushFilter () {
|
||||
(filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim())
|
||||
lastFilterIndex = i + 1
|
||||
}
|
||||
|
||||
if (filters) {
|
||||
for (i = 0; i < filters.length; i++) {
|
||||
expression = wrapFilter(expression, filters[i])
|
||||
}
|
||||
}
|
||||
|
||||
return expression
|
||||
}
|
||||
|
||||
function wrapFilter (exp: string, filter: string): string {
|
||||
const i = filter.indexOf('(')
|
||||
if (i < 0) {
|
||||
// _f: resolveFilter
|
||||
return `_f("${filter}")(${exp})`
|
||||
} else {
|
||||
const name = filter.slice(0, i)
|
||||
const args = filter.slice(i + 1)
|
||||
return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}`
|
||||
}
|
||||
}
|
306
express-server/node_modules/vue/src/compiler/parser/html-parser.js
generated
vendored
Normal file
306
express-server/node_modules/vue/src/compiler/parser/html-parser.js
generated
vendored
Normal file
@ -0,0 +1,306 @@
|
||||
/**
|
||||
* Not type-checking this file because it's mostly vendor code.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* HTML Parser By John Resig (ejohn.org)
|
||||
* Modified by Juriy "kangax" Zaytsev
|
||||
* Original code by Erik Arvidsson, Mozilla Public License
|
||||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||
*/
|
||||
|
||||
import { makeMap, no } from 'shared/util'
|
||||
import { isNonPhrasingTag } from 'web/compiler/util'
|
||||
import { unicodeRegExp } from 'core/util/lang'
|
||||
|
||||
// Regular Expressions for parsing tags and attributes
|
||||
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
|
||||
const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
|
||||
const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`
|
||||
const qnameCapture = `((?:${ncname}\\:)?${ncname})`
|
||||
const startTagOpen = new RegExp(`^<${qnameCapture}`)
|
||||
const startTagClose = /^\s*(\/?)>/
|
||||
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)
|
||||
const doctype = /^<!DOCTYPE [^>]+>/i
|
||||
// #7298: escape - to avoid being pased as HTML comment when inlined in page
|
||||
const comment = /^<!\--/
|
||||
const conditionalComment = /^<!\[/
|
||||
|
||||
// Special Elements (can contain anything)
|
||||
export const isPlainTextElement = makeMap('script,style,textarea', true)
|
||||
const reCache = {}
|
||||
|
||||
const decodingMap = {
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
'&': '&',
|
||||
' ': '\n',
|
||||
'	': '\t',
|
||||
''': "'"
|
||||
}
|
||||
const encodedAttr = /&(?:lt|gt|quot|amp|#39);/g
|
||||
const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#39|#10|#9);/g
|
||||
|
||||
// #5992
|
||||
const isIgnoreNewlineTag = makeMap('pre,textarea', true)
|
||||
const shouldIgnoreFirstNewline = (tag, html) => tag && isIgnoreNewlineTag(tag) && html[0] === '\n'
|
||||
|
||||
function decodeAttr (value, shouldDecodeNewlines) {
|
||||
const re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr
|
||||
return value.replace(re, match => decodingMap[match])
|
||||
}
|
||||
|
||||
export function parseHTML (html, options) {
|
||||
const stack = []
|
||||
const expectHTML = options.expectHTML
|
||||
const isUnaryTag = options.isUnaryTag || no
|
||||
const canBeLeftOpenTag = options.canBeLeftOpenTag || no
|
||||
let index = 0
|
||||
let last, lastTag
|
||||
while (html) {
|
||||
last = html
|
||||
// Make sure we're not in a plaintext content element like script/style
|
||||
if (!lastTag || !isPlainTextElement(lastTag)) {
|
||||
let textEnd = html.indexOf('<')
|
||||
if (textEnd === 0) {
|
||||
// Comment:
|
||||
if (comment.test(html)) {
|
||||
const commentEnd = html.indexOf('-->')
|
||||
|
||||
if (commentEnd >= 0) {
|
||||
if (options.shouldKeepComment) {
|
||||
options.comment(html.substring(4, commentEnd), index, index + commentEnd + 3)
|
||||
}
|
||||
advance(commentEnd + 3)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
|
||||
if (conditionalComment.test(html)) {
|
||||
const conditionalEnd = html.indexOf(']>')
|
||||
|
||||
if (conditionalEnd >= 0) {
|
||||
advance(conditionalEnd + 2)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Doctype:
|
||||
const doctypeMatch = html.match(doctype)
|
||||
if (doctypeMatch) {
|
||||
advance(doctypeMatch[0].length)
|
||||
continue
|
||||
}
|
||||
|
||||
// End tag:
|
||||
const endTagMatch = html.match(endTag)
|
||||
if (endTagMatch) {
|
||||
const curIndex = index
|
||||
advance(endTagMatch[0].length)
|
||||
parseEndTag(endTagMatch[1], curIndex, index)
|
||||
continue
|
||||
}
|
||||
|
||||
// Start tag:
|
||||
const startTagMatch = parseStartTag()
|
||||
if (startTagMatch) {
|
||||
handleStartTag(startTagMatch)
|
||||
if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
|
||||
advance(1)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
let text, rest, next
|
||||
if (textEnd >= 0) {
|
||||
rest = html.slice(textEnd)
|
||||
while (
|
||||
!endTag.test(rest) &&
|
||||
!startTagOpen.test(rest) &&
|
||||
!comment.test(rest) &&
|
||||
!conditionalComment.test(rest)
|
||||
) {
|
||||
// < in plain text, be forgiving and treat it as text
|
||||
next = rest.indexOf('<', 1)
|
||||
if (next < 0) break
|
||||
textEnd += next
|
||||
rest = html.slice(textEnd)
|
||||
}
|
||||
text = html.substring(0, textEnd)
|
||||
}
|
||||
|
||||
if (textEnd < 0) {
|
||||
text = html
|
||||
}
|
||||
|
||||
if (text) {
|
||||
advance(text.length)
|
||||
}
|
||||
|
||||
if (options.chars && text) {
|
||||
options.chars(text, index - text.length, index)
|
||||
}
|
||||
} else {
|
||||
let endTagLength = 0
|
||||
const stackedTag = lastTag.toLowerCase()
|
||||
const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'))
|
||||
const rest = html.replace(reStackedTag, function (all, text, endTag) {
|
||||
endTagLength = endTag.length
|
||||
if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
|
||||
text = text
|
||||
.replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298
|
||||
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
|
||||
}
|
||||
if (shouldIgnoreFirstNewline(stackedTag, text)) {
|
||||
text = text.slice(1)
|
||||
}
|
||||
if (options.chars) {
|
||||
options.chars(text)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
index += html.length - rest.length
|
||||
html = rest
|
||||
parseEndTag(stackedTag, index - endTagLength, index)
|
||||
}
|
||||
|
||||
if (html === last) {
|
||||
options.chars && options.chars(html)
|
||||
if (process.env.NODE_ENV !== 'production' && !stack.length && options.warn) {
|
||||
options.warn(`Mal-formatted tag at end of template: "${html}"`, { start: index + html.length })
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up any remaining tags
|
||||
parseEndTag()
|
||||
|
||||
function advance (n) {
|
||||
index += n
|
||||
html = html.substring(n)
|
||||
}
|
||||
|
||||
function parseStartTag () {
|
||||
const start = html.match(startTagOpen)
|
||||
if (start) {
|
||||
const match = {
|
||||
tagName: start[1],
|
||||
attrs: [],
|
||||
start: index
|
||||
}
|
||||
advance(start[0].length)
|
||||
let end, attr
|
||||
while (!(end = html.match(startTagClose)) && (attr = html.match(dynamicArgAttribute) || html.match(attribute))) {
|
||||
attr.start = index
|
||||
advance(attr[0].length)
|
||||
attr.end = index
|
||||
match.attrs.push(attr)
|
||||
}
|
||||
if (end) {
|
||||
match.unarySlash = end[1]
|
||||
advance(end[0].length)
|
||||
match.end = index
|
||||
return match
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleStartTag (match) {
|
||||
const tagName = match.tagName
|
||||
const unarySlash = match.unarySlash
|
||||
|
||||
if (expectHTML) {
|
||||
if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
|
||||
parseEndTag(lastTag)
|
||||
}
|
||||
if (canBeLeftOpenTag(tagName) && lastTag === tagName) {
|
||||
parseEndTag(tagName)
|
||||
}
|
||||
}
|
||||
|
||||
const unary = isUnaryTag(tagName) || !!unarySlash
|
||||
|
||||
const l = match.attrs.length
|
||||
const attrs = new Array(l)
|
||||
for (let i = 0; i < l; i++) {
|
||||
const args = match.attrs[i]
|
||||
const value = args[3] || args[4] || args[5] || ''
|
||||
const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
|
||||
? options.shouldDecodeNewlinesForHref
|
||||
: options.shouldDecodeNewlines
|
||||
attrs[i] = {
|
||||
name: args[1],
|
||||
value: decodeAttr(value, shouldDecodeNewlines)
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
|
||||
attrs[i].start = args.start + args[0].match(/^\s*/).length
|
||||
attrs[i].end = args.end
|
||||
}
|
||||
}
|
||||
|
||||
if (!unary) {
|
||||
stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end })
|
||||
lastTag = tagName
|
||||
}
|
||||
|
||||
if (options.start) {
|
||||
options.start(tagName, attrs, unary, match.start, match.end)
|
||||
}
|
||||
}
|
||||
|
||||
function parseEndTag (tagName, start, end) {
|
||||
let pos, lowerCasedTagName
|
||||
if (start == null) start = index
|
||||
if (end == null) end = index
|
||||
|
||||
// Find the closest opened tag of the same type
|
||||
if (tagName) {
|
||||
lowerCasedTagName = tagName.toLowerCase()
|
||||
for (pos = stack.length - 1; pos >= 0; pos--) {
|
||||
if (stack[pos].lowerCasedTag === lowerCasedTagName) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If no tag name is provided, clean shop
|
||||
pos = 0
|
||||
}
|
||||
|
||||
if (pos >= 0) {
|
||||
// Close all the open elements, up the stack
|
||||
for (let i = stack.length - 1; i >= pos; i--) {
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
(i > pos || !tagName) &&
|
||||
options.warn
|
||||
) {
|
||||
options.warn(
|
||||
`tag <${stack[i].tag}> has no matching end tag.`,
|
||||
{ start: stack[i].start, end: stack[i].end }
|
||||
)
|
||||
}
|
||||
if (options.end) {
|
||||
options.end(stack[i].tag, start, end)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the open elements from the stack
|
||||
stack.length = pos
|
||||
lastTag = pos && stack[pos - 1].tag
|
||||
} else if (lowerCasedTagName === 'br') {
|
||||
if (options.start) {
|
||||
options.start(tagName, [], true, start, end)
|
||||
}
|
||||
} else if (lowerCasedTagName === 'p') {
|
||||
if (options.start) {
|
||||
options.start(tagName, [], false, start, end)
|
||||
}
|
||||
if (options.end) {
|
||||
options.end(tagName, start, end)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
975
express-server/node_modules/vue/src/compiler/parser/index.js
generated
vendored
Normal file
975
express-server/node_modules/vue/src/compiler/parser/index.js
generated
vendored
Normal file
@ -0,0 +1,975 @@
|
||||
/* @flow */
|
||||
|
||||
import he from 'he'
|
||||
import { parseHTML } from './html-parser'
|
||||
import { parseText } from './text-parser'
|
||||
import { parseFilters } from './filter-parser'
|
||||
import { genAssignmentCode } from '../directives/model'
|
||||
import { extend, cached, no, camelize, hyphenate } from 'shared/util'
|
||||
import { isIE, isEdge, isServerRendering } from 'core/util/env'
|
||||
|
||||
import {
|
||||
addProp,
|
||||
addAttr,
|
||||
baseWarn,
|
||||
addHandler,
|
||||
addDirective,
|
||||
getBindingAttr,
|
||||
getAndRemoveAttr,
|
||||
getRawBindingAttr,
|
||||
pluckModuleFunction,
|
||||
getAndRemoveAttrByRegex
|
||||
} from '../helpers'
|
||||
|
||||
export const onRE = /^@|^v-on:/
|
||||
export const dirRE = process.env.VBIND_PROP_SHORTHAND
|
||||
? /^v-|^@|^:|^\./
|
||||
: /^v-|^@|^:/
|
||||
export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
|
||||
export const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
|
||||
const stripParensRE = /^\(|\)$/g
|
||||
const dynamicArgRE = /^\[.*\]$/
|
||||
|
||||
const argRE = /:(.*)$/
|
||||
export const bindRE = /^:|^\.|^v-bind:/
|
||||
const propBindRE = /^\./
|
||||
const modifierRE = /\.[^.\]]+(?=[^\]]*$)/g
|
||||
|
||||
const slotRE = /^v-slot(:|$)|^#/
|
||||
|
||||
const lineBreakRE = /[\r\n]/
|
||||
const whitespaceRE = /\s+/g
|
||||
|
||||
const invalidAttributeRE = /[\s"'<>\/=]/
|
||||
|
||||
const decodeHTMLCached = cached(he.decode)
|
||||
|
||||
export const emptySlotScopeToken = `_empty_`
|
||||
|
||||
// configurable state
|
||||
export let warn: any
|
||||
let delimiters
|
||||
let transforms
|
||||
let preTransforms
|
||||
let postTransforms
|
||||
let platformIsPreTag
|
||||
let platformMustUseProp
|
||||
let platformGetTagNamespace
|
||||
let maybeComponent
|
||||
|
||||
export function createASTElement (
|
||||
tag: string,
|
||||
attrs: Array<ASTAttr>,
|
||||
parent: ASTElement | void
|
||||
): ASTElement {
|
||||
return {
|
||||
type: 1,
|
||||
tag,
|
||||
attrsList: attrs,
|
||||
attrsMap: makeAttrsMap(attrs),
|
||||
rawAttrsMap: {},
|
||||
parent,
|
||||
children: []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert HTML string to AST.
|
||||
*/
|
||||
export function parse (
|
||||
template: string,
|
||||
options: CompilerOptions
|
||||
): ASTElement | void {
|
||||
warn = options.warn || baseWarn
|
||||
|
||||
platformIsPreTag = options.isPreTag || no
|
||||
platformMustUseProp = options.mustUseProp || no
|
||||
platformGetTagNamespace = options.getTagNamespace || no
|
||||
const isReservedTag = options.isReservedTag || no
|
||||
maybeComponent = (el: ASTElement) => !!el.component || !isReservedTag(el.tag)
|
||||
|
||||
transforms = pluckModuleFunction(options.modules, 'transformNode')
|
||||
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode')
|
||||
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode')
|
||||
|
||||
delimiters = options.delimiters
|
||||
|
||||
const stack = []
|
||||
const preserveWhitespace = options.preserveWhitespace !== false
|
||||
const whitespaceOption = options.whitespace
|
||||
let root
|
||||
let currentParent
|
||||
let inVPre = false
|
||||
let inPre = false
|
||||
let warned = false
|
||||
|
||||
function warnOnce (msg, range) {
|
||||
if (!warned) {
|
||||
warned = true
|
||||
warn(msg, range)
|
||||
}
|
||||
}
|
||||
|
||||
function closeElement (element) {
|
||||
trimEndingWhitespace(element)
|
||||
if (!inVPre && !element.processed) {
|
||||
element = processElement(element, options)
|
||||
}
|
||||
// tree management
|
||||
if (!stack.length && element !== root) {
|
||||
// allow root elements with v-if, v-else-if and v-else
|
||||
if (root.if && (element.elseif || element.else)) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkRootConstraints(element)
|
||||
}
|
||||
addIfCondition(root, {
|
||||
exp: element.elseif,
|
||||
block: element
|
||||
})
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warnOnce(
|
||||
`Component template should contain exactly one root element. ` +
|
||||
`If you are using v-if on multiple elements, ` +
|
||||
`use v-else-if to chain them instead.`,
|
||||
{ start: element.start }
|
||||
)
|
||||
}
|
||||
}
|
||||
if (currentParent && !element.forbidden) {
|
||||
if (element.elseif || element.else) {
|
||||
processIfConditions(element, currentParent)
|
||||
} else {
|
||||
if (element.slotScope) {
|
||||
// scoped slot
|
||||
// keep it in the children list so that v-else(-if) conditions can
|
||||
// find it as the prev node.
|
||||
const name = element.slotTarget || '"default"'
|
||||
;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element
|
||||
}
|
||||
currentParent.children.push(element)
|
||||
element.parent = currentParent
|
||||
}
|
||||
}
|
||||
|
||||
// final children cleanup
|
||||
// filter out scoped slots
|
||||
element.children = element.children.filter(c => !(c: any).slotScope)
|
||||
// remove trailing whitespace node again
|
||||
trimEndingWhitespace(element)
|
||||
|
||||
// check pre state
|
||||
if (element.pre) {
|
||||
inVPre = false
|
||||
}
|
||||
if (platformIsPreTag(element.tag)) {
|
||||
inPre = false
|
||||
}
|
||||
// apply post-transforms
|
||||
for (let i = 0; i < postTransforms.length; i++) {
|
||||
postTransforms[i](element, options)
|
||||
}
|
||||
}
|
||||
|
||||
function trimEndingWhitespace (el) {
|
||||
// remove trailing whitespace node
|
||||
if (!inPre) {
|
||||
let lastNode
|
||||
while (
|
||||
(lastNode = el.children[el.children.length - 1]) &&
|
||||
lastNode.type === 3 &&
|
||||
lastNode.text === ' '
|
||||
) {
|
||||
el.children.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkRootConstraints (el) {
|
||||
if (el.tag === 'slot' || el.tag === 'template') {
|
||||
warnOnce(
|
||||
`Cannot use <${el.tag}> as component root element because it may ` +
|
||||
'contain multiple nodes.',
|
||||
{ start: el.start }
|
||||
)
|
||||
}
|
||||
if (el.attrsMap.hasOwnProperty('v-for')) {
|
||||
warnOnce(
|
||||
'Cannot use v-for on stateful component root element because ' +
|
||||
'it renders multiple elements.',
|
||||
el.rawAttrsMap['v-for']
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
parseHTML(template, {
|
||||
warn,
|
||||
expectHTML: options.expectHTML,
|
||||
isUnaryTag: options.isUnaryTag,
|
||||
canBeLeftOpenTag: options.canBeLeftOpenTag,
|
||||
shouldDecodeNewlines: options.shouldDecodeNewlines,
|
||||
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
|
||||
shouldKeepComment: options.comments,
|
||||
outputSourceRange: options.outputSourceRange,
|
||||
start (tag, attrs, unary, start, end) {
|
||||
// check namespace.
|
||||
// inherit parent ns if there is one
|
||||
const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
|
||||
|
||||
// handle IE svg bug
|
||||
/* istanbul ignore if */
|
||||
if (isIE && ns === 'svg') {
|
||||
attrs = guardIESVGBug(attrs)
|
||||
}
|
||||
|
||||
let element: ASTElement = createASTElement(tag, attrs, currentParent)
|
||||
if (ns) {
|
||||
element.ns = ns
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (options.outputSourceRange) {
|
||||
element.start = start
|
||||
element.end = end
|
||||
element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) => {
|
||||
cumulated[attr.name] = attr
|
||||
return cumulated
|
||||
}, {})
|
||||
}
|
||||
attrs.forEach(attr => {
|
||||
if (invalidAttributeRE.test(attr.name)) {
|
||||
warn(
|
||||
`Invalid dynamic argument expression: attribute names cannot contain ` +
|
||||
`spaces, quotes, <, >, / or =.`,
|
||||
{
|
||||
start: attr.start + attr.name.indexOf(`[`),
|
||||
end: attr.start + attr.name.length
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (isForbiddenTag(element) && !isServerRendering()) {
|
||||
element.forbidden = true
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'Templates should only be responsible for mapping the state to the ' +
|
||||
'UI. Avoid placing tags with side-effects in your templates, such as ' +
|
||||
`<${tag}>` + ', as they will not be parsed.',
|
||||
{ start: element.start }
|
||||
)
|
||||
}
|
||||
|
||||
// apply pre-transforms
|
||||
for (let i = 0; i < preTransforms.length; i++) {
|
||||
element = preTransforms[i](element, options) || element
|
||||
}
|
||||
|
||||
if (!inVPre) {
|
||||
processPre(element)
|
||||
if (element.pre) {
|
||||
inVPre = true
|
||||
}
|
||||
}
|
||||
if (platformIsPreTag(element.tag)) {
|
||||
inPre = true
|
||||
}
|
||||
if (inVPre) {
|
||||
processRawAttrs(element)
|
||||
} else if (!element.processed) {
|
||||
// structural directives
|
||||
processFor(element)
|
||||
processIf(element)
|
||||
processOnce(element)
|
||||
}
|
||||
|
||||
if (!root) {
|
||||
root = element
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkRootConstraints(root)
|
||||
}
|
||||
}
|
||||
|
||||
if (!unary) {
|
||||
currentParent = element
|
||||
stack.push(element)
|
||||
} else {
|
||||
closeElement(element)
|
||||
}
|
||||
},
|
||||
|
||||
end (tag, start, end) {
|
||||
const element = stack[stack.length - 1]
|
||||
// pop stack
|
||||
stack.length -= 1
|
||||
currentParent = stack[stack.length - 1]
|
||||
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
|
||||
element.end = end
|
||||
}
|
||||
closeElement(element)
|
||||
},
|
||||
|
||||
chars (text: string, start: number, end: number) {
|
||||
if (!currentParent) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (text === template) {
|
||||
warnOnce(
|
||||
'Component template requires a root element, rather than just text.',
|
||||
{ start }
|
||||
)
|
||||
} else if ((text = text.trim())) {
|
||||
warnOnce(
|
||||
`text "${text}" outside root element will be ignored.`,
|
||||
{ start }
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
// IE textarea placeholder bug
|
||||
/* istanbul ignore if */
|
||||
if (isIE &&
|
||||
currentParent.tag === 'textarea' &&
|
||||
currentParent.attrsMap.placeholder === text
|
||||
) {
|
||||
return
|
||||
}
|
||||
const children = currentParent.children
|
||||
if (inPre || text.trim()) {
|
||||
text = isTextTag(currentParent) ? text : decodeHTMLCached(text)
|
||||
} else if (!children.length) {
|
||||
// remove the whitespace-only node right after an opening tag
|
||||
text = ''
|
||||
} else if (whitespaceOption) {
|
||||
if (whitespaceOption === 'condense') {
|
||||
// in condense mode, remove the whitespace node if it contains
|
||||
// line break, otherwise condense to a single space
|
||||
text = lineBreakRE.test(text) ? '' : ' '
|
||||
} else {
|
||||
text = ' '
|
||||
}
|
||||
} else {
|
||||
text = preserveWhitespace ? ' ' : ''
|
||||
}
|
||||
if (text) {
|
||||
if (!inPre && whitespaceOption === 'condense') {
|
||||
// condense consecutive whitespaces into single space
|
||||
text = text.replace(whitespaceRE, ' ')
|
||||
}
|
||||
let res
|
||||
let child: ?ASTNode
|
||||
if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) {
|
||||
child = {
|
||||
type: 2,
|
||||
expression: res.expression,
|
||||
tokens: res.tokens,
|
||||
text
|
||||
}
|
||||
} else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {
|
||||
child = {
|
||||
type: 3,
|
||||
text
|
||||
}
|
||||
}
|
||||
if (child) {
|
||||
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
|
||||
child.start = start
|
||||
child.end = end
|
||||
}
|
||||
children.push(child)
|
||||
}
|
||||
}
|
||||
},
|
||||
comment (text: string, start, end) {
|
||||
// adding anyting as a sibling to the root node is forbidden
|
||||
// comments should still be allowed, but ignored
|
||||
if (currentParent) {
|
||||
const child: ASTText = {
|
||||
type: 3,
|
||||
text,
|
||||
isComment: true
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
|
||||
child.start = start
|
||||
child.end = end
|
||||
}
|
||||
currentParent.children.push(child)
|
||||
}
|
||||
}
|
||||
})
|
||||
return root
|
||||
}
|
||||
|
||||
function processPre (el) {
|
||||
if (getAndRemoveAttr(el, 'v-pre') != null) {
|
||||
el.pre = true
|
||||
}
|
||||
}
|
||||
|
||||
function processRawAttrs (el) {
|
||||
const list = el.attrsList
|
||||
const len = list.length
|
||||
if (len) {
|
||||
const attrs: Array<ASTAttr> = el.attrs = new Array(len)
|
||||
for (let i = 0; i < len; i++) {
|
||||
attrs[i] = {
|
||||
name: list[i].name,
|
||||
value: JSON.stringify(list[i].value)
|
||||
}
|
||||
if (list[i].start != null) {
|
||||
attrs[i].start = list[i].start
|
||||
attrs[i].end = list[i].end
|
||||
}
|
||||
}
|
||||
} else if (!el.pre) {
|
||||
// non root node in pre blocks with no attributes
|
||||
el.plain = true
|
||||
}
|
||||
}
|
||||
|
||||
export function processElement (
|
||||
element: ASTElement,
|
||||
options: CompilerOptions
|
||||
) {
|
||||
processKey(element)
|
||||
|
||||
// determine whether this is a plain element after
|
||||
// removing structural attributes
|
||||
element.plain = (
|
||||
!element.key &&
|
||||
!element.scopedSlots &&
|
||||
!element.attrsList.length
|
||||
)
|
||||
|
||||
processRef(element)
|
||||
processSlotContent(element)
|
||||
processSlotOutlet(element)
|
||||
processComponent(element)
|
||||
for (let i = 0; i < transforms.length; i++) {
|
||||
element = transforms[i](element, options) || element
|
||||
}
|
||||
processAttrs(element)
|
||||
return element
|
||||
}
|
||||
|
||||
function processKey (el) {
|
||||
const exp = getBindingAttr(el, 'key')
|
||||
if (exp) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (el.tag === 'template') {
|
||||
warn(
|
||||
`<template> cannot be keyed. Place the key on real elements instead.`,
|
||||
getRawBindingAttr(el, 'key')
|
||||
)
|
||||
}
|
||||
if (el.for) {
|
||||
const iterator = el.iterator2 || el.iterator1
|
||||
const parent = el.parent
|
||||
if (iterator && iterator === exp && parent && parent.tag === 'transition-group') {
|
||||
warn(
|
||||
`Do not use v-for index as key on <transition-group> children, ` +
|
||||
`this is the same as not using keys.`,
|
||||
getRawBindingAttr(el, 'key'),
|
||||
true /* tip */
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
el.key = exp
|
||||
}
|
||||
}
|
||||
|
||||
function processRef (el) {
|
||||
const ref = getBindingAttr(el, 'ref')
|
||||
if (ref) {
|
||||
el.ref = ref
|
||||
el.refInFor = checkInFor(el)
|
||||
}
|
||||
}
|
||||
|
||||
export function processFor (el: ASTElement) {
|
||||
let exp
|
||||
if ((exp = getAndRemoveAttr(el, 'v-for'))) {
|
||||
const res = parseFor(exp)
|
||||
if (res) {
|
||||
extend(el, res)
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
`Invalid v-for expression: ${exp}`,
|
||||
el.rawAttrsMap['v-for']
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ForParseResult = {
|
||||
for: string;
|
||||
alias: string;
|
||||
iterator1?: string;
|
||||
iterator2?: string;
|
||||
};
|
||||
|
||||
export function parseFor (exp: string): ?ForParseResult {
|
||||
const inMatch = exp.match(forAliasRE)
|
||||
if (!inMatch) return
|
||||
const res = {}
|
||||
res.for = inMatch[2].trim()
|
||||
const alias = inMatch[1].trim().replace(stripParensRE, '')
|
||||
const iteratorMatch = alias.match(forIteratorRE)
|
||||
if (iteratorMatch) {
|
||||
res.alias = alias.replace(forIteratorRE, '').trim()
|
||||
res.iterator1 = iteratorMatch[1].trim()
|
||||
if (iteratorMatch[2]) {
|
||||
res.iterator2 = iteratorMatch[2].trim()
|
||||
}
|
||||
} else {
|
||||
res.alias = alias
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function processIf (el) {
|
||||
const exp = getAndRemoveAttr(el, 'v-if')
|
||||
if (exp) {
|
||||
el.if = exp
|
||||
addIfCondition(el, {
|
||||
exp: exp,
|
||||
block: el
|
||||
})
|
||||
} else {
|
||||
if (getAndRemoveAttr(el, 'v-else') != null) {
|
||||
el.else = true
|
||||
}
|
||||
const elseif = getAndRemoveAttr(el, 'v-else-if')
|
||||
if (elseif) {
|
||||
el.elseif = elseif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processIfConditions (el, parent) {
|
||||
const prev = findPrevElement(parent.children)
|
||||
if (prev && prev.if) {
|
||||
addIfCondition(prev, {
|
||||
exp: el.elseif,
|
||||
block: el
|
||||
})
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
`v-${el.elseif ? ('else-if="' + el.elseif + '"') : 'else'} ` +
|
||||
`used on element <${el.tag}> without corresponding v-if.`,
|
||||
el.rawAttrsMap[el.elseif ? 'v-else-if' : 'v-else']
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function findPrevElement (children: Array<any>): ASTElement | void {
|
||||
let i = children.length
|
||||
while (i--) {
|
||||
if (children[i].type === 1) {
|
||||
return children[i]
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production' && children[i].text !== ' ') {
|
||||
warn(
|
||||
`text "${children[i].text.trim()}" between v-if and v-else(-if) ` +
|
||||
`will be ignored.`,
|
||||
children[i]
|
||||
)
|
||||
}
|
||||
children.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function addIfCondition (el: ASTElement, condition: ASTIfCondition) {
|
||||
if (!el.ifConditions) {
|
||||
el.ifConditions = []
|
||||
}
|
||||
el.ifConditions.push(condition)
|
||||
}
|
||||
|
||||
function processOnce (el) {
|
||||
const once = getAndRemoveAttr(el, 'v-once')
|
||||
if (once != null) {
|
||||
el.once = true
|
||||
}
|
||||
}
|
||||
|
||||
// handle content being passed to a component as slot,
|
||||
// e.g. <template slot="xxx">, <div slot-scope="xxx">
|
||||
function processSlotContent (el) {
|
||||
let slotScope
|
||||
if (el.tag === 'template') {
|
||||
slotScope = getAndRemoveAttr(el, 'scope')
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && slotScope) {
|
||||
warn(
|
||||
`the "scope" attribute for scoped slots have been deprecated and ` +
|
||||
`replaced by "slot-scope" since 2.5. The new "slot-scope" attribute ` +
|
||||
`can also be used on plain elements in addition to <template> to ` +
|
||||
`denote scoped slots.`,
|
||||
el.rawAttrsMap['scope'],
|
||||
true
|
||||
)
|
||||
}
|
||||
el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope')
|
||||
} else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && el.attrsMap['v-for']) {
|
||||
warn(
|
||||
`Ambiguous combined usage of slot-scope and v-for on <${el.tag}> ` +
|
||||
`(v-for takes higher priority). Use a wrapper <template> for the ` +
|
||||
`scoped slot to make it clearer.`,
|
||||
el.rawAttrsMap['slot-scope'],
|
||||
true
|
||||
)
|
||||
}
|
||||
el.slotScope = slotScope
|
||||
}
|
||||
|
||||
// slot="xxx"
|
||||
const slotTarget = getBindingAttr(el, 'slot')
|
||||
if (slotTarget) {
|
||||
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget
|
||||
el.slotTargetDynamic = !!(el.attrsMap[':slot'] || el.attrsMap['v-bind:slot'])
|
||||
// preserve slot as an attribute for native shadow DOM compat
|
||||
// only for non-scoped slots.
|
||||
if (el.tag !== 'template' && !el.slotScope) {
|
||||
addAttr(el, 'slot', slotTarget, getRawBindingAttr(el, 'slot'))
|
||||
}
|
||||
}
|
||||
|
||||
// 2.6 v-slot syntax
|
||||
if (process.env.NEW_SLOT_SYNTAX) {
|
||||
if (el.tag === 'template') {
|
||||
// v-slot on <template>
|
||||
const slotBinding = getAndRemoveAttrByRegex(el, slotRE)
|
||||
if (slotBinding) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (el.slotTarget || el.slotScope) {
|
||||
warn(
|
||||
`Unexpected mixed usage of different slot syntaxes.`,
|
||||
el
|
||||
)
|
||||
}
|
||||
if (el.parent && !maybeComponent(el.parent)) {
|
||||
warn(
|
||||
`<template v-slot> can only appear at the root level inside ` +
|
||||
`the receiving the component`,
|
||||
el
|
||||
)
|
||||
}
|
||||
}
|
||||
const { name, dynamic } = getSlotName(slotBinding)
|
||||
el.slotTarget = name
|
||||
el.slotTargetDynamic = dynamic
|
||||
el.slotScope = slotBinding.value || emptySlotScopeToken // force it into a scoped slot for perf
|
||||
}
|
||||
} else {
|
||||
// v-slot on component, denotes default slot
|
||||
const slotBinding = getAndRemoveAttrByRegex(el, slotRE)
|
||||
if (slotBinding) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!maybeComponent(el)) {
|
||||
warn(
|
||||
`v-slot can only be used on components or <template>.`,
|
||||
slotBinding
|
||||
)
|
||||
}
|
||||
if (el.slotScope || el.slotTarget) {
|
||||
warn(
|
||||
`Unexpected mixed usage of different slot syntaxes.`,
|
||||
el
|
||||
)
|
||||
}
|
||||
if (el.scopedSlots) {
|
||||
warn(
|
||||
`To avoid scope ambiguity, the default slot should also use ` +
|
||||
`<template> syntax when there are other named slots.`,
|
||||
slotBinding
|
||||
)
|
||||
}
|
||||
}
|
||||
// add the component's children to its default slot
|
||||
const slots = el.scopedSlots || (el.scopedSlots = {})
|
||||
const { name, dynamic } = getSlotName(slotBinding)
|
||||
const slotContainer = slots[name] = createASTElement('template', [], el)
|
||||
slotContainer.slotTarget = name
|
||||
slotContainer.slotTargetDynamic = dynamic
|
||||
slotContainer.children = el.children.filter((c: any) => {
|
||||
if (!c.slotScope) {
|
||||
c.parent = slotContainer
|
||||
return true
|
||||
}
|
||||
})
|
||||
slotContainer.slotScope = slotBinding.value || emptySlotScopeToken
|
||||
// remove children as they are returned from scopedSlots now
|
||||
el.children = []
|
||||
// mark el non-plain so data gets generated
|
||||
el.plain = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSlotName (binding) {
|
||||
let name = binding.name.replace(slotRE, '')
|
||||
if (!name) {
|
||||
if (binding.name[0] !== '#') {
|
||||
name = 'default'
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
`v-slot shorthand syntax requires a slot name.`,
|
||||
binding
|
||||
)
|
||||
}
|
||||
}
|
||||
return dynamicArgRE.test(name)
|
||||
// dynamic [name]
|
||||
? { name: name.slice(1, -1), dynamic: true }
|
||||
// static name
|
||||
: { name: `"${name}"`, dynamic: false }
|
||||
}
|
||||
|
||||
// handle <slot/> outlets
|
||||
function processSlotOutlet (el) {
|
||||
if (el.tag === 'slot') {
|
||||
el.slotName = getBindingAttr(el, 'name')
|
||||
if (process.env.NODE_ENV !== 'production' && el.key) {
|
||||
warn(
|
||||
`\`key\` does not work on <slot> because slots are abstract outlets ` +
|
||||
`and can possibly expand into multiple elements. ` +
|
||||
`Use the key on a wrapping element instead.`,
|
||||
getRawBindingAttr(el, 'key')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processComponent (el) {
|
||||
let binding
|
||||
if ((binding = getBindingAttr(el, 'is'))) {
|
||||
el.component = binding
|
||||
}
|
||||
if (getAndRemoveAttr(el, 'inline-template') != null) {
|
||||
el.inlineTemplate = true
|
||||
}
|
||||
}
|
||||
|
||||
function processAttrs (el) {
|
||||
const list = el.attrsList
|
||||
let i, l, name, rawName, value, modifiers, syncGen, isDynamic
|
||||
for (i = 0, l = list.length; i < l; i++) {
|
||||
name = rawName = list[i].name
|
||||
value = list[i].value
|
||||
if (dirRE.test(name)) {
|
||||
// mark element as dynamic
|
||||
el.hasBindings = true
|
||||
// modifiers
|
||||
modifiers = parseModifiers(name.replace(dirRE, ''))
|
||||
// support .foo shorthand syntax for the .prop modifier
|
||||
if (process.env.VBIND_PROP_SHORTHAND && propBindRE.test(name)) {
|
||||
(modifiers || (modifiers = {})).prop = true
|
||||
name = `.` + name.slice(1).replace(modifierRE, '')
|
||||
} else if (modifiers) {
|
||||
name = name.replace(modifierRE, '')
|
||||
}
|
||||
if (bindRE.test(name)) { // v-bind
|
||||
name = name.replace(bindRE, '')
|
||||
value = parseFilters(value)
|
||||
isDynamic = dynamicArgRE.test(name)
|
||||
if (isDynamic) {
|
||||
name = name.slice(1, -1)
|
||||
}
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
value.trim().length === 0
|
||||
) {
|
||||
warn(
|
||||
`The value for a v-bind expression cannot be empty. Found in "v-bind:${name}"`
|
||||
)
|
||||
}
|
||||
if (modifiers) {
|
||||
if (modifiers.prop && !isDynamic) {
|
||||
name = camelize(name)
|
||||
if (name === 'innerHtml') name = 'innerHTML'
|
||||
}
|
||||
if (modifiers.camel && !isDynamic) {
|
||||
name = camelize(name)
|
||||
}
|
||||
if (modifiers.sync) {
|
||||
syncGen = genAssignmentCode(value, `$event`)
|
||||
if (!isDynamic) {
|
||||
addHandler(
|
||||
el,
|
||||
`update:${camelize(name)}`,
|
||||
syncGen,
|
||||
null,
|
||||
false,
|
||||
warn,
|
||||
list[i]
|
||||
)
|
||||
if (hyphenate(name) !== camelize(name)) {
|
||||
addHandler(
|
||||
el,
|
||||
`update:${hyphenate(name)}`,
|
||||
syncGen,
|
||||
null,
|
||||
false,
|
||||
warn,
|
||||
list[i]
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// handler w/ dynamic event name
|
||||
addHandler(
|
||||
el,
|
||||
`"update:"+(${name})`,
|
||||
syncGen,
|
||||
null,
|
||||
false,
|
||||
warn,
|
||||
list[i],
|
||||
true // dynamic
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((modifiers && modifiers.prop) || (
|
||||
!el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
|
||||
)) {
|
||||
addProp(el, name, value, list[i], isDynamic)
|
||||
} else {
|
||||
addAttr(el, name, value, list[i], isDynamic)
|
||||
}
|
||||
} else if (onRE.test(name)) { // v-on
|
||||
name = name.replace(onRE, '')
|
||||
isDynamic = dynamicArgRE.test(name)
|
||||
if (isDynamic) {
|
||||
name = name.slice(1, -1)
|
||||
}
|
||||
addHandler(el, name, value, modifiers, false, warn, list[i], isDynamic)
|
||||
} else { // normal directives
|
||||
name = name.replace(dirRE, '')
|
||||
// parse arg
|
||||
const argMatch = name.match(argRE)
|
||||
let arg = argMatch && argMatch[1]
|
||||
isDynamic = false
|
||||
if (arg) {
|
||||
name = name.slice(0, -(arg.length + 1))
|
||||
if (dynamicArgRE.test(arg)) {
|
||||
arg = arg.slice(1, -1)
|
||||
isDynamic = true
|
||||
}
|
||||
}
|
||||
addDirective(el, name, rawName, value, arg, isDynamic, modifiers, list[i])
|
||||
if (process.env.NODE_ENV !== 'production' && name === 'model') {
|
||||
checkForAliasModel(el, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// literal attribute
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const res = parseText(value, delimiters)
|
||||
if (res) {
|
||||
warn(
|
||||
`${name}="${value}": ` +
|
||||
'Interpolation inside attributes has been removed. ' +
|
||||
'Use v-bind or the colon shorthand instead. For example, ' +
|
||||
'instead of <div id="{{ val }}">, use <div :id="val">.',
|
||||
list[i]
|
||||
)
|
||||
}
|
||||
}
|
||||
addAttr(el, name, JSON.stringify(value), list[i])
|
||||
// #6887 firefox doesn't update muted state if set via attribute
|
||||
// even immediately after element creation
|
||||
if (!el.component &&
|
||||
name === 'muted' &&
|
||||
platformMustUseProp(el.tag, el.attrsMap.type, name)) {
|
||||
addProp(el, name, 'true', list[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkInFor (el: ASTElement): boolean {
|
||||
let parent = el
|
||||
while (parent) {
|
||||
if (parent.for !== undefined) {
|
||||
return true
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function parseModifiers (name: string): Object | void {
|
||||
const match = name.match(modifierRE)
|
||||
if (match) {
|
||||
const ret = {}
|
||||
match.forEach(m => { ret[m.slice(1)] = true })
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
function makeAttrsMap (attrs: Array<Object>): Object {
|
||||
const map = {}
|
||||
for (let i = 0, l = attrs.length; i < l; i++) {
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
map[attrs[i].name] && !isIE && !isEdge
|
||||
) {
|
||||
warn('duplicate attribute: ' + attrs[i].name, attrs[i])
|
||||
}
|
||||
map[attrs[i].name] = attrs[i].value
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
// for script (e.g. type="x/template") or style, do not decode content
|
||||
function isTextTag (el): boolean {
|
||||
return el.tag === 'script' || el.tag === 'style'
|
||||
}
|
||||
|
||||
function isForbiddenTag (el): boolean {
|
||||
return (
|
||||
el.tag === 'style' ||
|
||||
(el.tag === 'script' && (
|
||||
!el.attrsMap.type ||
|
||||
el.attrsMap.type === 'text/javascript'
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
const ieNSBug = /^xmlns:NS\d+/
|
||||
const ieNSPrefix = /^NS\d+:/
|
||||
|
||||
/* istanbul ignore next */
|
||||
function guardIESVGBug (attrs) {
|
||||
const res = []
|
||||
for (let i = 0; i < attrs.length; i++) {
|
||||
const attr = attrs[i]
|
||||
if (!ieNSBug.test(attr.name)) {
|
||||
attr.name = attr.name.replace(ieNSPrefix, '')
|
||||
res.push(attr)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function checkForAliasModel (el, value) {
|
||||
let _el = el
|
||||
while (_el) {
|
||||
if (_el.for && _el.alias === value) {
|
||||
warn(
|
||||
`<${el.tag} v-model="${value}">: ` +
|
||||
`You are binding v-model directly to a v-for iteration alias. ` +
|
||||
`This will not be able to modify the v-for source array because ` +
|
||||
`writing to the alias is like modifying a function local variable. ` +
|
||||
`Consider using an array of objects and use v-model on an object property instead.`,
|
||||
el.rawAttrsMap['v-model']
|
||||
)
|
||||
}
|
||||
_el = _el.parent
|
||||
}
|
||||
}
|
53
express-server/node_modules/vue/src/compiler/parser/text-parser.js
generated
vendored
Normal file
53
express-server/node_modules/vue/src/compiler/parser/text-parser.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/* @flow */
|
||||
|
||||
import { cached } from 'shared/util'
|
||||
import { parseFilters } from './filter-parser'
|
||||
|
||||
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g
|
||||
const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g
|
||||
|
||||
const buildRegex = cached(delimiters => {
|
||||
const open = delimiters[0].replace(regexEscapeRE, '\\$&')
|
||||
const close = delimiters[1].replace(regexEscapeRE, '\\$&')
|
||||
return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
|
||||
})
|
||||
|
||||
type TextParseResult = {
|
||||
expression: string,
|
||||
tokens: Array<string | { '@binding': string }>
|
||||
}
|
||||
|
||||
export function parseText (
|
||||
text: string,
|
||||
delimiters?: [string, string]
|
||||
): TextParseResult | void {
|
||||
const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE
|
||||
if (!tagRE.test(text)) {
|
||||
return
|
||||
}
|
||||
const tokens = []
|
||||
const rawTokens = []
|
||||
let lastIndex = tagRE.lastIndex = 0
|
||||
let match, index, tokenValue
|
||||
while ((match = tagRE.exec(text))) {
|
||||
index = match.index
|
||||
// push text token
|
||||
if (index > lastIndex) {
|
||||
rawTokens.push(tokenValue = text.slice(lastIndex, index))
|
||||
tokens.push(JSON.stringify(tokenValue))
|
||||
}
|
||||
// tag token
|
||||
const exp = parseFilters(match[1].trim())
|
||||
tokens.push(`_s(${exp})`)
|
||||
rawTokens.push({ '@binding': exp })
|
||||
lastIndex = index + match[0].length
|
||||
}
|
||||
if (lastIndex < text.length) {
|
||||
rawTokens.push(tokenValue = text.slice(lastIndex))
|
||||
tokens.push(JSON.stringify(tokenValue))
|
||||
}
|
||||
return {
|
||||
expression: tokens.join('+'),
|
||||
tokens: rawTokens
|
||||
}
|
||||
}
|
114
express-server/node_modules/vue/src/compiler/to-function.js
generated
vendored
Normal file
114
express-server/node_modules/vue/src/compiler/to-function.js
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/* @flow */
|
||||
|
||||
import { noop, extend } from 'shared/util'
|
||||
import { warn as baseWarn, tip } from 'core/util/debug'
|
||||
import { generateCodeFrame } from './codeframe'
|
||||
|
||||
type CompiledFunctionResult = {
|
||||
render: Function;
|
||||
staticRenderFns: Array<Function>;
|
||||
};
|
||||
|
||||
function createFunction (code, errors) {
|
||||
try {
|
||||
return new Function(code)
|
||||
} catch (err) {
|
||||
errors.push({ err, code })
|
||||
return noop
|
||||
}
|
||||
}
|
||||
|
||||
export function createCompileToFunctionFn (compile: Function): Function {
|
||||
const cache = Object.create(null)
|
||||
|
||||
return function compileToFunctions (
|
||||
template: string,
|
||||
options?: CompilerOptions,
|
||||
vm?: Component
|
||||
): CompiledFunctionResult {
|
||||
options = extend({}, options)
|
||||
const warn = options.warn || baseWarn
|
||||
delete options.warn
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// detect possible CSP restriction
|
||||
try {
|
||||
new Function('return 1')
|
||||
} catch (e) {
|
||||
if (e.toString().match(/unsafe-eval|CSP/)) {
|
||||
warn(
|
||||
'It seems you are using the standalone build of Vue.js in an ' +
|
||||
'environment with Content Security Policy that prohibits unsafe-eval. ' +
|
||||
'The template compiler cannot work in this environment. Consider ' +
|
||||
'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
|
||||
'templates into render functions.'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check cache
|
||||
const key = options.delimiters
|
||||
? String(options.delimiters) + template
|
||||
: template
|
||||
if (cache[key]) {
|
||||
return cache[key]
|
||||
}
|
||||
|
||||
// compile
|
||||
const compiled = compile(template, options)
|
||||
|
||||
// check compilation errors/tips
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (compiled.errors && compiled.errors.length) {
|
||||
if (options.outputSourceRange) {
|
||||
compiled.errors.forEach(e => {
|
||||
warn(
|
||||
`Error compiling template:\n\n${e.msg}\n\n` +
|
||||
generateCodeFrame(template, e.start, e.end),
|
||||
vm
|
||||
)
|
||||
})
|
||||
} else {
|
||||
warn(
|
||||
`Error compiling template:\n\n${template}\n\n` +
|
||||
compiled.errors.map(e => `- ${e}`).join('\n') + '\n',
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
if (compiled.tips && compiled.tips.length) {
|
||||
if (options.outputSourceRange) {
|
||||
compiled.tips.forEach(e => tip(e.msg, vm))
|
||||
} else {
|
||||
compiled.tips.forEach(msg => tip(msg, vm))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turn code into functions
|
||||
const res = {}
|
||||
const fnGenErrors = []
|
||||
res.render = createFunction(compiled.render, fnGenErrors)
|
||||
res.staticRenderFns = compiled.staticRenderFns.map(code => {
|
||||
return createFunction(code, fnGenErrors)
|
||||
})
|
||||
|
||||
// check function generation errors.
|
||||
// this should only happen if there is a bug in the compiler itself.
|
||||
// mostly for codegen development use
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
|
||||
warn(
|
||||
`Failed to generate render function:\n\n` +
|
||||
fnGenErrors.map(({ err, code }) => `${err.toString()} in\n\n${code}\n`).join('\n'),
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (cache[key] = res)
|
||||
}
|
||||
}
|
5
express-server/node_modules/vue/src/core/components/index.js
generated
vendored
Normal file
5
express-server/node_modules/vue/src/core/components/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import KeepAlive from './keep-alive'
|
||||
|
||||
export default {
|
||||
KeepAlive
|
||||
}
|
124
express-server/node_modules/vue/src/core/components/keep-alive.js
generated
vendored
Normal file
124
express-server/node_modules/vue/src/core/components/keep-alive.js
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/* @flow */
|
||||
|
||||
import { isRegExp, remove } from 'shared/util'
|
||||
import { getFirstComponentChild } from 'core/vdom/helpers/index'
|
||||
|
||||
type VNodeCache = { [key: string]: ?VNode };
|
||||
|
||||
function getComponentName (opts: ?VNodeComponentOptions): ?string {
|
||||
return opts && (opts.Ctor.options.name || opts.tag)
|
||||
}
|
||||
|
||||
function matches (pattern: string | RegExp | Array<string>, name: string): boolean {
|
||||
if (Array.isArray(pattern)) {
|
||||
return pattern.indexOf(name) > -1
|
||||
} else if (typeof pattern === 'string') {
|
||||
return pattern.split(',').indexOf(name) > -1
|
||||
} else if (isRegExp(pattern)) {
|
||||
return pattern.test(name)
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return false
|
||||
}
|
||||
|
||||
function pruneCache (keepAliveInstance: any, filter: Function) {
|
||||
const { cache, keys, _vnode } = keepAliveInstance
|
||||
for (const key in cache) {
|
||||
const cachedNode: ?VNode = cache[key]
|
||||
if (cachedNode) {
|
||||
const name: ?string = getComponentName(cachedNode.componentOptions)
|
||||
if (name && !filter(name)) {
|
||||
pruneCacheEntry(cache, key, keys, _vnode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pruneCacheEntry (
|
||||
cache: VNodeCache,
|
||||
key: string,
|
||||
keys: Array<string>,
|
||||
current?: VNode
|
||||
) {
|
||||
const cached = cache[key]
|
||||
if (cached && (!current || cached.tag !== current.tag)) {
|
||||
cached.componentInstance.$destroy()
|
||||
}
|
||||
cache[key] = null
|
||||
remove(keys, key)
|
||||
}
|
||||
|
||||
const patternTypes: Array<Function> = [String, RegExp, Array]
|
||||
|
||||
export default {
|
||||
name: 'keep-alive',
|
||||
abstract: true,
|
||||
|
||||
props: {
|
||||
include: patternTypes,
|
||||
exclude: patternTypes,
|
||||
max: [String, Number]
|
||||
},
|
||||
|
||||
created () {
|
||||
this.cache = Object.create(null)
|
||||
this.keys = []
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
for (const key in this.cache) {
|
||||
pruneCacheEntry(this.cache, key, this.keys)
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$watch('include', val => {
|
||||
pruneCache(this, name => matches(val, name))
|
||||
})
|
||||
this.$watch('exclude', val => {
|
||||
pruneCache(this, name => !matches(val, name))
|
||||
})
|
||||
},
|
||||
|
||||
render () {
|
||||
const slot = this.$slots.default
|
||||
const vnode: VNode = getFirstComponentChild(slot)
|
||||
const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
|
||||
if (componentOptions) {
|
||||
// check pattern
|
||||
const name: ?string = getComponentName(componentOptions)
|
||||
const { include, exclude } = this
|
||||
if (
|
||||
// not included
|
||||
(include && (!name || !matches(include, name))) ||
|
||||
// excluded
|
||||
(exclude && name && matches(exclude, name))
|
||||
) {
|
||||
return vnode
|
||||
}
|
||||
|
||||
const { cache, keys } = this
|
||||
const key: ?string = vnode.key == null
|
||||
// same constructor may get registered as different local components
|
||||
// so cid alone is not enough (#3269)
|
||||
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
|
||||
: vnode.key
|
||||
if (cache[key]) {
|
||||
vnode.componentInstance = cache[key].componentInstance
|
||||
// make current key freshest
|
||||
remove(keys, key)
|
||||
keys.push(key)
|
||||
} else {
|
||||
cache[key] = vnode
|
||||
keys.push(key)
|
||||
// prune oldest entry
|
||||
if (this.max && keys.length > parseInt(this.max)) {
|
||||
pruneCacheEntry(cache, keys[0], keys, this._vnode)
|
||||
}
|
||||
}
|
||||
|
||||
vnode.data.keepAlive = true
|
||||
}
|
||||
return vnode || (slot && slot[0])
|
||||
}
|
||||
}
|
130
express-server/node_modules/vue/src/core/config.js
generated
vendored
Normal file
130
express-server/node_modules/vue/src/core/config.js
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
no,
|
||||
noop,
|
||||
identity
|
||||
} from 'shared/util'
|
||||
|
||||
import { LIFECYCLE_HOOKS } from 'shared/constants'
|
||||
|
||||
export type Config = {
|
||||
// user
|
||||
optionMergeStrategies: { [key: string]: Function };
|
||||
silent: boolean;
|
||||
productionTip: boolean;
|
||||
performance: boolean;
|
||||
devtools: boolean;
|
||||
errorHandler: ?(err: Error, vm: Component, info: string) => void;
|
||||
warnHandler: ?(msg: string, vm: Component, trace: string) => void;
|
||||
ignoredElements: Array<string | RegExp>;
|
||||
keyCodes: { [key: string]: number | Array<number> };
|
||||
|
||||
// platform
|
||||
isReservedTag: (x?: string) => boolean;
|
||||
isReservedAttr: (x?: string) => boolean;
|
||||
parsePlatformTagName: (x: string) => string;
|
||||
isUnknownElement: (x?: string) => boolean;
|
||||
getTagNamespace: (x?: string) => string | void;
|
||||
mustUseProp: (tag: string, type: ?string, name: string) => boolean;
|
||||
|
||||
// private
|
||||
async: boolean;
|
||||
|
||||
// legacy
|
||||
_lifecycleHooks: Array<string>;
|
||||
};
|
||||
|
||||
export default ({
|
||||
/**
|
||||
* Option merge strategies (used in core/util/options)
|
||||
*/
|
||||
// $flow-disable-line
|
||||
optionMergeStrategies: Object.create(null),
|
||||
|
||||
/**
|
||||
* Whether to suppress warnings.
|
||||
*/
|
||||
silent: false,
|
||||
|
||||
/**
|
||||
* Show production mode tip message on boot?
|
||||
*/
|
||||
productionTip: process.env.NODE_ENV !== 'production',
|
||||
|
||||
/**
|
||||
* Whether to enable devtools
|
||||
*/
|
||||
devtools: process.env.NODE_ENV !== 'production',
|
||||
|
||||
/**
|
||||
* Whether to record perf
|
||||
*/
|
||||
performance: false,
|
||||
|
||||
/**
|
||||
* Error handler for watcher errors
|
||||
*/
|
||||
errorHandler: null,
|
||||
|
||||
/**
|
||||
* Warn handler for watcher warns
|
||||
*/
|
||||
warnHandler: null,
|
||||
|
||||
/**
|
||||
* Ignore certain custom elements
|
||||
*/
|
||||
ignoredElements: [],
|
||||
|
||||
/**
|
||||
* Custom user key aliases for v-on
|
||||
*/
|
||||
// $flow-disable-line
|
||||
keyCodes: Object.create(null),
|
||||
|
||||
/**
|
||||
* Check if a tag is reserved so that it cannot be registered as a
|
||||
* component. This is platform-dependent and may be overwritten.
|
||||
*/
|
||||
isReservedTag: no,
|
||||
|
||||
/**
|
||||
* Check if an attribute is reserved so that it cannot be used as a component
|
||||
* prop. This is platform-dependent and may be overwritten.
|
||||
*/
|
||||
isReservedAttr: no,
|
||||
|
||||
/**
|
||||
* Check if a tag is an unknown element.
|
||||
* Platform-dependent.
|
||||
*/
|
||||
isUnknownElement: no,
|
||||
|
||||
/**
|
||||
* Get the namespace of an element
|
||||
*/
|
||||
getTagNamespace: noop,
|
||||
|
||||
/**
|
||||
* Parse the real tag name for the specific platform.
|
||||
*/
|
||||
parsePlatformTagName: identity,
|
||||
|
||||
/**
|
||||
* Check if an attribute must be bound using property, e.g. value
|
||||
* Platform-dependent.
|
||||
*/
|
||||
mustUseProp: no,
|
||||
|
||||
/**
|
||||
* Perform updates asynchronously. Intended to be used by Vue Test Utils
|
||||
* This will significantly reduce performance if set to false.
|
||||
*/
|
||||
async: true,
|
||||
|
||||
/**
|
||||
* Exposed for legacy reasons
|
||||
*/
|
||||
_lifecycleHooks: LIFECYCLE_HOOKS
|
||||
}: Config)
|
34
express-server/node_modules/vue/src/core/global-api/assets.js
generated
vendored
Normal file
34
express-server/node_modules/vue/src/core/global-api/assets.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/* @flow */
|
||||
|
||||
import { ASSET_TYPES } from 'shared/constants'
|
||||
import { isPlainObject, validateComponentName } from '../util/index'
|
||||
|
||||
export function initAssetRegisters (Vue: GlobalAPI) {
|
||||
/**
|
||||
* Create asset registration methods.
|
||||
*/
|
||||
ASSET_TYPES.forEach(type => {
|
||||
Vue[type] = function (
|
||||
id: string,
|
||||
definition: Function | Object
|
||||
): Function | Object | void {
|
||||
if (!definition) {
|
||||
return this.options[type + 's'][id]
|
||||
} else {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && type === 'component') {
|
||||
validateComponentName(id)
|
||||
}
|
||||
if (type === 'component' && isPlainObject(definition)) {
|
||||
definition.name = definition.name || id
|
||||
definition = this.options._base.extend(definition)
|
||||
}
|
||||
if (type === 'directive' && typeof definition === 'function') {
|
||||
definition = { bind: definition, update: definition }
|
||||
}
|
||||
this.options[type + 's'][id] = definition
|
||||
return definition
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
95
express-server/node_modules/vue/src/core/global-api/extend.js
generated
vendored
Normal file
95
express-server/node_modules/vue/src/core/global-api/extend.js
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/* @flow */
|
||||
|
||||
import { ASSET_TYPES } from 'shared/constants'
|
||||
import { defineComputed, proxy } from '../instance/state'
|
||||
import { extend, mergeOptions, validateComponentName } from '../util/index'
|
||||
|
||||
export function initExtend (Vue: GlobalAPI) {
|
||||
/**
|
||||
* Each instance constructor, including Vue, has a unique
|
||||
* cid. This enables us to create wrapped "child
|
||||
* constructors" for prototypal inheritance and cache them.
|
||||
*/
|
||||
Vue.cid = 0
|
||||
let cid = 1
|
||||
|
||||
/**
|
||||
* Class inheritance
|
||||
*/
|
||||
Vue.extend = function (extendOptions: Object): Function {
|
||||
extendOptions = extendOptions || {}
|
||||
const Super = this
|
||||
const SuperId = Super.cid
|
||||
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
|
||||
if (cachedCtors[SuperId]) {
|
||||
return cachedCtors[SuperId]
|
||||
}
|
||||
|
||||
const name = extendOptions.name || Super.options.name
|
||||
if (process.env.NODE_ENV !== 'production' && name) {
|
||||
validateComponentName(name)
|
||||
}
|
||||
|
||||
const Sub = function VueComponent (options) {
|
||||
this._init(options)
|
||||
}
|
||||
Sub.prototype = Object.create(Super.prototype)
|
||||
Sub.prototype.constructor = Sub
|
||||
Sub.cid = cid++
|
||||
Sub.options = mergeOptions(
|
||||
Super.options,
|
||||
extendOptions
|
||||
)
|
||||
Sub['super'] = Super
|
||||
|
||||
// For props and computed properties, we define the proxy getters on
|
||||
// the Vue instances at extension time, on the extended prototype. This
|
||||
// avoids Object.defineProperty calls for each instance created.
|
||||
if (Sub.options.props) {
|
||||
initProps(Sub)
|
||||
}
|
||||
if (Sub.options.computed) {
|
||||
initComputed(Sub)
|
||||
}
|
||||
|
||||
// allow further extension/mixin/plugin usage
|
||||
Sub.extend = Super.extend
|
||||
Sub.mixin = Super.mixin
|
||||
Sub.use = Super.use
|
||||
|
||||
// create asset registers, so extended classes
|
||||
// can have their private assets too.
|
||||
ASSET_TYPES.forEach(function (type) {
|
||||
Sub[type] = Super[type]
|
||||
})
|
||||
// enable recursive self-lookup
|
||||
if (name) {
|
||||
Sub.options.components[name] = Sub
|
||||
}
|
||||
|
||||
// keep a reference to the super options at extension time.
|
||||
// later at instantiation we can check if Super's options have
|
||||
// been updated.
|
||||
Sub.superOptions = Super.options
|
||||
Sub.extendOptions = extendOptions
|
||||
Sub.sealedOptions = extend({}, Sub.options)
|
||||
|
||||
// cache constructor
|
||||
cachedCtors[SuperId] = Sub
|
||||
return Sub
|
||||
}
|
||||
}
|
||||
|
||||
function initProps (Comp) {
|
||||
const props = Comp.options.props
|
||||
for (const key in props) {
|
||||
proxy(Comp.prototype, `_props`, key)
|
||||
}
|
||||
}
|
||||
|
||||
function initComputed (Comp) {
|
||||
const computed = Comp.options.computed
|
||||
for (const key in computed) {
|
||||
defineComputed(Comp.prototype, key, computed[key])
|
||||
}
|
||||
}
|
69
express-server/node_modules/vue/src/core/global-api/index.js
generated
vendored
Normal file
69
express-server/node_modules/vue/src/core/global-api/index.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import { initUse } from './use'
|
||||
import { initMixin } from './mixin'
|
||||
import { initExtend } from './extend'
|
||||
import { initAssetRegisters } from './assets'
|
||||
import { set, del } from '../observer/index'
|
||||
import { ASSET_TYPES } from 'shared/constants'
|
||||
import builtInComponents from '../components/index'
|
||||
import { observe } from 'core/observer/index'
|
||||
|
||||
import {
|
||||
warn,
|
||||
extend,
|
||||
nextTick,
|
||||
mergeOptions,
|
||||
defineReactive
|
||||
} from '../util/index'
|
||||
|
||||
export function initGlobalAPI (Vue: GlobalAPI) {
|
||||
// config
|
||||
const configDef = {}
|
||||
configDef.get = () => config
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
configDef.set = () => {
|
||||
warn(
|
||||
'Do not replace the Vue.config object, set individual fields instead.'
|
||||
)
|
||||
}
|
||||
}
|
||||
Object.defineProperty(Vue, 'config', configDef)
|
||||
|
||||
// exposed util methods.
|
||||
// NOTE: these are not considered part of the public API - avoid relying on
|
||||
// them unless you are aware of the risk.
|
||||
Vue.util = {
|
||||
warn,
|
||||
extend,
|
||||
mergeOptions,
|
||||
defineReactive
|
||||
}
|
||||
|
||||
Vue.set = set
|
||||
Vue.delete = del
|
||||
Vue.nextTick = nextTick
|
||||
|
||||
// 2.6 explicit observable API
|
||||
Vue.observable = <T>(obj: T): T => {
|
||||
observe(obj)
|
||||
return obj
|
||||
}
|
||||
|
||||
Vue.options = Object.create(null)
|
||||
ASSET_TYPES.forEach(type => {
|
||||
Vue.options[type + 's'] = Object.create(null)
|
||||
})
|
||||
|
||||
// this is used to identify the "base" constructor to extend all plain-object
|
||||
// components with in Weex's multi-instance scenarios.
|
||||
Vue.options._base = Vue
|
||||
|
||||
extend(Vue.options.components, builtInComponents)
|
||||
|
||||
initUse(Vue)
|
||||
initMixin(Vue)
|
||||
initExtend(Vue)
|
||||
initAssetRegisters(Vue)
|
||||
}
|
10
express-server/node_modules/vue/src/core/global-api/mixin.js
generated
vendored
Normal file
10
express-server/node_modules/vue/src/core/global-api/mixin.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import { mergeOptions } from '../util/index'
|
||||
|
||||
export function initMixin (Vue: GlobalAPI) {
|
||||
Vue.mixin = function (mixin: Object) {
|
||||
this.options = mergeOptions(this.options, mixin)
|
||||
return this
|
||||
}
|
||||
}
|
23
express-server/node_modules/vue/src/core/global-api/use.js
generated
vendored
Normal file
23
express-server/node_modules/vue/src/core/global-api/use.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/* @flow */
|
||||
|
||||
import { toArray } from '../util/index'
|
||||
|
||||
export function initUse (Vue: GlobalAPI) {
|
||||
Vue.use = function (plugin: Function | Object) {
|
||||
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
|
||||
if (installedPlugins.indexOf(plugin) > -1) {
|
||||
return this
|
||||
}
|
||||
|
||||
// additional parameters
|
||||
const args = toArray(arguments, 1)
|
||||
args.unshift(this)
|
||||
if (typeof plugin.install === 'function') {
|
||||
plugin.install.apply(plugin, args)
|
||||
} else if (typeof plugin === 'function') {
|
||||
plugin.apply(null, args)
|
||||
}
|
||||
installedPlugins.push(plugin)
|
||||
return this
|
||||
}
|
||||
}
|
26
express-server/node_modules/vue/src/core/index.js
generated
vendored
Normal file
26
express-server/node_modules/vue/src/core/index.js
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import Vue from './instance/index'
|
||||
import { initGlobalAPI } from './global-api/index'
|
||||
import { isServerRendering } from 'core/util/env'
|
||||
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
|
||||
|
||||
initGlobalAPI(Vue)
|
||||
|
||||
Object.defineProperty(Vue.prototype, '$isServer', {
|
||||
get: isServerRendering
|
||||
})
|
||||
|
||||
Object.defineProperty(Vue.prototype, '$ssrContext', {
|
||||
get () {
|
||||
/* istanbul ignore next */
|
||||
return this.$vnode && this.$vnode.ssrContext
|
||||
}
|
||||
})
|
||||
|
||||
// expose FunctionalRenderContext for ssr runtime helper installation
|
||||
Object.defineProperty(Vue, 'FunctionalRenderContext', {
|
||||
value: FunctionalRenderContext
|
||||
})
|
||||
|
||||
Vue.version = '__VERSION__'
|
||||
|
||||
export default Vue
|
143
express-server/node_modules/vue/src/core/instance/events.js
generated
vendored
Normal file
143
express-server/node_modules/vue/src/core/instance/events.js
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
tip,
|
||||
toArray,
|
||||
hyphenate,
|
||||
formatComponentName,
|
||||
invokeWithErrorHandling
|
||||
} from '../util/index'
|
||||
import { updateListeners } from '../vdom/helpers/index'
|
||||
|
||||
export function initEvents (vm: Component) {
|
||||
vm._events = Object.create(null)
|
||||
vm._hasHookEvent = false
|
||||
// init parent attached events
|
||||
const listeners = vm.$options._parentListeners
|
||||
if (listeners) {
|
||||
updateComponentListeners(vm, listeners)
|
||||
}
|
||||
}
|
||||
|
||||
let target: any
|
||||
|
||||
function add (event, fn) {
|
||||
target.$on(event, fn)
|
||||
}
|
||||
|
||||
function remove (event, fn) {
|
||||
target.$off(event, fn)
|
||||
}
|
||||
|
||||
function createOnceHandler (event, fn) {
|
||||
const _target = target
|
||||
return function onceHandler () {
|
||||
const res = fn.apply(null, arguments)
|
||||
if (res !== null) {
|
||||
_target.$off(event, onceHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function updateComponentListeners (
|
||||
vm: Component,
|
||||
listeners: Object,
|
||||
oldListeners: ?Object
|
||||
) {
|
||||
target = vm
|
||||
updateListeners(listeners, oldListeners || {}, add, remove, createOnceHandler, vm)
|
||||
target = undefined
|
||||
}
|
||||
|
||||
export function eventsMixin (Vue: Class<Component>) {
|
||||
const hookRE = /^hook:/
|
||||
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
|
||||
const vm: Component = this
|
||||
if (Array.isArray(event)) {
|
||||
for (let i = 0, l = event.length; i < l; i++) {
|
||||
vm.$on(event[i], fn)
|
||||
}
|
||||
} else {
|
||||
(vm._events[event] || (vm._events[event] = [])).push(fn)
|
||||
// optimize hook:event cost by using a boolean flag marked at registration
|
||||
// instead of a hash lookup
|
||||
if (hookRE.test(event)) {
|
||||
vm._hasHookEvent = true
|
||||
}
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
Vue.prototype.$once = function (event: string, fn: Function): Component {
|
||||
const vm: Component = this
|
||||
function on () {
|
||||
vm.$off(event, on)
|
||||
fn.apply(vm, arguments)
|
||||
}
|
||||
on.fn = fn
|
||||
vm.$on(event, on)
|
||||
return vm
|
||||
}
|
||||
|
||||
Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {
|
||||
const vm: Component = this
|
||||
// all
|
||||
if (!arguments.length) {
|
||||
vm._events = Object.create(null)
|
||||
return vm
|
||||
}
|
||||
// array of events
|
||||
if (Array.isArray(event)) {
|
||||
for (let i = 0, l = event.length; i < l; i++) {
|
||||
vm.$off(event[i], fn)
|
||||
}
|
||||
return vm
|
||||
}
|
||||
// specific event
|
||||
const cbs = vm._events[event]
|
||||
if (!cbs) {
|
||||
return vm
|
||||
}
|
||||
if (!fn) {
|
||||
vm._events[event] = null
|
||||
return vm
|
||||
}
|
||||
// specific handler
|
||||
let cb
|
||||
let i = cbs.length
|
||||
while (i--) {
|
||||
cb = cbs[i]
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
cbs.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
Vue.prototype.$emit = function (event: string): Component {
|
||||
const vm: Component = this
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const lowerCaseEvent = event.toLowerCase()
|
||||
if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
|
||||
tip(
|
||||
`Event "${lowerCaseEvent}" is emitted in component ` +
|
||||
`${formatComponentName(vm)} but the handler is registered for "${event}". ` +
|
||||
`Note that HTML attributes are case-insensitive and you cannot use ` +
|
||||
`v-on to listen to camelCase events when using in-DOM templates. ` +
|
||||
`You should probably use "${hyphenate(event)}" instead of "${event}".`
|
||||
)
|
||||
}
|
||||
}
|
||||
let cbs = vm._events[event]
|
||||
if (cbs) {
|
||||
cbs = cbs.length > 1 ? toArray(cbs) : cbs
|
||||
const args = toArray(arguments, 1)
|
||||
const info = `event handler for "${event}"`
|
||||
for (let i = 0, l = cbs.length; i < l; i++) {
|
||||
invokeWithErrorHandling(cbs[i], vm, args, vm, info)
|
||||
}
|
||||
}
|
||||
return vm
|
||||
}
|
||||
}
|
23
express-server/node_modules/vue/src/core/instance/index.js
generated
vendored
Normal file
23
express-server/node_modules/vue/src/core/instance/index.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { initMixin } from './init'
|
||||
import { stateMixin } from './state'
|
||||
import { renderMixin } from './render'
|
||||
import { eventsMixin } from './events'
|
||||
import { lifecycleMixin } from './lifecycle'
|
||||
import { warn } from '../util/index'
|
||||
|
||||
function Vue (options) {
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
!(this instanceof Vue)
|
||||
) {
|
||||
warn('Vue is a constructor and should be called with the `new` keyword')
|
||||
}
|
||||
this._init(options)
|
||||
}
|
||||
|
||||
initMixin(Vue)
|
||||
stateMixin(Vue)
|
||||
eventsMixin(Vue)
|
||||
lifecycleMixin(Vue)
|
||||
renderMixin(Vue)
|
||||
|
||||
export default Vue
|
128
express-server/node_modules/vue/src/core/instance/init.js
generated
vendored
Normal file
128
express-server/node_modules/vue/src/core/instance/init.js
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import { initProxy } from './proxy'
|
||||
import { initState } from './state'
|
||||
import { initRender } from './render'
|
||||
import { initEvents } from './events'
|
||||
import { mark, measure } from '../util/perf'
|
||||
import { initLifecycle, callHook } from './lifecycle'
|
||||
import { initProvide, initInjections } from './inject'
|
||||
import { extend, mergeOptions, formatComponentName } from '../util/index'
|
||||
|
||||
let uid = 0
|
||||
|
||||
export function initMixin (Vue: Class<Component>) {
|
||||
Vue.prototype._init = function (options?: Object) {
|
||||
const vm: Component = this
|
||||
// a uid
|
||||
vm._uid = uid++
|
||||
|
||||
let startTag, endTag
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
|
||||
startTag = `vue-perf-start:${vm._uid}`
|
||||
endTag = `vue-perf-end:${vm._uid}`
|
||||
mark(startTag)
|
||||
}
|
||||
|
||||
// a flag to avoid this being observed
|
||||
vm._isVue = true
|
||||
// merge options
|
||||
if (options && options._isComponent) {
|
||||
// optimize internal component instantiation
|
||||
// since dynamic options merging is pretty slow, and none of the
|
||||
// internal component options needs special treatment.
|
||||
initInternalComponent(vm, options)
|
||||
} else {
|
||||
vm.$options = mergeOptions(
|
||||
resolveConstructorOptions(vm.constructor),
|
||||
options || {},
|
||||
vm
|
||||
)
|
||||
}
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
initProxy(vm)
|
||||
} else {
|
||||
vm._renderProxy = vm
|
||||
}
|
||||
// expose real self
|
||||
vm._self = vm
|
||||
initLifecycle(vm)
|
||||
initEvents(vm)
|
||||
initRender(vm)
|
||||
callHook(vm, 'beforeCreate')
|
||||
initInjections(vm) // resolve injections before data/props
|
||||
initState(vm)
|
||||
initProvide(vm) // resolve provide after data/props
|
||||
callHook(vm, 'created')
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
|
||||
vm._name = formatComponentName(vm, false)
|
||||
mark(endTag)
|
||||
measure(`vue ${vm._name} init`, startTag, endTag)
|
||||
}
|
||||
|
||||
if (vm.$options.el) {
|
||||
vm.$mount(vm.$options.el)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function initInternalComponent (vm: Component, options: InternalComponentOptions) {
|
||||
const opts = vm.$options = Object.create(vm.constructor.options)
|
||||
// doing this because it's faster than dynamic enumeration.
|
||||
const parentVnode = options._parentVnode
|
||||
opts.parent = options.parent
|
||||
opts._parentVnode = parentVnode
|
||||
|
||||
const vnodeComponentOptions = parentVnode.componentOptions
|
||||
opts.propsData = vnodeComponentOptions.propsData
|
||||
opts._parentListeners = vnodeComponentOptions.listeners
|
||||
opts._renderChildren = vnodeComponentOptions.children
|
||||
opts._componentTag = vnodeComponentOptions.tag
|
||||
|
||||
if (options.render) {
|
||||
opts.render = options.render
|
||||
opts.staticRenderFns = options.staticRenderFns
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveConstructorOptions (Ctor: Class<Component>) {
|
||||
let options = Ctor.options
|
||||
if (Ctor.super) {
|
||||
const superOptions = resolveConstructorOptions(Ctor.super)
|
||||
const cachedSuperOptions = Ctor.superOptions
|
||||
if (superOptions !== cachedSuperOptions) {
|
||||
// super option changed,
|
||||
// need to resolve new options.
|
||||
Ctor.superOptions = superOptions
|
||||
// check if there are any late-modified/attached options (#4976)
|
||||
const modifiedOptions = resolveModifiedOptions(Ctor)
|
||||
// update base extend options
|
||||
if (modifiedOptions) {
|
||||
extend(Ctor.extendOptions, modifiedOptions)
|
||||
}
|
||||
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
|
||||
if (options.name) {
|
||||
options.components[options.name] = Ctor
|
||||
}
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
function resolveModifiedOptions (Ctor: Class<Component>): ?Object {
|
||||
let modified
|
||||
const latest = Ctor.options
|
||||
const sealed = Ctor.sealedOptions
|
||||
for (const key in latest) {
|
||||
if (latest[key] !== sealed[key]) {
|
||||
if (!modified) modified = {}
|
||||
modified[key] = latest[key]
|
||||
}
|
||||
}
|
||||
return modified
|
||||
}
|
73
express-server/node_modules/vue/src/core/instance/inject.js
generated
vendored
Normal file
73
express-server/node_modules/vue/src/core/instance/inject.js
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/* @flow */
|
||||
|
||||
import { hasOwn } from 'shared/util'
|
||||
import { warn, hasSymbol } from '../util/index'
|
||||
import { defineReactive, toggleObserving } from '../observer/index'
|
||||
|
||||
export function initProvide (vm: Component) {
|
||||
const provide = vm.$options.provide
|
||||
if (provide) {
|
||||
vm._provided = typeof provide === 'function'
|
||||
? provide.call(vm)
|
||||
: provide
|
||||
}
|
||||
}
|
||||
|
||||
export function initInjections (vm: Component) {
|
||||
const result = resolveInject(vm.$options.inject, vm)
|
||||
if (result) {
|
||||
toggleObserving(false)
|
||||
Object.keys(result).forEach(key => {
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
defineReactive(vm, key, result[key], () => {
|
||||
warn(
|
||||
`Avoid mutating an injected value directly since the changes will be ` +
|
||||
`overwritten whenever the provided component re-renders. ` +
|
||||
`injection being mutated: "${key}"`,
|
||||
vm
|
||||
)
|
||||
})
|
||||
} else {
|
||||
defineReactive(vm, key, result[key])
|
||||
}
|
||||
})
|
||||
toggleObserving(true)
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveInject (inject: any, vm: Component): ?Object {
|
||||
if (inject) {
|
||||
// inject is :any because flow is not smart enough to figure out cached
|
||||
const result = Object.create(null)
|
||||
const keys = hasSymbol
|
||||
? Reflect.ownKeys(inject)
|
||||
: Object.keys(inject)
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i]
|
||||
// #6574 in case the inject object is observed...
|
||||
if (key === '__ob__') continue
|
||||
const provideKey = inject[key].from
|
||||
let source = vm
|
||||
while (source) {
|
||||
if (source._provided && hasOwn(source._provided, provideKey)) {
|
||||
result[key] = source._provided[provideKey]
|
||||
break
|
||||
}
|
||||
source = source.$parent
|
||||
}
|
||||
if (!source) {
|
||||
if ('default' in inject[key]) {
|
||||
const provideDefault = inject[key].default
|
||||
result[key] = typeof provideDefault === 'function'
|
||||
? provideDefault.call(vm)
|
||||
: provideDefault
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Injection "${key}" not found`, vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
350
express-server/node_modules/vue/src/core/instance/lifecycle.js
generated
vendored
Normal file
350
express-server/node_modules/vue/src/core/instance/lifecycle.js
generated
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import Watcher from '../observer/watcher'
|
||||
import { mark, measure } from '../util/perf'
|
||||
import { createEmptyVNode } from '../vdom/vnode'
|
||||
import { updateComponentListeners } from './events'
|
||||
import { resolveSlots } from './render-helpers/resolve-slots'
|
||||
import { toggleObserving } from '../observer/index'
|
||||
import { pushTarget, popTarget } from '../observer/dep'
|
||||
|
||||
import {
|
||||
warn,
|
||||
noop,
|
||||
remove,
|
||||
emptyObject,
|
||||
validateProp,
|
||||
invokeWithErrorHandling
|
||||
} from '../util/index'
|
||||
|
||||
export let activeInstance: any = null
|
||||
export let isUpdatingChildComponent: boolean = false
|
||||
|
||||
export function setActiveInstance(vm: Component) {
|
||||
const prevActiveInstance = activeInstance
|
||||
activeInstance = vm
|
||||
return () => {
|
||||
activeInstance = prevActiveInstance
|
||||
}
|
||||
}
|
||||
|
||||
export function initLifecycle (vm: Component) {
|
||||
const options = vm.$options
|
||||
|
||||
// locate first non-abstract parent
|
||||
let parent = options.parent
|
||||
if (parent && !options.abstract) {
|
||||
while (parent.$options.abstract && parent.$parent) {
|
||||
parent = parent.$parent
|
||||
}
|
||||
parent.$children.push(vm)
|
||||
}
|
||||
|
||||
vm.$parent = parent
|
||||
vm.$root = parent ? parent.$root : vm
|
||||
|
||||
vm.$children = []
|
||||
vm.$refs = {}
|
||||
|
||||
vm._watcher = null
|
||||
vm._inactive = null
|
||||
vm._directInactive = false
|
||||
vm._isMounted = false
|
||||
vm._isDestroyed = false
|
||||
vm._isBeingDestroyed = false
|
||||
}
|
||||
|
||||
export function lifecycleMixin (Vue: Class<Component>) {
|
||||
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
|
||||
const vm: Component = this
|
||||
const prevEl = vm.$el
|
||||
const prevVnode = vm._vnode
|
||||
const restoreActiveInstance = setActiveInstance(vm)
|
||||
vm._vnode = vnode
|
||||
// Vue.prototype.__patch__ is injected in entry points
|
||||
// based on the rendering backend used.
|
||||
if (!prevVnode) {
|
||||
// initial render
|
||||
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
|
||||
} else {
|
||||
// updates
|
||||
vm.$el = vm.__patch__(prevVnode, vnode)
|
||||
}
|
||||
restoreActiveInstance()
|
||||
// update __vue__ reference
|
||||
if (prevEl) {
|
||||
prevEl.__vue__ = null
|
||||
}
|
||||
if (vm.$el) {
|
||||
vm.$el.__vue__ = vm
|
||||
}
|
||||
// if parent is an HOC, update its $el as well
|
||||
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
|
||||
vm.$parent.$el = vm.$el
|
||||
}
|
||||
// updated hook is called by the scheduler to ensure that children are
|
||||
// updated in a parent's updated hook.
|
||||
}
|
||||
|
||||
Vue.prototype.$forceUpdate = function () {
|
||||
const vm: Component = this
|
||||
if (vm._watcher) {
|
||||
vm._watcher.update()
|
||||
}
|
||||
}
|
||||
|
||||
Vue.prototype.$destroy = function () {
|
||||
const vm: Component = this
|
||||
if (vm._isBeingDestroyed) {
|
||||
return
|
||||
}
|
||||
callHook(vm, 'beforeDestroy')
|
||||
vm._isBeingDestroyed = true
|
||||
// remove self from parent
|
||||
const parent = vm.$parent
|
||||
if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
|
||||
remove(parent.$children, vm)
|
||||
}
|
||||
// teardown watchers
|
||||
if (vm._watcher) {
|
||||
vm._watcher.teardown()
|
||||
}
|
||||
let i = vm._watchers.length
|
||||
while (i--) {
|
||||
vm._watchers[i].teardown()
|
||||
}
|
||||
// remove reference from data ob
|
||||
// frozen object may not have observer.
|
||||
if (vm._data.__ob__) {
|
||||
vm._data.__ob__.vmCount--
|
||||
}
|
||||
// call the last hook...
|
||||
vm._isDestroyed = true
|
||||
// invoke destroy hooks on current rendered tree
|
||||
vm.__patch__(vm._vnode, null)
|
||||
// fire destroyed hook
|
||||
callHook(vm, 'destroyed')
|
||||
// turn off all instance listeners.
|
||||
vm.$off()
|
||||
// remove __vue__ reference
|
||||
if (vm.$el) {
|
||||
vm.$el.__vue__ = null
|
||||
}
|
||||
// release circular reference (#6759)
|
||||
if (vm.$vnode) {
|
||||
vm.$vnode.parent = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function mountComponent (
|
||||
vm: Component,
|
||||
el: ?Element,
|
||||
hydrating?: boolean
|
||||
): Component {
|
||||
vm.$el = el
|
||||
if (!vm.$options.render) {
|
||||
vm.$options.render = createEmptyVNode
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
/* istanbul ignore if */
|
||||
if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
|
||||
vm.$options.el || el) {
|
||||
warn(
|
||||
'You are using the runtime-only build of Vue where the template ' +
|
||||
'compiler is not available. Either pre-compile the templates into ' +
|
||||
'render functions, or use the compiler-included build.',
|
||||
vm
|
||||
)
|
||||
} else {
|
||||
warn(
|
||||
'Failed to mount component: template or render function not defined.',
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
callHook(vm, 'beforeMount')
|
||||
|
||||
let updateComponent
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
|
||||
updateComponent = () => {
|
||||
const name = vm._name
|
||||
const id = vm._uid
|
||||
const startTag = `vue-perf-start:${id}`
|
||||
const endTag = `vue-perf-end:${id}`
|
||||
|
||||
mark(startTag)
|
||||
const vnode = vm._render()
|
||||
mark(endTag)
|
||||
measure(`vue ${name} render`, startTag, endTag)
|
||||
|
||||
mark(startTag)
|
||||
vm._update(vnode, hydrating)
|
||||
mark(endTag)
|
||||
measure(`vue ${name} patch`, startTag, endTag)
|
||||
}
|
||||
} else {
|
||||
updateComponent = () => {
|
||||
vm._update(vm._render(), hydrating)
|
||||
}
|
||||
}
|
||||
|
||||
// we set this to vm._watcher inside the watcher's constructor
|
||||
// since the watcher's initial patch may call $forceUpdate (e.g. inside child
|
||||
// component's mounted hook), which relies on vm._watcher being already defined
|
||||
new Watcher(vm, updateComponent, noop, {
|
||||
before () {
|
||||
if (vm._isMounted && !vm._isDestroyed) {
|
||||
callHook(vm, 'beforeUpdate')
|
||||
}
|
||||
}
|
||||
}, true /* isRenderWatcher */)
|
||||
hydrating = false
|
||||
|
||||
// manually mounted instance, call mounted on self
|
||||
// mounted is called for render-created child components in its inserted hook
|
||||
if (vm.$vnode == null) {
|
||||
vm._isMounted = true
|
||||
callHook(vm, 'mounted')
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
export function updateChildComponent (
|
||||
vm: Component,
|
||||
propsData: ?Object,
|
||||
listeners: ?Object,
|
||||
parentVnode: MountedComponentVNode,
|
||||
renderChildren: ?Array<VNode>
|
||||
) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
isUpdatingChildComponent = true
|
||||
}
|
||||
|
||||
// determine whether component has slot children
|
||||
// we need to do this before overwriting $options._renderChildren.
|
||||
|
||||
// check if there are dynamic scopedSlots (hand-written or compiled but with
|
||||
// dynamic slot names). Static scoped slots compiled from template has the
|
||||
// "$stable" marker.
|
||||
const newScopedSlots = parentVnode.data.scopedSlots
|
||||
const oldScopedSlots = vm.$scopedSlots
|
||||
const hasDynamicScopedSlot = !!(
|
||||
(newScopedSlots && !newScopedSlots.$stable) ||
|
||||
(oldScopedSlots !== emptyObject && !oldScopedSlots.$stable) ||
|
||||
(newScopedSlots && vm.$scopedSlots.$key !== newScopedSlots.$key)
|
||||
)
|
||||
|
||||
// Any static slot children from the parent may have changed during parent's
|
||||
// update. Dynamic scoped slots may also have changed. In such cases, a forced
|
||||
// update is necessary to ensure correctness.
|
||||
const needsForceUpdate = !!(
|
||||
renderChildren || // has new static slots
|
||||
vm.$options._renderChildren || // has old static slots
|
||||
hasDynamicScopedSlot
|
||||
)
|
||||
|
||||
vm.$options._parentVnode = parentVnode
|
||||
vm.$vnode = parentVnode // update vm's placeholder node without re-render
|
||||
|
||||
if (vm._vnode) { // update child tree's parent
|
||||
vm._vnode.parent = parentVnode
|
||||
}
|
||||
vm.$options._renderChildren = renderChildren
|
||||
|
||||
// update $attrs and $listeners hash
|
||||
// these are also reactive so they may trigger child update if the child
|
||||
// used them during render
|
||||
vm.$attrs = parentVnode.data.attrs || emptyObject
|
||||
vm.$listeners = listeners || emptyObject
|
||||
|
||||
// update props
|
||||
if (propsData && vm.$options.props) {
|
||||
toggleObserving(false)
|
||||
const props = vm._props
|
||||
const propKeys = vm.$options._propKeys || []
|
||||
for (let i = 0; i < propKeys.length; i++) {
|
||||
const key = propKeys[i]
|
||||
const propOptions: any = vm.$options.props // wtf flow?
|
||||
props[key] = validateProp(key, propOptions, propsData, vm)
|
||||
}
|
||||
toggleObserving(true)
|
||||
// keep a copy of raw propsData
|
||||
vm.$options.propsData = propsData
|
||||
}
|
||||
|
||||
// update listeners
|
||||
listeners = listeners || emptyObject
|
||||
const oldListeners = vm.$options._parentListeners
|
||||
vm.$options._parentListeners = listeners
|
||||
updateComponentListeners(vm, listeners, oldListeners)
|
||||
|
||||
// resolve slots + force update if has children
|
||||
if (needsForceUpdate) {
|
||||
vm.$slots = resolveSlots(renderChildren, parentVnode.context)
|
||||
vm.$forceUpdate()
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
isUpdatingChildComponent = false
|
||||
}
|
||||
}
|
||||
|
||||
function isInInactiveTree (vm) {
|
||||
while (vm && (vm = vm.$parent)) {
|
||||
if (vm._inactive) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export function activateChildComponent (vm: Component, direct?: boolean) {
|
||||
if (direct) {
|
||||
vm._directInactive = false
|
||||
if (isInInactiveTree(vm)) {
|
||||
return
|
||||
}
|
||||
} else if (vm._directInactive) {
|
||||
return
|
||||
}
|
||||
if (vm._inactive || vm._inactive === null) {
|
||||
vm._inactive = false
|
||||
for (let i = 0; i < vm.$children.length; i++) {
|
||||
activateChildComponent(vm.$children[i])
|
||||
}
|
||||
callHook(vm, 'activated')
|
||||
}
|
||||
}
|
||||
|
||||
export function deactivateChildComponent (vm: Component, direct?: boolean) {
|
||||
if (direct) {
|
||||
vm._directInactive = true
|
||||
if (isInInactiveTree(vm)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!vm._inactive) {
|
||||
vm._inactive = true
|
||||
for (let i = 0; i < vm.$children.length; i++) {
|
||||
deactivateChildComponent(vm.$children[i])
|
||||
}
|
||||
callHook(vm, 'deactivated')
|
||||
}
|
||||
}
|
||||
|
||||
export function callHook (vm: Component, hook: string) {
|
||||
// #7573 disable dep collection when invoking lifecycle hooks
|
||||
pushTarget()
|
||||
const handlers = vm.$options[hook]
|
||||
const info = `${hook} hook`
|
||||
if (handlers) {
|
||||
for (let i = 0, j = handlers.length; i < j; i++) {
|
||||
invokeWithErrorHandling(handlers[i], vm, null, vm, info)
|
||||
}
|
||||
}
|
||||
if (vm._hasHookEvent) {
|
||||
vm.$emit('hook:' + hook)
|
||||
}
|
||||
popTarget()
|
||||
}
|
92
express-server/node_modules/vue/src/core/instance/proxy.js
generated
vendored
Normal file
92
express-server/node_modules/vue/src/core/instance/proxy.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/* not type checking this file because flow doesn't play well with Proxy */
|
||||
|
||||
import config from 'core/config'
|
||||
import { warn, makeMap, isNative } from '../util/index'
|
||||
|
||||
let initProxy
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const allowedGlobals = makeMap(
|
||||
'Infinity,undefined,NaN,isFinite,isNaN,' +
|
||||
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
|
||||
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
|
||||
'require' // for Webpack/Browserify
|
||||
)
|
||||
|
||||
const warnNonPresent = (target, key) => {
|
||||
warn(
|
||||
`Property or method "${key}" is not defined on the instance but ` +
|
||||
'referenced during render. Make sure that this property is reactive, ' +
|
||||
'either in the data option, or for class-based components, by ' +
|
||||
'initializing the property. ' +
|
||||
'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
|
||||
target
|
||||
)
|
||||
}
|
||||
|
||||
const warnReservedPrefix = (target, key) => {
|
||||
warn(
|
||||
`Property "${key}" must be accessed with "$data.${key}" because ` +
|
||||
'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
|
||||
'prevent conflicts with Vue internals' +
|
||||
'See: https://vuejs.org/v2/api/#data',
|
||||
target
|
||||
)
|
||||
}
|
||||
|
||||
const hasProxy =
|
||||
typeof Proxy !== 'undefined' && isNative(Proxy)
|
||||
|
||||
if (hasProxy) {
|
||||
const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
|
||||
config.keyCodes = new Proxy(config.keyCodes, {
|
||||
set (target, key, value) {
|
||||
if (isBuiltInModifier(key)) {
|
||||
warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
|
||||
return false
|
||||
} else {
|
||||
target[key] = value
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const hasHandler = {
|
||||
has (target, key) {
|
||||
const has = key in target
|
||||
const isAllowed = allowedGlobals(key) ||
|
||||
(typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
|
||||
if (!has && !isAllowed) {
|
||||
if (key in target.$data) warnReservedPrefix(target, key)
|
||||
else warnNonPresent(target, key)
|
||||
}
|
||||
return has || !isAllowed
|
||||
}
|
||||
}
|
||||
|
||||
const getHandler = {
|
||||
get (target, key) {
|
||||
if (typeof key === 'string' && !(key in target)) {
|
||||
if (key in target.$data) warnReservedPrefix(target, key)
|
||||
else warnNonPresent(target, key)
|
||||
}
|
||||
return target[key]
|
||||
}
|
||||
}
|
||||
|
||||
initProxy = function initProxy (vm) {
|
||||
if (hasProxy) {
|
||||
// determine which proxy handler to use
|
||||
const options = vm.$options
|
||||
const handlers = options.render && options.render._withStripped
|
||||
? getHandler
|
||||
: hasHandler
|
||||
vm._renderProxy = new Proxy(vm, handlers)
|
||||
} else {
|
||||
vm._renderProxy = vm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { initProxy }
|
35
express-server/node_modules/vue/src/core/instance/render-helpers/bind-dynamic-keys.js
generated
vendored
Normal file
35
express-server/node_modules/vue/src/core/instance/render-helpers/bind-dynamic-keys.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/* @flow */
|
||||
|
||||
// helper to process dynamic keys for dynamic arguments in v-bind and v-on.
|
||||
// For example, the following template:
|
||||
//
|
||||
// <div id="foo" :[key]="value">
|
||||
//
|
||||
// compiles to the following:
|
||||
//
|
||||
// _c('div', { attrs: bindDynamicKeys({ "id": "app" }, [key, value]) })
|
||||
|
||||
import { warn } from 'core/util/debug'
|
||||
|
||||
export function bindDynamicKeys (baseObj: Object, values: Array<any>): Object {
|
||||
for (let i = 0; i < values.length; i += 2) {
|
||||
const key = values[i]
|
||||
if (typeof key === 'string' && key) {
|
||||
baseObj[values[i]] = values[i + 1]
|
||||
} else if (process.env.NODE_ENV !== 'production' && key !== '' && key !== null) {
|
||||
// null is a speical value for explicitly removing a binding
|
||||
warn(
|
||||
`Invalid value for dynamic directive argument (expected string or null): ${key}`,
|
||||
this
|
||||
)
|
||||
}
|
||||
}
|
||||
return baseObj
|
||||
}
|
||||
|
||||
// helper to dynamically append modifier runtime markers to event names.
|
||||
// ensure only append when value is already string, otherwise it will be cast
|
||||
// to string and cause the type check to miss.
|
||||
export function prependModifier (value: any, symbol: string): any {
|
||||
return typeof value === 'string' ? symbol + value : value
|
||||
}
|
22
express-server/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js
generated
vendored
Normal file
22
express-server/node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/* @flow */
|
||||
|
||||
import { warn, extend, isPlainObject } from 'core/util/index'
|
||||
|
||||
export function bindObjectListeners (data: any, value: any): VNodeData {
|
||||
if (value) {
|
||||
if (!isPlainObject(value)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'v-on without argument expects an Object value',
|
||||
this
|
||||
)
|
||||
} else {
|
||||
const on = data.on = data.on ? extend({}, data.on) : {}
|
||||
for (const key in value) {
|
||||
const existing = on[key]
|
||||
const ours = value[key]
|
||||
on[key] = existing ? [].concat(existing, ours) : ours
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
64
express-server/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js
generated
vendored
Normal file
64
express-server/node_modules/vue/src/core/instance/render-helpers/bind-object-props.js
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/* @flow */
|
||||
|
||||
import config from 'core/config'
|
||||
|
||||
import {
|
||||
warn,
|
||||
isObject,
|
||||
toObject,
|
||||
isReservedAttribute,
|
||||
camelize,
|
||||
hyphenate
|
||||
} from 'core/util/index'
|
||||
|
||||
/**
|
||||
* Runtime helper for merging v-bind="object" into a VNode's data.
|
||||
*/
|
||||
export function bindObjectProps (
|
||||
data: any,
|
||||
tag: string,
|
||||
value: any,
|
||||
asProp: boolean,
|
||||
isSync?: boolean
|
||||
): VNodeData {
|
||||
if (value) {
|
||||
if (!isObject(value)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'v-bind without argument expects an Object or Array value',
|
||||
this
|
||||
)
|
||||
} else {
|
||||
if (Array.isArray(value)) {
|
||||
value = toObject(value)
|
||||
}
|
||||
let hash
|
||||
for (const key in value) {
|
||||
if (
|
||||
key === 'class' ||
|
||||
key === 'style' ||
|
||||
isReservedAttribute(key)
|
||||
) {
|
||||
hash = data
|
||||
} else {
|
||||
const type = data.attrs && data.attrs.type
|
||||
hash = asProp || config.mustUseProp(tag, type, key)
|
||||
? data.domProps || (data.domProps = {})
|
||||
: data.attrs || (data.attrs = {})
|
||||
}
|
||||
const camelizedKey = camelize(key)
|
||||
const hyphenatedKey = hyphenate(key)
|
||||
if (!(camelizedKey in hash) && !(hyphenatedKey in hash)) {
|
||||
hash[key] = value[key]
|
||||
|
||||
if (isSync) {
|
||||
const on = data.on || (data.on = {})
|
||||
on[`update:${key}`] = function ($event) {
|
||||
value[key] = $event
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
34
express-server/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js
generated
vendored
Normal file
34
express-server/node_modules/vue/src/core/instance/render-helpers/check-keycodes.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/* @flow */
|
||||
|
||||
import config from 'core/config'
|
||||
import { hyphenate } from 'shared/util'
|
||||
|
||||
function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean {
|
||||
if (Array.isArray(expect)) {
|
||||
return expect.indexOf(actual) === -1
|
||||
} else {
|
||||
return expect !== actual
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime helper for checking keyCodes from config.
|
||||
* exposed as Vue.prototype._k
|
||||
* passing in eventKeyName as last argument separately for backwards compat
|
||||
*/
|
||||
export function checkKeyCodes (
|
||||
eventKeyCode: number,
|
||||
key: string,
|
||||
builtInKeyCode?: number | Array<number>,
|
||||
eventKeyName?: string,
|
||||
builtInKeyName?: string | Array<string>
|
||||
): ?boolean {
|
||||
const mappedKeyCode = config.keyCodes[key] || builtInKeyCode
|
||||
if (builtInKeyName && eventKeyName && !config.keyCodes[key]) {
|
||||
return isKeyNotMatch(builtInKeyName, eventKeyName)
|
||||
} else if (mappedKeyCode) {
|
||||
return isKeyNotMatch(mappedKeyCode, eventKeyCode)
|
||||
} else if (eventKeyName) {
|
||||
return hyphenate(eventKeyName) !== key
|
||||
}
|
||||
}
|
33
express-server/node_modules/vue/src/core/instance/render-helpers/index.js
generated
vendored
Normal file
33
express-server/node_modules/vue/src/core/instance/render-helpers/index.js
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/* @flow */
|
||||
|
||||
import { toNumber, toString, looseEqual, looseIndexOf } from 'shared/util'
|
||||
import { createTextVNode, createEmptyVNode } from 'core/vdom/vnode'
|
||||
import { renderList } from './render-list'
|
||||
import { renderSlot } from './render-slot'
|
||||
import { resolveFilter } from './resolve-filter'
|
||||
import { checkKeyCodes } from './check-keycodes'
|
||||
import { bindObjectProps } from './bind-object-props'
|
||||
import { renderStatic, markOnce } from './render-static'
|
||||
import { bindObjectListeners } from './bind-object-listeners'
|
||||
import { resolveScopedSlots } from './resolve-scoped-slots'
|
||||
import { bindDynamicKeys, prependModifier } from './bind-dynamic-keys'
|
||||
|
||||
export function installRenderHelpers (target: any) {
|
||||
target._o = markOnce
|
||||
target._n = toNumber
|
||||
target._s = toString
|
||||
target._l = renderList
|
||||
target._t = renderSlot
|
||||
target._q = looseEqual
|
||||
target._i = looseIndexOf
|
||||
target._m = renderStatic
|
||||
target._f = resolveFilter
|
||||
target._k = checkKeyCodes
|
||||
target._b = bindObjectProps
|
||||
target._v = createTextVNode
|
||||
target._e = createEmptyVNode
|
||||
target._u = resolveScopedSlots
|
||||
target._g = bindObjectListeners
|
||||
target._d = bindDynamicKeys
|
||||
target._p = prependModifier
|
||||
}
|
50
express-server/node_modules/vue/src/core/instance/render-helpers/render-list.js
generated
vendored
Normal file
50
express-server/node_modules/vue/src/core/instance/render-helpers/render-list.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* @flow */
|
||||
|
||||
import { isObject, isDef, hasSymbol } from 'core/util/index'
|
||||
|
||||
/**
|
||||
* Runtime helper for rendering v-for lists.
|
||||
*/
|
||||
export function renderList (
|
||||
val: any,
|
||||
render: (
|
||||
val: any,
|
||||
keyOrIndex: string | number,
|
||||
index?: number
|
||||
) => VNode
|
||||
): ?Array<VNode> {
|
||||
let ret: ?Array<VNode>, i, l, keys, key
|
||||
if (Array.isArray(val) || typeof val === 'string') {
|
||||
ret = new Array(val.length)
|
||||
for (i = 0, l = val.length; i < l; i++) {
|
||||
ret[i] = render(val[i], i)
|
||||
}
|
||||
} else if (typeof val === 'number') {
|
||||
ret = new Array(val)
|
||||
for (i = 0; i < val; i++) {
|
||||
ret[i] = render(i + 1, i)
|
||||
}
|
||||
} else if (isObject(val)) {
|
||||
if (hasSymbol && val[Symbol.iterator]) {
|
||||
ret = []
|
||||
const iterator: Iterator<any> = val[Symbol.iterator]()
|
||||
let result = iterator.next()
|
||||
while (!result.done) {
|
||||
ret.push(render(result.value, ret.length))
|
||||
result = iterator.next()
|
||||
}
|
||||
} else {
|
||||
keys = Object.keys(val)
|
||||
ret = new Array(keys.length)
|
||||
for (i = 0, l = keys.length; i < l; i++) {
|
||||
key = keys[i]
|
||||
ret[i] = render(val[key], key, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isDef(ret)) {
|
||||
ret = []
|
||||
}
|
||||
(ret: any)._isVList = true
|
||||
return ret
|
||||
}
|
38
express-server/node_modules/vue/src/core/instance/render-helpers/render-slot.js
generated
vendored
Normal file
38
express-server/node_modules/vue/src/core/instance/render-helpers/render-slot.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/* @flow */
|
||||
|
||||
import { extend, warn, isObject } from 'core/util/index'
|
||||
|
||||
/**
|
||||
* Runtime helper for rendering <slot>
|
||||
*/
|
||||
export function renderSlot (
|
||||
name: string,
|
||||
fallback: ?Array<VNode>,
|
||||
props: ?Object,
|
||||
bindObject: ?Object
|
||||
): ?Array<VNode> {
|
||||
const scopedSlotFn = this.$scopedSlots[name]
|
||||
let nodes
|
||||
if (scopedSlotFn) { // scoped slot
|
||||
props = props || {}
|
||||
if (bindObject) {
|
||||
if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
|
||||
warn(
|
||||
'slot v-bind without argument expects an Object',
|
||||
this
|
||||
)
|
||||
}
|
||||
props = extend(extend({}, bindObject), props)
|
||||
}
|
||||
nodes = scopedSlotFn(props) || fallback
|
||||
} else {
|
||||
nodes = this.$slots[name] || fallback
|
||||
}
|
||||
|
||||
const target = props && props.slot
|
||||
if (target) {
|
||||
return this.$createElement('template', { slot: target }, nodes)
|
||||
} else {
|
||||
return nodes
|
||||
}
|
||||
}
|
60
express-server/node_modules/vue/src/core/instance/render-helpers/render-static.js
generated
vendored
Normal file
60
express-server/node_modules/vue/src/core/instance/render-helpers/render-static.js
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/* @flow */
|
||||
|
||||
/**
|
||||
* Runtime helper for rendering static trees.
|
||||
*/
|
||||
export function renderStatic (
|
||||
index: number,
|
||||
isInFor: boolean
|
||||
): VNode | Array<VNode> {
|
||||
const cached = this._staticTrees || (this._staticTrees = [])
|
||||
let tree = cached[index]
|
||||
// if has already-rendered static tree and not inside v-for,
|
||||
// we can reuse the same tree.
|
||||
if (tree && !isInFor) {
|
||||
return tree
|
||||
}
|
||||
// otherwise, render a fresh tree.
|
||||
tree = cached[index] = this.$options.staticRenderFns[index].call(
|
||||
this._renderProxy,
|
||||
null,
|
||||
this // for render fns generated for functional component templates
|
||||
)
|
||||
markStatic(tree, `__static__${index}`, false)
|
||||
return tree
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime helper for v-once.
|
||||
* Effectively it means marking the node as static with a unique key.
|
||||
*/
|
||||
export function markOnce (
|
||||
tree: VNode | Array<VNode>,
|
||||
index: number,
|
||||
key: string
|
||||
) {
|
||||
markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true)
|
||||
return tree
|
||||
}
|
||||
|
||||
function markStatic (
|
||||
tree: VNode | Array<VNode>,
|
||||
key: string,
|
||||
isOnce: boolean
|
||||
) {
|
||||
if (Array.isArray(tree)) {
|
||||
for (let i = 0; i < tree.length; i++) {
|
||||
if (tree[i] && typeof tree[i] !== 'string') {
|
||||
markStaticNode(tree[i], `${key}_${i}`, isOnce)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
markStaticNode(tree, key, isOnce)
|
||||
}
|
||||
}
|
||||
|
||||
function markStaticNode (node, key, isOnce) {
|
||||
node.isStatic = true
|
||||
node.key = key
|
||||
node.isOnce = isOnce
|
||||
}
|
10
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js
generated
vendored
Normal file
10
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-filter.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import { identity, resolveAsset } from 'core/util/index'
|
||||
|
||||
/**
|
||||
* Runtime helper for resolving filters
|
||||
*/
|
||||
export function resolveFilter (id: string): Function {
|
||||
return resolveAsset(this.$options, 'filters', id, true) || identity
|
||||
}
|
27
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-scoped-slots.js
generated
vendored
Normal file
27
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-scoped-slots.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/* @flow */
|
||||
|
||||
export function resolveScopedSlots (
|
||||
fns: ScopedSlotsData, // see flow/vnode
|
||||
res?: Object,
|
||||
// the following are added in 2.6
|
||||
hasDynamicKeys?: boolean,
|
||||
contentHashKey?: number
|
||||
): { [key: string]: Function, $stable: boolean } {
|
||||
res = res || { $stable: !hasDynamicKeys }
|
||||
for (let i = 0; i < fns.length; i++) {
|
||||
const slot = fns[i]
|
||||
if (Array.isArray(slot)) {
|
||||
resolveScopedSlots(slot, res, hasDynamicKeys)
|
||||
} else if (slot) {
|
||||
// marker for reverse proxying v-slot without scope on this.$slots
|
||||
if (slot.proxy) {
|
||||
slot.fn.proxy = true
|
||||
}
|
||||
res[slot.key] = slot.fn
|
||||
}
|
||||
}
|
||||
if (contentHashKey) {
|
||||
(res: any).$key = contentHashKey
|
||||
}
|
||||
return res
|
||||
}
|
50
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js
generated
vendored
Normal file
50
express-server/node_modules/vue/src/core/instance/render-helpers/resolve-slots.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/* @flow */
|
||||
|
||||
import type VNode from 'core/vdom/vnode'
|
||||
|
||||
/**
|
||||
* Runtime helper for resolving raw children VNodes into a slot object.
|
||||
*/
|
||||
export function resolveSlots (
|
||||
children: ?Array<VNode>,
|
||||
context: ?Component
|
||||
): { [key: string]: Array<VNode> } {
|
||||
if (!children || !children.length) {
|
||||
return {}
|
||||
}
|
||||
const slots = {}
|
||||
for (let i = 0, l = children.length; i < l; i++) {
|
||||
const child = children[i]
|
||||
const data = child.data
|
||||
// remove slot attribute if the node is resolved as a Vue slot node
|
||||
if (data && data.attrs && data.attrs.slot) {
|
||||
delete data.attrs.slot
|
||||
}
|
||||
// named slots should only be respected if the vnode was rendered in the
|
||||
// same context.
|
||||
if ((child.context === context || child.fnContext === context) &&
|
||||
data && data.slot != null
|
||||
) {
|
||||
const name = data.slot
|
||||
const slot = (slots[name] || (slots[name] = []))
|
||||
if (child.tag === 'template') {
|
||||
slot.push.apply(slot, child.children || [])
|
||||
} else {
|
||||
slot.push(child)
|
||||
}
|
||||
} else {
|
||||
(slots.default || (slots.default = [])).push(child)
|
||||
}
|
||||
}
|
||||
// ignore slots that contains only whitespace
|
||||
for (const name in slots) {
|
||||
if (slots[name].every(isWhitespace)) {
|
||||
delete slots[name]
|
||||
}
|
||||
}
|
||||
return slots
|
||||
}
|
||||
|
||||
function isWhitespace (node: VNode): boolean {
|
||||
return (node.isComment && !node.asyncFactory) || node.text === ' '
|
||||
}
|
129
express-server/node_modules/vue/src/core/instance/render.js
generated
vendored
Normal file
129
express-server/node_modules/vue/src/core/instance/render.js
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
warn,
|
||||
nextTick,
|
||||
emptyObject,
|
||||
handleError,
|
||||
defineReactive
|
||||
} from '../util/index'
|
||||
|
||||
import { createElement } from '../vdom/create-element'
|
||||
import { installRenderHelpers } from './render-helpers/index'
|
||||
import { resolveSlots } from './render-helpers/resolve-slots'
|
||||
import { normalizeScopedSlots } from '../vdom/helpers/normalize-scoped-slots'
|
||||
import VNode, { createEmptyVNode } from '../vdom/vnode'
|
||||
|
||||
import { isUpdatingChildComponent } from './lifecycle'
|
||||
|
||||
export function initRender (vm: Component) {
|
||||
vm._vnode = null // the root of the child tree
|
||||
vm._staticTrees = null // v-once cached trees
|
||||
const options = vm.$options
|
||||
const parentVnode = vm.$vnode = options._parentVnode // the placeholder node in parent tree
|
||||
const renderContext = parentVnode && parentVnode.context
|
||||
vm.$slots = resolveSlots(options._renderChildren, renderContext)
|
||||
vm.$scopedSlots = emptyObject
|
||||
// bind the createElement fn to this instance
|
||||
// so that we get proper render context inside it.
|
||||
// args order: tag, data, children, normalizationType, alwaysNormalize
|
||||
// internal version is used by render functions compiled from templates
|
||||
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
|
||||
// normalization is always applied for the public version, used in
|
||||
// user-written render functions.
|
||||
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
|
||||
|
||||
// $attrs & $listeners are exposed for easier HOC creation.
|
||||
// they need to be reactive so that HOCs using them are always updated
|
||||
const parentData = parentVnode && parentVnode.data
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
|
||||
!isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
|
||||
}, true)
|
||||
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
|
||||
!isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
|
||||
}, true)
|
||||
} else {
|
||||
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)
|
||||
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)
|
||||
}
|
||||
}
|
||||
|
||||
export let currentRenderingInstance: Component | null = null
|
||||
|
||||
// for testing only
|
||||
export function setCurrentRenderingInstance (vm: Component) {
|
||||
currentRenderingInstance = vm
|
||||
}
|
||||
|
||||
export function renderMixin (Vue: Class<Component>) {
|
||||
// install runtime convenience helpers
|
||||
installRenderHelpers(Vue.prototype)
|
||||
|
||||
Vue.prototype.$nextTick = function (fn: Function) {
|
||||
return nextTick(fn, this)
|
||||
}
|
||||
|
||||
Vue.prototype._render = function (): VNode {
|
||||
const vm: Component = this
|
||||
const { render, _parentVnode } = vm.$options
|
||||
|
||||
if (_parentVnode) {
|
||||
vm.$scopedSlots = normalizeScopedSlots(
|
||||
_parentVnode.data.scopedSlots,
|
||||
vm.$slots,
|
||||
vm.$scopedSlots
|
||||
)
|
||||
}
|
||||
|
||||
// set parent vnode. this allows render functions to have access
|
||||
// to the data on the placeholder node.
|
||||
vm.$vnode = _parentVnode
|
||||
// render self
|
||||
let vnode
|
||||
try {
|
||||
// There's no need to maintain a stack becaues all render fns are called
|
||||
// separately from one another. Nested component's render fns are called
|
||||
// when parent component is patched.
|
||||
currentRenderingInstance = vm
|
||||
vnode = render.call(vm._renderProxy, vm.$createElement)
|
||||
} catch (e) {
|
||||
handleError(e, vm, `render`)
|
||||
// return error render result,
|
||||
// or previous vnode to prevent render error causing blank component
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production' && vm.$options.renderError) {
|
||||
try {
|
||||
vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
|
||||
} catch (e) {
|
||||
handleError(e, vm, `renderError`)
|
||||
vnode = vm._vnode
|
||||
}
|
||||
} else {
|
||||
vnode = vm._vnode
|
||||
}
|
||||
} finally {
|
||||
currentRenderingInstance = null
|
||||
}
|
||||
// if the returned array contains only a single node, allow it
|
||||
if (Array.isArray(vnode) && vnode.length === 1) {
|
||||
vnode = vnode[0]
|
||||
}
|
||||
// return empty vnode in case the render function errored out
|
||||
if (!(vnode instanceof VNode)) {
|
||||
if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
|
||||
warn(
|
||||
'Multiple root nodes returned from render function. Render function ' +
|
||||
'should return a single root node.',
|
||||
vm
|
||||
)
|
||||
}
|
||||
vnode = createEmptyVNode()
|
||||
}
|
||||
// set parent
|
||||
vnode.parent = _parentVnode
|
||||
return vnode
|
||||
}
|
||||
}
|
368
express-server/node_modules/vue/src/core/instance/state.js
generated
vendored
Normal file
368
express-server/node_modules/vue/src/core/instance/state.js
generated
vendored
Normal file
@ -0,0 +1,368 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import Watcher from '../observer/watcher'
|
||||
import Dep, { pushTarget, popTarget } from '../observer/dep'
|
||||
import { isUpdatingChildComponent } from './lifecycle'
|
||||
|
||||
import {
|
||||
set,
|
||||
del,
|
||||
observe,
|
||||
defineReactive,
|
||||
toggleObserving
|
||||
} from '../observer/index'
|
||||
|
||||
import {
|
||||
warn,
|
||||
bind,
|
||||
noop,
|
||||
hasOwn,
|
||||
hyphenate,
|
||||
isReserved,
|
||||
handleError,
|
||||
nativeWatch,
|
||||
validateProp,
|
||||
isPlainObject,
|
||||
isServerRendering,
|
||||
isReservedAttribute
|
||||
} from '../util/index'
|
||||
|
||||
const sharedPropertyDefinition = {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: noop,
|
||||
set: noop
|
||||
}
|
||||
|
||||
export function proxy (target: Object, sourceKey: string, key: string) {
|
||||
sharedPropertyDefinition.get = function proxyGetter () {
|
||||
return this[sourceKey][key]
|
||||
}
|
||||
sharedPropertyDefinition.set = function proxySetter (val) {
|
||||
this[sourceKey][key] = val
|
||||
}
|
||||
Object.defineProperty(target, key, sharedPropertyDefinition)
|
||||
}
|
||||
|
||||
export function initState (vm: Component) {
|
||||
vm._watchers = []
|
||||
const opts = vm.$options
|
||||
if (opts.props) initProps(vm, opts.props)
|
||||
if (opts.methods) initMethods(vm, opts.methods)
|
||||
if (opts.data) {
|
||||
initData(vm)
|
||||
} else {
|
||||
observe(vm._data = {}, true /* asRootData */)
|
||||
}
|
||||
if (opts.computed) initComputed(vm, opts.computed)
|
||||
if (opts.watch && opts.watch !== nativeWatch) {
|
||||
initWatch(vm, opts.watch)
|
||||
}
|
||||
}
|
||||
|
||||
function initProps (vm: Component, propsOptions: Object) {
|
||||
const propsData = vm.$options.propsData || {}
|
||||
const props = vm._props = {}
|
||||
// cache prop keys so that future props updates can iterate using Array
|
||||
// instead of dynamic object key enumeration.
|
||||
const keys = vm.$options._propKeys = []
|
||||
const isRoot = !vm.$parent
|
||||
// root instance props should be converted
|
||||
if (!isRoot) {
|
||||
toggleObserving(false)
|
||||
}
|
||||
for (const key in propsOptions) {
|
||||
keys.push(key)
|
||||
const value = validateProp(key, propsOptions, propsData, vm)
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const hyphenatedKey = hyphenate(key)
|
||||
if (isReservedAttribute(hyphenatedKey) ||
|
||||
config.isReservedAttr(hyphenatedKey)) {
|
||||
warn(
|
||||
`"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
defineReactive(props, key, value, () => {
|
||||
if (!isRoot && !isUpdatingChildComponent) {
|
||||
warn(
|
||||
`Avoid mutating a prop directly since the value will be ` +
|
||||
`overwritten whenever the parent component re-renders. ` +
|
||||
`Instead, use a data or computed property based on the prop's ` +
|
||||
`value. Prop being mutated: "${key}"`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
defineReactive(props, key, value)
|
||||
}
|
||||
// static props are already proxied on the component's prototype
|
||||
// during Vue.extend(). We only need to proxy props defined at
|
||||
// instantiation here.
|
||||
if (!(key in vm)) {
|
||||
proxy(vm, `_props`, key)
|
||||
}
|
||||
}
|
||||
toggleObserving(true)
|
||||
}
|
||||
|
||||
function initData (vm: Component) {
|
||||
let data = vm.$options.data
|
||||
data = vm._data = typeof data === 'function'
|
||||
? getData(data, vm)
|
||||
: data || {}
|
||||
if (!isPlainObject(data)) {
|
||||
data = {}
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'data functions should return an object:\n' +
|
||||
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
|
||||
vm
|
||||
)
|
||||
}
|
||||
// proxy data on instance
|
||||
const keys = Object.keys(data)
|
||||
const props = vm.$options.props
|
||||
const methods = vm.$options.methods
|
||||
let i = keys.length
|
||||
while (i--) {
|
||||
const key = keys[i]
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (methods && hasOwn(methods, key)) {
|
||||
warn(
|
||||
`Method "${key}" has already been defined as a data property.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
if (props && hasOwn(props, key)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`The data property "${key}" is already declared as a prop. ` +
|
||||
`Use prop default value instead.`,
|
||||
vm
|
||||
)
|
||||
} else if (!isReserved(key)) {
|
||||
proxy(vm, `_data`, key)
|
||||
}
|
||||
}
|
||||
// observe data
|
||||
observe(data, true /* asRootData */)
|
||||
}
|
||||
|
||||
export function getData (data: Function, vm: Component): any {
|
||||
// #7573 disable dep collection when invoking data getters
|
||||
pushTarget()
|
||||
try {
|
||||
return data.call(vm, vm)
|
||||
} catch (e) {
|
||||
handleError(e, vm, `data()`)
|
||||
return {}
|
||||
} finally {
|
||||
popTarget()
|
||||
}
|
||||
}
|
||||
|
||||
const computedWatcherOptions = { lazy: true }
|
||||
|
||||
function initComputed (vm: Component, computed: Object) {
|
||||
// $flow-disable-line
|
||||
const watchers = vm._computedWatchers = Object.create(null)
|
||||
// computed properties are just getters during SSR
|
||||
const isSSR = isServerRendering()
|
||||
|
||||
for (const key in computed) {
|
||||
const userDef = computed[key]
|
||||
const getter = typeof userDef === 'function' ? userDef : userDef.get
|
||||
if (process.env.NODE_ENV !== 'production' && getter == null) {
|
||||
warn(
|
||||
`Getter is missing for computed property "${key}".`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
|
||||
if (!isSSR) {
|
||||
// create internal watcher for the computed property.
|
||||
watchers[key] = new Watcher(
|
||||
vm,
|
||||
getter || noop,
|
||||
noop,
|
||||
computedWatcherOptions
|
||||
)
|
||||
}
|
||||
|
||||
// component-defined computed properties are already defined on the
|
||||
// component prototype. We only need to define computed properties defined
|
||||
// at instantiation here.
|
||||
if (!(key in vm)) {
|
||||
defineComputed(vm, key, userDef)
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
if (key in vm.$data) {
|
||||
warn(`The computed property "${key}" is already defined in data.`, vm)
|
||||
} else if (vm.$options.props && key in vm.$options.props) {
|
||||
warn(`The computed property "${key}" is already defined as a prop.`, vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function defineComputed (
|
||||
target: any,
|
||||
key: string,
|
||||
userDef: Object | Function
|
||||
) {
|
||||
const shouldCache = !isServerRendering()
|
||||
if (typeof userDef === 'function') {
|
||||
sharedPropertyDefinition.get = shouldCache
|
||||
? createComputedGetter(key)
|
||||
: createGetterInvoker(userDef)
|
||||
sharedPropertyDefinition.set = noop
|
||||
} else {
|
||||
sharedPropertyDefinition.get = userDef.get
|
||||
? shouldCache && userDef.cache !== false
|
||||
? createComputedGetter(key)
|
||||
: createGetterInvoker(userDef.get)
|
||||
: noop
|
||||
sharedPropertyDefinition.set = userDef.set || noop
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
sharedPropertyDefinition.set === noop) {
|
||||
sharedPropertyDefinition.set = function () {
|
||||
warn(
|
||||
`Computed property "${key}" was assigned to but it has no setter.`,
|
||||
this
|
||||
)
|
||||
}
|
||||
}
|
||||
Object.defineProperty(target, key, sharedPropertyDefinition)
|
||||
}
|
||||
|
||||
function createComputedGetter (key) {
|
||||
return function computedGetter () {
|
||||
const watcher = this._computedWatchers && this._computedWatchers[key]
|
||||
if (watcher) {
|
||||
if (watcher.dirty) {
|
||||
watcher.evaluate()
|
||||
}
|
||||
if (Dep.target) {
|
||||
watcher.depend()
|
||||
}
|
||||
return watcher.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createGetterInvoker(fn) {
|
||||
return function computedGetter () {
|
||||
return fn.call(this, this)
|
||||
}
|
||||
}
|
||||
|
||||
function initMethods (vm: Component, methods: Object) {
|
||||
const props = vm.$options.props
|
||||
for (const key in methods) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof methods[key] !== 'function') {
|
||||
warn(
|
||||
`Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +
|
||||
`Did you reference the function correctly?`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
if (props && hasOwn(props, key)) {
|
||||
warn(
|
||||
`Method "${key}" has already been defined as a prop.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
if ((key in vm) && isReserved(key)) {
|
||||
warn(
|
||||
`Method "${key}" conflicts with an existing Vue instance method. ` +
|
||||
`Avoid defining component methods that start with _ or $.`
|
||||
)
|
||||
}
|
||||
}
|
||||
vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
|
||||
}
|
||||
}
|
||||
|
||||
function initWatch (vm: Component, watch: Object) {
|
||||
for (const key in watch) {
|
||||
const handler = watch[key]
|
||||
if (Array.isArray(handler)) {
|
||||
for (let i = 0; i < handler.length; i++) {
|
||||
createWatcher(vm, key, handler[i])
|
||||
}
|
||||
} else {
|
||||
createWatcher(vm, key, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createWatcher (
|
||||
vm: Component,
|
||||
expOrFn: string | Function,
|
||||
handler: any,
|
||||
options?: Object
|
||||
) {
|
||||
if (isPlainObject(handler)) {
|
||||
options = handler
|
||||
handler = handler.handler
|
||||
}
|
||||
if (typeof handler === 'string') {
|
||||
handler = vm[handler]
|
||||
}
|
||||
return vm.$watch(expOrFn, handler, options)
|
||||
}
|
||||
|
||||
export function stateMixin (Vue: Class<Component>) {
|
||||
// flow somehow has problems with directly declared definition object
|
||||
// when using Object.defineProperty, so we have to procedurally build up
|
||||
// the object here.
|
||||
const dataDef = {}
|
||||
dataDef.get = function () { return this._data }
|
||||
const propsDef = {}
|
||||
propsDef.get = function () { return this._props }
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
dataDef.set = function () {
|
||||
warn(
|
||||
'Avoid replacing instance root $data. ' +
|
||||
'Use nested data properties instead.',
|
||||
this
|
||||
)
|
||||
}
|
||||
propsDef.set = function () {
|
||||
warn(`$props is readonly.`, this)
|
||||
}
|
||||
}
|
||||
Object.defineProperty(Vue.prototype, '$data', dataDef)
|
||||
Object.defineProperty(Vue.prototype, '$props', propsDef)
|
||||
|
||||
Vue.prototype.$set = set
|
||||
Vue.prototype.$delete = del
|
||||
|
||||
Vue.prototype.$watch = function (
|
||||
expOrFn: string | Function,
|
||||
cb: any,
|
||||
options?: Object
|
||||
): Function {
|
||||
const vm: Component = this
|
||||
if (isPlainObject(cb)) {
|
||||
return createWatcher(vm, expOrFn, cb, options)
|
||||
}
|
||||
options = options || {}
|
||||
options.user = true
|
||||
const watcher = new Watcher(vm, expOrFn, cb, options)
|
||||
if (options.immediate) {
|
||||
try {
|
||||
cb.call(vm, watcher.value)
|
||||
} catch (error) {
|
||||
handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)
|
||||
}
|
||||
}
|
||||
return function unwatchFn () {
|
||||
watcher.teardown()
|
||||
}
|
||||
}
|
||||
}
|
45
express-server/node_modules/vue/src/core/observer/array.js
generated
vendored
Normal file
45
express-server/node_modules/vue/src/core/observer/array.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* not type checking this file because flow doesn't play well with
|
||||
* dynamically accessing methods on Array prototype
|
||||
*/
|
||||
|
||||
import { def } from '../util/index'
|
||||
|
||||
const arrayProto = Array.prototype
|
||||
export const arrayMethods = Object.create(arrayProto)
|
||||
|
||||
const methodsToPatch = [
|
||||
'push',
|
||||
'pop',
|
||||
'shift',
|
||||
'unshift',
|
||||
'splice',
|
||||
'sort',
|
||||
'reverse'
|
||||
]
|
||||
|
||||
/**
|
||||
* Intercept mutating methods and emit events
|
||||
*/
|
||||
methodsToPatch.forEach(function (method) {
|
||||
// cache original method
|
||||
const original = arrayProto[method]
|
||||
def(arrayMethods, method, function mutator (...args) {
|
||||
const result = original.apply(this, args)
|
||||
const ob = this.__ob__
|
||||
let inserted
|
||||
switch (method) {
|
||||
case 'push':
|
||||
case 'unshift':
|
||||
inserted = args
|
||||
break
|
||||
case 'splice':
|
||||
inserted = args.slice(2)
|
||||
break
|
||||
}
|
||||
if (inserted) ob.observeArray(inserted)
|
||||
// notify change
|
||||
ob.dep.notify()
|
||||
return result
|
||||
})
|
||||
})
|
66
express-server/node_modules/vue/src/core/observer/dep.js
generated
vendored
Normal file
66
express-server/node_modules/vue/src/core/observer/dep.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/* @flow */
|
||||
|
||||
import type Watcher from './watcher'
|
||||
import { remove } from '../util/index'
|
||||
import config from '../config'
|
||||
|
||||
let uid = 0
|
||||
|
||||
/**
|
||||
* A dep is an observable that can have multiple
|
||||
* directives subscribing to it.
|
||||
*/
|
||||
export default class Dep {
|
||||
static target: ?Watcher;
|
||||
id: number;
|
||||
subs: Array<Watcher>;
|
||||
|
||||
constructor () {
|
||||
this.id = uid++
|
||||
this.subs = []
|
||||
}
|
||||
|
||||
addSub (sub: Watcher) {
|
||||
this.subs.push(sub)
|
||||
}
|
||||
|
||||
removeSub (sub: Watcher) {
|
||||
remove(this.subs, sub)
|
||||
}
|
||||
|
||||
depend () {
|
||||
if (Dep.target) {
|
||||
Dep.target.addDep(this)
|
||||
}
|
||||
}
|
||||
|
||||
notify () {
|
||||
// stabilize the subscriber list first
|
||||
const subs = this.subs.slice()
|
||||
if (process.env.NODE_ENV !== 'production' && !config.async) {
|
||||
// subs aren't sorted in scheduler if not running async
|
||||
// we need to sort them now to make sure they fire in correct
|
||||
// order
|
||||
subs.sort((a, b) => a.id - b.id)
|
||||
}
|
||||
for (let i = 0, l = subs.length; i < l; i++) {
|
||||
subs[i].update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The current target watcher being evaluated.
|
||||
// This is globally unique because only one watcher
|
||||
// can be evaluated at a time.
|
||||
Dep.target = null
|
||||
const targetStack = []
|
||||
|
||||
export function pushTarget (target: ?Watcher) {
|
||||
targetStack.push(target)
|
||||
Dep.target = target
|
||||
}
|
||||
|
||||
export function popTarget () {
|
||||
targetStack.pop()
|
||||
Dep.target = targetStack[targetStack.length - 1]
|
||||
}
|
276
express-server/node_modules/vue/src/core/observer/index.js
generated
vendored
Normal file
276
express-server/node_modules/vue/src/core/observer/index.js
generated
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
/* @flow */
|
||||
|
||||
import Dep from './dep'
|
||||
import VNode from '../vdom/vnode'
|
||||
import { arrayMethods } from './array'
|
||||
import {
|
||||
def,
|
||||
warn,
|
||||
hasOwn,
|
||||
hasProto,
|
||||
isObject,
|
||||
isPlainObject,
|
||||
isPrimitive,
|
||||
isUndef,
|
||||
isValidArrayIndex,
|
||||
isServerRendering
|
||||
} from '../util/index'
|
||||
|
||||
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
|
||||
|
||||
/**
|
||||
* In some cases we may want to disable observation inside a component's
|
||||
* update computation.
|
||||
*/
|
||||
export let shouldObserve: boolean = true
|
||||
|
||||
export function toggleObserving (value: boolean) {
|
||||
shouldObserve = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Observer class that is attached to each observed
|
||||
* object. Once attached, the observer converts the target
|
||||
* object's property keys into getter/setters that
|
||||
* collect dependencies and dispatch updates.
|
||||
*/
|
||||
export class Observer {
|
||||
value: any;
|
||||
dep: Dep;
|
||||
vmCount: number; // number of vms that have this object as root $data
|
||||
|
||||
constructor (value: any) {
|
||||
this.value = value
|
||||
this.dep = new Dep()
|
||||
this.vmCount = 0
|
||||
def(value, '__ob__', this)
|
||||
if (Array.isArray(value)) {
|
||||
if (hasProto) {
|
||||
protoAugment(value, arrayMethods)
|
||||
} else {
|
||||
copyAugment(value, arrayMethods, arrayKeys)
|
||||
}
|
||||
this.observeArray(value)
|
||||
} else {
|
||||
this.walk(value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk through all properties and convert them into
|
||||
* getter/setters. This method should only be called when
|
||||
* value type is Object.
|
||||
*/
|
||||
walk (obj: Object) {
|
||||
const keys = Object.keys(obj)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
defineReactive(obj, keys[i])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe a list of Array items.
|
||||
*/
|
||||
observeArray (items: Array<any>) {
|
||||
for (let i = 0, l = items.length; i < l; i++) {
|
||||
observe(items[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
/**
|
||||
* Augment a target Object or Array by intercepting
|
||||
* the prototype chain using __proto__
|
||||
*/
|
||||
function protoAugment (target, src: Object) {
|
||||
/* eslint-disable no-proto */
|
||||
target.__proto__ = src
|
||||
/* eslint-enable no-proto */
|
||||
}
|
||||
|
||||
/**
|
||||
* Augment a target Object or Array by defining
|
||||
* hidden properties.
|
||||
*/
|
||||
/* istanbul ignore next */
|
||||
function copyAugment (target: Object, src: Object, keys: Array<string>) {
|
||||
for (let i = 0, l = keys.length; i < l; i++) {
|
||||
const key = keys[i]
|
||||
def(target, key, src[key])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to create an observer instance for a value,
|
||||
* returns the new observer if successfully observed,
|
||||
* or the existing observer if the value already has one.
|
||||
*/
|
||||
export function observe (value: any, asRootData: ?boolean): Observer | void {
|
||||
if (!isObject(value) || value instanceof VNode) {
|
||||
return
|
||||
}
|
||||
let ob: Observer | void
|
||||
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
|
||||
ob = value.__ob__
|
||||
} else if (
|
||||
shouldObserve &&
|
||||
!isServerRendering() &&
|
||||
(Array.isArray(value) || isPlainObject(value)) &&
|
||||
Object.isExtensible(value) &&
|
||||
!value._isVue
|
||||
) {
|
||||
ob = new Observer(value)
|
||||
}
|
||||
if (asRootData && ob) {
|
||||
ob.vmCount++
|
||||
}
|
||||
return ob
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a reactive property on an Object.
|
||||
*/
|
||||
export function defineReactive (
|
||||
obj: Object,
|
||||
key: string,
|
||||
val: any,
|
||||
customSetter?: ?Function,
|
||||
shallow?: boolean
|
||||
) {
|
||||
const dep = new Dep()
|
||||
|
||||
const property = Object.getOwnPropertyDescriptor(obj, key)
|
||||
if (property && property.configurable === false) {
|
||||
return
|
||||
}
|
||||
|
||||
// cater for pre-defined getter/setters
|
||||
const getter = property && property.get
|
||||
const setter = property && property.set
|
||||
if ((!getter || setter) && arguments.length === 2) {
|
||||
val = obj[key]
|
||||
}
|
||||
|
||||
let childOb = !shallow && observe(val)
|
||||
Object.defineProperty(obj, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function reactiveGetter () {
|
||||
const value = getter ? getter.call(obj) : val
|
||||
if (Dep.target) {
|
||||
dep.depend()
|
||||
if (childOb) {
|
||||
childOb.dep.depend()
|
||||
if (Array.isArray(value)) {
|
||||
dependArray(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return value
|
||||
},
|
||||
set: function reactiveSetter (newVal) {
|
||||
const value = getter ? getter.call(obj) : val
|
||||
/* eslint-disable no-self-compare */
|
||||
if (newVal === value || (newVal !== newVal && value !== value)) {
|
||||
return
|
||||
}
|
||||
/* eslint-enable no-self-compare */
|
||||
if (process.env.NODE_ENV !== 'production' && customSetter) {
|
||||
customSetter()
|
||||
}
|
||||
// #7981: for accessor properties without setter
|
||||
if (getter && !setter) return
|
||||
if (setter) {
|
||||
setter.call(obj, newVal)
|
||||
} else {
|
||||
val = newVal
|
||||
}
|
||||
childOb = !shallow && observe(newVal)
|
||||
dep.notify()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property on an object. Adds the new property and
|
||||
* triggers change notification if the property doesn't
|
||||
* already exist.
|
||||
*/
|
||||
export function set (target: Array<any> | Object, key: any, val: any): any {
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
(isUndef(target) || isPrimitive(target))
|
||||
) {
|
||||
warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
|
||||
}
|
||||
if (Array.isArray(target) && isValidArrayIndex(key)) {
|
||||
target.length = Math.max(target.length, key)
|
||||
target.splice(key, 1, val)
|
||||
return val
|
||||
}
|
||||
if (key in target && !(key in Object.prototype)) {
|
||||
target[key] = val
|
||||
return val
|
||||
}
|
||||
const ob = (target: any).__ob__
|
||||
if (target._isVue || (ob && ob.vmCount)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'Avoid adding reactive properties to a Vue instance or its root $data ' +
|
||||
'at runtime - declare it upfront in the data option.'
|
||||
)
|
||||
return val
|
||||
}
|
||||
if (!ob) {
|
||||
target[key] = val
|
||||
return val
|
||||
}
|
||||
defineReactive(ob.value, key, val)
|
||||
ob.dep.notify()
|
||||
return val
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a property and trigger change if necessary.
|
||||
*/
|
||||
export function del (target: Array<any> | Object, key: any) {
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
(isUndef(target) || isPrimitive(target))
|
||||
) {
|
||||
warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target: any)}`)
|
||||
}
|
||||
if (Array.isArray(target) && isValidArrayIndex(key)) {
|
||||
target.splice(key, 1)
|
||||
return
|
||||
}
|
||||
const ob = (target: any).__ob__
|
||||
if (target._isVue || (ob && ob.vmCount)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'Avoid deleting properties on a Vue instance or its root $data ' +
|
||||
'- just set it to null.'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (!hasOwn(target, key)) {
|
||||
return
|
||||
}
|
||||
delete target[key]
|
||||
if (!ob) {
|
||||
return
|
||||
}
|
||||
ob.dep.notify()
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect dependencies on array elements when the array is touched, since
|
||||
* we cannot intercept array element access like property getters.
|
||||
*/
|
||||
function dependArray (value: Array<any>) {
|
||||
for (let e, i = 0, l = value.length; i < l; i++) {
|
||||
e = value[i]
|
||||
e && e.__ob__ && e.__ob__.dep.depend()
|
||||
if (Array.isArray(e)) {
|
||||
dependArray(e)
|
||||
}
|
||||
}
|
||||
}
|
184
express-server/node_modules/vue/src/core/observer/scheduler.js
generated
vendored
Normal file
184
express-server/node_modules/vue/src/core/observer/scheduler.js
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
/* @flow */
|
||||
|
||||
import type Watcher from './watcher'
|
||||
import config from '../config'
|
||||
import { callHook, activateChildComponent } from '../instance/lifecycle'
|
||||
|
||||
import {
|
||||
warn,
|
||||
nextTick,
|
||||
devtools,
|
||||
inBrowser
|
||||
} from '../util/index'
|
||||
|
||||
export const MAX_UPDATE_COUNT = 100
|
||||
|
||||
const queue: Array<Watcher> = []
|
||||
const activatedChildren: Array<Component> = []
|
||||
let has: { [key: number]: ?true } = {}
|
||||
let circular: { [key: number]: number } = {}
|
||||
let waiting = false
|
||||
let flushing = false
|
||||
let index = 0
|
||||
|
||||
/**
|
||||
* Reset the scheduler's state.
|
||||
*/
|
||||
function resetSchedulerState () {
|
||||
index = queue.length = activatedChildren.length = 0
|
||||
has = {}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
circular = {}
|
||||
}
|
||||
waiting = flushing = false
|
||||
}
|
||||
|
||||
// Async edge case #6566 requires saving the timestamp when event listeners are
|
||||
// attached. However, calling performance.now() has a perf overhead especially
|
||||
// if the page has thousands of event listeners. Instead, we take a timestamp
|
||||
// every time the scheduler flushes and use that for all event listeners
|
||||
// attached during that flush.
|
||||
export let currentFlushTimestamp = 0
|
||||
|
||||
// Async edge case fix requires storing an event listener's attach timestamp.
|
||||
let getNow: () => number = Date.now
|
||||
|
||||
// Determine what event timestamp the browser is using. Annoyingly, the
|
||||
// timestamp can either be hi-res (relative to page load) or low-res
|
||||
// (relative to UNIX epoch), so in order to compare time we have to use the
|
||||
// same timestamp type when saving the flush timestamp.
|
||||
if (
|
||||
inBrowser &&
|
||||
window.performance &&
|
||||
typeof performance.now === 'function' &&
|
||||
document.createEvent('Event').timeStamp <= performance.now()
|
||||
) {
|
||||
// if the event timestamp is bigger than the hi-res timestamp
|
||||
// (which is evaluated AFTER) it means the event is using a lo-res timestamp,
|
||||
// and we need to use the lo-res version for event listeners as well.
|
||||
getNow = () => performance.now()
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush both queues and run the watchers.
|
||||
*/
|
||||
function flushSchedulerQueue () {
|
||||
currentFlushTimestamp = getNow()
|
||||
flushing = true
|
||||
let watcher, id
|
||||
|
||||
// Sort queue before flush.
|
||||
// This ensures that:
|
||||
// 1. Components are updated from parent to child. (because parent is always
|
||||
// created before the child)
|
||||
// 2. A component's user watchers are run before its render watcher (because
|
||||
// user watchers are created before the render watcher)
|
||||
// 3. If a component is destroyed during a parent component's watcher run,
|
||||
// its watchers can be skipped.
|
||||
queue.sort((a, b) => a.id - b.id)
|
||||
|
||||
// do not cache length because more watchers might be pushed
|
||||
// as we run existing watchers
|
||||
for (index = 0; index < queue.length; index++) {
|
||||
watcher = queue[index]
|
||||
if (watcher.before) {
|
||||
watcher.before()
|
||||
}
|
||||
id = watcher.id
|
||||
has[id] = null
|
||||
watcher.run()
|
||||
// in dev build, check and stop circular updates.
|
||||
if (process.env.NODE_ENV !== 'production' && has[id] != null) {
|
||||
circular[id] = (circular[id] || 0) + 1
|
||||
if (circular[id] > MAX_UPDATE_COUNT) {
|
||||
warn(
|
||||
'You may have an infinite update loop ' + (
|
||||
watcher.user
|
||||
? `in watcher with expression "${watcher.expression}"`
|
||||
: `in a component render function.`
|
||||
),
|
||||
watcher.vm
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keep copies of post queues before resetting state
|
||||
const activatedQueue = activatedChildren.slice()
|
||||
const updatedQueue = queue.slice()
|
||||
|
||||
resetSchedulerState()
|
||||
|
||||
// call component updated and activated hooks
|
||||
callActivatedHooks(activatedQueue)
|
||||
callUpdatedHooks(updatedQueue)
|
||||
|
||||
// devtool hook
|
||||
/* istanbul ignore if */
|
||||
if (devtools && config.devtools) {
|
||||
devtools.emit('flush')
|
||||
}
|
||||
}
|
||||
|
||||
function callUpdatedHooks (queue) {
|
||||
let i = queue.length
|
||||
while (i--) {
|
||||
const watcher = queue[i]
|
||||
const vm = watcher.vm
|
||||
if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) {
|
||||
callHook(vm, 'updated')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a kept-alive component that was activated during patch.
|
||||
* The queue will be processed after the entire tree has been patched.
|
||||
*/
|
||||
export function queueActivatedComponent (vm: Component) {
|
||||
// setting _inactive to false here so that a render function can
|
||||
// rely on checking whether it's in an inactive tree (e.g. router-view)
|
||||
vm._inactive = false
|
||||
activatedChildren.push(vm)
|
||||
}
|
||||
|
||||
function callActivatedHooks (queue) {
|
||||
for (let i = 0; i < queue.length; i++) {
|
||||
queue[i]._inactive = true
|
||||
activateChildComponent(queue[i], true /* true */)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a watcher into the watcher queue.
|
||||
* Jobs with duplicate IDs will be skipped unless it's
|
||||
* pushed when the queue is being flushed.
|
||||
*/
|
||||
export function queueWatcher (watcher: Watcher) {
|
||||
const id = watcher.id
|
||||
if (has[id] == null) {
|
||||
has[id] = true
|
||||
if (!flushing) {
|
||||
queue.push(watcher)
|
||||
} else {
|
||||
// if already flushing, splice the watcher based on its id
|
||||
// if already past its id, it will be run next immediately.
|
||||
let i = queue.length - 1
|
||||
while (i > index && queue[i].id > watcher.id) {
|
||||
i--
|
||||
}
|
||||
queue.splice(i + 1, 0, watcher)
|
||||
}
|
||||
// queue the flush
|
||||
if (!waiting) {
|
||||
waiting = true
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' && !config.async) {
|
||||
flushSchedulerQueue()
|
||||
return
|
||||
}
|
||||
nextTick(flushSchedulerQueue)
|
||||
}
|
||||
}
|
||||
}
|
40
express-server/node_modules/vue/src/core/observer/traverse.js
generated
vendored
Normal file
40
express-server/node_modules/vue/src/core/observer/traverse.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/* @flow */
|
||||
|
||||
import { _Set as Set, isObject } from '../util/index'
|
||||
import type { SimpleSet } from '../util/index'
|
||||
import VNode from '../vdom/vnode'
|
||||
|
||||
const seenObjects = new Set()
|
||||
|
||||
/**
|
||||
* Recursively traverse an object to evoke all converted
|
||||
* getters, so that every nested property inside the object
|
||||
* is collected as a "deep" dependency.
|
||||
*/
|
||||
export function traverse (val: any) {
|
||||
_traverse(val, seenObjects)
|
||||
seenObjects.clear()
|
||||
}
|
||||
|
||||
function _traverse (val: any, seen: SimpleSet) {
|
||||
let i, keys
|
||||
const isA = Array.isArray(val)
|
||||
if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
|
||||
return
|
||||
}
|
||||
if (val.__ob__) {
|
||||
const depId = val.__ob__.dep.id
|
||||
if (seen.has(depId)) {
|
||||
return
|
||||
}
|
||||
seen.add(depId)
|
||||
}
|
||||
if (isA) {
|
||||
i = val.length
|
||||
while (i--) _traverse(val[i], seen)
|
||||
} else {
|
||||
keys = Object.keys(val)
|
||||
i = keys.length
|
||||
while (i--) _traverse(val[keys[i]], seen)
|
||||
}
|
||||
}
|
243
express-server/node_modules/vue/src/core/observer/watcher.js
generated
vendored
Normal file
243
express-server/node_modules/vue/src/core/observer/watcher.js
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
warn,
|
||||
remove,
|
||||
isObject,
|
||||
parsePath,
|
||||
_Set as Set,
|
||||
handleError,
|
||||
noop
|
||||
} from '../util/index'
|
||||
|
||||
import { traverse } from './traverse'
|
||||
import { queueWatcher } from './scheduler'
|
||||
import Dep, { pushTarget, popTarget } from './dep'
|
||||
|
||||
import type { SimpleSet } from '../util/index'
|
||||
|
||||
let uid = 0
|
||||
|
||||
/**
|
||||
* A watcher parses an expression, collects dependencies,
|
||||
* and fires callback when the expression value changes.
|
||||
* This is used for both the $watch() api and directives.
|
||||
*/
|
||||
export default class Watcher {
|
||||
vm: Component;
|
||||
expression: string;
|
||||
cb: Function;
|
||||
id: number;
|
||||
deep: boolean;
|
||||
user: boolean;
|
||||
lazy: boolean;
|
||||
sync: boolean;
|
||||
dirty: boolean;
|
||||
active: boolean;
|
||||
deps: Array<Dep>;
|
||||
newDeps: Array<Dep>;
|
||||
depIds: SimpleSet;
|
||||
newDepIds: SimpleSet;
|
||||
before: ?Function;
|
||||
getter: Function;
|
||||
value: any;
|
||||
|
||||
constructor (
|
||||
vm: Component,
|
||||
expOrFn: string | Function,
|
||||
cb: Function,
|
||||
options?: ?Object,
|
||||
isRenderWatcher?: boolean
|
||||
) {
|
||||
this.vm = vm
|
||||
if (isRenderWatcher) {
|
||||
vm._watcher = this
|
||||
}
|
||||
vm._watchers.push(this)
|
||||
// options
|
||||
if (options) {
|
||||
this.deep = !!options.deep
|
||||
this.user = !!options.user
|
||||
this.lazy = !!options.lazy
|
||||
this.sync = !!options.sync
|
||||
this.before = options.before
|
||||
} else {
|
||||
this.deep = this.user = this.lazy = this.sync = false
|
||||
}
|
||||
this.cb = cb
|
||||
this.id = ++uid // uid for batching
|
||||
this.active = true
|
||||
this.dirty = this.lazy // for lazy watchers
|
||||
this.deps = []
|
||||
this.newDeps = []
|
||||
this.depIds = new Set()
|
||||
this.newDepIds = new Set()
|
||||
this.expression = process.env.NODE_ENV !== 'production'
|
||||
? expOrFn.toString()
|
||||
: ''
|
||||
// parse expression for getter
|
||||
if (typeof expOrFn === 'function') {
|
||||
this.getter = expOrFn
|
||||
} else {
|
||||
this.getter = parsePath(expOrFn)
|
||||
if (!this.getter) {
|
||||
this.getter = noop
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`Failed watching path: "${expOrFn}" ` +
|
||||
'Watcher only accepts simple dot-delimited paths. ' +
|
||||
'For full control, use a function instead.',
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
this.value = this.lazy
|
||||
? undefined
|
||||
: this.get()
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the getter, and re-collect dependencies.
|
||||
*/
|
||||
get () {
|
||||
pushTarget(this)
|
||||
let value
|
||||
const vm = this.vm
|
||||
try {
|
||||
value = this.getter.call(vm, vm)
|
||||
} catch (e) {
|
||||
if (this.user) {
|
||||
handleError(e, vm, `getter for watcher "${this.expression}"`)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
} finally {
|
||||
// "touch" every property so they are all tracked as
|
||||
// dependencies for deep watching
|
||||
if (this.deep) {
|
||||
traverse(value)
|
||||
}
|
||||
popTarget()
|
||||
this.cleanupDeps()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a dependency to this directive.
|
||||
*/
|
||||
addDep (dep: Dep) {
|
||||
const id = dep.id
|
||||
if (!this.newDepIds.has(id)) {
|
||||
this.newDepIds.add(id)
|
||||
this.newDeps.push(dep)
|
||||
if (!this.depIds.has(id)) {
|
||||
dep.addSub(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up for dependency collection.
|
||||
*/
|
||||
cleanupDeps () {
|
||||
let i = this.deps.length
|
||||
while (i--) {
|
||||
const dep = this.deps[i]
|
||||
if (!this.newDepIds.has(dep.id)) {
|
||||
dep.removeSub(this)
|
||||
}
|
||||
}
|
||||
let tmp = this.depIds
|
||||
this.depIds = this.newDepIds
|
||||
this.newDepIds = tmp
|
||||
this.newDepIds.clear()
|
||||
tmp = this.deps
|
||||
this.deps = this.newDeps
|
||||
this.newDeps = tmp
|
||||
this.newDeps.length = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscriber interface.
|
||||
* Will be called when a dependency changes.
|
||||
*/
|
||||
update () {
|
||||
/* istanbul ignore else */
|
||||
if (this.lazy) {
|
||||
this.dirty = true
|
||||
} else if (this.sync) {
|
||||
this.run()
|
||||
} else {
|
||||
queueWatcher(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scheduler job interface.
|
||||
* Will be called by the scheduler.
|
||||
*/
|
||||
run () {
|
||||
if (this.active) {
|
||||
const value = this.get()
|
||||
if (
|
||||
value !== this.value ||
|
||||
// Deep watchers and watchers on Object/Arrays should fire even
|
||||
// when the value is the same, because the value may
|
||||
// have mutated.
|
||||
isObject(value) ||
|
||||
this.deep
|
||||
) {
|
||||
// set new value
|
||||
const oldValue = this.value
|
||||
this.value = value
|
||||
if (this.user) {
|
||||
try {
|
||||
this.cb.call(this.vm, value, oldValue)
|
||||
} catch (e) {
|
||||
handleError(e, this.vm, `callback for watcher "${this.expression}"`)
|
||||
}
|
||||
} else {
|
||||
this.cb.call(this.vm, value, oldValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the value of the watcher.
|
||||
* This only gets called for lazy watchers.
|
||||
*/
|
||||
evaluate () {
|
||||
this.value = this.get()
|
||||
this.dirty = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Depend on all deps collected by this watcher.
|
||||
*/
|
||||
depend () {
|
||||
let i = this.deps.length
|
||||
while (i--) {
|
||||
this.deps[i].depend()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove self from all dependencies' subscriber list.
|
||||
*/
|
||||
teardown () {
|
||||
if (this.active) {
|
||||
// remove self from vm's watcher list
|
||||
// this is a somewhat expensive operation so we skip it
|
||||
// if the vm is being destroyed.
|
||||
if (!this.vm._isBeingDestroyed) {
|
||||
remove(this.vm._watchers, this)
|
||||
}
|
||||
let i = this.deps.length
|
||||
while (i--) {
|
||||
this.deps[i].removeSub(this)
|
||||
}
|
||||
this.active = false
|
||||
}
|
||||
}
|
||||
}
|
100
express-server/node_modules/vue/src/core/util/debug.js
generated
vendored
Normal file
100
express-server/node_modules/vue/src/core/util/debug.js
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import { noop } from 'shared/util'
|
||||
|
||||
export let warn = noop
|
||||
export let tip = noop
|
||||
export let generateComponentTrace = (noop: any) // work around flow check
|
||||
export let formatComponentName = (noop: any)
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const hasConsole = typeof console !== 'undefined'
|
||||
const classifyRE = /(?:^|[-_])(\w)/g
|
||||
const classify = str => str
|
||||
.replace(classifyRE, c => c.toUpperCase())
|
||||
.replace(/[-_]/g, '')
|
||||
|
||||
warn = (msg, vm) => {
|
||||
const trace = vm ? generateComponentTrace(vm) : ''
|
||||
|
||||
if (config.warnHandler) {
|
||||
config.warnHandler.call(null, msg, vm, trace)
|
||||
} else if (hasConsole && (!config.silent)) {
|
||||
console.error(`[Vue warn]: ${msg}${trace}`)
|
||||
}
|
||||
}
|
||||
|
||||
tip = (msg, vm) => {
|
||||
if (hasConsole && (!config.silent)) {
|
||||
console.warn(`[Vue tip]: ${msg}` + (
|
||||
vm ? generateComponentTrace(vm) : ''
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
formatComponentName = (vm, includeFile) => {
|
||||
if (vm.$root === vm) {
|
||||
return '<Root>'
|
||||
}
|
||||
const options = typeof vm === 'function' && vm.cid != null
|
||||
? vm.options
|
||||
: vm._isVue
|
||||
? vm.$options || vm.constructor.options
|
||||
: vm
|
||||
let name = options.name || options._componentTag
|
||||
const file = options.__file
|
||||
if (!name && file) {
|
||||
const match = file.match(/([^/\\]+)\.vue$/)
|
||||
name = match && match[1]
|
||||
}
|
||||
|
||||
return (
|
||||
(name ? `<${classify(name)}>` : `<Anonymous>`) +
|
||||
(file && includeFile !== false ? ` at ${file}` : '')
|
||||
)
|
||||
}
|
||||
|
||||
const repeat = (str, n) => {
|
||||
let res = ''
|
||||
while (n) {
|
||||
if (n % 2 === 1) res += str
|
||||
if (n > 1) str += str
|
||||
n >>= 1
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
generateComponentTrace = vm => {
|
||||
if (vm._isVue && vm.$parent) {
|
||||
const tree = []
|
||||
let currentRecursiveSequence = 0
|
||||
while (vm) {
|
||||
if (tree.length > 0) {
|
||||
const last = tree[tree.length - 1]
|
||||
if (last.constructor === vm.constructor) {
|
||||
currentRecursiveSequence++
|
||||
vm = vm.$parent
|
||||
continue
|
||||
} else if (currentRecursiveSequence > 0) {
|
||||
tree[tree.length - 1] = [last, currentRecursiveSequence]
|
||||
currentRecursiveSequence = 0
|
||||
}
|
||||
}
|
||||
tree.push(vm)
|
||||
vm = vm.$parent
|
||||
}
|
||||
return '\n\nfound in\n\n' + tree
|
||||
.map((vm, i) => `${
|
||||
i === 0 ? '---> ' : repeat(' ', 5 + i * 2)
|
||||
}${
|
||||
Array.isArray(vm)
|
||||
? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)`
|
||||
: formatComponentName(vm)
|
||||
}`)
|
||||
.join('\n')
|
||||
} else {
|
||||
return `\n\n(found in ${formatComponentName(vm)})`
|
||||
}
|
||||
}
|
||||
}
|
97
express-server/node_modules/vue/src/core/util/env.js
generated
vendored
Normal file
97
express-server/node_modules/vue/src/core/util/env.js
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/* @flow */
|
||||
|
||||
// can we use __proto__?
|
||||
export const hasProto = '__proto__' in {}
|
||||
|
||||
// Browser environment sniffing
|
||||
export const inBrowser = typeof window !== 'undefined'
|
||||
export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
|
||||
export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
|
||||
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
|
||||
export const isIE = UA && /msie|trident/.test(UA)
|
||||
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
|
||||
export const isEdge = UA && UA.indexOf('edge/') > 0
|
||||
export const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
|
||||
export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
|
||||
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
|
||||
export const isPhantomJS = UA && /phantomjs/.test(UA)
|
||||
export const isFF = UA && UA.match(/firefox\/(\d+)/)
|
||||
|
||||
// Firefox has a "watch" function on Object.prototype...
|
||||
export const nativeWatch = ({}).watch
|
||||
|
||||
export let supportsPassive = false
|
||||
if (inBrowser) {
|
||||
try {
|
||||
const opts = {}
|
||||
Object.defineProperty(opts, 'passive', ({
|
||||
get () {
|
||||
/* istanbul ignore next */
|
||||
supportsPassive = true
|
||||
}
|
||||
}: Object)) // https://github.com/facebook/flow/issues/285
|
||||
window.addEventListener('test-passive', null, opts)
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// this needs to be lazy-evaled because vue may be required before
|
||||
// vue-server-renderer can set VUE_ENV
|
||||
let _isServer
|
||||
export const isServerRendering = () => {
|
||||
if (_isServer === undefined) {
|
||||
/* istanbul ignore if */
|
||||
if (!inBrowser && !inWeex && typeof global !== 'undefined') {
|
||||
// detect presence of vue-server-renderer and avoid
|
||||
// Webpack shimming the process
|
||||
_isServer = global['process'] && global['process'].env.VUE_ENV === 'server'
|
||||
} else {
|
||||
_isServer = false
|
||||
}
|
||||
}
|
||||
return _isServer
|
||||
}
|
||||
|
||||
// detect devtools
|
||||
export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
|
||||
|
||||
/* istanbul ignore next */
|
||||
export function isNative (Ctor: any): boolean {
|
||||
return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
|
||||
}
|
||||
|
||||
export const hasSymbol =
|
||||
typeof Symbol !== 'undefined' && isNative(Symbol) &&
|
||||
typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)
|
||||
|
||||
let _Set
|
||||
/* istanbul ignore if */ // $flow-disable-line
|
||||
if (typeof Set !== 'undefined' && isNative(Set)) {
|
||||
// use native Set when available.
|
||||
_Set = Set
|
||||
} else {
|
||||
// a non-standard Set polyfill that only works with primitive keys.
|
||||
_Set = class Set implements SimpleSet {
|
||||
set: Object;
|
||||
constructor () {
|
||||
this.set = Object.create(null)
|
||||
}
|
||||
has (key: string | number) {
|
||||
return this.set[key] === true
|
||||
}
|
||||
add (key: string | number) {
|
||||
this.set[key] = true
|
||||
}
|
||||
clear () {
|
||||
this.set = Object.create(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface SimpleSet {
|
||||
has(key: string | number): boolean;
|
||||
add(key: string | number): mixed;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
export { _Set }
|
||||
export type { SimpleSet }
|
83
express-server/node_modules/vue/src/core/util/error.js
generated
vendored
Normal file
83
express-server/node_modules/vue/src/core/util/error.js
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import { warn } from './debug'
|
||||
import { inBrowser, inWeex } from './env'
|
||||
import { isPromise } from 'shared/util'
|
||||
import { pushTarget, popTarget } from '../observer/dep'
|
||||
|
||||
export function handleError (err: Error, vm: any, info: string) {
|
||||
// Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
|
||||
// See: https://github.com/vuejs/vuex/issues/1505
|
||||
pushTarget()
|
||||
try {
|
||||
if (vm) {
|
||||
let cur = vm
|
||||
while ((cur = cur.$parent)) {
|
||||
const hooks = cur.$options.errorCaptured
|
||||
if (hooks) {
|
||||
for (let i = 0; i < hooks.length; i++) {
|
||||
try {
|
||||
const capture = hooks[i].call(cur, err, vm, info) === false
|
||||
if (capture) return
|
||||
} catch (e) {
|
||||
globalHandleError(e, cur, 'errorCaptured hook')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
globalHandleError(err, vm, info)
|
||||
} finally {
|
||||
popTarget()
|
||||
}
|
||||
}
|
||||
|
||||
export function invokeWithErrorHandling (
|
||||
handler: Function,
|
||||
context: any,
|
||||
args: null | any[],
|
||||
vm: any,
|
||||
info: string
|
||||
) {
|
||||
let res
|
||||
try {
|
||||
res = args ? handler.apply(context, args) : handler.call(context)
|
||||
if (res && !res._isVue && isPromise(res) && !res._handled) {
|
||||
res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
|
||||
// issue #9511
|
||||
// avoid catch triggering multiple times when nested calls
|
||||
res._handled = true
|
||||
}
|
||||
} catch (e) {
|
||||
handleError(e, vm, info)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function globalHandleError (err, vm, info) {
|
||||
if (config.errorHandler) {
|
||||
try {
|
||||
return config.errorHandler.call(null, err, vm, info)
|
||||
} catch (e) {
|
||||
// if the user intentionally throws the original error in the handler,
|
||||
// do not log it twice
|
||||
if (e !== err) {
|
||||
logError(e, null, 'config.errorHandler')
|
||||
}
|
||||
}
|
||||
}
|
||||
logError(err, vm, info)
|
||||
}
|
||||
|
||||
function logError (err, vm, info) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Error in ${info}: "${err.toString()}"`, vm)
|
||||
}
|
||||
/* istanbul ignore else */
|
||||
if ((inBrowser || inWeex) && typeof console !== 'undefined') {
|
||||
console.error(err)
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
11
express-server/node_modules/vue/src/core/util/index.js
generated
vendored
Normal file
11
express-server/node_modules/vue/src/core/util/index.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
export * from 'shared/util'
|
||||
export * from './lang'
|
||||
export * from './env'
|
||||
export * from './options'
|
||||
export * from './debug'
|
||||
export * from './props'
|
||||
export * from './error'
|
||||
export * from './next-tick'
|
||||
export { defineReactive } from '../observer/index'
|
46
express-server/node_modules/vue/src/core/util/lang.js
generated
vendored
Normal file
46
express-server/node_modules/vue/src/core/util/lang.js
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/* @flow */
|
||||
|
||||
/**
|
||||
* unicode letters used for parsing html tags, component names and property paths.
|
||||
* using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
|
||||
* skipping \u10000-\uEFFFF due to it freezing up PhantomJS
|
||||
*/
|
||||
export const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/
|
||||
|
||||
/**
|
||||
* Check if a string starts with $ or _
|
||||
*/
|
||||
export function isReserved (str: string): boolean {
|
||||
const c = (str + '').charCodeAt(0)
|
||||
return c === 0x24 || c === 0x5F
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a property.
|
||||
*/
|
||||
export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
|
||||
Object.defineProperty(obj, key, {
|
||||
value: val,
|
||||
enumerable: !!enumerable,
|
||||
writable: true,
|
||||
configurable: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse simple path.
|
||||
*/
|
||||
const bailRE = new RegExp(`[^${unicodeRegExp.source}.$_\\d]`)
|
||||
export function parsePath (path: string): any {
|
||||
if (bailRE.test(path)) {
|
||||
return
|
||||
}
|
||||
const segments = path.split('.')
|
||||
return function (obj) {
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
if (!obj) return
|
||||
obj = obj[segments[i]]
|
||||
}
|
||||
return obj
|
||||
}
|
||||
}
|
110
express-server/node_modules/vue/src/core/util/next-tick.js
generated
vendored
Normal file
110
express-server/node_modules/vue/src/core/util/next-tick.js
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/* @flow */
|
||||
/* globals MutationObserver */
|
||||
|
||||
import { noop } from 'shared/util'
|
||||
import { handleError } from './error'
|
||||
import { isIE, isIOS, isNative } from './env'
|
||||
|
||||
export let isUsingMicroTask = false
|
||||
|
||||
const callbacks = []
|
||||
let pending = false
|
||||
|
||||
function flushCallbacks () {
|
||||
pending = false
|
||||
const copies = callbacks.slice(0)
|
||||
callbacks.length = 0
|
||||
for (let i = 0; i < copies.length; i++) {
|
||||
copies[i]()
|
||||
}
|
||||
}
|
||||
|
||||
// Here we have async deferring wrappers using microtasks.
|
||||
// In 2.5 we used (macro) tasks (in combination with microtasks).
|
||||
// However, it has subtle problems when state is changed right before repaint
|
||||
// (e.g. #6813, out-in transitions).
|
||||
// Also, using (macro) tasks in event handler would cause some weird behaviors
|
||||
// that cannot be circumvented (e.g. #7109, #7153, #7546, #7834, #8109).
|
||||
// So we now use microtasks everywhere, again.
|
||||
// A major drawback of this tradeoff is that there are some scenarios
|
||||
// where microtasks have too high a priority and fire in between supposedly
|
||||
// sequential events (e.g. #4521, #6690, which have workarounds)
|
||||
// or even between bubbling of the same event (#6566).
|
||||
let timerFunc
|
||||
|
||||
// The nextTick behavior leverages the microtask queue, which can be accessed
|
||||
// via either native Promise.then or MutationObserver.
|
||||
// MutationObserver has wider support, however it is seriously bugged in
|
||||
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
|
||||
// completely stops working after triggering a few times... so, if native
|
||||
// Promise is available, we will use it:
|
||||
/* istanbul ignore next, $flow-disable-line */
|
||||
if (typeof Promise !== 'undefined' && isNative(Promise)) {
|
||||
const p = Promise.resolve()
|
||||
timerFunc = () => {
|
||||
p.then(flushCallbacks)
|
||||
// In problematic UIWebViews, Promise.then doesn't completely break, but
|
||||
// it can get stuck in a weird state where callbacks are pushed into the
|
||||
// microtask queue but the queue isn't being flushed, until the browser
|
||||
// needs to do some other work, e.g. handle a timer. Therefore we can
|
||||
// "force" the microtask queue to be flushed by adding an empty timer.
|
||||
if (isIOS) setTimeout(noop)
|
||||
}
|
||||
isUsingMicroTask = true
|
||||
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
|
||||
isNative(MutationObserver) ||
|
||||
// PhantomJS and iOS 7.x
|
||||
MutationObserver.toString() === '[object MutationObserverConstructor]'
|
||||
)) {
|
||||
// Use MutationObserver where native Promise is not available,
|
||||
// e.g. PhantomJS, iOS7, Android 4.4
|
||||
// (#6466 MutationObserver is unreliable in IE11)
|
||||
let counter = 1
|
||||
const observer = new MutationObserver(flushCallbacks)
|
||||
const textNode = document.createTextNode(String(counter))
|
||||
observer.observe(textNode, {
|
||||
characterData: true
|
||||
})
|
||||
timerFunc = () => {
|
||||
counter = (counter + 1) % 2
|
||||
textNode.data = String(counter)
|
||||
}
|
||||
isUsingMicroTask = true
|
||||
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
|
||||
// Fallback to setImmediate.
|
||||
// Techinically it leverages the (macro) task queue,
|
||||
// but it is still a better choice than setTimeout.
|
||||
timerFunc = () => {
|
||||
setImmediate(flushCallbacks)
|
||||
}
|
||||
} else {
|
||||
// Fallback to setTimeout.
|
||||
timerFunc = () => {
|
||||
setTimeout(flushCallbacks, 0)
|
||||
}
|
||||
}
|
||||
|
||||
export function nextTick (cb?: Function, ctx?: Object) {
|
||||
let _resolve
|
||||
callbacks.push(() => {
|
||||
if (cb) {
|
||||
try {
|
||||
cb.call(ctx)
|
||||
} catch (e) {
|
||||
handleError(e, ctx, 'nextTick')
|
||||
}
|
||||
} else if (_resolve) {
|
||||
_resolve(ctx)
|
||||
}
|
||||
})
|
||||
if (!pending) {
|
||||
pending = true
|
||||
timerFunc()
|
||||
}
|
||||
// $flow-disable-line
|
||||
if (!cb && typeof Promise !== 'undefined') {
|
||||
return new Promise(resolve => {
|
||||
_resolve = resolve
|
||||
})
|
||||
}
|
||||
}
|
468
express-server/node_modules/vue/src/core/util/options.js
generated
vendored
Normal file
468
express-server/node_modules/vue/src/core/util/options.js
generated
vendored
Normal file
@ -0,0 +1,468 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import { warn } from './debug'
|
||||
import { set } from '../observer/index'
|
||||
import { unicodeRegExp } from './lang'
|
||||
import { nativeWatch, hasSymbol } from './env'
|
||||
|
||||
import {
|
||||
ASSET_TYPES,
|
||||
LIFECYCLE_HOOKS
|
||||
} from 'shared/constants'
|
||||
|
||||
import {
|
||||
extend,
|
||||
hasOwn,
|
||||
camelize,
|
||||
toRawType,
|
||||
capitalize,
|
||||
isBuiltInTag,
|
||||
isPlainObject
|
||||
} from 'shared/util'
|
||||
|
||||
/**
|
||||
* Option overwriting strategies are functions that handle
|
||||
* how to merge a parent option value and a child option
|
||||
* value into the final value.
|
||||
*/
|
||||
const strats = config.optionMergeStrategies
|
||||
|
||||
/**
|
||||
* Options with restrictions
|
||||
*/
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
strats.el = strats.propsData = function (parent, child, vm, key) {
|
||||
if (!vm) {
|
||||
warn(
|
||||
`option "${key}" can only be used during instance ` +
|
||||
'creation with the `new` keyword.'
|
||||
)
|
||||
}
|
||||
return defaultStrat(parent, child)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that recursively merges two data objects together.
|
||||
*/
|
||||
function mergeData (to: Object, from: ?Object): Object {
|
||||
if (!from) return to
|
||||
let key, toVal, fromVal
|
||||
|
||||
const keys = hasSymbol
|
||||
? Reflect.ownKeys(from)
|
||||
: Object.keys(from)
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
key = keys[i]
|
||||
// in case the object is already observed...
|
||||
if (key === '__ob__') continue
|
||||
toVal = to[key]
|
||||
fromVal = from[key]
|
||||
if (!hasOwn(to, key)) {
|
||||
set(to, key, fromVal)
|
||||
} else if (
|
||||
toVal !== fromVal &&
|
||||
isPlainObject(toVal) &&
|
||||
isPlainObject(fromVal)
|
||||
) {
|
||||
mergeData(toVal, fromVal)
|
||||
}
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
/**
|
||||
* Data
|
||||
*/
|
||||
export function mergeDataOrFn (
|
||||
parentVal: any,
|
||||
childVal: any,
|
||||
vm?: Component
|
||||
): ?Function {
|
||||
if (!vm) {
|
||||
// in a Vue.extend merge, both should be functions
|
||||
if (!childVal) {
|
||||
return parentVal
|
||||
}
|
||||
if (!parentVal) {
|
||||
return childVal
|
||||
}
|
||||
// when parentVal & childVal are both present,
|
||||
// we need to return a function that returns the
|
||||
// merged result of both functions... no need to
|
||||
// check if parentVal is a function here because
|
||||
// it has to be a function to pass previous merges.
|
||||
return function mergedDataFn () {
|
||||
return mergeData(
|
||||
typeof childVal === 'function' ? childVal.call(this, this) : childVal,
|
||||
typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return function mergedInstanceDataFn () {
|
||||
// instance merge
|
||||
const instanceData = typeof childVal === 'function'
|
||||
? childVal.call(vm, vm)
|
||||
: childVal
|
||||
const defaultData = typeof parentVal === 'function'
|
||||
? parentVal.call(vm, vm)
|
||||
: parentVal
|
||||
if (instanceData) {
|
||||
return mergeData(instanceData, defaultData)
|
||||
} else {
|
||||
return defaultData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strats.data = function (
|
||||
parentVal: any,
|
||||
childVal: any,
|
||||
vm?: Component
|
||||
): ?Function {
|
||||
if (!vm) {
|
||||
if (childVal && typeof childVal !== 'function') {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
'The "data" option should be a function ' +
|
||||
'that returns a per-instance value in component ' +
|
||||
'definitions.',
|
||||
vm
|
||||
)
|
||||
|
||||
return parentVal
|
||||
}
|
||||
return mergeDataOrFn(parentVal, childVal)
|
||||
}
|
||||
|
||||
return mergeDataOrFn(parentVal, childVal, vm)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks and props are merged as arrays.
|
||||
*/
|
||||
function mergeHook (
|
||||
parentVal: ?Array<Function>,
|
||||
childVal: ?Function | ?Array<Function>
|
||||
): ?Array<Function> {
|
||||
const res = childVal
|
||||
? parentVal
|
||||
? parentVal.concat(childVal)
|
||||
: Array.isArray(childVal)
|
||||
? childVal
|
||||
: [childVal]
|
||||
: parentVal
|
||||
return res
|
||||
? dedupeHooks(res)
|
||||
: res
|
||||
}
|
||||
|
||||
function dedupeHooks (hooks) {
|
||||
const res = []
|
||||
for (let i = 0; i < hooks.length; i++) {
|
||||
if (res.indexOf(hooks[i]) === -1) {
|
||||
res.push(hooks[i])
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
LIFECYCLE_HOOKS.forEach(hook => {
|
||||
strats[hook] = mergeHook
|
||||
})
|
||||
|
||||
/**
|
||||
* Assets
|
||||
*
|
||||
* When a vm is present (instance creation), we need to do
|
||||
* a three-way merge between constructor options, instance
|
||||
* options and parent options.
|
||||
*/
|
||||
function mergeAssets (
|
||||
parentVal: ?Object,
|
||||
childVal: ?Object,
|
||||
vm?: Component,
|
||||
key: string
|
||||
): Object {
|
||||
const res = Object.create(parentVal || null)
|
||||
if (childVal) {
|
||||
process.env.NODE_ENV !== 'production' && assertObjectType(key, childVal, vm)
|
||||
return extend(res, childVal)
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
ASSET_TYPES.forEach(function (type) {
|
||||
strats[type + 's'] = mergeAssets
|
||||
})
|
||||
|
||||
/**
|
||||
* Watchers.
|
||||
*
|
||||
* Watchers hashes should not overwrite one
|
||||
* another, so we merge them as arrays.
|
||||
*/
|
||||
strats.watch = function (
|
||||
parentVal: ?Object,
|
||||
childVal: ?Object,
|
||||
vm?: Component,
|
||||
key: string
|
||||
): ?Object {
|
||||
// work around Firefox's Object.prototype.watch...
|
||||
if (parentVal === nativeWatch) parentVal = undefined
|
||||
if (childVal === nativeWatch) childVal = undefined
|
||||
/* istanbul ignore if */
|
||||
if (!childVal) return Object.create(parentVal || null)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertObjectType(key, childVal, vm)
|
||||
}
|
||||
if (!parentVal) return childVal
|
||||
const ret = {}
|
||||
extend(ret, parentVal)
|
||||
for (const key in childVal) {
|
||||
let parent = ret[key]
|
||||
const child = childVal[key]
|
||||
if (parent && !Array.isArray(parent)) {
|
||||
parent = [parent]
|
||||
}
|
||||
ret[key] = parent
|
||||
? parent.concat(child)
|
||||
: Array.isArray(child) ? child : [child]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Other object hashes.
|
||||
*/
|
||||
strats.props =
|
||||
strats.methods =
|
||||
strats.inject =
|
||||
strats.computed = function (
|
||||
parentVal: ?Object,
|
||||
childVal: ?Object,
|
||||
vm?: Component,
|
||||
key: string
|
||||
): ?Object {
|
||||
if (childVal && process.env.NODE_ENV !== 'production') {
|
||||
assertObjectType(key, childVal, vm)
|
||||
}
|
||||
if (!parentVal) return childVal
|
||||
const ret = Object.create(null)
|
||||
extend(ret, parentVal)
|
||||
if (childVal) extend(ret, childVal)
|
||||
return ret
|
||||
}
|
||||
strats.provide = mergeDataOrFn
|
||||
|
||||
/**
|
||||
* Default strategy.
|
||||
*/
|
||||
const defaultStrat = function (parentVal: any, childVal: any): any {
|
||||
return childVal === undefined
|
||||
? parentVal
|
||||
: childVal
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate component names
|
||||
*/
|
||||
function checkComponents (options: Object) {
|
||||
for (const key in options.components) {
|
||||
validateComponentName(key)
|
||||
}
|
||||
}
|
||||
|
||||
export function validateComponentName (name: string) {
|
||||
if (!new RegExp(`^[a-zA-Z][\\-\\.0-9_${unicodeRegExp.source}]*$`).test(name)) {
|
||||
warn(
|
||||
'Invalid component name: "' + name + '". Component names ' +
|
||||
'should conform to valid custom element name in html5 specification.'
|
||||
)
|
||||
}
|
||||
if (isBuiltInTag(name) || config.isReservedTag(name)) {
|
||||
warn(
|
||||
'Do not use built-in or reserved HTML elements as component ' +
|
||||
'id: ' + name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure all props option syntax are normalized into the
|
||||
* Object-based format.
|
||||
*/
|
||||
function normalizeProps (options: Object, vm: ?Component) {
|
||||
const props = options.props
|
||||
if (!props) return
|
||||
const res = {}
|
||||
let i, val, name
|
||||
if (Array.isArray(props)) {
|
||||
i = props.length
|
||||
while (i--) {
|
||||
val = props[i]
|
||||
if (typeof val === 'string') {
|
||||
name = camelize(val)
|
||||
res[name] = { type: null }
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn('props must be strings when using array syntax.')
|
||||
}
|
||||
}
|
||||
} else if (isPlainObject(props)) {
|
||||
for (const key in props) {
|
||||
val = props[key]
|
||||
name = camelize(key)
|
||||
res[name] = isPlainObject(val)
|
||||
? val
|
||||
: { type: val }
|
||||
}
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
`Invalid value for option "props": expected an Array or an Object, ` +
|
||||
`but got ${toRawType(props)}.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
options.props = res
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize all injections into Object-based format
|
||||
*/
|
||||
function normalizeInject (options: Object, vm: ?Component) {
|
||||
const inject = options.inject
|
||||
if (!inject) return
|
||||
const normalized = options.inject = {}
|
||||
if (Array.isArray(inject)) {
|
||||
for (let i = 0; i < inject.length; i++) {
|
||||
normalized[inject[i]] = { from: inject[i] }
|
||||
}
|
||||
} else if (isPlainObject(inject)) {
|
||||
for (const key in inject) {
|
||||
const val = inject[key]
|
||||
normalized[key] = isPlainObject(val)
|
||||
? extend({ from: key }, val)
|
||||
: { from: val }
|
||||
}
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
`Invalid value for option "inject": expected an Array or an Object, ` +
|
||||
`but got ${toRawType(inject)}.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize raw function directives into object format.
|
||||
*/
|
||||
function normalizeDirectives (options: Object) {
|
||||
const dirs = options.directives
|
||||
if (dirs) {
|
||||
for (const key in dirs) {
|
||||
const def = dirs[key]
|
||||
if (typeof def === 'function') {
|
||||
dirs[key] = { bind: def, update: def }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertObjectType (name: string, value: any, vm: ?Component) {
|
||||
if (!isPlainObject(value)) {
|
||||
warn(
|
||||
`Invalid value for option "${name}": expected an Object, ` +
|
||||
`but got ${toRawType(value)}.`,
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two option objects into a new one.
|
||||
* Core utility used in both instantiation and inheritance.
|
||||
*/
|
||||
export function mergeOptions (
|
||||
parent: Object,
|
||||
child: Object,
|
||||
vm?: Component
|
||||
): Object {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkComponents(child)
|
||||
}
|
||||
|
||||
if (typeof child === 'function') {
|
||||
child = child.options
|
||||
}
|
||||
|
||||
normalizeProps(child, vm)
|
||||
normalizeInject(child, vm)
|
||||
normalizeDirectives(child)
|
||||
|
||||
// Apply extends and mixins on the child options,
|
||||
// but only if it is a raw options object that isn't
|
||||
// the result of another mergeOptions call.
|
||||
// Only merged options has the _base property.
|
||||
if (!child._base) {
|
||||
if (child.extends) {
|
||||
parent = mergeOptions(parent, child.extends, vm)
|
||||
}
|
||||
if (child.mixins) {
|
||||
for (let i = 0, l = child.mixins.length; i < l; i++) {
|
||||
parent = mergeOptions(parent, child.mixins[i], vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const options = {}
|
||||
let key
|
||||
for (key in parent) {
|
||||
mergeField(key)
|
||||
}
|
||||
for (key in child) {
|
||||
if (!hasOwn(parent, key)) {
|
||||
mergeField(key)
|
||||
}
|
||||
}
|
||||
function mergeField (key) {
|
||||
const strat = strats[key] || defaultStrat
|
||||
options[key] = strat(parent[key], child[key], vm, key)
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an asset.
|
||||
* This function is used because child instances need access
|
||||
* to assets defined in its ancestor chain.
|
||||
*/
|
||||
export function resolveAsset (
|
||||
options: Object,
|
||||
type: string,
|
||||
id: string,
|
||||
warnMissing?: boolean
|
||||
): any {
|
||||
/* istanbul ignore if */
|
||||
if (typeof id !== 'string') {
|
||||
return
|
||||
}
|
||||
const assets = options[type]
|
||||
// check local registration variations first
|
||||
if (hasOwn(assets, id)) return assets[id]
|
||||
const camelizedId = camelize(id)
|
||||
if (hasOwn(assets, camelizedId)) return assets[camelizedId]
|
||||
const PascalCaseId = capitalize(camelizedId)
|
||||
if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId]
|
||||
// fallback to prototype chain
|
||||
const res = assets[id] || assets[camelizedId] || assets[PascalCaseId]
|
||||
if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {
|
||||
warn(
|
||||
'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
|
||||
options
|
||||
)
|
||||
}
|
||||
return res
|
||||
}
|
24
express-server/node_modules/vue/src/core/util/perf.js
generated
vendored
Normal file
24
express-server/node_modules/vue/src/core/util/perf.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { inBrowser } from './env'
|
||||
|
||||
export let mark
|
||||
export let measure
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const perf = inBrowser && window.performance
|
||||
/* istanbul ignore if */
|
||||
if (
|
||||
perf &&
|
||||
perf.mark &&
|
||||
perf.measure &&
|
||||
perf.clearMarks &&
|
||||
perf.clearMeasures
|
||||
) {
|
||||
mark = tag => perf.mark(tag)
|
||||
measure = (name, startTag, endTag) => {
|
||||
perf.measure(name, startTag, endTag)
|
||||
perf.clearMarks(startTag)
|
||||
perf.clearMarks(endTag)
|
||||
// perf.clearMeasures(name)
|
||||
}
|
||||
}
|
||||
}
|
241
express-server/node_modules/vue/src/core/util/props.js
generated
vendored
Normal file
241
express-server/node_modules/vue/src/core/util/props.js
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
/* @flow */
|
||||
|
||||
import { warn } from './debug'
|
||||
import { observe, toggleObserving, shouldObserve } from '../observer/index'
|
||||
import {
|
||||
hasOwn,
|
||||
isObject,
|
||||
toRawType,
|
||||
hyphenate,
|
||||
capitalize,
|
||||
isPlainObject
|
||||
} from 'shared/util'
|
||||
|
||||
type PropOptions = {
|
||||
type: Function | Array<Function> | null,
|
||||
default: any,
|
||||
required: ?boolean,
|
||||
validator: ?Function
|
||||
};
|
||||
|
||||
export function validateProp (
|
||||
key: string,
|
||||
propOptions: Object,
|
||||
propsData: Object,
|
||||
vm?: Component
|
||||
): any {
|
||||
const prop = propOptions[key]
|
||||
const absent = !hasOwn(propsData, key)
|
||||
let value = propsData[key]
|
||||
// boolean casting
|
||||
const booleanIndex = getTypeIndex(Boolean, prop.type)
|
||||
if (booleanIndex > -1) {
|
||||
if (absent && !hasOwn(prop, 'default')) {
|
||||
value = false
|
||||
} else if (value === '' || value === hyphenate(key)) {
|
||||
// only cast empty string / same name to boolean if
|
||||
// boolean has higher priority
|
||||
const stringIndex = getTypeIndex(String, prop.type)
|
||||
if (stringIndex < 0 || booleanIndex < stringIndex) {
|
||||
value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// check default value
|
||||
if (value === undefined) {
|
||||
value = getPropDefaultValue(vm, prop, key)
|
||||
// since the default value is a fresh copy,
|
||||
// make sure to observe it.
|
||||
const prevShouldObserve = shouldObserve
|
||||
toggleObserving(true)
|
||||
observe(value)
|
||||
toggleObserving(prevShouldObserve)
|
||||
}
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
// skip validation for weex recycle-list child component props
|
||||
!(__WEEX__ && isObject(value) && ('@binding' in value))
|
||||
) {
|
||||
assertProp(prop, key, value, vm, absent)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value of a prop.
|
||||
*/
|
||||
function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): any {
|
||||
// no default, return undefined
|
||||
if (!hasOwn(prop, 'default')) {
|
||||
return undefined
|
||||
}
|
||||
const def = prop.default
|
||||
// warn against non-factory defaults for Object & Array
|
||||
if (process.env.NODE_ENV !== 'production' && isObject(def)) {
|
||||
warn(
|
||||
'Invalid default value for prop "' + key + '": ' +
|
||||
'Props with type Object/Array must use a factory function ' +
|
||||
'to return the default value.',
|
||||
vm
|
||||
)
|
||||
}
|
||||
// the raw prop value was also undefined from previous render,
|
||||
// return previous default value to avoid unnecessary watcher trigger
|
||||
if (vm && vm.$options.propsData &&
|
||||
vm.$options.propsData[key] === undefined &&
|
||||
vm._props[key] !== undefined
|
||||
) {
|
||||
return vm._props[key]
|
||||
}
|
||||
// call factory function for non-Function types
|
||||
// a value is Function if its prototype is function even across different execution context
|
||||
return typeof def === 'function' && getType(prop.type) !== 'Function'
|
||||
? def.call(vm)
|
||||
: def
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert whether a prop is valid.
|
||||
*/
|
||||
function assertProp (
|
||||
prop: PropOptions,
|
||||
name: string,
|
||||
value: any,
|
||||
vm: ?Component,
|
||||
absent: boolean
|
||||
) {
|
||||
if (prop.required && absent) {
|
||||
warn(
|
||||
'Missing required prop: "' + name + '"',
|
||||
vm
|
||||
)
|
||||
return
|
||||
}
|
||||
if (value == null && !prop.required) {
|
||||
return
|
||||
}
|
||||
let type = prop.type
|
||||
let valid = !type || type === true
|
||||
const expectedTypes = []
|
||||
if (type) {
|
||||
if (!Array.isArray(type)) {
|
||||
type = [type]
|
||||
}
|
||||
for (let i = 0; i < type.length && !valid; i++) {
|
||||
const assertedType = assertType(value, type[i])
|
||||
expectedTypes.push(assertedType.expectedType || '')
|
||||
valid = assertedType.valid
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
warn(
|
||||
getInvalidTypeMessage(name, value, expectedTypes),
|
||||
vm
|
||||
)
|
||||
return
|
||||
}
|
||||
const validator = prop.validator
|
||||
if (validator) {
|
||||
if (!validator(value)) {
|
||||
warn(
|
||||
'Invalid prop: custom validator check failed for prop "' + name + '".',
|
||||
vm
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/
|
||||
|
||||
function assertType (value: any, type: Function): {
|
||||
valid: boolean;
|
||||
expectedType: string;
|
||||
} {
|
||||
let valid
|
||||
const expectedType = getType(type)
|
||||
if (simpleCheckRE.test(expectedType)) {
|
||||
const t = typeof value
|
||||
valid = t === expectedType.toLowerCase()
|
||||
// for primitive wrapper objects
|
||||
if (!valid && t === 'object') {
|
||||
valid = value instanceof type
|
||||
}
|
||||
} else if (expectedType === 'Object') {
|
||||
valid = isPlainObject(value)
|
||||
} else if (expectedType === 'Array') {
|
||||
valid = Array.isArray(value)
|
||||
} else {
|
||||
valid = value instanceof type
|
||||
}
|
||||
return {
|
||||
valid,
|
||||
expectedType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use function string name to check built-in types,
|
||||
* because a simple equality check will fail when running
|
||||
* across different vms / iframes.
|
||||
*/
|
||||
function getType (fn) {
|
||||
const match = fn && fn.toString().match(/^\s*function (\w+)/)
|
||||
return match ? match[1] : ''
|
||||
}
|
||||
|
||||
function isSameType (a, b) {
|
||||
return getType(a) === getType(b)
|
||||
}
|
||||
|
||||
function getTypeIndex (type, expectedTypes): number {
|
||||
if (!Array.isArray(expectedTypes)) {
|
||||
return isSameType(expectedTypes, type) ? 0 : -1
|
||||
}
|
||||
for (let i = 0, len = expectedTypes.length; i < len; i++) {
|
||||
if (isSameType(expectedTypes[i], type)) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
function getInvalidTypeMessage (name, value, expectedTypes) {
|
||||
let message = `Invalid prop: type check failed for prop "${name}".` +
|
||||
` Expected ${expectedTypes.map(capitalize).join(', ')}`
|
||||
const expectedType = expectedTypes[0]
|
||||
const receivedType = toRawType(value)
|
||||
const expectedValue = styleValue(value, expectedType)
|
||||
const receivedValue = styleValue(value, receivedType)
|
||||
// check if we need to specify expected value
|
||||
if (expectedTypes.length === 1 &&
|
||||
isExplicable(expectedType) &&
|
||||
!isBoolean(expectedType, receivedType)) {
|
||||
message += ` with value ${expectedValue}`
|
||||
}
|
||||
message += `, got ${receivedType} `
|
||||
// check if we need to specify received value
|
||||
if (isExplicable(receivedType)) {
|
||||
message += `with value ${receivedValue}.`
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
function styleValue (value, type) {
|
||||
if (type === 'String') {
|
||||
return `"${value}"`
|
||||
} else if (type === 'Number') {
|
||||
return `${Number(value)}`
|
||||
} else {
|
||||
return `${value}`
|
||||
}
|
||||
}
|
||||
|
||||
function isExplicable (value) {
|
||||
const explicitTypes = ['string', 'number', 'boolean']
|
||||
return explicitTypes.some(elem => value.toLowerCase() === elem)
|
||||
}
|
||||
|
||||
function isBoolean (...args) {
|
||||
return args.some(elem => elem.toLowerCase() === 'boolean')
|
||||
}
|
268
express-server/node_modules/vue/src/core/vdom/create-component.js
generated
vendored
Normal file
268
express-server/node_modules/vue/src/core/vdom/create-component.js
generated
vendored
Normal file
@ -0,0 +1,268 @@
|
||||
/* @flow */
|
||||
|
||||
import VNode from './vnode'
|
||||
import { resolveConstructorOptions } from 'core/instance/init'
|
||||
import { queueActivatedComponent } from 'core/observer/scheduler'
|
||||
import { createFunctionalComponent } from './create-functional-component'
|
||||
|
||||
import {
|
||||
warn,
|
||||
isDef,
|
||||
isUndef,
|
||||
isTrue,
|
||||
isObject
|
||||
} from '../util/index'
|
||||
|
||||
import {
|
||||
resolveAsyncComponent,
|
||||
createAsyncPlaceholder,
|
||||
extractPropsFromVNodeData
|
||||
} from './helpers/index'
|
||||
|
||||
import {
|
||||
callHook,
|
||||
activeInstance,
|
||||
updateChildComponent,
|
||||
activateChildComponent,
|
||||
deactivateChildComponent
|
||||
} from '../instance/lifecycle'
|
||||
|
||||
import {
|
||||
isRecyclableComponent,
|
||||
renderRecyclableComponentTemplate
|
||||
} from 'weex/runtime/recycle-list/render-component-template'
|
||||
|
||||
// inline hooks to be invoked on component VNodes during patch
|
||||
const componentVNodeHooks = {
|
||||
init (vnode: VNodeWithData, hydrating: boolean): ?boolean {
|
||||
if (
|
||||
vnode.componentInstance &&
|
||||
!vnode.componentInstance._isDestroyed &&
|
||||
vnode.data.keepAlive
|
||||
) {
|
||||
// kept-alive components, treat as a patch
|
||||
const mountedNode: any = vnode // work around flow
|
||||
componentVNodeHooks.prepatch(mountedNode, mountedNode)
|
||||
} else {
|
||||
const child = vnode.componentInstance = createComponentInstanceForVnode(
|
||||
vnode,
|
||||
activeInstance
|
||||
)
|
||||
child.$mount(hydrating ? vnode.elm : undefined, hydrating)
|
||||
}
|
||||
},
|
||||
|
||||
prepatch (oldVnode: MountedComponentVNode, vnode: MountedComponentVNode) {
|
||||
const options = vnode.componentOptions
|
||||
const child = vnode.componentInstance = oldVnode.componentInstance
|
||||
updateChildComponent(
|
||||
child,
|
||||
options.propsData, // updated props
|
||||
options.listeners, // updated listeners
|
||||
vnode, // new parent vnode
|
||||
options.children // new children
|
||||
)
|
||||
},
|
||||
|
||||
insert (vnode: MountedComponentVNode) {
|
||||
const { context, componentInstance } = vnode
|
||||
if (!componentInstance._isMounted) {
|
||||
componentInstance._isMounted = true
|
||||
callHook(componentInstance, 'mounted')
|
||||
}
|
||||
if (vnode.data.keepAlive) {
|
||||
if (context._isMounted) {
|
||||
// vue-router#1212
|
||||
// During updates, a kept-alive component's child components may
|
||||
// change, so directly walking the tree here may call activated hooks
|
||||
// on incorrect children. Instead we push them into a queue which will
|
||||
// be processed after the whole patch process ended.
|
||||
queueActivatedComponent(componentInstance)
|
||||
} else {
|
||||
activateChildComponent(componentInstance, true /* direct */)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
destroy (vnode: MountedComponentVNode) {
|
||||
const { componentInstance } = vnode
|
||||
if (!componentInstance._isDestroyed) {
|
||||
if (!vnode.data.keepAlive) {
|
||||
componentInstance.$destroy()
|
||||
} else {
|
||||
deactivateChildComponent(componentInstance, true /* direct */)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hooksToMerge = Object.keys(componentVNodeHooks)
|
||||
|
||||
export function createComponent (
|
||||
Ctor: Class<Component> | Function | Object | void,
|
||||
data: ?VNodeData,
|
||||
context: Component,
|
||||
children: ?Array<VNode>,
|
||||
tag?: string
|
||||
): VNode | Array<VNode> | void {
|
||||
if (isUndef(Ctor)) {
|
||||
return
|
||||
}
|
||||
|
||||
const baseCtor = context.$options._base
|
||||
|
||||
// plain options object: turn it into a constructor
|
||||
if (isObject(Ctor)) {
|
||||
Ctor = baseCtor.extend(Ctor)
|
||||
}
|
||||
|
||||
// if at this stage it's not a constructor or an async component factory,
|
||||
// reject.
|
||||
if (typeof Ctor !== 'function') {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warn(`Invalid Component definition: ${String(Ctor)}`, context)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// async component
|
||||
let asyncFactory
|
||||
if (isUndef(Ctor.cid)) {
|
||||
asyncFactory = Ctor
|
||||
Ctor = resolveAsyncComponent(asyncFactory, baseCtor)
|
||||
if (Ctor === undefined) {
|
||||
// return a placeholder node for async component, which is rendered
|
||||
// as a comment node but preserves all the raw information for the node.
|
||||
// the information will be used for async server-rendering and hydration.
|
||||
return createAsyncPlaceholder(
|
||||
asyncFactory,
|
||||
data,
|
||||
context,
|
||||
children,
|
||||
tag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data = data || {}
|
||||
|
||||
// resolve constructor options in case global mixins are applied after
|
||||
// component constructor creation
|
||||
resolveConstructorOptions(Ctor)
|
||||
|
||||
// transform component v-model data into props & events
|
||||
if (isDef(data.model)) {
|
||||
transformModel(Ctor.options, data)
|
||||
}
|
||||
|
||||
// extract props
|
||||
const propsData = extractPropsFromVNodeData(data, Ctor, tag)
|
||||
|
||||
// functional component
|
||||
if (isTrue(Ctor.options.functional)) {
|
||||
return createFunctionalComponent(Ctor, propsData, data, context, children)
|
||||
}
|
||||
|
||||
// extract listeners, since these needs to be treated as
|
||||
// child component listeners instead of DOM listeners
|
||||
const listeners = data.on
|
||||
// replace with listeners with .native modifier
|
||||
// so it gets processed during parent component patch.
|
||||
data.on = data.nativeOn
|
||||
|
||||
if (isTrue(Ctor.options.abstract)) {
|
||||
// abstract components do not keep anything
|
||||
// other than props & listeners & slot
|
||||
|
||||
// work around flow
|
||||
const slot = data.slot
|
||||
data = {}
|
||||
if (slot) {
|
||||
data.slot = slot
|
||||
}
|
||||
}
|
||||
|
||||
// install component management hooks onto the placeholder node
|
||||
installComponentHooks(data)
|
||||
|
||||
// return a placeholder vnode
|
||||
const name = Ctor.options.name || tag
|
||||
const vnode = new VNode(
|
||||
`vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
|
||||
data, undefined, undefined, undefined, context,
|
||||
{ Ctor, propsData, listeners, tag, children },
|
||||
asyncFactory
|
||||
)
|
||||
|
||||
// Weex specific: invoke recycle-list optimized @render function for
|
||||
// extracting cell-slot template.
|
||||
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && isRecyclableComponent(vnode)) {
|
||||
return renderRecyclableComponentTemplate(vnode)
|
||||
}
|
||||
|
||||
return vnode
|
||||
}
|
||||
|
||||
export function createComponentInstanceForVnode (
|
||||
vnode: any, // we know it's MountedComponentVNode but flow doesn't
|
||||
parent: any, // activeInstance in lifecycle state
|
||||
): Component {
|
||||
const options: InternalComponentOptions = {
|
||||
_isComponent: true,
|
||||
_parentVnode: vnode,
|
||||
parent
|
||||
}
|
||||
// check inline-template render functions
|
||||
const inlineTemplate = vnode.data.inlineTemplate
|
||||
if (isDef(inlineTemplate)) {
|
||||
options.render = inlineTemplate.render
|
||||
options.staticRenderFns = inlineTemplate.staticRenderFns
|
||||
}
|
||||
return new vnode.componentOptions.Ctor(options)
|
||||
}
|
||||
|
||||
function installComponentHooks (data: VNodeData) {
|
||||
const hooks = data.hook || (data.hook = {})
|
||||
for (let i = 0; i < hooksToMerge.length; i++) {
|
||||
const key = hooksToMerge[i]
|
||||
const existing = hooks[key]
|
||||
const toMerge = componentVNodeHooks[key]
|
||||
if (existing !== toMerge && !(existing && existing._merged)) {
|
||||
hooks[key] = existing ? mergeHook(toMerge, existing) : toMerge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mergeHook (f1: any, f2: any): Function {
|
||||
const merged = (a, b) => {
|
||||
// flow complains about extra args which is why we use any
|
||||
f1(a, b)
|
||||
f2(a, b)
|
||||
}
|
||||
merged._merged = true
|
||||
return merged
|
||||
}
|
||||
|
||||
// transform component v-model info (value and callback) into
|
||||
// prop and event handler respectively.
|
||||
function transformModel (options, data: any) {
|
||||
const prop = (options.model && options.model.prop) || 'value'
|
||||
const event = (options.model && options.model.event) || 'input'
|
||||
;(data.attrs || (data.attrs = {}))[prop] = data.model.value
|
||||
const on = data.on || (data.on = {})
|
||||
const existing = on[event]
|
||||
const callback = data.model.callback
|
||||
if (isDef(existing)) {
|
||||
if (
|
||||
Array.isArray(existing)
|
||||
? existing.indexOf(callback) === -1
|
||||
: existing !== callback
|
||||
) {
|
||||
on[event] = [callback].concat(existing)
|
||||
}
|
||||
} else {
|
||||
on[event] = callback
|
||||
}
|
||||
}
|
160
express-server/node_modules/vue/src/core/vdom/create-element.js
generated
vendored
Normal file
160
express-server/node_modules/vue/src/core/vdom/create-element.js
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/* @flow */
|
||||
|
||||
import config from '../config'
|
||||
import VNode, { createEmptyVNode } from './vnode'
|
||||
import { createComponent } from './create-component'
|
||||
import { traverse } from '../observer/traverse'
|
||||
|
||||
import {
|
||||
warn,
|
||||
isDef,
|
||||
isUndef,
|
||||
isTrue,
|
||||
isObject,
|
||||
isPrimitive,
|
||||
resolveAsset
|
||||
} from '../util/index'
|
||||
|
||||
import {
|
||||
normalizeChildren,
|
||||
simpleNormalizeChildren
|
||||
} from './helpers/index'
|
||||
|
||||
const SIMPLE_NORMALIZE = 1
|
||||
const ALWAYS_NORMALIZE = 2
|
||||
|
||||
// wrapper function for providing a more flexible interface
|
||||
// without getting yelled at by flow
|
||||
export function createElement (
|
||||
context: Component,
|
||||
tag: any,
|
||||
data: any,
|
||||
children: any,
|
||||
normalizationType: any,
|
||||
alwaysNormalize: boolean
|
||||
): VNode | Array<VNode> {
|
||||
if (Array.isArray(data) || isPrimitive(data)) {
|
||||
normalizationType = children
|
||||
children = data
|
||||
data = undefined
|
||||
}
|
||||
if (isTrue(alwaysNormalize)) {
|
||||
normalizationType = ALWAYS_NORMALIZE
|
||||
}
|
||||
return _createElement(context, tag, data, children, normalizationType)
|
||||
}
|
||||
|
||||
export function _createElement (
|
||||
context: Component,
|
||||
tag?: string | Class<Component> | Function | Object,
|
||||
data?: VNodeData,
|
||||
children?: any,
|
||||
normalizationType?: number
|
||||
): VNode | Array<VNode> {
|
||||
if (isDef(data) && isDef((data: any).__ob__)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
|
||||
'Always create fresh vnode data objects in each render!',
|
||||
context
|
||||
)
|
||||
return createEmptyVNode()
|
||||
}
|
||||
// object syntax in v-bind
|
||||
if (isDef(data) && isDef(data.is)) {
|
||||
tag = data.is
|
||||
}
|
||||
if (!tag) {
|
||||
// in case of component :is set to falsy value
|
||||
return createEmptyVNode()
|
||||
}
|
||||
// warn against non-primitive key
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
isDef(data) && isDef(data.key) && !isPrimitive(data.key)
|
||||
) {
|
||||
if (!__WEEX__ || !('@binding' in data.key)) {
|
||||
warn(
|
||||
'Avoid using non-primitive value as key, ' +
|
||||
'use string/number value instead.',
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
// support single function children as default scoped slot
|
||||
if (Array.isArray(children) &&
|
||||
typeof children[0] === 'function'
|
||||
) {
|
||||
data = data || {}
|
||||
data.scopedSlots = { default: children[0] }
|
||||
children.length = 0
|
||||
}
|
||||
if (normalizationType === ALWAYS_NORMALIZE) {
|
||||
children = normalizeChildren(children)
|
||||
} else if (normalizationType === SIMPLE_NORMALIZE) {
|
||||
children = simpleNormalizeChildren(children)
|
||||
}
|
||||
let vnode, ns
|
||||
if (typeof tag === 'string') {
|
||||
let Ctor
|
||||
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
|
||||
if (config.isReservedTag(tag)) {
|
||||
// platform built-in elements
|
||||
vnode = new VNode(
|
||||
config.parsePlatformTagName(tag), data, children,
|
||||
undefined, undefined, context
|
||||
)
|
||||
} else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
|
||||
// component
|
||||
vnode = createComponent(Ctor, data, context, children, tag)
|
||||
} else {
|
||||
// unknown or unlisted namespaced elements
|
||||
// check at runtime because it may get assigned a namespace when its
|
||||
// parent normalizes children
|
||||
vnode = new VNode(
|
||||
tag, data, children,
|
||||
undefined, undefined, context
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// direct component options / constructor
|
||||
vnode = createComponent(tag, data, context, children)
|
||||
}
|
||||
if (Array.isArray(vnode)) {
|
||||
return vnode
|
||||
} else if (isDef(vnode)) {
|
||||
if (isDef(ns)) applyNS(vnode, ns)
|
||||
if (isDef(data)) registerDeepBindings(data)
|
||||
return vnode
|
||||
} else {
|
||||
return createEmptyVNode()
|
||||
}
|
||||
}
|
||||
|
||||
function applyNS (vnode, ns, force) {
|
||||
vnode.ns = ns
|
||||
if (vnode.tag === 'foreignObject') {
|
||||
// use default namespace inside foreignObject
|
||||
ns = undefined
|
||||
force = true
|
||||
}
|
||||
if (isDef(vnode.children)) {
|
||||
for (let i = 0, l = vnode.children.length; i < l; i++) {
|
||||
const child = vnode.children[i]
|
||||
if (isDef(child.tag) && (
|
||||
isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {
|
||||
applyNS(child, ns, force)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ref #5318
|
||||
// necessary to ensure parent re-render when deep bindings like :style and
|
||||
// :class are used on slot nodes
|
||||
function registerDeepBindings (data) {
|
||||
if (isObject(data.style)) {
|
||||
traverse(data.style)
|
||||
}
|
||||
if (isObject(data.class)) {
|
||||
traverse(data.class)
|
||||
}
|
||||
}
|
155
express-server/node_modules/vue/src/core/vdom/create-functional-component.js
generated
vendored
Normal file
155
express-server/node_modules/vue/src/core/vdom/create-functional-component.js
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
/* @flow */
|
||||
|
||||
import VNode, { cloneVNode } from './vnode'
|
||||
import { createElement } from './create-element'
|
||||
import { resolveInject } from '../instance/inject'
|
||||
import { normalizeChildren } from '../vdom/helpers/normalize-children'
|
||||
import { resolveSlots } from '../instance/render-helpers/resolve-slots'
|
||||
import { normalizeScopedSlots } from '../vdom/helpers/normalize-scoped-slots'
|
||||
import { installRenderHelpers } from '../instance/render-helpers/index'
|
||||
|
||||
import {
|
||||
isDef,
|
||||
isTrue,
|
||||
hasOwn,
|
||||
camelize,
|
||||
emptyObject,
|
||||
validateProp
|
||||
} from '../util/index'
|
||||
|
||||
export function FunctionalRenderContext (
|
||||
data: VNodeData,
|
||||
props: Object,
|
||||
children: ?Array<VNode>,
|
||||
parent: Component,
|
||||
Ctor: Class<Component>
|
||||
) {
|
||||
const options = Ctor.options
|
||||
// ensure the createElement function in functional components
|
||||
// gets a unique context - this is necessary for correct named slot check
|
||||
let contextVm
|
||||
if (hasOwn(parent, '_uid')) {
|
||||
contextVm = Object.create(parent)
|
||||
// $flow-disable-line
|
||||
contextVm._original = parent
|
||||
} else {
|
||||
// the context vm passed in is a functional context as well.
|
||||
// in this case we want to make sure we are able to get a hold to the
|
||||
// real context instance.
|
||||
contextVm = parent
|
||||
// $flow-disable-line
|
||||
parent = parent._original
|
||||
}
|
||||
const isCompiled = isTrue(options._compiled)
|
||||
const needNormalization = !isCompiled
|
||||
|
||||
this.data = data
|
||||
this.props = props
|
||||
this.children = children
|
||||
this.parent = parent
|
||||
this.listeners = data.on || emptyObject
|
||||
this.injections = resolveInject(options.inject, parent)
|
||||
this.slots = () => {
|
||||
if (!this.$slots) {
|
||||
normalizeScopedSlots(
|
||||
data.scopedSlots,
|
||||
this.$slots = resolveSlots(children, parent)
|
||||
)
|
||||
}
|
||||
return this.$slots
|
||||
}
|
||||
|
||||
Object.defineProperty(this, 'scopedSlots', ({
|
||||
enumerable: true,
|
||||
get () {
|
||||
return normalizeScopedSlots(data.scopedSlots, this.slots())
|
||||
}
|
||||
}: any))
|
||||
|
||||
// support for compiled functional template
|
||||
if (isCompiled) {
|
||||
// exposing $options for renderStatic()
|
||||
this.$options = options
|
||||
// pre-resolve slots for renderSlot()
|
||||
this.$slots = this.slots()
|
||||
this.$scopedSlots = normalizeScopedSlots(data.scopedSlots, this.$slots)
|
||||
}
|
||||
|
||||
if (options._scopeId) {
|
||||
this._c = (a, b, c, d) => {
|
||||
const vnode = createElement(contextVm, a, b, c, d, needNormalization)
|
||||
if (vnode && !Array.isArray(vnode)) {
|
||||
vnode.fnScopeId = options._scopeId
|
||||
vnode.fnContext = parent
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
} else {
|
||||
this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization)
|
||||
}
|
||||
}
|
||||
|
||||
installRenderHelpers(FunctionalRenderContext.prototype)
|
||||
|
||||
export function createFunctionalComponent (
|
||||
Ctor: Class<Component>,
|
||||
propsData: ?Object,
|
||||
data: VNodeData,
|
||||
contextVm: Component,
|
||||
children: ?Array<VNode>
|
||||
): VNode | Array<VNode> | void {
|
||||
const options = Ctor.options
|
||||
const props = {}
|
||||
const propOptions = options.props
|
||||
if (isDef(propOptions)) {
|
||||
for (const key in propOptions) {
|
||||
props[key] = validateProp(key, propOptions, propsData || emptyObject)
|
||||
}
|
||||
} else {
|
||||
if (isDef(data.attrs)) mergeProps(props, data.attrs)
|
||||
if (isDef(data.props)) mergeProps(props, data.props)
|
||||
}
|
||||
|
||||
const renderContext = new FunctionalRenderContext(
|
||||
data,
|
||||
props,
|
||||
children,
|
||||
contextVm,
|
||||
Ctor
|
||||
)
|
||||
|
||||
const vnode = options.render.call(null, renderContext._c, renderContext)
|
||||
|
||||
if (vnode instanceof VNode) {
|
||||
return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options, renderContext)
|
||||
} else if (Array.isArray(vnode)) {
|
||||
const vnodes = normalizeChildren(vnode) || []
|
||||
const res = new Array(vnodes.length)
|
||||
for (let i = 0; i < vnodes.length; i++) {
|
||||
res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options, renderContext)
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
function cloneAndMarkFunctionalResult (vnode, data, contextVm, options, renderContext) {
|
||||
// #7817 clone node before setting fnContext, otherwise if the node is reused
|
||||
// (e.g. it was from a cached normal slot) the fnContext causes named slots
|
||||
// that should not be matched to match.
|
||||
const clone = cloneVNode(vnode)
|
||||
clone.fnContext = contextVm
|
||||
clone.fnOptions = options
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
(clone.devtoolsMeta = clone.devtoolsMeta || {}).renderContext = renderContext
|
||||
}
|
||||
if (data.slot) {
|
||||
(clone.data || (clone.data = {})).slot = data.slot
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
function mergeProps (to, from) {
|
||||
for (const key in from) {
|
||||
to[camelize(key)] = from[key]
|
||||
}
|
||||
}
|
75
express-server/node_modules/vue/src/core/vdom/helpers/extract-props.js
generated
vendored
Normal file
75
express-server/node_modules/vue/src/core/vdom/helpers/extract-props.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
tip,
|
||||
hasOwn,
|
||||
isDef,
|
||||
isUndef,
|
||||
hyphenate,
|
||||
formatComponentName
|
||||
} from 'core/util/index'
|
||||
|
||||
export function extractPropsFromVNodeData (
|
||||
data: VNodeData,
|
||||
Ctor: Class<Component>,
|
||||
tag?: string
|
||||
): ?Object {
|
||||
// we are only extracting raw values here.
|
||||
// validation and default values are handled in the child
|
||||
// component itself.
|
||||
const propOptions = Ctor.options.props
|
||||
if (isUndef(propOptions)) {
|
||||
return
|
||||
}
|
||||
const res = {}
|
||||
const { attrs, props } = data
|
||||
if (isDef(attrs) || isDef(props)) {
|
||||
for (const key in propOptions) {
|
||||
const altKey = hyphenate(key)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const keyInLowerCase = key.toLowerCase()
|
||||
if (
|
||||
key !== keyInLowerCase &&
|
||||
attrs && hasOwn(attrs, keyInLowerCase)
|
||||
) {
|
||||
tip(
|
||||
`Prop "${keyInLowerCase}" is passed to component ` +
|
||||
`${formatComponentName(tag || Ctor)}, but the declared prop name is` +
|
||||
` "${key}". ` +
|
||||
`Note that HTML attributes are case-insensitive and camelCased ` +
|
||||
`props need to use their kebab-case equivalents when using in-DOM ` +
|
||||
`templates. You should probably use "${altKey}" instead of "${key}".`
|
||||
)
|
||||
}
|
||||
}
|
||||
checkProp(res, props, key, altKey, true) ||
|
||||
checkProp(res, attrs, key, altKey, false)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function checkProp (
|
||||
res: Object,
|
||||
hash: ?Object,
|
||||
key: string,
|
||||
altKey: string,
|
||||
preserve: boolean
|
||||
): boolean {
|
||||
if (isDef(hash)) {
|
||||
if (hasOwn(hash, key)) {
|
||||
res[key] = hash[key]
|
||||
if (!preserve) {
|
||||
delete hash[key]
|
||||
}
|
||||
return true
|
||||
} else if (hasOwn(hash, altKey)) {
|
||||
res[key] = hash[altKey]
|
||||
if (!preserve) {
|
||||
delete hash[altKey]
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
15
express-server/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js
generated
vendored
Normal file
15
express-server/node_modules/vue/src/core/vdom/helpers/get-first-component-child.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/* @flow */
|
||||
|
||||
import { isDef } from 'shared/util'
|
||||
import { isAsyncPlaceholder } from './is-async-placeholder'
|
||||
|
||||
export function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
|
||||
if (Array.isArray(children)) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const c = children[i]
|
||||
if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
express-server/node_modules/vue/src/core/vdom/helpers/index.js
generated
vendored
Normal file
9
express-server/node_modules/vue/src/core/vdom/helpers/index.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
export * from './merge-hook'
|
||||
export * from './extract-props'
|
||||
export * from './update-listeners'
|
||||
export * from './normalize-children'
|
||||
export * from './resolve-async-component'
|
||||
export * from './get-first-component-child'
|
||||
export * from './is-async-placeholder'
|
5
express-server/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js
generated
vendored
Normal file
5
express-server/node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
export function isAsyncPlaceholder (node: VNode): boolean {
|
||||
return node.isComment && node.asyncFactory
|
||||
}
|
38
express-server/node_modules/vue/src/core/vdom/helpers/merge-hook.js
generated
vendored
Normal file
38
express-server/node_modules/vue/src/core/vdom/helpers/merge-hook.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/* @flow */
|
||||
|
||||
import VNode from '../vnode'
|
||||
import { createFnInvoker } from './update-listeners'
|
||||
import { remove, isDef, isUndef, isTrue } from 'shared/util'
|
||||
|
||||
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) {
|
||||
if (def instanceof VNode) {
|
||||
def = def.data.hook || (def.data.hook = {})
|
||||
}
|
||||
let invoker
|
||||
const oldHook = def[hookKey]
|
||||
|
||||
function wrappedHook () {
|
||||
hook.apply(this, arguments)
|
||||
// important: remove merged hook to ensure it's called only once
|
||||
// and prevent memory leak
|
||||
remove(invoker.fns, wrappedHook)
|
||||
}
|
||||
|
||||
if (isUndef(oldHook)) {
|
||||
// no existing hook
|
||||
invoker = createFnInvoker([wrappedHook])
|
||||
} else {
|
||||
/* istanbul ignore if */
|
||||
if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
|
||||
// already a merged invoker
|
||||
invoker = oldHook
|
||||
invoker.fns.push(wrappedHook)
|
||||
} else {
|
||||
// existing plain hook
|
||||
invoker = createFnInvoker([oldHook, wrappedHook])
|
||||
}
|
||||
}
|
||||
|
||||
invoker.merged = true
|
||||
def[hookKey] = invoker
|
||||
}
|
89
express-server/node_modules/vue/src/core/vdom/helpers/normalize-children.js
generated
vendored
Normal file
89
express-server/node_modules/vue/src/core/vdom/helpers/normalize-children.js
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/* @flow */
|
||||
|
||||
import VNode, { createTextVNode } from 'core/vdom/vnode'
|
||||
import { isFalse, isTrue, isDef, isUndef, isPrimitive } from 'shared/util'
|
||||
|
||||
// The template compiler attempts to minimize the need for normalization by
|
||||
// statically analyzing the template at compile time.
|
||||
//
|
||||
// For plain HTML markup, normalization can be completely skipped because the
|
||||
// generated render function is guaranteed to return Array<VNode>. There are
|
||||
// two cases where extra normalization is needed:
|
||||
|
||||
// 1. When the children contains components - because a functional component
|
||||
// may return an Array instead of a single root. In this case, just a simple
|
||||
// normalization is needed - if any child is an Array, we flatten the whole
|
||||
// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
|
||||
// because functional components already normalize their own children.
|
||||
export function simpleNormalizeChildren (children: any) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (Array.isArray(children[i])) {
|
||||
return Array.prototype.concat.apply([], children)
|
||||
}
|
||||
}
|
||||
return children
|
||||
}
|
||||
|
||||
// 2. When the children contains constructs that always generated nested Arrays,
|
||||
// e.g. <template>, <slot>, v-for, or when the children is provided by user
|
||||
// with hand-written render functions / JSX. In such cases a full normalization
|
||||
// is needed to cater to all possible types of children values.
|
||||
export function normalizeChildren (children: any): ?Array<VNode> {
|
||||
return isPrimitive(children)
|
||||
? [createTextVNode(children)]
|
||||
: Array.isArray(children)
|
||||
? normalizeArrayChildren(children)
|
||||
: undefined
|
||||
}
|
||||
|
||||
function isTextNode (node): boolean {
|
||||
return isDef(node) && isDef(node.text) && isFalse(node.isComment)
|
||||
}
|
||||
|
||||
function normalizeArrayChildren (children: any, nestedIndex?: string): Array<VNode> {
|
||||
const res = []
|
||||
let i, c, lastIndex, last
|
||||
for (i = 0; i < children.length; i++) {
|
||||
c = children[i]
|
||||
if (isUndef(c) || typeof c === 'boolean') continue
|
||||
lastIndex = res.length - 1
|
||||
last = res[lastIndex]
|
||||
// nested
|
||||
if (Array.isArray(c)) {
|
||||
if (c.length > 0) {
|
||||
c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`)
|
||||
// merge adjacent text nodes
|
||||
if (isTextNode(c[0]) && isTextNode(last)) {
|
||||
res[lastIndex] = createTextVNode(last.text + (c[0]: any).text)
|
||||
c.shift()
|
||||
}
|
||||
res.push.apply(res, c)
|
||||
}
|
||||
} else if (isPrimitive(c)) {
|
||||
if (isTextNode(last)) {
|
||||
// merge adjacent text nodes
|
||||
// this is necessary for SSR hydration because text nodes are
|
||||
// essentially merged when rendered to HTML strings
|
||||
res[lastIndex] = createTextVNode(last.text + c)
|
||||
} else if (c !== '') {
|
||||
// convert primitive to vnode
|
||||
res.push(createTextVNode(c))
|
||||
}
|
||||
} else {
|
||||
if (isTextNode(c) && isTextNode(last)) {
|
||||
// merge adjacent text nodes
|
||||
res[lastIndex] = createTextVNode(last.text + c.text)
|
||||
} else {
|
||||
// default key for nested array children (likely generated by v-for)
|
||||
if (isTrue(children._isVList) &&
|
||||
isDef(c.tag) &&
|
||||
isUndef(c.key) &&
|
||||
isDef(nestedIndex)) {
|
||||
c.key = `__vlist${nestedIndex}_${i}__`
|
||||
}
|
||||
res.push(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
84
express-server/node_modules/vue/src/core/vdom/helpers/normalize-scoped-slots.js
generated
vendored
Normal file
84
express-server/node_modules/vue/src/core/vdom/helpers/normalize-scoped-slots.js
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/* @flow */
|
||||
|
||||
import { def } from 'core/util/lang'
|
||||
import { normalizeChildren } from 'core/vdom/helpers/normalize-children'
|
||||
import { emptyObject } from 'shared/util'
|
||||
|
||||
export function normalizeScopedSlots (
|
||||
slots: { [key: string]: Function } | void,
|
||||
normalSlots: { [key: string]: Array<VNode> },
|
||||
prevSlots?: { [key: string]: Function } | void
|
||||
): any {
|
||||
let res
|
||||
const isStable = slots ? !!slots.$stable : true
|
||||
const hasNormalSlots = Object.keys(normalSlots).length > 0
|
||||
const key = slots && slots.$key
|
||||
if (!slots) {
|
||||
res = {}
|
||||
} else if (slots._normalized) {
|
||||
// fast path 1: child component re-render only, parent did not change
|
||||
return slots._normalized
|
||||
} else if (
|
||||
isStable &&
|
||||
prevSlots &&
|
||||
prevSlots !== emptyObject &&
|
||||
key === prevSlots.$key &&
|
||||
!hasNormalSlots &&
|
||||
!prevSlots.$hasNormal
|
||||
) {
|
||||
// fast path 2: stable scoped slots w/ no normal slots to proxy,
|
||||
// only need to normalize once
|
||||
return prevSlots
|
||||
} else {
|
||||
res = {}
|
||||
for (const key in slots) {
|
||||
if (slots[key] && key[0] !== '$') {
|
||||
res[key] = normalizeScopedSlot(normalSlots, key, slots[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
// expose normal slots on scopedSlots
|
||||
for (const key in normalSlots) {
|
||||
if (!(key in res)) {
|
||||
res[key] = proxyNormalSlot(normalSlots, key)
|
||||
}
|
||||
}
|
||||
// avoriaz seems to mock a non-extensible $scopedSlots object
|
||||
// and when that is passed down this would cause an error
|
||||
if (slots && Object.isExtensible(slots)) {
|
||||
(slots: any)._normalized = res
|
||||
}
|
||||
def(res, '$stable', isStable)
|
||||
def(res, '$key', key)
|
||||
def(res, '$hasNormal', hasNormalSlots)
|
||||
return res
|
||||
}
|
||||
|
||||
function normalizeScopedSlot(normalSlots, key, fn) {
|
||||
const normalized = function () {
|
||||
let res = arguments.length ? fn.apply(null, arguments) : fn({})
|
||||
res = res && typeof res === 'object' && !Array.isArray(res)
|
||||
? [res] // single vnode
|
||||
: normalizeChildren(res)
|
||||
return res && (
|
||||
res.length === 0 ||
|
||||
(res.length === 1 && res[0].isComment) // #9658
|
||||
) ? undefined
|
||||
: res
|
||||
}
|
||||
// this is a slot using the new v-slot syntax without scope. although it is
|
||||
// compiled as a scoped slot, render fn users would expect it to be present
|
||||
// on this.$slots because the usage is semantically a normal slot.
|
||||
if (fn.proxy) {
|
||||
Object.defineProperty(normalSlots, key, {
|
||||
get: normalized,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
})
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
|
||||
function proxyNormalSlot(slots, key) {
|
||||
return () => slots[key]
|
||||
}
|
153
express-server/node_modules/vue/src/core/vdom/helpers/resolve-async-component.js
generated
vendored
Normal file
153
express-server/node_modules/vue/src/core/vdom/helpers/resolve-async-component.js
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
warn,
|
||||
once,
|
||||
isDef,
|
||||
isUndef,
|
||||
isTrue,
|
||||
isObject,
|
||||
hasSymbol,
|
||||
isPromise,
|
||||
remove
|
||||
} from 'core/util/index'
|
||||
|
||||
import { createEmptyVNode } from 'core/vdom/vnode'
|
||||
import { currentRenderingInstance } from 'core/instance/render'
|
||||
|
||||
function ensureCtor (comp: any, base) {
|
||||
if (
|
||||
comp.__esModule ||
|
||||
(hasSymbol && comp[Symbol.toStringTag] === 'Module')
|
||||
) {
|
||||
comp = comp.default
|
||||
}
|
||||
return isObject(comp)
|
||||
? base.extend(comp)
|
||||
: comp
|
||||
}
|
||||
|
||||
export function createAsyncPlaceholder (
|
||||
factory: Function,
|
||||
data: ?VNodeData,
|
||||
context: Component,
|
||||
children: ?Array<VNode>,
|
||||
tag: ?string
|
||||
): VNode {
|
||||
const node = createEmptyVNode()
|
||||
node.asyncFactory = factory
|
||||
node.asyncMeta = { data, context, children, tag }
|
||||
return node
|
||||
}
|
||||
|
||||
export function resolveAsyncComponent (
|
||||
factory: Function,
|
||||
baseCtor: Class<Component>
|
||||
): Class<Component> | void {
|
||||
if (isTrue(factory.error) && isDef(factory.errorComp)) {
|
||||
return factory.errorComp
|
||||
}
|
||||
|
||||
if (isDef(factory.resolved)) {
|
||||
return factory.resolved
|
||||
}
|
||||
|
||||
const owner = currentRenderingInstance
|
||||
if (owner && isDef(factory.owners) && factory.owners.indexOf(owner) === -1) {
|
||||
// already pending
|
||||
factory.owners.push(owner)
|
||||
}
|
||||
|
||||
if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
|
||||
return factory.loadingComp
|
||||
}
|
||||
|
||||
if (owner && !isDef(factory.owners)) {
|
||||
const owners = factory.owners = [owner]
|
||||
let sync = true
|
||||
|
||||
;(owner: any).$on('hook:destroyed', () => remove(owners, owner))
|
||||
|
||||
const forceRender = (renderCompleted: boolean) => {
|
||||
for (let i = 0, l = owners.length; i < l; i++) {
|
||||
(owners[i]: any).$forceUpdate()
|
||||
}
|
||||
|
||||
if (renderCompleted) {
|
||||
owners.length = 0
|
||||
}
|
||||
}
|
||||
|
||||
const resolve = once((res: Object | Class<Component>) => {
|
||||
// cache resolved
|
||||
factory.resolved = ensureCtor(res, baseCtor)
|
||||
// invoke callbacks only if this is not a synchronous resolve
|
||||
// (async resolves are shimmed as synchronous during SSR)
|
||||
if (!sync) {
|
||||
forceRender(true)
|
||||
} else {
|
||||
owners.length = 0
|
||||
}
|
||||
})
|
||||
|
||||
const reject = once(reason => {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`Failed to resolve async component: ${String(factory)}` +
|
||||
(reason ? `\nReason: ${reason}` : '')
|
||||
)
|
||||
if (isDef(factory.errorComp)) {
|
||||
factory.error = true
|
||||
forceRender(true)
|
||||
}
|
||||
})
|
||||
|
||||
const res = factory(resolve, reject)
|
||||
|
||||
if (isObject(res)) {
|
||||
if (isPromise(res)) {
|
||||
// () => Promise
|
||||
if (isUndef(factory.resolved)) {
|
||||
res.then(resolve, reject)
|
||||
}
|
||||
} else if (isPromise(res.component)) {
|
||||
res.component.then(resolve, reject)
|
||||
|
||||
if (isDef(res.error)) {
|
||||
factory.errorComp = ensureCtor(res.error, baseCtor)
|
||||
}
|
||||
|
||||
if (isDef(res.loading)) {
|
||||
factory.loadingComp = ensureCtor(res.loading, baseCtor)
|
||||
if (res.delay === 0) {
|
||||
factory.loading = true
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
if (isUndef(factory.resolved) && isUndef(factory.error)) {
|
||||
factory.loading = true
|
||||
forceRender(false)
|
||||
}
|
||||
}, res.delay || 200)
|
||||
}
|
||||
}
|
||||
|
||||
if (isDef(res.timeout)) {
|
||||
setTimeout(() => {
|
||||
if (isUndef(factory.resolved)) {
|
||||
reject(
|
||||
process.env.NODE_ENV !== 'production'
|
||||
? `timeout (${res.timeout}ms)`
|
||||
: null
|
||||
)
|
||||
}
|
||||
}, res.timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sync = false
|
||||
// return in case resolved synchronously
|
||||
return factory.loading
|
||||
? factory.loadingComp
|
||||
: factory.resolved
|
||||
}
|
||||
}
|
95
express-server/node_modules/vue/src/core/vdom/helpers/update-listeners.js
generated
vendored
Normal file
95
express-server/node_modules/vue/src/core/vdom/helpers/update-listeners.js
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/* @flow */
|
||||
|
||||
import {
|
||||
warn,
|
||||
invokeWithErrorHandling
|
||||
} from 'core/util/index'
|
||||
import {
|
||||
cached,
|
||||
isUndef,
|
||||
isTrue,
|
||||
isPlainObject
|
||||
} from 'shared/util'
|
||||
|
||||
const normalizeEvent = cached((name: string): {
|
||||
name: string,
|
||||
once: boolean,
|
||||
capture: boolean,
|
||||
passive: boolean,
|
||||
handler?: Function,
|
||||
params?: Array<any>
|
||||
} => {
|
||||
const passive = name.charAt(0) === '&'
|
||||
name = passive ? name.slice(1) : name
|
||||
const once = name.charAt(0) === '~' // Prefixed last, checked first
|
||||
name = once ? name.slice(1) : name
|
||||
const capture = name.charAt(0) === '!'
|
||||
name = capture ? name.slice(1) : name
|
||||
return {
|
||||
name,
|
||||
once,
|
||||
capture,
|
||||
passive
|
||||
}
|
||||
})
|
||||
|
||||
export function createFnInvoker (fns: Function | Array<Function>, vm: ?Component): Function {
|
||||
function invoker () {
|
||||
const fns = invoker.fns
|
||||
if (Array.isArray(fns)) {
|
||||
const cloned = fns.slice()
|
||||
for (let i = 0; i < cloned.length; i++) {
|
||||
invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`)
|
||||
}
|
||||
} else {
|
||||
// return handler return value for single handlers
|
||||
return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
|
||||
}
|
||||
}
|
||||
invoker.fns = fns
|
||||
return invoker
|
||||
}
|
||||
|
||||
export function updateListeners (
|
||||
on: Object,
|
||||
oldOn: Object,
|
||||
add: Function,
|
||||
remove: Function,
|
||||
createOnceHandler: Function,
|
||||
vm: Component
|
||||
) {
|
||||
let name, def, cur, old, event
|
||||
for (name in on) {
|
||||
def = cur = on[name]
|
||||
old = oldOn[name]
|
||||
event = normalizeEvent(name)
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && isPlainObject(def)) {
|
||||
cur = def.handler
|
||||
event.params = def.params
|
||||
}
|
||||
if (isUndef(cur)) {
|
||||
process.env.NODE_ENV !== 'production' && warn(
|
||||
`Invalid handler for event "${event.name}": got ` + String(cur),
|
||||
vm
|
||||
)
|
||||
} else if (isUndef(old)) {
|
||||
if (isUndef(cur.fns)) {
|
||||
cur = on[name] = createFnInvoker(cur, vm)
|
||||
}
|
||||
if (isTrue(event.once)) {
|
||||
cur = on[name] = createOnceHandler(event.name, cur, event.capture)
|
||||
}
|
||||
add(event.name, cur, event.capture, event.passive, event.params)
|
||||
} else if (cur !== old) {
|
||||
old.fns = cur
|
||||
on[name] = old
|
||||
}
|
||||
}
|
||||
for (name in oldOn) {
|
||||
if (isUndef(on[name])) {
|
||||
event = normalizeEvent(name)
|
||||
remove(event.name, oldOn[name], event.capture)
|
||||
}
|
||||
}
|
||||
}
|
120
express-server/node_modules/vue/src/core/vdom/modules/directives.js
generated
vendored
Normal file
120
express-server/node_modules/vue/src/core/vdom/modules/directives.js
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/* @flow */
|
||||
|
||||
import { emptyNode } from 'core/vdom/patch'
|
||||
import { resolveAsset, handleError } from 'core/util/index'
|
||||
import { mergeVNodeHook } from 'core/vdom/helpers/index'
|
||||
|
||||
export default {
|
||||
create: updateDirectives,
|
||||
update: updateDirectives,
|
||||
destroy: function unbindDirectives (vnode: VNodeWithData) {
|
||||
updateDirectives(vnode, emptyNode)
|
||||
}
|
||||
}
|
||||
|
||||
function updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
||||
if (oldVnode.data.directives || vnode.data.directives) {
|
||||
_update(oldVnode, vnode)
|
||||
}
|
||||
}
|
||||
|
||||
function _update (oldVnode, vnode) {
|
||||
const isCreate = oldVnode === emptyNode
|
||||
const isDestroy = vnode === emptyNode
|
||||
const oldDirs = normalizeDirectives(oldVnode.data.directives, oldVnode.context)
|
||||
const newDirs = normalizeDirectives(vnode.data.directives, vnode.context)
|
||||
|
||||
const dirsWithInsert = []
|
||||
const dirsWithPostpatch = []
|
||||
|
||||
let key, oldDir, dir
|
||||
for (key in newDirs) {
|
||||
oldDir = oldDirs[key]
|
||||
dir = newDirs[key]
|
||||
if (!oldDir) {
|
||||
// new directive, bind
|
||||
callHook(dir, 'bind', vnode, oldVnode)
|
||||
if (dir.def && dir.def.inserted) {
|
||||
dirsWithInsert.push(dir)
|
||||
}
|
||||
} else {
|
||||
// existing directive, update
|
||||
dir.oldValue = oldDir.value
|
||||
dir.oldArg = oldDir.arg
|
||||
callHook(dir, 'update', vnode, oldVnode)
|
||||
if (dir.def && dir.def.componentUpdated) {
|
||||
dirsWithPostpatch.push(dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dirsWithInsert.length) {
|
||||
const callInsert = () => {
|
||||
for (let i = 0; i < dirsWithInsert.length; i++) {
|
||||
callHook(dirsWithInsert[i], 'inserted', vnode, oldVnode)
|
||||
}
|
||||
}
|
||||
if (isCreate) {
|
||||
mergeVNodeHook(vnode, 'insert', callInsert)
|
||||
} else {
|
||||
callInsert()
|
||||
}
|
||||
}
|
||||
|
||||
if (dirsWithPostpatch.length) {
|
||||
mergeVNodeHook(vnode, 'postpatch', () => {
|
||||
for (let i = 0; i < dirsWithPostpatch.length; i++) {
|
||||
callHook(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!isCreate) {
|
||||
for (key in oldDirs) {
|
||||
if (!newDirs[key]) {
|
||||
// no longer present, unbind
|
||||
callHook(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const emptyModifiers = Object.create(null)
|
||||
|
||||
function normalizeDirectives (
|
||||
dirs: ?Array<VNodeDirective>,
|
||||
vm: Component
|
||||
): { [key: string]: VNodeDirective } {
|
||||
const res = Object.create(null)
|
||||
if (!dirs) {
|
||||
// $flow-disable-line
|
||||
return res
|
||||
}
|
||||
let i, dir
|
||||
for (i = 0; i < dirs.length; i++) {
|
||||
dir = dirs[i]
|
||||
if (!dir.modifiers) {
|
||||
// $flow-disable-line
|
||||
dir.modifiers = emptyModifiers
|
||||
}
|
||||
res[getRawDirName(dir)] = dir
|
||||
dir.def = resolveAsset(vm.$options, 'directives', dir.name, true)
|
||||
}
|
||||
// $flow-disable-line
|
||||
return res
|
||||
}
|
||||
|
||||
function getRawDirName (dir: VNodeDirective): string {
|
||||
return dir.rawName || `${dir.name}.${Object.keys(dir.modifiers || {}).join('.')}`
|
||||
}
|
||||
|
||||
function callHook (dir, hook, vnode, oldVnode, isDestroy) {
|
||||
const fn = dir.def && dir.def[hook]
|
||||
if (fn) {
|
||||
try {
|
||||
fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
|
||||
} catch (e) {
|
||||
handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`)
|
||||
}
|
||||
}
|
||||
}
|
7
express-server/node_modules/vue/src/core/vdom/modules/index.js
generated
vendored
Normal file
7
express-server/node_modules/vue/src/core/vdom/modules/index.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import directives from './directives'
|
||||
import ref from './ref'
|
||||
|
||||
export default [
|
||||
ref,
|
||||
directives
|
||||
]
|
45
express-server/node_modules/vue/src/core/vdom/modules/ref.js
generated
vendored
Normal file
45
express-server/node_modules/vue/src/core/vdom/modules/ref.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/* @flow */
|
||||
|
||||
import { remove, isDef } from 'shared/util'
|
||||
|
||||
export default {
|
||||
create (_: any, vnode: VNodeWithData) {
|
||||
registerRef(vnode)
|
||||
},
|
||||
update (oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
||||
if (oldVnode.data.ref !== vnode.data.ref) {
|
||||
registerRef(oldVnode, true)
|
||||
registerRef(vnode)
|
||||
}
|
||||
},
|
||||
destroy (vnode: VNodeWithData) {
|
||||
registerRef(vnode, true)
|
||||
}
|
||||
}
|
||||
|
||||
export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) {
|
||||
const key = vnode.data.ref
|
||||
if (!isDef(key)) return
|
||||
|
||||
const vm = vnode.context
|
||||
const ref = vnode.componentInstance || vnode.elm
|
||||
const refs = vm.$refs
|
||||
if (isRemoval) {
|
||||
if (Array.isArray(refs[key])) {
|
||||
remove(refs[key], ref)
|
||||
} else if (refs[key] === ref) {
|
||||
refs[key] = undefined
|
||||
}
|
||||
} else {
|
||||
if (vnode.data.refInFor) {
|
||||
if (!Array.isArray(refs[key])) {
|
||||
refs[key] = [ref]
|
||||
} else if (refs[key].indexOf(ref) < 0) {
|
||||
// $flow-disable-line
|
||||
refs[key].push(ref)
|
||||
}
|
||||
} else {
|
||||
refs[key] = ref
|
||||
}
|
||||
}
|
||||
}
|
803
express-server/node_modules/vue/src/core/vdom/patch.js
generated
vendored
Normal file
803
express-server/node_modules/vue/src/core/vdom/patch.js
generated
vendored
Normal file
@ -0,0 +1,803 @@
|
||||
/**
|
||||
* Virtual DOM patching algorithm based on Snabbdom by
|
||||
* Simon Friis Vindum (@paldepind)
|
||||
* Licensed under the MIT License
|
||||
* https://github.com/paldepind/snabbdom/blob/master/LICENSE
|
||||
*
|
||||
* modified by Evan You (@yyx990803)
|
||||
*
|
||||
* Not type-checking this because this file is perf-critical and the cost
|
||||
* of making flow understand it is not worth it.
|
||||
*/
|
||||
|
||||
import VNode, { cloneVNode } from './vnode'
|
||||
import config from '../config'
|
||||
import { SSR_ATTR } from 'shared/constants'
|
||||
import { registerRef } from './modules/ref'
|
||||
import { traverse } from '../observer/traverse'
|
||||
import { activeInstance } from '../instance/lifecycle'
|
||||
import { isTextInputType } from 'web/util/element'
|
||||
|
||||
import {
|
||||
warn,
|
||||
isDef,
|
||||
isUndef,
|
||||
isTrue,
|
||||
makeMap,
|
||||
isRegExp,
|
||||
isPrimitive
|
||||
} from '../util/index'
|
||||
|
||||
export const emptyNode = new VNode('', {}, [])
|
||||
|
||||
const hooks = ['create', 'activate', 'update', 'remove', 'destroy']
|
||||
|
||||
function sameVnode (a, b) {
|
||||
return (
|
||||
a.key === b.key && (
|
||||
(
|
||||
a.tag === b.tag &&
|
||||
a.isComment === b.isComment &&
|
||||
isDef(a.data) === isDef(b.data) &&
|
||||
sameInputType(a, b)
|
||||
) || (
|
||||
isTrue(a.isAsyncPlaceholder) &&
|
||||
a.asyncFactory === b.asyncFactory &&
|
||||
isUndef(b.asyncFactory.error)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
function sameInputType (a, b) {
|
||||
if (a.tag !== 'input') return true
|
||||
let i
|
||||
const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type
|
||||
const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type
|
||||
return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
|
||||
}
|
||||
|
||||
function createKeyToOldIdx (children, beginIdx, endIdx) {
|
||||
let i, key
|
||||
const map = {}
|
||||
for (i = beginIdx; i <= endIdx; ++i) {
|
||||
key = children[i].key
|
||||
if (isDef(key)) map[key] = i
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
export function createPatchFunction (backend) {
|
||||
let i, j
|
||||
const cbs = {}
|
||||
|
||||
const { modules, nodeOps } = backend
|
||||
|
||||
for (i = 0; i < hooks.length; ++i) {
|
||||
cbs[hooks[i]] = []
|
||||
for (j = 0; j < modules.length; ++j) {
|
||||
if (isDef(modules[j][hooks[i]])) {
|
||||
cbs[hooks[i]].push(modules[j][hooks[i]])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emptyNodeAt (elm) {
|
||||
return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
|
||||
}
|
||||
|
||||
function createRmCb (childElm, listeners) {
|
||||
function remove () {
|
||||
if (--remove.listeners === 0) {
|
||||
removeNode(childElm)
|
||||
}
|
||||
}
|
||||
remove.listeners = listeners
|
||||
return remove
|
||||
}
|
||||
|
||||
function removeNode (el) {
|
||||
const parent = nodeOps.parentNode(el)
|
||||
// element may have already been removed due to v-html / v-text
|
||||
if (isDef(parent)) {
|
||||
nodeOps.removeChild(parent, el)
|
||||
}
|
||||
}
|
||||
|
||||
function isUnknownElement (vnode, inVPre) {
|
||||
return (
|
||||
!inVPre &&
|
||||
!vnode.ns &&
|
||||
!(
|
||||
config.ignoredElements.length &&
|
||||
config.ignoredElements.some(ignore => {
|
||||
return isRegExp(ignore)
|
||||
? ignore.test(vnode.tag)
|
||||
: ignore === vnode.tag
|
||||
})
|
||||
) &&
|
||||
config.isUnknownElement(vnode.tag)
|
||||
)
|
||||
}
|
||||
|
||||
let creatingElmInVPre = 0
|
||||
|
||||
function createElm (
|
||||
vnode,
|
||||
insertedVnodeQueue,
|
||||
parentElm,
|
||||
refElm,
|
||||
nested,
|
||||
ownerArray,
|
||||
index
|
||||
) {
|
||||
if (isDef(vnode.elm) && isDef(ownerArray)) {
|
||||
// This vnode was used in a previous render!
|
||||
// now it's used as a new node, overwriting its elm would cause
|
||||
// potential patch errors down the road when it's used as an insertion
|
||||
// reference node. Instead, we clone the node on-demand before creating
|
||||
// associated DOM element for it.
|
||||
vnode = ownerArray[index] = cloneVNode(vnode)
|
||||
}
|
||||
|
||||
vnode.isRootInsert = !nested // for transition enter check
|
||||
if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
|
||||
return
|
||||
}
|
||||
|
||||
const data = vnode.data
|
||||
const children = vnode.children
|
||||
const tag = vnode.tag
|
||||
if (isDef(tag)) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (data && data.pre) {
|
||||
creatingElmInVPre++
|
||||
}
|
||||
if (isUnknownElement(vnode, creatingElmInVPre)) {
|
||||
warn(
|
||||
'Unknown custom element: <' + tag + '> - did you ' +
|
||||
'register the component correctly? For recursive components, ' +
|
||||
'make sure to provide the "name" option.',
|
||||
vnode.context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
vnode.elm = vnode.ns
|
||||
? nodeOps.createElementNS(vnode.ns, tag)
|
||||
: nodeOps.createElement(tag, vnode)
|
||||
setScope(vnode)
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__) {
|
||||
// in Weex, the default insertion order is parent-first.
|
||||
// List items can be optimized to use children-first insertion
|
||||
// with append="tree".
|
||||
const appendAsTree = isDef(data) && isTrue(data.appendAsTree)
|
||||
if (!appendAsTree) {
|
||||
if (isDef(data)) {
|
||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||
}
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
}
|
||||
createChildren(vnode, children, insertedVnodeQueue)
|
||||
if (appendAsTree) {
|
||||
if (isDef(data)) {
|
||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||
}
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
}
|
||||
} else {
|
||||
createChildren(vnode, children, insertedVnodeQueue)
|
||||
if (isDef(data)) {
|
||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||
}
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' && data && data.pre) {
|
||||
creatingElmInVPre--
|
||||
}
|
||||
} else if (isTrue(vnode.isComment)) {
|
||||
vnode.elm = nodeOps.createComment(vnode.text)
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
} else {
|
||||
vnode.elm = nodeOps.createTextNode(vnode.text)
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
}
|
||||
}
|
||||
|
||||
function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
|
||||
let i = vnode.data
|
||||
if (isDef(i)) {
|
||||
const isReactivated = isDef(vnode.componentInstance) && i.keepAlive
|
||||
if (isDef(i = i.hook) && isDef(i = i.init)) {
|
||||
i(vnode, false /* hydrating */)
|
||||
}
|
||||
// after calling the init hook, if the vnode is a child component
|
||||
// it should've created a child instance and mounted it. the child
|
||||
// component also has set the placeholder vnode's elm.
|
||||
// in that case we can just return the element and be done.
|
||||
if (isDef(vnode.componentInstance)) {
|
||||
initComponent(vnode, insertedVnodeQueue)
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
if (isTrue(isReactivated)) {
|
||||
reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initComponent (vnode, insertedVnodeQueue) {
|
||||
if (isDef(vnode.data.pendingInsert)) {
|
||||
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)
|
||||
vnode.data.pendingInsert = null
|
||||
}
|
||||
vnode.elm = vnode.componentInstance.$el
|
||||
if (isPatchable(vnode)) {
|
||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||
setScope(vnode)
|
||||
} else {
|
||||
// empty component root.
|
||||
// skip all element-related modules except for ref (#3455)
|
||||
registerRef(vnode)
|
||||
// make sure to invoke the insert hook
|
||||
insertedVnodeQueue.push(vnode)
|
||||
}
|
||||
}
|
||||
|
||||
function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
|
||||
let i
|
||||
// hack for #4339: a reactivated component with inner transition
|
||||
// does not trigger because the inner node's created hooks are not called
|
||||
// again. It's not ideal to involve module-specific logic in here but
|
||||
// there doesn't seem to be a better way to do it.
|
||||
let innerNode = vnode
|
||||
while (innerNode.componentInstance) {
|
||||
innerNode = innerNode.componentInstance._vnode
|
||||
if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
|
||||
for (i = 0; i < cbs.activate.length; ++i) {
|
||||
cbs.activate[i](emptyNode, innerNode)
|
||||
}
|
||||
insertedVnodeQueue.push(innerNode)
|
||||
break
|
||||
}
|
||||
}
|
||||
// unlike a newly created component,
|
||||
// a reactivated keep-alive component doesn't insert itself
|
||||
insert(parentElm, vnode.elm, refElm)
|
||||
}
|
||||
|
||||
function insert (parent, elm, ref) {
|
||||
if (isDef(parent)) {
|
||||
if (isDef(ref)) {
|
||||
if (nodeOps.parentNode(ref) === parent) {
|
||||
nodeOps.insertBefore(parent, elm, ref)
|
||||
}
|
||||
} else {
|
||||
nodeOps.appendChild(parent, elm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createChildren (vnode, children, insertedVnodeQueue) {
|
||||
if (Array.isArray(children)) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkDuplicateKeys(children)
|
||||
}
|
||||
for (let i = 0; i < children.length; ++i) {
|
||||
createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i)
|
||||
}
|
||||
} else if (isPrimitive(vnode.text)) {
|
||||
nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))
|
||||
}
|
||||
}
|
||||
|
||||
function isPatchable (vnode) {
|
||||
while (vnode.componentInstance) {
|
||||
vnode = vnode.componentInstance._vnode
|
||||
}
|
||||
return isDef(vnode.tag)
|
||||
}
|
||||
|
||||
function invokeCreateHooks (vnode, insertedVnodeQueue) {
|
||||
for (let i = 0; i < cbs.create.length; ++i) {
|
||||
cbs.create[i](emptyNode, vnode)
|
||||
}
|
||||
i = vnode.data.hook // Reuse variable
|
||||
if (isDef(i)) {
|
||||
if (isDef(i.create)) i.create(emptyNode, vnode)
|
||||
if (isDef(i.insert)) insertedVnodeQueue.push(vnode)
|
||||
}
|
||||
}
|
||||
|
||||
// set scope id attribute for scoped CSS.
|
||||
// this is implemented as a special case to avoid the overhead
|
||||
// of going through the normal attribute patching process.
|
||||
function setScope (vnode) {
|
||||
let i
|
||||
if (isDef(i = vnode.fnScopeId)) {
|
||||
nodeOps.setStyleScope(vnode.elm, i)
|
||||
} else {
|
||||
let ancestor = vnode
|
||||
while (ancestor) {
|
||||
if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
|
||||
nodeOps.setStyleScope(vnode.elm, i)
|
||||
}
|
||||
ancestor = ancestor.parent
|
||||
}
|
||||
}
|
||||
// for slot content they should also get the scopeId from the host instance.
|
||||
if (isDef(i = activeInstance) &&
|
||||
i !== vnode.context &&
|
||||
i !== vnode.fnContext &&
|
||||
isDef(i = i.$options._scopeId)
|
||||
) {
|
||||
nodeOps.setStyleScope(vnode.elm, i)
|
||||
}
|
||||
}
|
||||
|
||||
function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
|
||||
for (; startIdx <= endIdx; ++startIdx) {
|
||||
createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx)
|
||||
}
|
||||
}
|
||||
|
||||
function invokeDestroyHook (vnode) {
|
||||
let i, j
|
||||
const data = vnode.data
|
||||
if (isDef(data)) {
|
||||
if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode)
|
||||
for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode)
|
||||
}
|
||||
if (isDef(i = vnode.children)) {
|
||||
for (j = 0; j < vnode.children.length; ++j) {
|
||||
invokeDestroyHook(vnode.children[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
|
||||
for (; startIdx <= endIdx; ++startIdx) {
|
||||
const ch = vnodes[startIdx]
|
||||
if (isDef(ch)) {
|
||||
if (isDef(ch.tag)) {
|
||||
removeAndInvokeRemoveHook(ch)
|
||||
invokeDestroyHook(ch)
|
||||
} else { // Text node
|
||||
removeNode(ch.elm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeAndInvokeRemoveHook (vnode, rm) {
|
||||
if (isDef(rm) || isDef(vnode.data)) {
|
||||
let i
|
||||
const listeners = cbs.remove.length + 1
|
||||
if (isDef(rm)) {
|
||||
// we have a recursively passed down rm callback
|
||||
// increase the listeners count
|
||||
rm.listeners += listeners
|
||||
} else {
|
||||
// directly removing
|
||||
rm = createRmCb(vnode.elm, listeners)
|
||||
}
|
||||
// recursively invoke hooks on child component root node
|
||||
if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
|
||||
removeAndInvokeRemoveHook(i, rm)
|
||||
}
|
||||
for (i = 0; i < cbs.remove.length; ++i) {
|
||||
cbs.remove[i](vnode, rm)
|
||||
}
|
||||
if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
|
||||
i(vnode, rm)
|
||||
} else {
|
||||
rm()
|
||||
}
|
||||
} else {
|
||||
removeNode(vnode.elm)
|
||||
}
|
||||
}
|
||||
|
||||
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
|
||||
let oldStartIdx = 0
|
||||
let newStartIdx = 0
|
||||
let oldEndIdx = oldCh.length - 1
|
||||
let oldStartVnode = oldCh[0]
|
||||
let oldEndVnode = oldCh[oldEndIdx]
|
||||
let newEndIdx = newCh.length - 1
|
||||
let newStartVnode = newCh[0]
|
||||
let newEndVnode = newCh[newEndIdx]
|
||||
let oldKeyToIdx, idxInOld, vnodeToMove, refElm
|
||||
|
||||
// removeOnly is a special flag used only by <transition-group>
|
||||
// to ensure removed elements stay in correct relative positions
|
||||
// during leaving transitions
|
||||
const canMove = !removeOnly
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkDuplicateKeys(newCh)
|
||||
}
|
||||
|
||||
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
||||
if (isUndef(oldStartVnode)) {
|
||||
oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left
|
||||
} else if (isUndef(oldEndVnode)) {
|
||||
oldEndVnode = oldCh[--oldEndIdx]
|
||||
} else if (sameVnode(oldStartVnode, newStartVnode)) {
|
||||
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
|
||||
oldStartVnode = oldCh[++oldStartIdx]
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
} else if (sameVnode(oldEndVnode, newEndVnode)) {
|
||||
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)
|
||||
oldEndVnode = oldCh[--oldEndIdx]
|
||||
newEndVnode = newCh[--newEndIdx]
|
||||
} else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
|
||||
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)
|
||||
canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
|
||||
oldStartVnode = oldCh[++oldStartIdx]
|
||||
newEndVnode = newCh[--newEndIdx]
|
||||
} else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
|
||||
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
|
||||
canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
|
||||
oldEndVnode = oldCh[--oldEndIdx]
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
} else {
|
||||
if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
|
||||
idxInOld = isDef(newStartVnode.key)
|
||||
? oldKeyToIdx[newStartVnode.key]
|
||||
: findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
|
||||
if (isUndef(idxInOld)) { // New element
|
||||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
|
||||
} else {
|
||||
vnodeToMove = oldCh[idxInOld]
|
||||
if (sameVnode(vnodeToMove, newStartVnode)) {
|
||||
patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
|
||||
oldCh[idxInOld] = undefined
|
||||
canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
|
||||
} else {
|
||||
// same key but different element. treat as new element
|
||||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
|
||||
}
|
||||
}
|
||||
newStartVnode = newCh[++newStartIdx]
|
||||
}
|
||||
}
|
||||
if (oldStartIdx > oldEndIdx) {
|
||||
refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
|
||||
addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
|
||||
} else if (newStartIdx > newEndIdx) {
|
||||
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
|
||||
}
|
||||
}
|
||||
|
||||
function checkDuplicateKeys (children) {
|
||||
const seenKeys = {}
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const vnode = children[i]
|
||||
const key = vnode.key
|
||||
if (isDef(key)) {
|
||||
if (seenKeys[key]) {
|
||||
warn(
|
||||
`Duplicate keys detected: '${key}'. This may cause an update error.`,
|
||||
vnode.context
|
||||
)
|
||||
} else {
|
||||
seenKeys[key] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findIdxInOld (node, oldCh, start, end) {
|
||||
for (let i = start; i < end; i++) {
|
||||
const c = oldCh[i]
|
||||
if (isDef(c) && sameVnode(node, c)) return i
|
||||
}
|
||||
}
|
||||
|
||||
function patchVnode (
|
||||
oldVnode,
|
||||
vnode,
|
||||
insertedVnodeQueue,
|
||||
ownerArray,
|
||||
index,
|
||||
removeOnly
|
||||
) {
|
||||
if (oldVnode === vnode) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isDef(vnode.elm) && isDef(ownerArray)) {
|
||||
// clone reused vnode
|
||||
vnode = ownerArray[index] = cloneVNode(vnode)
|
||||
}
|
||||
|
||||
const elm = vnode.elm = oldVnode.elm
|
||||
|
||||
if (isTrue(oldVnode.isAsyncPlaceholder)) {
|
||||
if (isDef(vnode.asyncFactory.resolved)) {
|
||||
hydrate(oldVnode.elm, vnode, insertedVnodeQueue)
|
||||
} else {
|
||||
vnode.isAsyncPlaceholder = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// reuse element for static trees.
|
||||
// note we only do this if the vnode is cloned -
|
||||
// if the new node is not cloned it means the render functions have been
|
||||
// reset by the hot-reload-api and we need to do a proper re-render.
|
||||
if (isTrue(vnode.isStatic) &&
|
||||
isTrue(oldVnode.isStatic) &&
|
||||
vnode.key === oldVnode.key &&
|
||||
(isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
|
||||
) {
|
||||
vnode.componentInstance = oldVnode.componentInstance
|
||||
return
|
||||
}
|
||||
|
||||
let i
|
||||
const data = vnode.data
|
||||
if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
|
||||
i(oldVnode, vnode)
|
||||
}
|
||||
|
||||
const oldCh = oldVnode.children
|
||||
const ch = vnode.children
|
||||
if (isDef(data) && isPatchable(vnode)) {
|
||||
for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode)
|
||||
if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode)
|
||||
}
|
||||
if (isUndef(vnode.text)) {
|
||||
if (isDef(oldCh) && isDef(ch)) {
|
||||
if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly)
|
||||
} else if (isDef(ch)) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
checkDuplicateKeys(ch)
|
||||
}
|
||||
if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '')
|
||||
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)
|
||||
} else if (isDef(oldCh)) {
|
||||
removeVnodes(elm, oldCh, 0, oldCh.length - 1)
|
||||
} else if (isDef(oldVnode.text)) {
|
||||
nodeOps.setTextContent(elm, '')
|
||||
}
|
||||
} else if (oldVnode.text !== vnode.text) {
|
||||
nodeOps.setTextContent(elm, vnode.text)
|
||||
}
|
||||
if (isDef(data)) {
|
||||
if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode)
|
||||
}
|
||||
}
|
||||
|
||||
function invokeInsertHook (vnode, queue, initial) {
|
||||
// delay insert hooks for component root nodes, invoke them after the
|
||||
// element is really inserted
|
||||
if (isTrue(initial) && isDef(vnode.parent)) {
|
||||
vnode.parent.data.pendingInsert = queue
|
||||
} else {
|
||||
for (let i = 0; i < queue.length; ++i) {
|
||||
queue[i].data.hook.insert(queue[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let hydrationBailed = false
|
||||
// list of modules that can skip create hook during hydration because they
|
||||
// are already rendered on the client or has no need for initialization
|
||||
// Note: style is excluded because it relies on initial clone for future
|
||||
// deep updates (#7063).
|
||||
const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key')
|
||||
|
||||
// Note: this is a browser-only function so we can assume elms are DOM nodes.
|
||||
function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
|
||||
let i
|
||||
const { tag, data, children } = vnode
|
||||
inVPre = inVPre || (data && data.pre)
|
||||
vnode.elm = elm
|
||||
|
||||
if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
|
||||
vnode.isAsyncPlaceholder = true
|
||||
return true
|
||||
}
|
||||
// assert node match
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!assertNodeMatch(elm, vnode, inVPre)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (isDef(data)) {
|
||||
if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */)
|
||||
if (isDef(i = vnode.componentInstance)) {
|
||||
// child component. it should have hydrated its own tree.
|
||||
initComponent(vnode, insertedVnodeQueue)
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (isDef(tag)) {
|
||||
if (isDef(children)) {
|
||||
// empty element, allow client to pick up and populate children
|
||||
if (!elm.hasChildNodes()) {
|
||||
createChildren(vnode, children, insertedVnodeQueue)
|
||||
} else {
|
||||
// v-html and domProps: innerHTML
|
||||
if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
|
||||
if (i !== elm.innerHTML) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
typeof console !== 'undefined' &&
|
||||
!hydrationBailed
|
||||
) {
|
||||
hydrationBailed = true
|
||||
console.warn('Parent: ', elm)
|
||||
console.warn('server innerHTML: ', i)
|
||||
console.warn('client innerHTML: ', elm.innerHTML)
|
||||
}
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// iterate and compare children lists
|
||||
let childrenMatch = true
|
||||
let childNode = elm.firstChild
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {
|
||||
childrenMatch = false
|
||||
break
|
||||
}
|
||||
childNode = childNode.nextSibling
|
||||
}
|
||||
// if childNode is not null, it means the actual childNodes list is
|
||||
// longer than the virtual children list.
|
||||
if (!childrenMatch || childNode) {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
typeof console !== 'undefined' &&
|
||||
!hydrationBailed
|
||||
) {
|
||||
hydrationBailed = true
|
||||
console.warn('Parent: ', elm)
|
||||
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isDef(data)) {
|
||||
let fullInvoke = false
|
||||
for (const key in data) {
|
||||
if (!isRenderedModule(key)) {
|
||||
fullInvoke = true
|
||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!fullInvoke && data['class']) {
|
||||
// ensure collecting deps for deep class bindings for future updates
|
||||
traverse(data['class'])
|
||||
}
|
||||
}
|
||||
} else if (elm.data !== vnode.text) {
|
||||
elm.data = vnode.text
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function assertNodeMatch (node, vnode, inVPre) {
|
||||
if (isDef(vnode.tag)) {
|
||||
return vnode.tag.indexOf('vue-component') === 0 || (
|
||||
!isUnknownElement(vnode, inVPre) &&
|
||||
vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
|
||||
)
|
||||
} else {
|
||||
return node.nodeType === (vnode.isComment ? 8 : 3)
|
||||
}
|
||||
}
|
||||
|
||||
return function patch (oldVnode, vnode, hydrating, removeOnly) {
|
||||
if (isUndef(vnode)) {
|
||||
if (isDef(oldVnode)) invokeDestroyHook(oldVnode)
|
||||
return
|
||||
}
|
||||
|
||||
let isInitialPatch = false
|
||||
const insertedVnodeQueue = []
|
||||
|
||||
if (isUndef(oldVnode)) {
|
||||
// empty mount (likely as component), create new root element
|
||||
isInitialPatch = true
|
||||
createElm(vnode, insertedVnodeQueue)
|
||||
} else {
|
||||
const isRealElement = isDef(oldVnode.nodeType)
|
||||
if (!isRealElement && sameVnode(oldVnode, vnode)) {
|
||||
// patch existing root node
|
||||
patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly)
|
||||
} else {
|
||||
if (isRealElement) {
|
||||
// mounting to a real element
|
||||
// check if this is server-rendered content and if we can perform
|
||||
// a successful hydration.
|
||||
if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
|
||||
oldVnode.removeAttribute(SSR_ATTR)
|
||||
hydrating = true
|
||||
}
|
||||
if (isTrue(hydrating)) {
|
||||
if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
|
||||
invokeInsertHook(vnode, insertedVnodeQueue, true)
|
||||
return oldVnode
|
||||
} else if (process.env.NODE_ENV !== 'production') {
|
||||
warn(
|
||||
'The client-side rendered virtual DOM tree is not matching ' +
|
||||
'server-rendered content. This is likely caused by incorrect ' +
|
||||
'HTML markup, for example nesting block-level elements inside ' +
|
||||
'<p>, or missing <tbody>. Bailing hydration and performing ' +
|
||||
'full client-side render.'
|
||||
)
|
||||
}
|
||||
}
|
||||
// either not server-rendered, or hydration failed.
|
||||
// create an empty node and replace it
|
||||
oldVnode = emptyNodeAt(oldVnode)
|
||||
}
|
||||
|
||||
// replacing existing element
|
||||
const oldElm = oldVnode.elm
|
||||
const parentElm = nodeOps.parentNode(oldElm)
|
||||
|
||||
// create new node
|
||||
createElm(
|
||||
vnode,
|
||||
insertedVnodeQueue,
|
||||
// extremely rare edge case: do not insert if old element is in a
|
||||
// leaving transition. Only happens when combining transition +
|
||||
// keep-alive + HOCs. (#4590)
|
||||
oldElm._leaveCb ? null : parentElm,
|
||||
nodeOps.nextSibling(oldElm)
|
||||
)
|
||||
|
||||
// update parent placeholder node element, recursively
|
||||
if (isDef(vnode.parent)) {
|
||||
let ancestor = vnode.parent
|
||||
const patchable = isPatchable(vnode)
|
||||
while (ancestor) {
|
||||
for (let i = 0; i < cbs.destroy.length; ++i) {
|
||||
cbs.destroy[i](ancestor)
|
||||
}
|
||||
ancestor.elm = vnode.elm
|
||||
if (patchable) {
|
||||
for (let i = 0; i < cbs.create.length; ++i) {
|
||||
cbs.create[i](emptyNode, ancestor)
|
||||
}
|
||||
// #6513
|
||||
// invoke insert hooks that may have been merged by create hooks.
|
||||
// e.g. for directives that uses the "inserted" hook.
|
||||
const insert = ancestor.data.hook.insert
|
||||
if (insert.merged) {
|
||||
// start at index 1 to avoid re-invoking component mounted hook
|
||||
for (let i = 1; i < insert.fns.length; i++) {
|
||||
insert.fns[i]()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
registerRef(ancestor)
|
||||
}
|
||||
ancestor = ancestor.parent
|
||||
}
|
||||
}
|
||||
|
||||
// destroy old node
|
||||
if (isDef(parentElm)) {
|
||||
removeVnodes(parentElm, [oldVnode], 0, 0)
|
||||
} else if (isDef(oldVnode.tag)) {
|
||||
invokeDestroyHook(oldVnode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch)
|
||||
return vnode.elm
|
||||
}
|
||||
}
|
113
express-server/node_modules/vue/src/core/vdom/vnode.js
generated
vendored
Normal file
113
express-server/node_modules/vue/src/core/vdom/vnode.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/* @flow */
|
||||
|
||||
export default class VNode {
|
||||
tag: string | void;
|
||||
data: VNodeData | void;
|
||||
children: ?Array<VNode>;
|
||||
text: string | void;
|
||||
elm: Node | void;
|
||||
ns: string | void;
|
||||
context: Component | void; // rendered in this component's scope
|
||||
key: string | number | void;
|
||||
componentOptions: VNodeComponentOptions | void;
|
||||
componentInstance: Component | void; // component instance
|
||||
parent: VNode | void; // component placeholder node
|
||||
|
||||
// strictly internal
|
||||
raw: boolean; // contains raw HTML? (server only)
|
||||
isStatic: boolean; // hoisted static node
|
||||
isRootInsert: boolean; // necessary for enter transition check
|
||||
isComment: boolean; // empty comment placeholder?
|
||||
isCloned: boolean; // is a cloned node?
|
||||
isOnce: boolean; // is a v-once node?
|
||||
asyncFactory: Function | void; // async component factory function
|
||||
asyncMeta: Object | void;
|
||||
isAsyncPlaceholder: boolean;
|
||||
ssrContext: Object | void;
|
||||
fnContext: Component | void; // real context vm for functional nodes
|
||||
fnOptions: ?ComponentOptions; // for SSR caching
|
||||
devtoolsMeta: ?Object; // used to store functional render context for devtools
|
||||
fnScopeId: ?string; // functional scope id support
|
||||
|
||||
constructor (
|
||||
tag?: string,
|
||||
data?: VNodeData,
|
||||
children?: ?Array<VNode>,
|
||||
text?: string,
|
||||
elm?: Node,
|
||||
context?: Component,
|
||||
componentOptions?: VNodeComponentOptions,
|
||||
asyncFactory?: Function
|
||||
) {
|
||||
this.tag = tag
|
||||
this.data = data
|
||||
this.children = children
|
||||
this.text = text
|
||||
this.elm = elm
|
||||
this.ns = undefined
|
||||
this.context = context
|
||||
this.fnContext = undefined
|
||||
this.fnOptions = undefined
|
||||
this.fnScopeId = undefined
|
||||
this.key = data && data.key
|
||||
this.componentOptions = componentOptions
|
||||
this.componentInstance = undefined
|
||||
this.parent = undefined
|
||||
this.raw = false
|
||||
this.isStatic = false
|
||||
this.isRootInsert = true
|
||||
this.isComment = false
|
||||
this.isCloned = false
|
||||
this.isOnce = false
|
||||
this.asyncFactory = asyncFactory
|
||||
this.asyncMeta = undefined
|
||||
this.isAsyncPlaceholder = false
|
||||
}
|
||||
|
||||
// DEPRECATED: alias for componentInstance for backwards compat.
|
||||
/* istanbul ignore next */
|
||||
get child (): Component | void {
|
||||
return this.componentInstance
|
||||
}
|
||||
}
|
||||
|
||||
export const createEmptyVNode = (text: string = '') => {
|
||||
const node = new VNode()
|
||||
node.text = text
|
||||
node.isComment = true
|
||||
return node
|
||||
}
|
||||
|
||||
export function createTextVNode (val: string | number) {
|
||||
return new VNode(undefined, undefined, undefined, String(val))
|
||||
}
|
||||
|
||||
// optimized shallow clone
|
||||
// used for static nodes and slot nodes because they may be reused across
|
||||
// multiple renders, cloning them avoids errors when DOM manipulations rely
|
||||
// on their elm reference.
|
||||
export function cloneVNode (vnode: VNode): VNode {
|
||||
const cloned = new VNode(
|
||||
vnode.tag,
|
||||
vnode.data,
|
||||
// #7975
|
||||
// clone children array to avoid mutating original in case of cloning
|
||||
// a child.
|
||||
vnode.children && vnode.children.slice(),
|
||||
vnode.text,
|
||||
vnode.elm,
|
||||
vnode.context,
|
||||
vnode.componentOptions,
|
||||
vnode.asyncFactory
|
||||
)
|
||||
cloned.ns = vnode.ns
|
||||
cloned.isStatic = vnode.isStatic
|
||||
cloned.key = vnode.key
|
||||
cloned.isComment = vnode.isComment
|
||||
cloned.fnContext = vnode.fnContext
|
||||
cloned.fnOptions = vnode.fnOptions
|
||||
cloned.fnScopeId = vnode.fnScopeId
|
||||
cloned.asyncMeta = vnode.asyncMeta
|
||||
cloned.isCloned = true
|
||||
return cloned
|
||||
}
|
BIN
express-server/node_modules/vue/src/platforms/.DS_Store
generated
vendored
Normal file
BIN
express-server/node_modules/vue/src/platforms/.DS_Store
generated
vendored
Normal file
Binary file not shown.
9
express-server/node_modules/vue/src/platforms/web/compiler/directives/html.js
generated
vendored
Normal file
9
express-server/node_modules/vue/src/platforms/web/compiler/directives/html.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import { addProp } from 'compiler/helpers'
|
||||
|
||||
export default function html (el: ASTElement, dir: ASTDirective) {
|
||||
if (dir.value) {
|
||||
addProp(el, 'innerHTML', `_s(${dir.value})`, dir)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user