diff --git a/.editorconfig b/.editorconfig index f1cc3ad329c..01a20f16fe3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# http://editorconfig.org +# https://editorconfig.org root = true diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 4ead0e1daf2..b39f08e2d28 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -2,7 +2,7 @@ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. -We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. +We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. diff --git a/.github/COMMIT_CONVENTION.md b/.github/COMMIT_CONVENTION.md index 02e7ad26ab1..381bf17baab 100644 --- a/.github/COMMIT_CONVENTION.md +++ b/.github/COMMIT_CONVENTION.md @@ -58,24 +58,24 @@ The **header** is mandatory and the **scope** of the header is optional. ### Revert -If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit .`, where the hash is the SHA of the commit being reverted. +If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body, it should say: `This reverts commit .`, where the hash is the SHA of the commit being reverted. ### Type -If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog. +If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However, if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog. Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks. ### Scope -The scope could be anything specifying place of the commit change. For example `core`, `compiler`, `ssr`, `v-model`, `transition` etc... +The scope could be anything specifying the place of the commit change. For example `core`, `compiler`, `ssr`, `v-model`, `transition` etc... ### Subject -The subject contains succinct description of the change: +The subject contains a succinct description of the change: * use the imperative, present tense: "change" not "changed" nor "changes" -* don't capitalize first letter +* don't capitalize the first letter * no dot (.) at the end ### Body diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 38d9618e4a9..0c03779a886 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Vue.js Contributing Guide -Hi! I’m really excited that you are interested in contributing to Vue.js. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. +Hi! I'm really excited that you are interested in contributing to Vue.js. Before submitting your contribution, please make sure to take a moment and read through the following guidelines: - [Code of Conduct](https://github.com/vuejs/vue/blob/dev/.github/CODE_OF_CONDUCT.md) - [Issue Reporting Guidelines](#issue-reporting-guidelines) @@ -14,33 +14,33 @@ Hi! I’m really excited that you are interested in contributing to Vue.js. Befo ## Pull Request Guidelines -- The `master` branch is basically just a snapshot of the latest stable release. All development should be done in dedicated branches. **Do not submit PRs against the `master` branch.** +- The `master` branch is just a snapshot of the latest stable release. All development should be done in dedicated branches. **Do not submit PRs against the `master` branch.** - Checkout a topic branch from the relevant branch, e.g. `dev`, and merge back against that branch. - Work in the `src` folder and **DO NOT** checkin `dist` in the commits. -- It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging. +- It's OK to have multiple small commits as you work on the PR - GitHub will automatically squash it before merging. - Make sure `npm test` passes. (see [development setup](#development-setup)) -- If adding new feature: +- If adding a new feature: - Add accompanying test case. - - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it. + - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it. -- If fixing a bug: - - If you are resolving a special issue, add `(fix #xxxx[,#xxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`. - - Provide detailed description of the bug in the PR. Live demo preferred. +- If fixing bug: + - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`. + - Provide a detailed description of the bug in the PR. Live demo preferred. - Add appropriate test coverage if applicable. ## Development Setup -You will need [Node.js](http://nodejs.org) **version 6+** and [Java Runtime Environment](http://www.oracle.com/technetwork/java/javase/downloads/index.html) (needed for running Selenium server during e2e tests). +You will need [Node.js](http://nodejs.org) **version 8+**, [Java Runtime Environment](http://www.oracle.com/technetwork/java/javase/downloads/index.html) (for running Selenium server during e2e tests) and [yarn](https://yarnpkg.com/en/docs/install). After cloning the repo, run: ``` bash -$ npm install # or yarn +$ yarn # install the dependencies of the project ``` ### Committing Changes @@ -59,17 +59,17 @@ $ npm run dev:test # build all dist files, including npm packages $ npm run build -# run the full test suite, include linting / type checking +# run the full test suite, including linting/type checking $ npm test ``` There are some other scripts available in the `scripts` section of the `package.json` file. -The default test script will do the following: lint with ESLint -> type check with Flow -> unit tests with coverage -> e2e tests. **Please make sure to have this pass successfully before submitting a PR.** Although the same tests will be run against your PR on the CI server, it is better to have it working locally beforehand. +The default test script will do the following: lint with ESLint -> type check with Flow -> unit tests with coverage -> e2e tests. **Please make sure to have this pass successfully before submitting a PR.** Although the same tests will be run against your PR on the CI server, it is better to have it working locally. ## Project Structure -- **`scripts`**: contains build-related scripts and configuration files. In most cases you don't need to touch them. However, it would be helpful to familiarize yourself with the following files: +- **`scripts`**: contains build-related scripts and configuration files. Usually, you don't need to touch them. However, it would be helpful to familiarize yourself with the following files: - `scripts/alias.js`: module import aliases used across all source code and tests. @@ -85,15 +85,15 @@ The default test script will do the following: lint with ESLint -> type check wi - **`test`**: contains all tests. The unit tests are written with [Jasmine](http://jasmine.github.io/2.3/introduction.html) and run with [Karma](http://karma-runner.github.io/0.13/index.html). The e2e tests are written for and run with [Nightwatch.js](http://nightwatchjs.org/). -- **`src`**: contains the source code, obviously. The codebase is written in ES2015 with [Flow](https://flowtype.org/) type annotations. +- **`src`**: contains the source code. The codebase is written in ES2015 with [Flow](https://flowtype.org/) type annotations. - **`compiler`**: contains code for the template-to-render-function compiler. - The compiler consists of a parser (converts template strings to element ASTs), an optimizer (detects static trees for vdom render optimization), and a code generator (generate render function code from element ASTs). Note the codegen directly generates code strings from the element AST - it's done this way for smaller code size because the compiler is shipped to the browser in the standalone build. + The compiler consists of a parser (converts template strings to element ASTs), an optimizer (detects static trees for vdom render optimization), and a code generator (generate render function code from element ASTs). Note that codegen directly generates code strings from the element AST - it's done this way for smaller code size because the compiler is shipped to the browser in the standalone build. - **`core`**: contains universal, platform-agnostic runtime code. - The Vue 2.0 core is platform-agnostic - which means code inside `core` should be able to run in any JavaScript environment, be it the browser, Node.js, or an embedded JavaScript runtime in native applications. + The Vue 2.0 core is platform-agnostic. That is, the code inside `core` is able to be run in any JavaScript environment, be it the browser, Node.js, or an embedded JavaScript runtime in native applications. - **`observer`**: contains code related to the reactivity system. @@ -101,9 +101,9 @@ The default test script will do the following: lint with ESLint -> type check wi - **`instance`**: contains Vue instance constructor and prototype methods. - - **`global-api`**: as the name suggests. + - **`global-api`**: contains Vue global api. - - **`components`**: universal abstract components. Currently `keep-alive` is the only one. + - **`components`**: contains universal abstract components. - **`server`**: contains code related to server-side rendering. @@ -111,7 +111,7 @@ The default test script will do the following: lint with ESLint -> type check wi Entry files for dist builds are located in their respective platform directory. - Each platform module contains three parts: `compiler`, `runtime` and `server`, corresponding to the three directories above. Each part contains platform-specific modules/utilities which are then imported and injected to the core counterparts in platform-specific entry files. For example, the code implementing the logic behind `v-bind:class` is in `platforms/web/runtime/modules/class.js` - which is imported in `entries/web-runtime.js` and used to create the browser-specific vdom patching function. + Each platform module contains three parts: `compiler`, `runtime` and `server`, corresponding to the three directories above. Each part contains platform-specific modules/utilities which are imported and injected to the core counterparts in platform-specific entry files. For example, the code implementing the logic behind `v-bind:class` is in `platforms/web/runtime/modules/class.js` - which is imported in `entries/web-runtime.js` and used to create the browser-specific vdom patching function. - **`sfc`**: contains single-file component (`*.vue` files) parsing logic. This is used in the `vue-template-compiler` package. @@ -119,17 +119,18 @@ The default test script will do the following: lint with ESLint -> type check wi - **`types`**: contains TypeScript type definitions - - **`test`**: type definitions tests + - **`test`**: contains type definitions tests ## Financial Contribution -As a pure community-driven project without major corporate backing, we also welcome financial contributions via Patreon or OpenCollective. +As a pure community-driven project without major corporate backing, we also welcome financial contributions via Patreon and OpenCollective. - [Become a backer or sponsor on Patreon](https://www.patreon.com/evanyou) - [Become a backer or sponsor on OpenCollective](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? +### What's the difference between Patreon and OpenCollective funding? 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. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000000..652c1192b7b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,8 @@ +# These are supported funding model platforms + +github: [yyx990803, posva] +patreon: evanyou +open_collective: vuejs +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/vue +custom: # Replace with a single custom sponsorship URL diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index cb7f961992c..00000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..675eea91e7c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Create new issue + url: https://new-issue.vuejs.org/ + about: Please use the following link to create a new issue. + - name: Patreon + url: https://www.patreon.com/evanyou + about: Love Vue.js? Please consider supporting us via Patreon. + - name: Open Collective + url: https://opencollective.com/vuejs/donate + about: Love Vue.js? Please consider supporting us via Open Collective. diff --git a/BACKERS.md b/BACKERS.md index 78b783482af..d509d8c4629 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -17,8 +17,8 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu

- - + +

@@ -31,30 +31,40 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + @@ -67,11 +77,6 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu - + + + + + + + + + + + + + + + + @@ -227,13 +296,33 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu + + + + @@ -246,6 +335,13 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu + + + + + + +

Bronze via Patreon

@@ -254,33 +350,28 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu - @@ -324,121 +415,91 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu

Generous Backers via Patreon ($50+)

-- Wasim Khamlichi +- Yoshitaka M +- Peter Imburg +- Sean Ferguson +- Johnny Ray Austin - errorrik -- Alex Balashov -- Konstantin Levinski -- Ernest Sim -- Blaise Laflamme -- Dilettant +- Wasim Khamlichi

Backers via Patreon

-- Luca Borghini -- kazuya kawaguchi -- Keisuke KITA -- Santa Cruz -- Simon East -- Benjamin Listwon -- Lars Andreas Ness -- Victor Tolbert -- Stephen Hartley -- Wen-Tien Chang -- Kirk Lewis -- Karol F -- Miljan Aleksic -- 叶解 -- Jake Ingman -- Barbara Liau -- 4 -- Jarek Tkaczyk -- Niannian Modisette -- Ivan Sieder -- Matt Jones -- Duncan J Kenzie -- Mike Margerum -- Guy Gavergun -- Intevation GmbH -- Luiz Eduardo Tanure Bacelar -- Zoran Knezevic -- Pierre Vanhulst -- Jon Hobbs-Smith -- Akiho Nagao -- Asaf Yishai -- Estebe Anthony -- Haim Yulzari -- Jeremy Tan -- Jim Raden -- Fille Åström -- Samuel Smith -- Tyler Scott -- Thong Yong Jun -- Matias Verdier -- Jamie McElwain -- Vivekanandhan Natarajan -- Rafael Belvederese -- Mickaël Andrieu -- Guilherme S L de Souza -- Rob Yedlin -- Daniel Waghorn -- Chih-Hsuan, Fan -- Jordan Oroshiba -- Cliff Hess -- Joe Ray Gregory -- RADD Creative -- Rua Cura D'ars -- Richard Simpson -- Jessie Hernandez -- Eric Fong -- Aparajita Fishman -- Romain Lienard -- Bohdan Kokotko -- Donald Fischer -- Alexander Weiher -- Shinya Katayama -- Jere Sjöroos -- Wakana Seki -- David Ang -- Dom -- Ben Hong -- David Kaplan -- John Cleveland -- Jaeyoung Lee -- Amor -- Tom Ootes -- Andy Foster -- Joe Cochran -- Matt Sencenbaugh -- Daniel Mattingley -- Teon Ooi +- Sara McVey +- Keisuke Kita +- Alex Riviere +- Thomas Sittig +- WhereJuly +- Fontis +- Jack +- Nick Carr +- Artur Bańka +- Traversy Media +- Pierre Baron +- Donghai Gai +- Aleksander Figiel +- Faizal Andyka +- wickedwei +- Sunny Yuen +- Jules +- Zeth Odderskov +- Santi Sanchez Canals +- Thomas Wiedemann +- Nobuhide Esaki +- Roy Segall +- Allan McKernan +- 琚致远 +- Diana Bergholz +- Riki Fridrich +- Alfonso Herrera +- Bichinger Software & Consulting +- username +- Pierre Lebrun +- Peter Matkovsky +- 龙腾道 +- Nick Dandakis +- Yusuke Kawabata +- Shawn Wildermuth +- Andrew Willis +- Elon Hung +- Роман Латкин +- Juan Bermudez - Hannes Kochniß -- Colt Borg +- Daniel Mattingley +- Matt Sencenbaugh +- Jaeyoung Lee +- David Kaplan +- David Ang +- Wakana Seki +- Jere Sjöroos +- Donald Fischer +- Eric +- tyler madsen +- Joe Gregory +- Masahiro Tanaka +- Tyler +- IMGNRY +- Jim Raden +- Haim Yulzari +- Anthony Estebe +- Asaf Yishai +- Jon Hobbs-Smith +- Pierre Vanhulst +- Zoran Knezevic +- Luiz +- Bernhard E. Reiter +- Guy Gavergun +- Matt Jones +- Niannian Modisette +- Matsumoto Takamasa +- Barbara Liau +- Wen-Tien Chang +- Stephen Michael Hartley +- Victor Tolbert +- Lars Andreas Ness +- Benjamin Listwon - Chris Calo -- Christo Crampton -- Johnny Austin -- Aaron Hung -- Soichiro Isshiki -- Tom Meagher -- Abraham Arango -- Marko Bošković -- Ed Linklater -- Garion Herman -- Chris Bemister -- Anfrew Willis -- Shawn Wildermuth -- Carlos Adrián -- Timothy J Bass -- Yusuke Kawabata -- Nick Dandakis -- JI CAI -- 龙腾道 -- Milos Stojanovic -- Matkovsky Peter -- shimbaco -- Princeyesuraj Edward -- Kenneth Crawford

Backers via OpenCollective

diff --git a/README.md b/README.md index 0f3999237c3..862d58f8a6f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@

Vue logo

- Build Status - Coverage Status - Downloads - Version - License - Chat + Build Status + Coverage Status + Downloads + Version + License + Chat
Build Status

@@ -17,7 +17,7 @@ Vue.js is an MIT-licensed open source project with its ongoing development made - [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) +- [One-time donation via PayPal or crypto-currencies](https://vuejs.org/support-vuejs/#One-time-Donations). #### What's the difference between Patreon and OpenCollective? @@ -27,8 +27,8 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu

- - + +

@@ -41,30 +41,40 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu + + @@ -77,11 +87,6 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
- - - - @@ -105,98 +110,162 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu - + - - + + - - + + - - + +
- - + + - - + + - - + + - - + + - - + + - - + +
- - + + - - + + - - + + - - + + - - + + - - + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
- - + + - - + +
- - + + - - + + + + + + + + + + + + + + + + + +
- - - - - - + + - - + + - - + + - - + + - - + +
- - + + - - + + - - + + - - + +
- - + + + + + + + + + +
-
- - - - @@ -92,7 +97,7 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu
-

Gold Sponsors

+

Gold Sponsors

@@ -110,98 +115,162 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu + + + + + + + + + + + + + + + + @@ -213,16 +282,21 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu

Platinum

- - + +

Gold

- - - - - + + + + + + + + + + --- @@ -232,7 +306,7 @@ Vue (pronounced `/vjuː/`, like view) is a **progressive framework** for buildin #### Browser Compatibility -Vue.js supports all browsers that are [ES5-compliant](http://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). +Vue.js supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). ## Ecosystem @@ -280,7 +354,7 @@ To check out [live examples](https://vuejs.org/v2/examples/) and docs, visit [vu ## 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. +For questions and support please use [the official forum](https://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 @@ -307,6 +381,6 @@ Thank you to all the people who already contributed to Vue! ## License -[MIT](http://opensource.org/licenses/MIT) +[MIT](https://opensource.org/licenses/MIT) Copyright (c) 2013-present, Yuxi (Evan) You diff --git a/benchmarks/ssr/README.md b/benchmarks/ssr/README.md index 2f0529c1fd8..c61d6daa57d 100644 --- a/benchmarks/ssr/README.md +++ b/benchmarks/ssr/README.md @@ -2,7 +2,7 @@ This benchmark renders a table of 1000 rows with 10 columns (10k components), with around 30k normal elements on the page. Note this is not something likely to be seen in a typical app. This benchmark is mostly for stress/regression testing and comparing between `renderToString` and `renderToStream`. -To view the results follow the run section. Note that the overall completion time for the results are variable, this is due to other system related variants at run time (available memory, processing power, etc). In ideal circumstances both should finish within similar results. +To view the results follow the run section. Note that the overall completion time for the results is variable, this is due to other system related variants at run time (available memory, processing power, etc). In ideal circumstances, both should finish within similar results. `renderToStream` pipes the content through a stream which provides considerable performance benefits (faster time-to-first-byte and non-event-loop-blocking) over `renderToString`. This can be observed through the benchmark. diff --git a/benchmarks/uptime/index.html b/benchmarks/uptime/index.html index 4a375152cf2..d43c93010a6 100644 --- a/benchmarks/uptime/index.html +++ b/benchmarks/uptime/index.html @@ -38,7 +38,7 @@ .days { display: flex; flex-direction: row; - flex-flow: wrap; + flex-wrap: wrap; } .uptime-day { @@ -82,7 +82,7 @@ ") + ? ("window." + windowKey + "=" + state + autoRemove + "") : '' }; @@ -8123,7 +9100,7 @@ TemplateRenderer.prototype.renderScripts = function renderScripts (context) { return isJS(file); }); - var needed = [initial[0]].concat(async || [], initial.slice(1)); + var needed = [initial[0]].concat(async, initial.slice(1)); return needed.map(function (ref) { var file = ref.file; @@ -8196,6 +9173,7 @@ function createRenderer (ref) { var shouldPreload = ref.shouldPreload; var shouldPrefetch = ref.shouldPrefetch; var clientManifest = ref.clientManifest; + var serializer = ref.serializer; var render = createRenderFunction(modules, directives, isUnaryTag, cache); var templateRenderer = new TemplateRenderer({ @@ -8203,7 +9181,8 @@ function createRenderer (ref) { inject: inject, shouldPreload: shouldPreload, shouldPrefetch: shouldPrefetch, - clientManifest: clientManifest + clientManifest: clientManifest, + serializer: serializer }); return { @@ -8235,11 +9214,26 @@ function createRenderer (ref) { }, cb); try { render(component, write, context, function (err) { - if (template) { - result = templateRenderer.renderSync(result, context); - } if (err) { - cb(err); + return cb(err) + } + if (context && context.rendered) { + context.rendered(context); + } + if (template) { + try { + var res = templateRenderer.render(result, context); + if (typeof res !== 'string') { + // function template returning promise + res + .then(function (html) { return cb(null, html); }) + .catch(cb); + } else { + cb(null, res); + } + } catch (e) { + cb(e); + } } else { cb(null, result); } @@ -8262,13 +9256,27 @@ function createRenderer (ref) { render(component, write, context, done); }); if (!template) { + if (context && context.rendered) { + var rendered = context.rendered; + renderStream.once('beforeEnd', function () { + rendered(context); + }); + } return renderStream + } else if (typeof template === 'function') { + throw new Error("function template is only supported in renderToString.") } else { var templateStream = templateRenderer.createStream(context); renderStream.on('error', function (err) { templateStream.emit('error', err); }); renderStream.pipe(templateStream); + if (context && context.rendered) { + var rendered$1 = context.rendered; + renderStream.once('beforeEnd', function () { + rendered$1(context); + }); + } return templateStream } } diff --git a/packages/vue-server-renderer/build.prod.js b/packages/vue-server-renderer/build.prod.js index 5cabfe6b407..01a786d489f 100644 --- a/packages/vue-server-renderer/build.prod.js +++ b/packages/vue-server-renderer/build.prod.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=(e=require("he"))&&"object"==typeof e&&"default"in e?e.default:e,r=Object.freeze({});function n(e){return null==e}function i(e){return null!=e}function o(e){return!0===e}function a(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function s(e){return null!==e&&"object"==typeof e}var c=Object.prototype.toString;function u(e){return"[object Object]"===c.call(e)}function f(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function l(e){var t=parseFloat(e);return isNaN(t)?e:t}function p(e,t){for(var r=Object.create(null),n=e.split(","),i=0;i\/="'\u0009\u000a\u000c\u0020]/,N=function(e){return F.test(e)},E=function(e){return P(e)||0===e.indexOf("data-")||0===e.indexOf("aria-")},L={acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},I={"<":"<",">":">",'"':""","&":"&"};function M(e){return e.replace(/[<>"&]/g,R)}function R(e){return I[e]||e}var U=p("input,textarea,option,select,progress"),D=p("contenteditable,draggable,spellcheck"),B=p("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),q=function(e){return null==e||!1===e};function z(e,t){if(B(e)){if(!q(t))return" "+e+'="'+e+'"'}else{if(D(e))return" "+e+'="'+(q(t)||"false"===t?"false":"true")+'"';if(!q(t))return" "+e+'="'+M(String(t))+'"'}return""}var J=function(e,t,r,n,i,o,a,s){this.tag=e,this.data=t,this.children=r,this.text=n,this.elm=i,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1},H={child:{configurable:!0}};H.child.get=function(){return this.componentInstance},Object.defineProperties(J.prototype,H);var K=function(e){void 0===e&&(e="");var t=new J;return t.text=e,t.isComment=!0,t};function V(e){return new J(void 0,void 0,void 0,String(e))}function W(e,t,r){var n=new J(void 0,void 0,void 0,t);n.raw=r,e.children=[n]}function X(e,t,r,n){Object.defineProperty(e,t,{value:r,enumerable:!!n,writable:!0,configurable:!0})}var G,Z="__proto__"in{},Q="undefined"!=typeof window,Y="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,ee=Y&&WXEnvironment.platform.toLowerCase(),te=Q&&window.navigator.userAgent.toLowerCase(),re=te&&/msie|trident/.test(te),ne=(te&&te.indexOf("msie 9.0"),te&&te.indexOf("edge/")>0),ie=(te&&te.indexOf("android"),te&&/iphone|ipad|ipod|ios/.test(te),te&&/chrome\/\d+/.test(te),{}.watch);if(Q)try{var oe={};Object.defineProperty(oe,"passive",{get:function(){}}),window.addEventListener("test-passive",null,oe)}catch(e){}var ae=function(){return void 0===G&&(G=!Q&&!Y&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),G};Q&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function se(e){return"function"==typeof e&&/native code/.test(e.toString())}var ce,ue="undefined"!=typeof Symbol&&se(Symbol)&&"undefined"!=typeof Reflect&&se(Reflect.ownKeys);ce="undefined"!=typeof Set&&se(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var fe="data-server-rendered",le=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],pe={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:A,isReservedAttr:A,isUnknownElement:A,getTagNamespace:O,parsePlatformTagName:k,mustUseProp:A,async:!0,_lifecycleHooks:le},de=O,ve=0,he=function(){this.id=ve++,this.subs=[]};he.prototype.addSub=function(e){this.subs.push(e)},he.prototype.removeSub=function(e){!function(e,t){if(e.length){var r=e.indexOf(t);if(r>-1)e.splice(r,1)}}(this.subs,e)},he.prototype.depend=function(){he.target&&he.target.addDep(this)},he.prototype.notify=function(){for(var e=this.subs.slice(),t=0,r=e.length;t=0&&Math.floor(t)===t&&isFinite(e)}(t))return e.length=Math.max(e.length,t),e.splice(t,1,r),r;if(t in e&&!(t in Object.prototype))return e[t]=r,r;var n=e.__ob__;return e._isVue||n&&n.vmCount?r:n?($e(n.value,t,r),n.dep.notify(),r):(e[t]=r,r)}we.prototype.walk=function(e){for(var t=Object.keys(e),r=0;r-1)if(o&&!m(i,"default"))a=!1;else if(""===a||a===w(e)){var c=Me(String,i.type);(c<0||s1&&(t[n[0].trim()]=n[1].trim())}}),t});function We(e){var t=Xe(e.style);return e.staticStyle?S(e.staticStyle,t):t}function Xe(e){return Array.isArray(e)?$(e):"string"==typeof e?Ve(e):e}function Ge(e){var t="";for(var r in e){var n=e[r],i=w(r);if(Array.isArray(n))for(var o=0,a=n.length;o-1&&Ye(a);else if(C(r,Qe(a)))return void Ye(a)}}},tt=p("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),rt=p("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),nt=p("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),it=900,ot=function(e){return e},at="undefined"!=typeof process&&process.nextTick?process.nextTick:"undefined"!=typeof Promise?function(e){return Promise.resolve().then(e)}:"undefined"!=typeof setTimeout?setTimeout:ot;if(at===ot)throw new Error("Your JavaScript runtime does not support any asynchronous primitives that are required by vue-server-renderer. Please use a polyfill for either Promise or setTimeout.");function st(e,t){var r=0,n=function(i,o){i&&n.caching&&(n.cacheBuffer[n.cacheBuffer.length-1]+=i),!0!==e(i,o)&&(r>=it?at(function(){try{o()}catch(e){t(e)}}):(r++,o(),r--))};return n.caching=!1,n.cacheBuffer=[],n.componentBuffer=[],n}var ct=function(e){function t(t){var r=this;e.call(this),this.buffer="",this.render=t,this.expectedSize=0,this.write=st(function(e,t){var n=r.expectedSize;return r.buffer+=e,r.buffer.length>=n&&(r.next=t,r.pushBySize(n),!0)},function(e){r.emit("error",e)}),this.end=function(){r.done=!0,r.push(r.buffer)}}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.pushBySize=function(e){var t=this.buffer.substring(0,e);this.buffer=this.buffer.substring(e),this.push(t)},t.prototype.tryRender=function(){try{this.render(this.write,this.end)}catch(e){this.emit("error",e)}},t.prototype.tryNext=function(){try{this.next()}catch(e){this.emit("error",e)}},t.prototype._read=function(e){this.expectedSize=e,o(this.done)?this.push(null):this.buffer.length>=e?this.pushBySize(e):n(this.next)?this.tryRender():this.tryNext()},t}(require("stream").Readable),ut=function(e){this.userContext=e.userContext,this.activeInstance=e.activeInstance,this.renderStates=[],this.write=e.write,this.done=e.done,this.renderNode=e.renderNode,this.isUnaryTag=e.isUnaryTag,this.modules=e.modules,this.directives=e.directives;var t=e.cache;if(t&&(!t.get||!t.set))throw new Error("renderer cache must implement at least get & set.");this.cache=t,this.get=t&&ft(t,"get"),this.has=t&&ft(t,"has"),this.next=this.next.bind(this)};function ft(e,t){var r=e[t];return n(r)?void 0:r.length>1?function(t,n){return r.call(e,t,n)}:function(t,n){return n(r.call(e,t))}}ut.prototype.next=function(){for(;;){var e=this.renderStates[this.renderStates.length-1];if(n(e))return this.done();switch(e.type){case"Element":case"Fragment":var t=e.children,r=e.total,i=e.rendered++;if(i=0&&" "===(h=e.charAt(v));v--);h&<.test(h)||(u=!0)}}else void 0===i?(d=n+1,i=e.slice(0,n).trim()):m();function m(){(o||(o=[])).push(e.slice(d,n).trim()),d=n+1}if(void 0===i?i=e.slice(0,n).trim():0!==d&&m(),o)for(n=0;n\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Lt="[a-zA-Z_][\\w\\-\\.]*",It="((?:"+Lt+"\\:)?"+Lt+")",Mt=new RegExp("^<"+It),Rt=/^\s*(\/?)>/,Ut=new RegExp("^<\\/"+It+"[^>]*>"),Dt=/^]+>/i,Bt=/^",""":'"',"&":"&"," ":"\n"," ":"\t"},Kt=/&(?:lt|gt|quot|amp);/g,Vt=/&(?:lt|gt|quot|amp|#10|#9);/g,Wt=p("pre,textarea",!0),Xt=function(e,t){return e&&Wt(e)&&"\n"===t[0]};function Gt(e,t){var r=t?Vt:Kt;return e.replace(r,function(e){return Ht[e]})}function Zt(e,t,r){var n=r||{},i=n.number,o="$$v";n.trim&&(o="(typeof $$v === 'string'? $$v.trim(): $$v)"),i&&(o="_n("+o+")");var a=Qt(t,o);e.model={value:"("+t+")",expression:'"'+t+'"',callback:"function ($$v) {"+a+"}"}}function Qt(e,t){var r=function(e){if(e=e.trim(),kt=e.length,e.indexOf("[")<0||e.lastIndexOf("]")-1?{exp:e.slice(0,jt),key:'"'+e.slice(jt+1)+'"'}:{exp:e,key:null};Ct=e,jt=Pt=Ft=0;for(;!er();)tr(Tt=Yt())?nr(Tt):91===Tt&&rr(Tt);return{exp:e.slice(0,Pt),key:e.slice(Pt+1,Ft)}}(e);return null===r.key?e+"="+t:"$set("+r.exp+", "+r.key+", "+t+")"}function Yt(){return Ct.charCodeAt(++jt)}function er(){return jt>=kt}function tr(e){return 34===e||39===e}function rr(e){var t=1;for(Pt=jt;!er();)if(tr(e=Yt()))nr(e);else if(91===e&&t++,93===e&&t--,0===t){Ft=jt;break}}function nr(e){for(var t=e;!er()&&(e=Yt())!==t;);}var ir,or,ar,sr,cr,ur,fr,lr,pr=/^@|^v-on:/,dr=/^v-|^@|^:/,vr=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,hr=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,mr=/^\(|\)$/g,yr=/:(.*)$/,gr=/^:|^v-bind:/,br=/\.[^.]+/g,_r=y(t.decode);function xr(e,t,r){return{type:1,tag:e,attrsList:t,attrsMap:function(e){for(var t={},r=0,n=e.length;r]*>)","i")),p=e.replace(l,function(e,r,n){return u=n.length,zt(f)||"noscript"===f||(r=r.replace(//g,"$1").replace(//g,"$1")),Xt(f,r)&&(r=r.slice(1)),t.chars&&t.chars(r),""});c+=e.length-p.length,e=p,k(f,c-u,c)}else{var d=e.indexOf("<");if(0===d){if(Bt.test(e)){var v=e.indexOf("--\x3e");if(v>=0){t.shouldKeepComment&&t.comment(e.substring(4,v)),S(v+3);continue}}if(qt.test(e)){var h=e.indexOf("]>");if(h>=0){S(h+2);continue}}var m=e.match(Dt);if(m){S(m[0].length);continue}var y=e.match(Ut);if(y){var g=c;S(y[0].length),k(y[1],g,c);continue}var b=$();if(b){O(b),Xt(b.tagName,e)&&S(1);continue}}var _=void 0,x=void 0,w=void 0;if(d>=0){for(x=e.slice(d);!(Ut.test(x)||Mt.test(x)||Bt.test(x)||qt.test(x)||(w=x.indexOf("<",1))<0);)d+=w,x=e.slice(d);_=e.substring(0,d),S(d)}d<0&&(_=e,e=""),t.chars&&_&&t.chars(_)}if(e===r){t.chars&&t.chars(e);break}}function S(t){c+=t,e=e.substring(t)}function $(){var t=e.match(Mt);if(t){var r,n,i={tagName:t[1],attrs:[],start:c};for(S(t[0].length);!(r=e.match(Rt))&&(n=e.match(Et));)S(n[0].length),i.attrs.push(n);if(r)return i.unarySlash=r[1],S(r[0].length),i.end=c,i}}function O(e){var r=e.tagName,c=e.unarySlash;o&&("p"===n&&nt(r)&&k(n),s(r)&&n===r&&k(r));for(var u=a(r)||!!c,f=e.attrs.length,l=new Array(f),p=0;p=0&&i[a].lowerCasedTag!==s;a--);else a=0;if(a>=0){for(var u=i.length-1;u>=a;u--)t.end&&t.end(i[u].tag,r,o);i.length=a,n=a&&i[a-1].tag}else"br"===s?t.start&&t.start(e,[],!0,r,o):"p"===s&&(t.start&&t.start(e,[],!1,r,o),t.end&&t.end(e,r,o))}k()}(e,{warn:ir,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,start:function(e,o,u){var f=n&&n.ns||lr(e);re&&"svg"===f&&(o=function(e){for(var t=[],r=0;rc&&(s.push(o=e.slice(c,i)),a.push(JSON.stringify(o)));var u=pt(n[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=i+n[0].length}return c-1"+("true"===o?":("+t+")":":_q("+t+","+o+")")),St(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(n?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Qt(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Qt(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Qt(t,"$$c")+"}",null,!0)}(e,n,i);else if("input"===o&&"radio"===a)!function(e,t,r){var n=r&&r.number,i=$t(e,"value")||"null";bt(e,"checked","_q("+t+","+(i=n?"_n("+i+")":i)+")"),St(e,"change",Qt(t,i),null,!0)}(e,n,i);else{if("input"!==o&&"textarea"!==o)return Zt(e,n,i),!1;!function(e,t,r){var n=e.attrsMap.type,i=r||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==n,u=o?"change":"range"===n?Pr:"input",f="$event.target.value";s&&(f="$event.target.value.trim()"),a&&(f="_n("+f+")");var l=Qt(t,f);c&&(l="if($event.target.composing)return;"+l),bt(e,"value","("+t+")"),St(e,u,l,null,!0),(s||a)&&St(e,"blur","$forceUpdate()")}(e,n,i)}return!0},text:function(e,t){t.value&&bt(e,"textContent","_s("+t.value+")")},html:function(e,t){t.value&&bt(e,"innerHTML","_s("+t.value+")")}},isPreTag:function(e){return"pre"===e},isUnaryTag:tt,mustUseProp:function(e,t,r){return"value"===r&&U(e)&&"button"!==t||"selected"===r&&"option"===e||"checked"===r&&"input"===e||"muted"===r&&"video"===e},canBeLeftOpenTag:rt,isReservedTag:function(e){return He(e)||Ke(e)},getTagNamespace:function(e){return Ke(e)?"svg":"math"===e?"math":void 0},staticKeys:function(e){return e.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(",")}(jr)},Nr=/^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/,Er=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Lr={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},Ir={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:" ",up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete"]},Mr=function(e){return"if("+e+")return null;"},Rr={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:Mr("$event.target !== $event.currentTarget"),ctrl:Mr("!$event.ctrlKey"),shift:Mr("!$event.shiftKey"),alt:Mr("!$event.altKey"),meta:Mr("!$event.metaKey"),left:Mr("'button' in $event && $event.button !== 0"),middle:Mr("'button' in $event && $event.button !== 1"),right:Mr("'button' in $event && $event.button !== 2")};function Ur(e,t){var r=t?"nativeOn:{":"on:{";for(var n in e)r+='"'+n+'":'+Dr(n,e[n])+",";return r.slice(0,-1)+"}"}function Dr(e,t){if(!t)return"function(){}";if(Array.isArray(t))return"["+t.map(function(t){return Dr(e,t)}).join(",")+"]";var r=Er.test(t.value),n=Nr.test(t.value);if(t.modifiers){var i="",o="",a=[];for(var s in t.modifiers)if(Rr[s])o+=Rr[s],Lr[s]&&a.push(s);else if("exact"===s){var c=t.modifiers;o+=Mr(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+=function(e){return"if(!('button' in $event)&&"+e.map(Br).join("&&")+")return null;"}(a)),o&&(i+=o),"function($event){"+i+(r?"return "+t.value+"($event)":n?"return ("+t.value+")($event)":t.value)+"}"}return r||n?t.value:"function($event){"+t.value+"}"}function Br(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var r=Lr[e],n=Ir[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(r)+",$event.key,"+JSON.stringify(n)+")"}var qr={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(e,t){e.wrapData=function(r){return"_b("+r+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}},cloak:O},zr=function(e){this.options=e,this.warn=e.warn||yt,this.transforms=gt(e.modules,"transformCode"),this.dataGenFns=gt(e.modules,"genData"),this.directives=S(S({},qr),e.directives);var t=e.isReservedTag||A;this.maybeComponent=function(e){return!(t(e.tag)&&!e.component)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function Jr(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Hr(e,t);if(e.once&&!e.onceProcessed)return Kr(e,t);if(e.for&&!e.forProcessed)return Wr(e,t);if(e.if&&!e.ifProcessed)return Vr(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return function(e,t){var r=e.slotName||'"default"',n=Zr(e,t),i="_t("+r+(n?","+n:""),o=e.attrs&&"{"+e.attrs.map(function(e){return b(e.name)+":"+e.value}).join(",")+"}",a=e.attrsMap["v-bind"];!o&&!a||n||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var r;if(e.component)r=function(e,t,r){var n=t.inlineTemplate?null:Zr(t,r,!0);return"_c("+e+","+Xr(t,r)+(n?","+n:"")+")"}(e.component,e,t);else{var n;(!e.plain||e.pre&&t.maybeComponent(e))&&(n=Xr(e,t));var i=e.inlineTemplate?null:Zr(e,t,!0);r="_c('"+e.tag+"'"+(n?","+n:"")+(i?","+i:"")+")"}for(var o=0;o"'+(r?","+r:"")+")"}(e,t);case sn.CHILDREN:return vn(e,t,!0);case sn.PARTIAL:return vn(e,t,!1);default:return Jr(e,t)}}function vn(e,t,r){var n=e.plain?void 0:Xr(e,t),i=r?"["+yn(e,t)+"]":hn(e,t,!0);return"_c('"+e.tag+"'"+(n?","+n:"")+(i?","+i:"")+")"}function hn(e,t,r){return Zr(e,t,r,dn,mn)}function mn(e,t){return 1===e.type?dn(e,t):en(e)}function yn(e,t){return e.children.length?"_ssrNode("+wn(xn(e,t))+")":""}function gn(e,t){return"("+wn(bn(e,t))+")"}function bn(e,t){if(e.for&&!e.forProcessed)return e.forProcessed=!0,[{type:pn,value:Wr(e,t,gn,"_ssrList")}];if(e.if&&!e.ifProcessed)return e.ifProcessed=!0,[{type:pn,value:Vr(e,t,gn,'"\x3c!----\x3e"')}];if("template"===e.tag)return xn(e,t);var r=_n(e,t),n=xn(e,t),i=t.options.isUnaryTag,o=i&&i(e.tag)?[]:[{type:fn,value:""}];return r.concat(n,o)}function _n(e,t){var r;!function(e,t){if(e.directives)for(var r=0;r"}),u}function xn(e,t){var r;return(r=e.attrsMap["v-html"])?[{type:pn,value:"_s("+r+")"}]:(r=e.attrsMap["v-text"])?[{type:ln,value:"_s("+r+")"}]:"textarea"===e.tag&&(r=e.attrsMap["v-model"])?[{type:ln,value:"_s("+r+")"}]:e.children?function(e,t){for(var r=[],n=0;n0&&(Tn((u=e(u,(r||"")+"_"+c))[0])&&Tn(l)&&(s[f]=V(l.text+u[0].text),u.shift()),s.push.apply(s,u)):a(u)?Tn(l)?s[f]=V(l.text+u):""!==u&&s.push(V(u)):Tn(u)&&Tn(l)?s[f]=V(l.text+u.text):(o(t._isVList)&&i(u.tag)&&n(u.key)&&i(r)&&(u.key="__vlist"+r+"_"+c+"__"),s.push(u)));return s}(e):void 0}function Tn(e){return i(e)&&i(e.text)&&!1===e.isComment}var jn={_ssrEscape:M,_ssrNode:function(e,t,r,n){return new Pn(e,t,r,n)},_ssrList:function(e,t){var r,n,i,o,a="";if(Array.isArray(e)||"string"==typeof e)for(r=0,n=e.length;r=0||r.indexOf(e[i])<0)&&n.push(e[i]);return n}return e}function fi(e,t,n,i,a){var s,c=a.options;m(i,"_uid")?(s=Object.create(i))._original=i:(s=i,i=i._original);var u=o(c._compiled),f=!u;this.data=e,this.props=t,this.children=n,this.parent=i,this.listeners=e.on||r,this.injections=function(e,t){if(e){for(var r=Object.create(null),n=ue?Reflect.ownKeys(e).filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}):Object.keys(e),i=0;i"}(e,r),u="";if(r.isUnaryTag(e.tag))a(c,s);else if(n(e.children)||0===e.children.length)a(c+u,s);else{var f=e.children;r.renderStates.push({type:"Element",children:f,rendered:0,total:f.length,endTag:u}),a(c,s)}}(e,t,r):o(e.isComment)?i(e.asyncFactory)?function(e,t,r){var n=e.asyncFactory,i=function(n){n.__esModule&&n.default&&(n=n.default);var i=e.asyncMeta,o=i.data,a=i.children,s=i.tag,c=e.asyncMeta.context,u=hi(n,o,c,a,s);u?u.componentOptions?$i(u,t,r):Array.isArray(u)?(r.renderStates.push({type:"Fragment",children:u,rendered:0,total:u.length}),r.next()):wi(u,t,r):r.write("\x3c!----\x3e",r.next)};if(n.resolved)return void i(n.resolved);var o,a=r.done;try{o=n(i,a)}catch(e){a(e)}if(o)if("function"==typeof o.then)o.then(i,a).catch(a);else{var s=o.component;s&&"function"==typeof s.then&&s.then(i,a).catch(a)}}(e,t,r):r.write("\x3c!--"+e.text+"--\x3e",r.next):r.write(e.raw?e.text:M(String(e.text)),r.next)}function Si(e,t){var r=e._ssrRegister;return t.caching&&i(r)&&t.componentBuffer[t.componentBuffer.length-1].add(r),r}function $i(e,t,r){var o=r.write,a=r.next,s=r.userContext,c=e.componentOptions.Ctor,u=c.options.serverCacheKey,f=c.options.name,l=r.cache,p=Si(c.options,o);if(i(u)&&i(l)&&i(f)){var d=f+"::"+u(e.componentOptions.propsData),v=r.has,h=r.get;i(v)?v(d,function(n){!0===n&&i(h)?h(d,function(e){i(p)&&p(s),e.components.forEach(function(e){return e(s)}),o(e.html,a)}):Oi(e,t,d,r)}):i(h)&&h(d,function(n){i(n)?(i(p)&&p(s),n.components.forEach(function(e){return e(s)}),o(n.html,a)):Oi(e,t,d,r)})}else i(u)&&n(l)&&bi("[vue-server-renderer] Component "+(c.options.name||"(anonymous)")+" implemented serverCacheKey, but no cache was provided to the renderer."),i(u)&&n(f)&&bi('[vue-server-renderer] Components that implement "serverCacheKey" must also define a unique "name" option.'),Ai(e,t,r)}function Oi(e,t,r,n){var i=n.write;i.caching=!0;var o=i.cacheBuffer,a=o.push("")-1,s=i.componentBuffer;s.push(new Set),n.renderStates.push({type:"ComponentWithCache",key:r,buffer:o,bufferIndex:a,componentBuffer:s}),Ai(e,t,n)}function Ai(e,t,r){var n=r.activeInstance;e.ssrContext=r.userContext;var i=r.activeInstance=mi(e,r.activeInstance);xi(i);var o=i._render();o.parent=e,r.renderStates.push({type:"Component",prevActive:n}),wi(o,t,r)}function ki(e,t,r,n){return function(i,o,a,s){gi=Object.create(null);var c=new ut({activeInstance:i,userContext:a,write:o,done:s,renderNode:wi,isUnaryTag:r,modules:e,directives:t,cache:n});!function(e){if(!e._ssrNode){for(var t=e.constructor;t.super;)t=t.super;S(t.prototype,jn),t.FunctionalRenderContext&&S(t.FunctionalRenderContext.prototype,jn)}}(i),xi(i),wi(i._render(),!0,c)}}var Ci=function(e){return/\.js(\?[^.]+)?$/.test(e)};function Ti(){var e,t;return{promise:new Promise(function(r,n){e=r,t=n}),cb:function(r,n){if(r)return t(r);e(n||"")}}}var ji=function(e){function t(t,r,n){e.call(this),this.started=!1,this.renderer=t,this.template=r,this.context=n||{},this.inject=t.inject}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype._transform=function(e,t,r){this.started||(this.emit("beforeStart"),this.start()),this.push(e),r()},t.prototype.start=function(){if(this.started=!0,this.push(this.template.head(this.context)),this.inject){this.context.head&&this.push(this.context.head);var e=this.renderer.renderResourceHints(this.context);e&&this.push(e);var t=this.renderer.renderStyles(this.context);t&&this.push(t)}this.push(this.template.neck(this.context))},t.prototype._flush=function(e){if(this.emit("beforeEnd"),this.inject){var t=this.renderer.renderState(this.context);t&&this.push(t);var r=this.renderer.renderScripts(this.context);r&&this.push(r)}this.push(this.template.tail(this.context)),e()},t}(require("stream").Transform),Pi=require("lodash.template"),Fi={escape:/{{([^{][\s\S]+?[^}])}}/g,interpolate:/{{{([\s\S]+?)}}}/g};function Ni(e){var t=function(e){var t=new Map;return Object.keys(e.modules).forEach(function(r){t.set(r,function(e,t){var r=[],n=t.modules[e];return n&&n.forEach(function(e){var n=t.all[e];(t.async.indexOf(n)>-1||!/\.js($|\?)/.test(n))&&r.push(n)}),r}(r,e))}),t}(e);return function(e){for(var r=new Set,n=0;n"),n=e.indexOf(t);if(n<0)throw new Error("Content placeholder not found in template.");return r<0&&(r=e.indexOf(""))<0&&(r=n),{head:Pi(e.slice(0,r),Fi),neck:Pi(e.slice(r,n),Fi),tail:Pi(e.slice(n+t.length),Fi)}}(e.template):null,e.clientManifest){var t=this.clientManifest=e.clientManifest;this.publicPath=t.publicPath,this.preloadFiles=(t.initial||[]).map(Mi),this.prefetchFiles=(t.async||[]).map(Mi),this.mapFiles=Ni(t)}};function Mi(e){var t,r=e.replace(/\?.*/,""),n=Ei.extname(r).slice(1);return{file:e,extension:n,fileWithoutQuery:r,asType:(t=n,"js"===t?"script":"css"===t?"style":/jpe?g|png|svg|gif|webp|ico/.test(t)?"image":/woff2?|ttf|otf|eot/.test(t)?"font":"")}}Ii.prototype.bindRenderFns=function(e){var t=this;["ResourceHints","State","Scripts","Styles"].forEach(function(r){e["render"+r]=t["render"+r].bind(t,e)}),e.getPreloadFiles=t.getPreloadFiles.bind(t,e)},Ii.prototype.renderSync=function(e,t){var r=this.parsedTemplate;if(!r)throw new Error("renderSync cannot be called without a template.");return t=t||{},this.inject?r.head(t)+(t.head||"")+this.renderResourceHints(t)+this.renderStyles(t)+r.neck(t)+e+this.renderState(t)+this.renderScripts(t)+r.tail(t):r.head(t)+r.neck(t)+e+r.tail(t)},Ii.prototype.renderStyles=function(e){var t=this,r=this.preloadFiles||[],n=this.getUsedAsyncFiles(e)||[],i=r.concat(n).filter(function(e){return function(e){return/\.css(\?[^.]+)?$/.test(e)}(e.file)});return(i.length?i.map(function(e){var r=e.file;return''}).join(""):"")+(e.styles||"")},Ii.prototype.renderResourceHints=function(e){return this.renderPreloadLinks(e)+this.renderPrefetchLinks(e)},Ii.prototype.getPreloadFiles=function(e){var t=this.getUsedAsyncFiles(e);return this.preloadFiles||t?(this.preloadFiles||[]).concat(t||[]):[]},Ii.prototype.renderPreloadLinks=function(e){var t=this,r=this.getPreloadFiles(e),n=this.options.shouldPreload;return r.length?r.map(function(e){var r=e.file,i=e.extension,o=e.fileWithoutQuery,a=e.asType,s="";return n||"script"===a||"style"===a?n&&!n(o,a)?"":("font"===a&&(s=' type="font/'+i+'" crossorigin'),'"):""}).join(""):""},Ii.prototype.renderPrefetchLinks=function(e){var t=this,r=this.options.shouldPrefetch;if(this.prefetchFiles){var n=this.getUsedAsyncFiles(e);return this.prefetchFiles.map(function(e){var i=e.file,o=e.fileWithoutQuery,a=e.asType;return r&&!r(o,a)?"":function(e){return n&&n.some(function(t){return t.file===e})}(i)?"":''}).join("")}return""},Ii.prototype.renderState=function(e,t){var r=t||{},n=r.contextKey;void 0===n&&(n="state");var i=r.windowKey;void 0===i&&(i="__INITIAL_STATE__");var o=Li(e[n],{isJSON:!0});return e[n]?"' + } + } + }).$mount() + expect(vm.$el.nodeName).toBe('#comment') + expect('Templates should only be responsible for mapping the state').toHaveBeenWarned() + }) }) diff --git a/test/unit/features/directives/bind.spec.js b/test/unit/features/directives/bind.spec.js index 8d7f7c4847a..7e4827dc061 100644 --- a/test/unit/features/directives/bind.spec.js +++ b/test/unit/features/directives/bind.spec.js @@ -69,25 +69,25 @@ describe('Directive v-bind', () => { it('enumerated attr', done => { const vm = new Vue({ - template: '
hello
', + template: '
hello
', data: { foo: true } }).$mount() - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true') - vm.foo = 'again' + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('true') + vm.foo = 'plaintext-only' // allow special values waitForUpdate(() => { - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true') + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('plaintext-only') vm.foo = null }).then(() => { - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false') vm.foo = '' }).then(() => { - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('true') + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('true') vm.foo = false }).then(() => { - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false') vm.foo = 'false' }).then(() => { - expect(vm.$el.firstChild.getAttribute('draggable')).toBe('false') + expect(vm.$el.firstChild.getAttribute('contenteditable')).toBe('false') }).then(done) }) @@ -133,17 +133,19 @@ describe('Directive v-bind', () => { expect(vm.$el.getAttribute('id')).toBe(null) }) - it('.prop modifier shorthand', () => { - const vm = new Vue({ - template: '
', - data: { - foo: 'hello', - bar: 'qux' - } - }).$mount() - expect(vm.$el.children[0].textContent).toBe('hello') - expect(vm.$el.children[1].innerHTML).toBe('qux') - }) + if (process.env.VBIND_PROP_SHORTHAND) { + it('.prop modifier shorthand', () => { + const vm = new Vue({ + template: '
', + data: { + foo: 'hello', + bar: 'qux' + } + }).$mount() + expect(vm.$el.children[0].textContent).toBe('hello') + expect(vm.$el.children[1].innerHTML).toBe('qux') + }) + } it('.camel modifier', () => { const vm = new Vue({ @@ -232,7 +234,7 @@ describe('Directive v-bind', () => { template: ``, components: { test: { - template: '
', + template: '
{{ dataFoo }} {{ dataBar }}
', props: ['dataFoo', 'dataBar'] } }, @@ -243,8 +245,7 @@ describe('Directive v-bind', () => { } } }).$mount() - expect(vm.$el.getAttribute('data-foo')).toBe('foo') - expect(vm.$el.getAttribute('data-bar')).toBe('bar') + expect(vm.$el.textContent).toBe('foo bar') }) it('.sync modifier with bind object', done => { @@ -473,4 +474,130 @@ describe('Directive v-bind', () => { expect(vm.$el.innerHTML).toBe('
comp
') }) }) + + describe('dynamic arguments', () => { + it('basic', done => { + const vm = new Vue({ + template: `
`, + data: { + key: 'id', + value: 'hello' + } + }).$mount() + expect(vm.$el.id).toBe('hello') + vm.key = 'class' + waitForUpdate(() => { + expect(vm.$el.id).toBe('') + expect(vm.$el.className).toBe('hello') + // explicit null value + vm.key = null + }).then(() => { + expect(vm.$el.className).toBe('') + expect(vm.$el.id).toBe('') + vm.key = undefined + }).then(() => { + expect(`Invalid value for dynamic directive argument`).toHaveBeenWarned() + }).then(done) + }) + + it('shorthand', done => { + const vm = new Vue({ + template: `
`, + data: { + key: 'id', + value: 'hello' + } + }).$mount() + expect(vm.$el.id).toBe('hello') + vm.key = 'class' + waitForUpdate(() => { + expect(vm.$el.className).toBe('hello') + }).then(done) + }) + + it('with .prop modifier', done => { + const vm = new Vue({ + template: `
`, + data: { + key: 'id', + value: 'hello' + } + }).$mount() + expect(vm.$el.id).toBe('hello') + vm.key = 'textContent' + waitForUpdate(() => { + expect(vm.$el.textContent).toBe('hello') + }).then(done) + }) + + if (process.env.VBIND_PROP_SHORTHAND) { + it('.prop shorthand', done => { + const vm = new Vue({ + template: `
`, + data: { + key: 'id', + value: 'hello' + } + }).$mount() + expect(vm.$el.id).toBe('hello') + vm.key = 'textContent' + waitForUpdate(() => { + expect(vm.$el.textContent).toBe('hello') + }).then(done) + }) + } + + it('handle class and style', () => { + const vm = new Vue({ + template: `
`, + data: { + key: 'class', + value: ['hello', 'world'], + key2: 'style', + value2: { + color: 'red' + } + } + }).$mount() + expect(vm.$el.className).toBe('hello world') + expect(vm.$el.style.color).toBe('red') + }) + + it('handle shouldUseProp', done => { + const vm = new Vue({ + template: ``, + data: { + key: 'value', + value: 'foo' + } + }).$mount() + expect(vm.$el.value).toBe('foo') + vm.value = 'bar' + waitForUpdate(() => { + expect(vm.$el.value).toBe('bar') + }).then(done) + }) + + it('with .sync modifier', done => { + const vm = new Vue({ + template: ``, + data: { + key: 'foo', + value: 'bar' + }, + components: { + foo: { + props: ['foo'], + template: `
{{ foo }}
` + } + } + }).$mount() + expect(vm.$el.textContent).toBe('bar') + vm.$refs.child.$emit('update:foo', 'baz') + waitForUpdate(() => { + expect(vm.value).toBe('baz') + expect(vm.$el.textContent).toBe('baz') + }).then(done) + }) + }) }) diff --git a/test/unit/features/directives/model-checkbox.spec.js b/test/unit/features/directives/model-checkbox.spec.js index 7d48dd1b8ad..0d6ba2f7d15 100644 --- a/test/unit/features/directives/model-checkbox.spec.js +++ b/test/unit/features/directives/model-checkbox.spec.js @@ -56,6 +56,7 @@ describe('Directive v-model checkbox', () => { }, template: `
+ {{ test }}
@@ -65,13 +66,16 @@ describe('Directive v-model checkbox', () => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) vm.$el.children[0].click() - expect(vm.test.length).toBe(0) - vm.$el.children[1].click() - expect(vm.test).toEqual(['2']) - vm.$el.children[0].click() - expect(vm.test).toEqual(['2', '1']) - vm.test = ['1'] waitForUpdate(() => { + expect(vm.test.length).toBe(0) + vm.$el.children[1].click() + }).then(() => { + expect(vm.test).toEqual(['2']) + vm.$el.children[0].click() + }).then(() => { + expect(vm.test).toEqual(['2', '1']) + vm.test = ['1'] + }).then(() => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) }).then(done) @@ -93,13 +97,16 @@ describe('Directive v-model checkbox', () => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) vm.$el.children[0].click() - expect(vm.test.length).toBe(0) - vm.$el.children[1].click() - expect(vm.test).toEqual(['2']) - vm.$el.children[0].click() - expect(vm.test).toEqual(['2', '1']) - vm.test = ['1'] waitForUpdate(() => { + expect(vm.test.length).toBe(0) + vm.$el.children[1].click() + }).then(() => { + expect(vm.test).toEqual(['2']) + vm.$el.children[0].click() + }).then(() => { + expect(vm.test).toEqual(['2', '1']) + vm.test = ['1'] + }).then(() => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) }).then(done) @@ -121,13 +128,16 @@ describe('Directive v-model checkbox', () => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) vm.$el.children[0].click() - expect(vm.test.length).toBe(0) - vm.$el.children[1].click() - expect(vm.test).toEqual([2]) - vm.$el.children[0].click() - expect(vm.test).toEqual([2, 1]) - vm.test = [1] waitForUpdate(() => { + expect(vm.test.length).toBe(0) + vm.$el.children[1].click() + }).then(() => { + expect(vm.test).toEqual([2]) + vm.$el.children[0].click() + }).then(() => { + expect(vm.test).toEqual([2, 1]) + vm.test = [1] + }).then(() => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) }).then(done) @@ -149,13 +159,16 @@ describe('Directive v-model checkbox', () => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) vm.$el.children[0].click() - expect(vm.test.length).toBe(0) - vm.$el.children[1].click() - expect(vm.test).toEqual([{ a: 2 }]) - vm.$el.children[0].click() - expect(vm.test).toEqual([{ a: 2 }, { a: 1 }]) - vm.test = [{ a: 1 }] waitForUpdate(() => { + expect(vm.test.length).toBe(0) + vm.$el.children[1].click() + }).then(() => { + expect(vm.test).toEqual([{ a: 2 }]) + vm.$el.children[0].click() + }).then(() => { + expect(vm.test).toEqual([{ a: 2 }, { a: 1 }]) + vm.test = [{ a: 1 }] + }).then(() => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) }).then(done) @@ -177,13 +190,16 @@ describe('Directive v-model checkbox', () => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) vm.$el.children[0].click() - expect(vm.test.length).toBe(0) - vm.$el.children[1].click() - expect(vm.test).toEqual([[2]]) - vm.$el.children[0].click() - expect(vm.test).toEqual([[2], { a: 1 }]) - vm.test = [{ a: 1 }] waitForUpdate(() => { + expect(vm.test.length).toBe(0) + vm.$el.children[1].click() + }).then(() => { + expect(vm.test).toEqual([[2]]) + vm.$el.children[0].click() + }).then(() => { + expect(vm.test).toEqual([[2], { a: 1 }]) + vm.test = [{ a: 1 }] + }).then(() => { expect(vm.$el.children[0].checked).toBe(true) expect(vm.$el.children[1].checked).toBe(false) }).then(done) diff --git a/test/unit/features/directives/model-component.spec.js b/test/unit/features/directives/model-component.spec.js index 9f9536ada09..49ff4ddb138 100644 --- a/test/unit/features/directives/model-component.spec.js +++ b/test/unit/features/directives/model-component.spec.js @@ -204,4 +204,30 @@ describe('Directive v-model component', () => { expect(triggerCount).toBe(1) document.body.removeChild(vm.$el) }) + + // #9330 + it('should add value to $attrs if not defined in props', () => { + const TestComponent = { + inheritAttrs: false, + render (h) { + return h('div', this.$attrs.value) + } + } + + const vm = new Vue({ + components: { + TestComponent + }, + template: ` +
+ +
+ `, + data: { + val: 'foo' + } + }).$mount() + + expect(vm.$el.innerHTML).toBe('
foo
'); + }) }) diff --git a/test/unit/features/directives/model-text.spec.js b/test/unit/features/directives/model-text.spec.js index 69e9851368a..7cf5167461f 100644 --- a/test/unit/features/directives/model-text.spec.js +++ b/test/unit/features/directives/model-text.spec.js @@ -437,8 +437,8 @@ describe('Directive v-model text', () => { }) } - // #7138 if (isIE && !isIE9) { + // #7138 it('should not fire input on initial render of textarea with placeholder in IE10/11', done => { const el = document.createElement('div') document.body.appendChild(el) @@ -452,5 +452,21 @@ describe('Directive v-model text', () => { done() }, 17) }) + + // #9042 + it('should not block the first input event when placeholder is empty', done => { + const el = document.createElement('div') + document.body.appendChild(el) + const vm = new Vue({ + el, + data: { evtCount: 0 }, + template: ``, + }) + triggerEvent(vm.$el, 'input') + setTimeout(() => { + expect(vm.evtCount).toBe(1) + done() + }, 17) + }) } }) diff --git a/test/unit/features/directives/on.spec.js b/test/unit/features/directives/on.spec.js index 74d65376494..7c252031172 100644 --- a/test/unit/features/directives/on.spec.js +++ b/test/unit/features/directives/on.spec.js @@ -280,7 +280,7 @@ describe('Directive v-on', () => { expect(spy.calls.count()).toBe(1) }) - it('should support system modifers with exact', () => { + it('should support system modifiers with exact', () => { vm = new Vue({ el, template: ` @@ -405,7 +405,7 @@ describe('Directive v-on', () => { Vue.config.keyCodes = Object.create(null) }) - it('should override build-in keyCode', () => { + it('should override built-in keyCode', () => { Vue.config.keyCodes.up = [1, 87] vm = new Vue({ el, @@ -420,7 +420,7 @@ describe('Directive v-on', () => { e.keyCode = 1 }) expect(spy).toHaveBeenCalledTimes(2) - // should not affect build-in down keycode + // should not affect built-in down keycode triggerEvent(vm.$el, 'keyup', e => { e.keyCode = 40 }) @@ -460,6 +460,34 @@ describe('Directive v-on', () => { expect(spy).toHaveBeenCalled() }) + it('should throw a warning if native modifier is used on native HTML element', () => { + vm = new Vue({ + el, + template: ` + + `, + methods: { foo: spy }, + }) + + triggerEvent(vm.$el, 'click') + expect(`The .native modifier for v-on is only valid on components but it was used on
- + - - + + - - + + - - + +
- - + + - - + + - - + + - - + + - - + + - - + +
- - + + - - + + - - + + - - + + - - + + - - + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
- - + + - - + +