diff --git a/.babelrc b/.babelrc index c687bbc3a..689c3e542 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ { - "presets": ["es2015-loose", "flow-vue"], + "presets": ["es2015", "flow-vue"], "plugins": ["syntax-dynamic-import"] } diff --git a/build/build.js b/build/build.js index 6d5b8c42c..0175de415 100644 --- a/build/build.js +++ b/build/build.js @@ -92,9 +92,7 @@ function buildEntry (config) { const code = bundle.generate(config).code if (isProd) { var minified = (config.banner ? config.banner + '\n' : '') + uglify.minify(code, { - fromString: true, output: { - screw_ie8: true, ascii_only: true }, compress: { diff --git a/docs/LANGS.md b/docs/LANGS.md index 6654d54e8..2af5399fd 100644 --- a/docs/LANGS.md +++ b/docs/LANGS.md @@ -1,4 +1,5 @@ * [2.0 - English](en/) +* [2.0 - French](fr/) * [2.0 - Japanese](ja/) * [2.0 - 中文](zh-cn/) * [2.0 - German](de/) diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index 8c11415e9..49f522268 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -7,7 +7,7 @@ - [Installation](installation.md) - Essentiel - [Pour commencer](essentials/getting-started.md) - - [Dynamic Route Matching (En)](essentials/dynamic-matching.md) + - [Concordance dynamique de route](essentials/dynamic-matching.md) - [Nested Routes (En)](essentials/nested-routes.md) - [Programmatic Navigation (En)](essentials/navigation.md) - [Named Routes (En)](essentials/named-routes.md) diff --git a/docs/en/essentials/dynamic-matching.md b/docs/en/essentials/dynamic-matching.md index b52be5088..f0d0f6df7 100644 --- a/docs/en/essentials/dynamic-matching.md +++ b/docs/en/essentials/dynamic-matching.md @@ -1,74 +1,74 @@ -# Dynamic Route Matching (En)

*Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* +# Concordance dynamique de route -Very often we will need to map routes with the given pattern to the same component. For example we may have a `User` component which should be rendered for all users but with different user IDs. In `vue-router` we can use a dynamic segment in the path to achieve that: +Vous allez très souvent associer des routes avec un motif donné à un même composant. Par exemple nous pourrions avoir le composant `User` qui devrait être rendu pour tous les utilisateurs mais avec différents identifiants. Avec `vue-router` nous pouvons utiliser des segments dynamiques dans le chemin de la route pour réaliser cela : ``` js const User = { - template: '
User
' + template: '
Utilisateur
' } const router = new VueRouter({ routes: [ - // dynamic segments start with a colon - { path: '/user/:id', component: User } + // Les segments dynamiques commencent avec la ponctuation deux-points + { path: '/utilisateur/:id', component: User } ] }) ``` -Now URLs like `/user/foo` and `/user/bar` will both map to the same route. +Maintenant des URLs comme `/utilisateur/foo` et `/utilisateur/bar` seront chacune associée à la même route. -A dynamic segment is denoted by a colon `:`. When a route is matched, the value of the dynamic segments will be exposed as `this.$route.params` in every component. Therefore, we can render the current user ID by updating `User`'s template to this: +Un segment dynamique se repère avec les deux-points `:`. Quand une route concorde, la valeur du segment dynamique est exposée via `this.$route.params` dans tous les composants. Et donc, nous pouvons faire le rendu de l'identifiant de l'utilisateur courant en mettant à jour le template de `User` ainsi : ``` js const User = { - template: '
User {{ $route.params.id }}
' + template: '
Utilisateur {{ $route.params.id }}
' } ``` -You can checkout a live example [here](http://jsfiddle.net/yyx990803/4xfa2f19/). +Vous pouvez regarder un exemple en ligne [ici](http://jsfiddle.net/yyx990803/4xfa2f19/). -You can have multiple dynamic segments in the same route, and they will map to corresponding fields on `$route.params`. Examples: +Vous pouvez avoir plusieurs segments dynamiques pour une même route, et ils seront associés aux champs associés dans `$route.params`. Des exemples : -| pattern | matched path | $route.params | +| motif | chemin concordant | $route.params | |---------|------|--------| -| /user/:username | /user/evan | `{ username: 'evan' }` | -| /user/:username/post/:post_id | /user/evan/post/123 | `{ username: 'evan', post_id: 123 }` | +| /utilisateur/:username | /utilisateur/evan | `{ username: 'evan' }` | +| /utilisateur/:username/billet/:post_id | /utilisateur/evan/billet/123 | `{ username: 'evan', post_id: 123 }` | -In addition to `$route.params`, the `$route` object also exposes other useful information such as `$route.query` (if there is a query in the URL), `$route.hash`, etc. You can check out the full details in the [API Reference](../api/route-object.md). +En plus de `$route.params`, l'objet `$route` expose également d'autres informations utiles comme la `$route.query` (s'il y a une requête dans l'URL), `$route.hash`, etc. Vous pouvez accéder à tous les détails de cela dans la [référence de l'API](../api/route-object.md). -### Reacting to Params Changes +### Réactivité au changement de paramètres -One thing to note when using routes with params is that when the user navigates from `/user/foo` to `/user/bar`, **the same component instance will be reused**. Since both routes render the same component, this is more efficient than destroying the old instance and then creating a new one. **However, this also means that the lifecycle hooks of the component will not be called**. +Une chose à noter quand vous utilisez des routes avec des paramètres (segments), c'est que lors de la navigation de l'utilisateur de `/utilisateur/foo` vers `/utilisateur/bar`, **la même instance de composant va être réutilisée**. Puisque les deux routes font le rendu du même composant, cela est plus performant que de détruire l'ancienne instance et dans créer une nouvelle. **Cependant, cela signifie également que les hooks de cycle de vie ne seront pas appelés**. -To react to params changes in the same component, you can simply watch the `$route` object: +Pour réagir aux changements de paramètres dans le même composant, vous pouvez simplement observer l'objet `$route` : ``` js const User = { template: '...', watch: { '$route' (to, from) { - // react to route changes... + // réagir au changement de route... } } } ``` -Or, use the `beforeRouteUpdate` guard introduced in 2.2: +Ou utiliser la fonction de sécurisation `beforeRouteUpdate` introduite avec la 2.2 : ``` js const User = { template: '...', beforeRouteUpdate (to, from, next) { - // react to route changes... - // don't forget to call next() + // réagir au changement de route... + // n'oubliez pas d'appeler `next()` } } ``` -### Advanced Matching Patterns +### Motifs de concordance avancés -`vue-router` uses [path-to-regexp](https://github.com/pillarjs/path-to-regexp) as its path matching engine, so it supports many advanced matching patterns such as optional dynamic segments, zero or more / one or more requirements, and even custom regex patterns. Check out its [documentation](https://github.com/pillarjs/path-to-regexp#parameters) for these advanced patterns, and [this example](https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js) of using them in `vue-router`. +`vue-router` utilise [path-to-regexp](https://github.com/pillarjs/path-to-regexp) comme moteur de concordance de chemin, il supporte donc plusieurs motifs de concordance avancés tel que la présence optionnelle de segments dynamiques, aucun ou plusieurs motifs, plus d'options par motifs, et même des motifs d'expressions régulières personnalisés. Consultez cette [documentation](https://github.com/pillarjs/path-to-regexp#parameters) pour utiliser ces motifs avancés et [cet exemple](https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js) pour les utiliser avec `vue-router`. -### Matching Priority +### Priorité de concordance -Sometimes the same URL may be matched by multiple routes. In such a case the matching priority is determined by the order of route definition: the earlier a route is defined, the higher priority it gets. +Parfois la même URL peut être adressée par de multiples routes. Dans ce cas, la priorité de concordance est déterminée par l'ordre de la définition des routes : plus la route est définie tôt, plus sa priorité est élevée. diff --git a/docs/fr/README.md b/docs/fr/README.md new file mode 100644 index 000000000..f8a898044 --- /dev/null +++ b/docs/fr/README.md @@ -0,0 +1 @@ +{% include "./SUMMARY.md" %} diff --git a/docs/fr/SUMMARY.md b/docs/fr/SUMMARY.md new file mode 100644 index 000000000..8c11415e9 --- /dev/null +++ b/docs/fr/SUMMARY.md @@ -0,0 +1,32 @@ +# vue-router 2 + +> Note: vue-router@2.x fonctionne uniquement avec Vue 2.x. La doc pour la 0.7.x est [ici](https://github.com/vuejs/vue-router/tree/1.0/docs/en). + +**[Notes de release](https://github.com/vuejs/vue-router/releases)** + +- [Installation](installation.md) +- Essentiel + - [Pour commencer](essentials/getting-started.md) + - [Dynamic Route Matching (En)](essentials/dynamic-matching.md) + - [Nested Routes (En)](essentials/nested-routes.md) + - [Programmatic Navigation (En)](essentials/navigation.md) + - [Named Routes (En)](essentials/named-routes.md) + - [Named Views (En)](essentials/named-views.md) + - [Redirect and Alias (En)](essentials/redirect-and-alias.md) + - [Passing Props to Route Components (En)](essentials/passing-props.md) + - [HTML5 History Mode (En)](essentials/history-mode.md) +- Avancé + - [Navigation Guards (En)](advanced/navigation-guards.md) + - [Route Meta Fields (En)](advanced/meta.md) + - [Transitions (En)](advanced/transitions.md) + - [La récupération de données](advanced/data-fetching.md) + - [Les transitions](advanced/transitions.md) + - [Comportement du défilement](advanced/scroll-behavior.md) + - [Le chargement à la volée](advanced/lazy-loading.md) +- Réference de l'API + - [router-link](api/router-link.md) + - [router-view](api/router-view.md) + - [L'objet Route](api/route-object.md) + - [Options de construction du routeur](api/options.md) + - [L'Instance du routeur](api/router-instance.md) + - [Injections de composant](api/component-injections.md) \ No newline at end of file diff --git a/docs/fr/advanced/data-fetching.md b/docs/fr/advanced/data-fetching.md new file mode 100644 index 000000000..29f67715c --- /dev/null +++ b/docs/fr/advanced/data-fetching.md @@ -0,0 +1,110 @@ +# La récupération de données + +Parfois vous avez besoin de récupérer des données depuis le serveur lorsqu'une route est activée. Par exemple, avant de faire le rendu d'un profil utilisateur, vous avez besoin de récupérer les données de l'utilisateur depuis le serveur. Nous pouvons y parvenir de deux façons différentes : + +- **Récupération de donnée après la navigation** : effectue la navigation en premier, et récupère les données dans le hook entrant du cycle de vie d'un composant. Affiche un état de chargement pendant que les données sont en train d'être récupérées. + +- **Récupération de donnée avant la navigation** : récupère les données avant la navigation dans la fonction de sécurisation d'entrée de la route, et effectue la navigation après que les données aient été récupérées. + +Techniquement, les deux choix sont valides. Cela dépend de l'expérience utilisateur que vous souhaitez apporter. + +## Récupération de données après la navigation + +En utilisant cette approche, nous naviguons et faisons immédiatement le rendu du composant et récupérons les données via le hook `created` du composant. Cela nous donne l'opportunité d'afficher un état de chargement pendant que les données sont récupérées à travers le réseau, et nous pouvons aussi gérer le chargement différemment pour chaque vue. + +Assumons que nous ayons un composant `Post` qui a besoin de récupérer des données pour un billet identifié par `$route.params.id` : + +``` html + +``` + +``` js +export default { + data () { + return { + loading: false, + post: null, + error: null + } + }, + created () { + // récupérer les données lorsque la vue est créée et + // que les données sont déjà observées + this.fetchData() + }, + watch: { + // appeler encore la méthode si la route change + '$route': 'fetchData' + }, + methods: { + fetchData () { + this.error = this.post = null + this.loading = true + // remplacer `getPost` par une fonction de récupération de données + getPost(this.$route.params.id, (err, post) => { + this.loading = false + if (err) { + this.error = err.toString() + } else { + this.post = post + } + }) + } + } +} +``` + +## Récupération de données avant la navigation + +Avec cette approche, nous récupérerons les données avant de naviguer vers la nouvelle route. Nous pouvons effectuer la récupération de données dans la fonction de sécurisation `beforeRouteEnter` du composant à venir, et seulement appeler `next` lorsque la récupération est terminée : + +``` js +export default { + data () { + return { + post: null, + error: null + } + }, + beforeRouteEnter (to, from, next) { + getPost(to.params.id, (err, post) => { + next(vm => vm.setData(err, post)) + }) + }, + // quand la route change et que ce composant est déjà rendu, + // la logique est un peu différente + beforeRouteUpdate (to, from, next) { + this.post = null + getPost(to.params.id, (err, post) => { + this.setData(err, post) + next() + }) + }, + methods: { + setData (err, post) { + if (err) { + this.error = err.toString() + } else { + this.post = post + } + } + } +} +``` + +L'utilisateur va rester sur la vue précédente pendant que la ressource est en train d'être récupérée pour la vue à venir. Il est cependant recommandé d'afficher une barre de progression ou un autre type d'indicateur pendant que les données sont en train d'être récupérées. Si la récupération échoue, il est aussi recommandé d'afficher une sorte de message d'erreur global. diff --git a/docs/fr/advanced/lazy-loading.md b/docs/fr/advanced/lazy-loading.md new file mode 100644 index 000000000..728f6403a --- /dev/null +++ b/docs/fr/advanced/lazy-loading.md @@ -0,0 +1,47 @@ +# Le chargement à la volée + +Pendant la construction d'applications avec un empaqueteur (« bundler »), le paquetage JavaScript peut devenir un peu lourd, et donc cela peut affecter le temps de chargement de la page. Il serait plus efficace si l'on pouvait séparer chaque composant de route dans des fragments séparés, et de les charger uniquement lorsque la route est visitée. + +En combinant la [fonctionnalité de composant asynchrone](https://fr.vuejs.org/v2/guide/components.html#Composants-asynchrones) de Vue et la [fonctionnalité de séparation de code](https://webpack.js.org/guides/code-splitting-async/) de webpack, il est très facile de charger à la volée les composants de route. + +Premièrement, un composant asynchrone peut définir une fonction fabrique qui retourne une Promesse (qui devrait résoudre le composant lui-même) : + +``` js +const Foo = () => Promise.resolve({ /* définition du composant */ }) +``` + +Deuxièmement, avec webpack 2, nous pouvons utiliser la syntaxe d'[import dynamique](https://github.com/tc39/proposal-dynamic-import) pour indiquer un point de scission de code : + +``` js +import('./Foo.vue') // returns a Promise +``` + +> Note: if you are using Babel, you will need to add the [syntax-dynamic-import](http://babeljs.io/docs/plugins/syntax-dynamic-import/) plugin so that Babel can properly parse the syntax. + +Combining the two, this is how to define an async component that will be automatically code-split by webpack: + +``` js +const Foo = () => import('./Foo.vue') +``` + +Rien n'a besoin d'être modifié dans la configuration de la route, utilisez `Foo` comme d'habitude. + +``` js +const router = new VueRouter({ + routes: [ + { path: '/foo', component: Foo } + ] +}) +``` + +### Grouper des composants dans le même fragment + +Parfois on aimerait grouper tous les composants imbriqués sous la même route, dans un seul et même fragment asynchrone. Pour arriver à cela, nous avons besoin d'utiliser les [fragments nommés](https://webpack.js.org/guides/code-splitting-async/#chunk-names) en donnant un nom au fragment en utilisant une syntaxe de commentaire spéciale (requires webpack > 2.4) : + +``` js +const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') +const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') +const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue') +``` + +webpack groupera tous les modules asynchrones avec le même nom de fragment dans le même fragment asynchrone. diff --git a/docs/fr/advanced/meta.md b/docs/fr/advanced/meta.md new file mode 100644 index 000000000..998b6c134 --- /dev/null +++ b/docs/fr/advanced/meta.md @@ -0,0 +1,51 @@ +# Route Meta Fields (En)

*Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +You can include a `meta` field when defining a route: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/foo', + component: Foo, + children: [ + { + path: 'bar', + component: Bar, + // a meta field + meta: { requiresAuth: true } + } + ] + } + ] +}) +``` + +So how do we access this `meta` field? + +First, each route object in the `routes` configuration is called a **route record**. Route records may be nested. Therefore when a route is matched, it can potentially match more than one route record. + +For example, with the above route config, the URL `/foo/bar` will match both the parent route record and the child route record. + +All route records matched by a route are exposed on the `$route` object (and also route objects in navigation guards) as the `$route.matched` Array. Therefore, we will need to iterate over `$route.matched` to check for meta fields in route records. + +An example use case is checking for a meta field in the global navigation guard: + +``` js +router.beforeEach((to, from, next) => { + if (to.matched.some(record => record.meta.requiresAuth)) { + // this route requires auth, check if logged in + // if not, redirect to login page. + if (!auth.loggedIn()) { + next({ + path: '/login', + query: { redirect: to.fullPath } + }) + } else { + next() + } + } else { + next() // make sure to always call next()! + } +}) +``` diff --git a/docs/fr/advanced/navigation-guards.md b/docs/fr/advanced/navigation-guards.md new file mode 100644 index 000000000..97dfb6903 --- /dev/null +++ b/docs/fr/advanced/navigation-guards.md @@ -0,0 +1,134 @@ +# Navigation Guards (En)

*Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +As the name suggests, the navigation guards provided by `vue-router` are primarily used to guard navigations either by redirecting it or canceling it. There are a number of ways to hook into the route navigation process: globally, per-route, or in-component. + +Remember that **params or query changes won't trigger enter/leave navigation guards**. You can either [watch the `$route` object](../essentials/dynamic-matching.md#reacting-to-params-changes) to react to those changes, or use the `beforeRouteUpdate` in-component guard. + +### Global Guards + +You can register global before guards using `router.beforeEach`: + +``` js +const router = new VueRouter({ ... }) + +router.beforeEach((to, from, next) => { + // ... +}) +``` + +Global before guards are called in creation order, whenever a navigation is triggered. Guards may be resolved asynchronously, and the navigation is considered **pending** before all hooks have been resolved. + +Every guard function receives three arguments: + +- **`to: Route`**: the target [Route Object](../api/route-object.md) being navigated to. + +- **`from: Route`**: the current route being navigated away from. + +- **`next: Function`**: this function must be called to **resolve** the hook. The action depends on the arguments provided to `next`: + + - **`next()`**: move on to the next hook in the pipeline. If no hooks are left, the navigation is **confirmed**. + + - **`next(false)`**: abort the current navigation. If the browser URL was changed (either manually by the user or via back button), it will be reset to that of the `from` route. + + - **`next('/')` or `next({ path: '/' })`**: redirect to a different location. The current navigation will be aborted and a new one will be started. + + - **`next(error)`**: (2.4.0+) if the argument passed to `next` is an instance of `Error`, the navigation will be aborted and the error will be passed to callbacks registered via `router.onError()`. + +**Make sure to always call the `next` function, otherwise the hook will never be resolved.** + +### Global Resolve Guards + +> New in 2.5.0 + +In 2.5.0+ you can register a global guard with `router.beforeResolve`. This is similar to `router.beforeEach`, with the difference that resolve guards will be called right before the navigation is confirmed, **after all in-component guards and async route components are resolved**. + +### Global After Hooks + +You can also register global after hooks, however unlike guards, these hooks do not get a `next` function and cannot affect the navigation: + +``` js +router.afterEach((to, from) => { + // ... +}) +``` + +### Per-Route Guard + +You can define `beforeEnter` guards directly on a route's configuration object: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/foo', + component: Foo, + beforeEnter: (to, from, next) => { + // ... + } + } + ] +}) +``` + +These guards have the exact same signature as global before guards. + +### Sécurisation intra-composants + +Finally, you can directly define route navigation guards inside route components (the ones passed to the router configuration) with the following options: + +- `beforeRouteEnter` +- `beforeRouteUpdate` (added in 2.2) +- `beforeRouteLeave` + +``` js +const Foo = { + template: `...`, + beforeRouteEnter (to, from, next) { + // called before the route that renders this component is confirmed. + // does NOT have access to `this` component instance, + // because it has not been created yet when this guard is called! + }, + beforeRouteUpdate (to, from, next) { + // called when the route that renders this component has changed, + // but this component is reused in the new route. + // For example, for a route with dynamic params /foo/:id, when we + // navigate between /foo/1 and /foo/2, the same Foo component instance + // will be reused, and this hook will be called when that happens. + // has access to `this` component instance. + }, + beforeRouteLeave (to, from, next) { + // called when the route that renders this component is about to + // be navigated away from. + // has access to `this` component instance. + } +} +``` + +The `beforeRouteEnter` guard does **NOT** have access to `this`, because the guard is called before the navigation is confirmed, thus the new entering component has not even been created yet. + +However, you can access the instance by passing a callback to `next`. The callback will be called when the navigation is confirmed, and the component instance will be passed to the callback as the argument: + +``` js +beforeRouteEnter (to, from, next) { + next(vm => { + // access to component instance via `vm` + }) +} +``` + +You can directly access `this` inside `beforeRouteLeave`. The leave guard is usually used to prevent the user from accidentally leaving the route with unsaved edits. The navigation can be canceled by calling `next(false)`. + +### The Full Navigation Resolution Flow + +1. Navigation triggered +2. Call leave guards in deactivated components +3. Call global `beforeEach` guards +4. Call `beforeRouteUpdate` guards in reused components (2.2+) +5. Call `beforeEnter` in route configs +6. Resolve async route components +7. Call `beforeRouteEnter` in activated components +8. Call global `beforeResolve` guards (2.5+) +9. Navigation confirmed. +10. Call global `afterEach` hooks. +11. DOM updates triggered. +12. Call callbacks passed to `next` in `beforeRouteEnter` guards with instantiated instances. diff --git a/docs/fr/advanced/scroll-behavior.md b/docs/fr/advanced/scroll-behavior.md new file mode 100644 index 000000000..2d176188c --- /dev/null +++ b/docs/fr/advanced/scroll-behavior.md @@ -0,0 +1,61 @@ +# Comportement du défilement + +En utilisant le routage côté client, nous pourrions vouloir faire défiler la page jusqu'en haut lorsqu'on navigue vers une nouvelle route, ou alors préserver la position du défilement des entrées de l'historique comme le ferait une page réelle. `vue-router` vous permet de faire cela et, encore mieux, vous permet de changer le comportement du défilement pendant la navigation. + +**Note : cette fonctionnalité ne fonctionne qu'avec le mode historique HTML5.** + +Pendant la création de l'instance du routeur, vous pouvez renseigner la fonction `scrollBehavior` : + +``` js +const router = new VueRouter({ + routes: [...], + scrollBehavior (to, from, savedPosition) { + // retourner la position désirée + } +}) +``` + +La fonction `scrollBehavior` reçoit les objets de route `to` et `from`. Le troisième argument, `savedPosition`, est disponible uniquement si c'est une navigation `popstate` (déclenchée par les boutons précédent/suivant du navigateur). + +La fonction peut retourner un objet décrivant la position du défilement. L'objet peut être de la forme : + +- `{ x: number, y: number }` +- `{ selector: String }` + +Si une valeur équivalente à `false` ou un objet vide est retourné, aucun défilement ne sera produit. + +Par exemple : + +``` js +scrollBehavior (to, from, savedPosition) { + return { x: 0, y: 0 } +} +``` + +Cela permettra de défiler au haut de page à chaque navigation à travers les routes. + +Retourner l'objet `savedPosition` résultera en un comportement quasi-natif en naviguant avec les boutons précédents/suivants : + +``` js +scrollBehavior (to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } else { + return { x: 0, y: 0 } + } +} +``` + +Si vous voulez simuler le comportement « aller à l'ancre » : + +``` js +scrollBehavior (to, from, savedPosition) { + if (to.hash) { + return { + selector: to.hash + } + } +} +``` + +On peut aussi utiliser les [champs meta de route](meta.md) pour implémenter un contrôle bien précis pour le comportement du défilement. Allez voir un exemple complet [ici](https://github.com/vuejs/vue-router/blob/dev/examples/scroll-behavior/app.js). diff --git a/docs/fr/advanced/transitions.md b/docs/fr/advanced/transitions.md new file mode 100644 index 000000000..d90dc45cc --- /dev/null +++ b/docs/fr/advanced/transitions.md @@ -0,0 +1,58 @@ +# Les transitions + +Vu que `` est essentiellement un composant dynamique, on peut lui appliquer certains effets de transitions en utilisant le composant `` : + +``` html + + + +``` + +[Tout à propos de ``](http://fr.vuejs.org/v2/guide/transitions.html) fonctionne également ici de la même manière. + +### Transition par route + +L'utilisation au dessus applique la même transition pour chaque route. Si vous voulez que les composants de route aient des transitions différentes, vous pouvez utiliser à la place `` avec des noms différents à l'intérieur de chaque composant de route : + +``` js +const Foo = { + template: ` + +
...
+
+ ` +} + +const Bar = { + template: ` + +
...
+
+ ` +} +``` + +# Transition dynamique basée sur la route + +Il est aussi possible de déterminer la transition à utiliser en se basant sur la relation entre la route cible et la route actuelle : + +``` html + + + + +``` + +``` js +// et dans le composant parent, +// observer la `$route` pour déterminer la transition à utiliser +watch: { + '$route' (to, from) { + const toDepth = to.path.split('/').length + const fromDepth = from.path.split('/').length + this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' + } +} +``` + +Voir un exemple complet [ici](https://github.com/vuejs/vue-router/blob/dev/examples/transitions/app.js). diff --git a/docs/fr/api/component-injections.md b/docs/fr/api/component-injections.md new file mode 100644 index 000000000..c98415a6b --- /dev/null +++ b/docs/fr/api/component-injections.md @@ -0,0 +1,21 @@ +# Injections de composant + +### Propriétés injectées + +Ces propriétés sont injectées dans chacun des composants enfants, en passant l'instance du routeur à l'application racine de Vue en tant qu'option `router`. + +- #### $router + + L'instance du routeur. + +- #### $route + + La [Route](route-object.md) actuellement active. C'est une propriété en lecture seule et ses propriétés sont immutables, mais elles restent malgré tout observables. + +### Options activées + +- **beforeRouteEnter** +- **beforeRouteUpdate** (ajouté en 2.2) +- **beforeRouteLeave** + + Voir la [Sécurisation intra-composants](../advanced/navigation-guards.md#securisation-intra-composants). diff --git a/docs/fr/api/options.md b/docs/fr/api/options.md new file mode 100644 index 000000000..ee608d967 --- /dev/null +++ b/docs/fr/api/options.md @@ -0,0 +1,88 @@ +# Options de construction du routeur + +### routes + +- type: `Array` + + Déclaration de type pour `RouteConfig` : + + ``` js + declare type RouteConfig = { + path: string; + component?: Component; + name?: string; // pour les routes nommées + components?: { [name: string]: Component }; // pour les vues nommées + redirect?: string | Location | Function; + props?: boolean | string | Function; + alias?: string | Array; + children?: Array; // pour les routes imbriquées + beforeEnter?: (to: Route, from: Route, next: Function) => void; + meta?: any; + } + ``` + +### mode + +- type : `string` + +- défaut : `"hash" (dans le navigateur) | "abstract" (en Node.js)` + +- valeurs disponibles : `"hash" | "history" | "abstract"` + + Configure le mode du routeur. + + - `hash` : utilise le hash de l'URL pour le routage. Fonctionne dans tous les navigateurs supportés par Vue, ainsi que ceux qui ne supportent pas l'API History d'HTML5. + + - `history` : nécessite l'API History d'HTML 5 et la configuration du serveur. Voir [Mode historique de HTML5](../essentials/history-mode.md). + + - `abstract` : fonctionne dans tous les environnements JavaScript, ex. côté serveur avec Node.js. **Le routeur sera automatiquement forcé d'utiliser ce mode si aucune API navigateur n'est présente.** + +### base + +- type : `string` + +- défaut : `"/"` + + L'URL de base de l'application. Par exemple, si l'application monopage entière est distribuée sous `/app/`, alors `base` doit utiliser la valeur `"/app/"`. + +### linkActiveClass + +- type : `string` + +- défaut : `"router-link-active"` + + Configure de manière globale la classe active par défaut de ``. Voir aussi [router-link](router-link.md). + +### linkExactActiveClass + +> 2.5.0+ + +- type : `string` + +- default : `"router-link-exact-active"` + + Configure de manière globale la classe active par défaut de `` lors d'une correspondance exact. Voir aussi [router-link](router-link.md). + +### scrollBehavior + +- type : `Function` + + Signature : + + ``` + ( + to: Route, + from: Route, + savedPosition?: { x: number, y: number } + ) => { x: number, y: number } | { selector: string } | ?{} + ``` + + Pour plus de détails, voir [Comportement du Scroll](../advanced/scroll-behavior.md). + +### parseQuery / stringifyQuery + +> 2.4.0+ + +- type : `Function` + + Permet de spécifier des fonctions personnalisées pour formater en objet ou en chaîne de caractères la requête. Surcharge les fonctions par défaut. diff --git a/docs/fr/api/route-object.md b/docs/fr/api/route-object.md new file mode 100644 index 000000000..fb9696c34 --- /dev/null +++ b/docs/fr/api/route-object.md @@ -0,0 +1,89 @@ +# L'objet `Route` + +Un **objet `Route`** représente l'état actuel de la route active. Il contient des informations analysées à propos de l'URL courante et **les itinéraires de route** appariés par l'URL. + +L'objet `Route` est immutable. Chaque navigation qui se déroule avec succès résultera en un nouvel objet `Route`. + +L'objet `Route` peut être trouvé à plusieurs endroits : + +- À l'intérieur des composants en tant que `this.$route` + +- À l'intérieur des fonctions de rappel des observateurs de `$route` + +- Comme valeur de retour après l'appel de `router.match(location)` + +- À l'intérieur des fonctions de sécurisation de la navigation, dans les deux premiers paramètres de la fonction : + + ``` js + router.beforeEach((to, from, next) => { + // `to` et `from` sont tous les deux des objets Route + }) + ``` + +- À l'intérieur de la fonction `scrollBehavior` dans les deux premiers arguments : + + ``` js + const router = new VueRouter({ + scrollBehavior (to, from, savedPosition) { + // `to` et `from` sont tous les deux des objets Route + } + }) + ``` + +### Propriétés de l'objet `Route` + +- **$route.path** + + - type : `string` + + Une chaîne de caractères représentant le chemin de la route en cours, toujours résolue en tant que chemin absolu, ex : `"/foo/bar"`. + +- **$route.params** + + - type : `Object` + + Un objet qui contient des pairs clé/valeur de segments dynamiques et segments *star*. S'il n'y a pas de paramètres, alors la valeur sera un objet vide. + +- **$route.query** + + - type : `Object` + + Un objet qui contient des pairs clé/valeur de la requête au format d'une chaîne de caractères. Par exemple, pour un chemin `/foo?user=1`, on aura `$route.query.user == 1`. S'il n'y a pas de requête, alors la valeur sera un objet vide. + +- **$route.hash** + + - type : `string` + + Le hash de la route courante (avec le `#`), s'il y en a un. S'il n'y a pas de hash, alors la valeur sera une chaîne de caractères vide. + +- **$route.fullPath** + + - type : `string` + + L'URL entièrement résolue, incluant la requête et le hash. + +- **$route.matched** + + - type : `Array` + + Un `Array` contenant les **les itinéraires de la route** pour chaque segment de chemin imbriqué de la route courante. Les itinéraires de la route sont des copies des objets dans le tableau de configuration `routes` (et dans les tableaux `children`). + + ``` js + const router = new VueRouter({ + routes: [ + // l'objet qui suit est un itinéraire de route + { path: '/foo', component: Foo, + children: [ + // c'est aussi un itinéraire + { path: 'bar', component: Bar } + ] + } + ] + }) + ``` + + Lorsque l'URL sera `/foo/bar`, `$route.matched` sera un `Array` contenant les deux objets (clonés), dans l'ordre parent à l'enfant. + +- **$route.name** + + Le nom de la route courante, si elle en a un. (Voir [Routes nommées](../essentials/named-routes.md)). diff --git a/docs/fr/api/router-instance.md b/docs/fr/api/router-instance.md new file mode 100644 index 000000000..2f3d98562 --- /dev/null +++ b/docs/fr/api/router-instance.md @@ -0,0 +1,86 @@ +# L'Instance du routeur + +### Propriétés + +#### router.app + +- type: `instance de Vue` + + L'instance racine de Vue dans laquelle l'instance de `routeur` a été injectée. + +#### router.mode + +- type: `string` + + Le [mode](options.md#mode) que le routeur utilise. + +#### router.currentRoute + +- type: `Route` + + La route actuelle représentée en tant qu'un [objet route](route-object.md). + +### Méthodes + +- **router.beforeEach(guard)** +- **router.beforeResolve(guard)** (2.5.0+) +- **router.afterEach(hook)** + + Ajout de sécurités globales de navigation. Voir les [sécurités de navigation](../advanced/navigation-guards.md). + + Dans la version 2.5.0+, ces trois méthodes retournent une fonction qui enlève les fonctions de sécurisations et hooks enregistrés. + +- **router.push(location, onComplete?, onAbort?)** +- **router.replace(location, onComplete?, onAbort?)** +- **router.go(n)** +- **router.back()** +- **router.forward()** + + Navigue à une nouvelle URL de façon programmée. Voir [Navigation de façon programmée](../essentials/navigation.md). + +- **router.getMatchedComponents(location?)** + + Retourne un tableau de composants (définition/constructeur et non les instances) correspondant à la `location` passée en paramètre, ou alors de la route actuelle. Cette fonction est principalement utilisée pendant le rendu côté serveur afin d'effectuer une pré-récupération des données. + +- **router.resolve(location, current?, append?)** + + > 2.1.0+ + + Inverse la résolution d'URL. La `location` doit avoir la même forme qu'utilisée dans ``, retourne un objet avec les propriétés suivantes : + + ``` js + { + location: Location; + route: Route; + href: string; + } + ``` + + +- **router.addRoutes(routes)** + + > 2.2.0+ + + Permet d'ajouter dynamiquement des routes au routeur. L'argument doit être un tableau utilisant le même format de configuration que l'option `routes` du constructeur. + +- **router.onReady(callback, [errorCallback])** + + > 2.2.0+ + + Cette méthode met en file d'attente une fonction de rappel qui sera appelée lorsque le routeur aura complété la navigation initiale, ce qui signifie qu'il a résolu tous les hooks d'entrées asynchrones et composants asynchrones qui sont associés à la route initiale. + + C'est utile pendant un rendu côté serveur pour assurer une sortie consistance sur le serveur et le client. + + Le deuxième argument `errorCallback` est uniquement supporté à partir de la version 2.4. Il sera appelé lorsque la résolution de la route initiale résultera en une erreur (ex : la résolution d'un composant asynchrone qui a échouée). + +- **router.onError(callback)** + + > 2.4.0+ + + Enregistre une fonction de rappel qui sera appelée lorsqu'une erreur sera capturée pendant la navigation vers une route. Notez que pour qu'une erreur soit appelée, cela doit correspondre à l'un des scénarios suivants : + + - L'erreur est lancée de manière synchrone à l'intérieur d'une fonction de sécurisation de route ; + + - L'erreur est capturée et traitée de manière asynchrone en appelant `next(err)` à l'intérieur d'une fonction de sécurisation de route ; + + - Une erreur est survenue pendant la résolution d'un composant asynchrone qui est requis pour faire le rendu d'une route. diff --git a/docs/fr/api/router-link.md b/docs/fr/api/router-link.md new file mode 100644 index 000000000..74fe81872 --- /dev/null +++ b/docs/fr/api/router-link.md @@ -0,0 +1,142 @@ +# `` + +`` est le composant pour activer la navigation utilisateur dans une application où le routeur est activé. La localisation cible est spécifiée grâce à la prop `to`. Il est rendu en tant que balise `` avec le `href` correct par défaut, mais peut être configuré grâce à la prop `tag`. De plus, le lien se vera attribuer une classe CSS active lorsque la route cible est active. + +`` est préféré par rapport au `` en dur dans le code pour les raisons suivantes : + +- Cela fonctionne de la même manière qu'on soit dans le mode historique HTML5 ou le mode hash, donc si vous avez décidé de changer de mode, ou alors que le routeur se replie sur le mode hash pour IE9, rien n'a besoin d'être changé. + +- Dans le mode historique HTML5, `router-link` interceptera l'évènement du clic, comme ça le navigateur n'essaiera pas de rafraîchir la page. + +- En utilisant l'option `base` dans le mode historique HTML5, vous n'avez pas besoin de l'inclure dans les props `to` des URLs. + +### Props + +- **to** + + - type : `string | Location` + + - requis + + Désigne la route cible du lien. Lorsqu'il est cliqué, la valeur de la prop `to` va être passée de manière interne à `router.push`, donc la valeur peut soit être une chaîne de caractères, ou alors un objet décrivant une localisation. + + ``` html + + Accueil + + Accueil + + + Accueil + + + Accueil + + + Accueil + + + Utilisateur + + + S'enregistrer + ``` + + +- **replace** + + - type : `boolean` + + - défaut : `false` + + Configurer la prop `replace` appellera `router.replace()` au lieu de `router.push()` lors du clic, comme ça, la navigation ne laissera pas un enregistrement dans l'historique. + + ``` html + + ``` + + +- **append** + + - type : `boolean` + + - défaut : `false` + + Configurer la propriété `append` suffixe toujours le chemin relatif au chemin courant. Par exemple, assumons que nous naviguons de `/a` à un lien relatif `b`, sans `append` on finira sur `/b`, mais avec `append` on finira sur `/a/b`. + + ``` html + + ``` + + +- **tag** + + - type : `string` + + - défaut : `"a"` + + Parfois, on veut que `` soit rendu avec une balise différente, ex : `
  • `. On peut alors utiliser la prop `tag` pour modifier la balise qui sera rendue, et elle écoutera toujours les évènements de clic pour la navigation + + ``` html + foo + +
  • foo
  • + ``` + + +- **active-class** + + - type : `string` + + - défaut : `"router-link-active"` + + Configure la classe CSS active qui sera appliquée lorsque le lien sera actif. Notez que la valeur par défaut peut aussi être configurée de manière globale via l'option `linkActiveClass` du constructeur du routeur. + +- **exact** + + - type : `boolean` + + - défaut : `false` + + Le comportement par défaut de la correspondance de classe active est une **correspondance inclusive**. Par exemple, `` vera cette classe appliquée tant que le chemin courant commencera par `/a/` ou `/a`. + + Une conséquence de cela est que `` sera actif pour toutes les routes ! Pour forcer le lien dans un « mode correspondance exacte », utilisez la prop `exact`. + + ``` html + + + ``` + + Allez voir les exemples expliquant la classe active pour les liens [ici](https://jsfiddle.net/8xrk1n9f/). + +- **event** + + > 2.1.0+ + + - type : `string | Array` + + - défaut : `'click'` + + Spécifie les évènement(s) que peu(ven)t lancer la navigation de lien. + +- **exact-active-class** + + > 2.5.0+ + + - type : `string` + + - défaut : `"router-link-exact-active"` + + Configure la classe CSS active qui sera appliquée lorsqu'un lien sera actif avec une correspondance exact. Notez que la valeur par défaut peut aussi être configurée de manière globale via l'option `linkExactActiveClass` du constructeur du routeur. + +### Appliquer la classe active à l'élément extérieur + +Parfois, on voudrait que la classe active soit appliquée à un élément extérieur au lieu de l'élément `` lui-même, dans ce cas, vous pouvez faire le rendu de cet élément extérieur en utilisant `` et en entourant le tag `` : + +``` html + + /foo + +``` + +Dans ce cas, `` sera le lien actuel (et récupérera le bon `href`), mais la classe active sera appliquée à l'élément extérieur `
  • `. diff --git a/docs/fr/api/router-view.md b/docs/fr/api/router-view.md new file mode 100644 index 000000000..abce22d1d --- /dev/null +++ b/docs/fr/api/router-view.md @@ -0,0 +1,27 @@ +# `` + +Le composant `` est un composant fonctionnel qui fait le rendu du composant correspondant au chemin donné. Les composants rendus dans `` peuvent aussi contenir leur propre ``, qui fera le rendu des composants pour les chemins imbriqués. + +### Props + +- **name** + + - type : `string` + + - défaut : `"default"` + + Lorsqu'un `` a un nom, il fera le rendu du composant correspondant à ce nom dans les itinéraires de route correspondant à l'option `components`. Voir les [Routes nommées](../essentials/named-views.md) pour un example. + +### Comportement + +Les propriétés sans nom seront passées le long du composant rendu, toutefois la plupart du temps, les données par route seront contenues dans les paramètres de la route. + +Car c'est juste un composant, il fonctionne avec `` et ``. Lorsque vous utilisez les deux ensemble, soyez sûr d'utiliser ` à l'intérieur : + +``` html + + + + + +``` diff --git a/docs/fr/essentials/dynamic-matching.md b/docs/fr/essentials/dynamic-matching.md new file mode 100644 index 000000000..b52be5088 --- /dev/null +++ b/docs/fr/essentials/dynamic-matching.md @@ -0,0 +1,74 @@ +# Dynamic Route Matching (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Very often we will need to map routes with the given pattern to the same component. For example we may have a `User` component which should be rendered for all users but with different user IDs. In `vue-router` we can use a dynamic segment in the path to achieve that: + +``` js +const User = { + template: '
    User
    ' +} + +const router = new VueRouter({ + routes: [ + // dynamic segments start with a colon + { path: '/user/:id', component: User } + ] +}) +``` + +Now URLs like `/user/foo` and `/user/bar` will both map to the same route. + +A dynamic segment is denoted by a colon `:`. When a route is matched, the value of the dynamic segments will be exposed as `this.$route.params` in every component. Therefore, we can render the current user ID by updating `User`'s template to this: + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} +``` + +You can checkout a live example [here](http://jsfiddle.net/yyx990803/4xfa2f19/). + +You can have multiple dynamic segments in the same route, and they will map to corresponding fields on `$route.params`. Examples: + +| pattern | matched path | $route.params | +|---------|------|--------| +| /user/:username | /user/evan | `{ username: 'evan' }` | +| /user/:username/post/:post_id | /user/evan/post/123 | `{ username: 'evan', post_id: 123 }` | + +In addition to `$route.params`, the `$route` object also exposes other useful information such as `$route.query` (if there is a query in the URL), `$route.hash`, etc. You can check out the full details in the [API Reference](../api/route-object.md). + +### Reacting to Params Changes + +One thing to note when using routes with params is that when the user navigates from `/user/foo` to `/user/bar`, **the same component instance will be reused**. Since both routes render the same component, this is more efficient than destroying the old instance and then creating a new one. **However, this also means that the lifecycle hooks of the component will not be called**. + +To react to params changes in the same component, you can simply watch the `$route` object: + +``` js +const User = { + template: '...', + watch: { + '$route' (to, from) { + // react to route changes... + } + } +} +``` + +Or, use the `beforeRouteUpdate` guard introduced in 2.2: + +``` js +const User = { + template: '...', + beforeRouteUpdate (to, from, next) { + // react to route changes... + // don't forget to call next() + } +} +``` + +### Advanced Matching Patterns + +`vue-router` uses [path-to-regexp](https://github.com/pillarjs/path-to-regexp) as its path matching engine, so it supports many advanced matching patterns such as optional dynamic segments, zero or more / one or more requirements, and even custom regex patterns. Check out its [documentation](https://github.com/pillarjs/path-to-regexp#parameters) for these advanced patterns, and [this example](https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js) of using them in `vue-router`. + +### Matching Priority + +Sometimes the same URL may be matched by multiple routes. In such a case the matching priority is determined by the order of route definition: the earlier a route is defined, the higher priority it gets. diff --git a/docs/fr/essentials/getting-started.md b/docs/fr/essentials/getting-started.md new file mode 100644 index 000000000..05e3cf2c7 --- /dev/null +++ b/docs/fr/essentials/getting-started.md @@ -0,0 +1,69 @@ +# Pour commencer + +> Nous utiliserons [ES2015](https://github.com/lukehoban/es6features) dans les exemples de code dans ce guide. + +Créer une application monopage avec Vue.js + vue-router est vraiment simple. Avec Vue.js, nous concevons déjà notre application avec des composants. En ajoutant vue-router dans notre application, tout ce qu'il nous reste à faire est de relier nos composants aux routes, et de laisser vue-router faire le rendu. Voici un exemple de base : + +> Tous les exemples utiliseront la version complète de Vue pour rendre l'analyse de template possible. Plus de détails [ici](https://fr.vuejs.org/guide/installation.html#Runtime-Compiler-vs-Runtime-seul). + +### HTML + +``` html + + + +
    +

    Bonjour l'application !

    +

    + + + + Aller à Foo + Aller à Bar +

    + + + +
    +``` + +### JavaScript + +``` js +// 0. Si vous utilisez un système de module (ex : via vue-cli), il faut importer Vue et VueRouter et ensuite appeler `Vue.use(VueRouter)`. + +// 1. Définissez les composants de route. +// Ces derniers peuvent être importés depuis d'autre fichier +const Foo = { template: '
    foo
    ' } +const Bar = { template: '
    bar
    ' } + +// 2. Définissez des routes. +// Chaque route doit correspondre à un composant. Le « composant » peut +// soit être un véritable composant créé via `Vue.extend()`, ou juste un +// objet d'options. +// Nous parlerons plus tard des routes imbriquées. +const routes = [ + { path: '/foo', component: Foo }, + { path: '/bar', component: Bar } +] + +// 3. Créez l'instance du routeur et passez l'option `routes`. +// Vous pouvez également passer des options supplémentaires, +// mais nous allons faire simple pour l'instant. +const router = new VueRouter({ + routes // raccourci pour `routes: routes` +}) + +// 5. Créez et montez l'instance de Vue. +// Soyez sûr d'injecter le routeur avec l'option `router` pour +// permettre à l'application tout entière d'être à l'écoute du routeur. +const app = new Vue({ + router +}).$mount('#app') + +// L'application est maintenant en marche ! +``` + +Vous pouvez aussi regarder cet [exemple](http://jsfiddle.net/yyx990803/xgrjzsup/). + +Notez qu'un `` obtiendra automatiquement la classe `.router-link-active` lorsque sa route cible correspond à la route actuelle. Vous pouvez en apprendre plus à propos de cela dans sa [documentation d'API](../api/router-link.md). diff --git a/docs/fr/essentials/history-mode.md b/docs/fr/essentials/history-mode.md new file mode 100644 index 000000000..36e1a1b2e --- /dev/null +++ b/docs/fr/essentials/history-mode.md @@ -0,0 +1,60 @@ +# HTML5 History Mode (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +The default mode for `vue-router` is _hash mode_ - it uses the URL hash to simulate a full URL so that the page won't be reloaded when the URL changes. + +To get rid of the hash, we can use the router's **history mode**, which leverages the `history.pushState` API to achieve URL navigation without a page reload: + +``` js +const router = new VueRouter({ + mode: 'history', + routes: [...] +}) +``` + +When using history mode, the URL will look "normal," e.g. `http://oursite.com/user/id`. Beautiful! + +Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access `http://oursite.com/user/id` directly in their browser. Now that's ugly. + +Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same `index.html` page that your app lives in. Beautiful, again! + +## Example Server Configurations + +#### Apache + +```apache + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.html$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.html [L] + +``` + +#### nginx + +```nginx +location / { + try_files $uri $uri/ /index.html; +} +``` + +#### Node.js (Express) + +For Node.js/Express, consider using [connect-history-api-fallback middleware](https://github.com/bripkens/connect-history-api-fallback). + +## Caveat + +There is a caveat to this: Your server will no longer report 404 errors as all not-found paths now serve up your `index.html` file. To get around the issue, you should implement a catch-all route within your Vue app to show a 404 page: + +``` js +const router = new VueRouter({ + mode: 'history', + routes: [ + { path: '*', component: NotFoundComponent } + ] +}) +``` + +Alternatively, if you are using a Node.js server, you can implement the fallback by using the router on the server side to match the incoming URL and respond with 404 if no route is matched. diff --git a/docs/fr/essentials/named-routes.md b/docs/fr/essentials/named-routes.md new file mode 100644 index 000000000..8e03b5dd6 --- /dev/null +++ b/docs/fr/essentials/named-routes.md @@ -0,0 +1,32 @@ +# Named Routes (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Sometimes it is more convenient to identify a route with a name, especially when linking to a route or performing navigations. You can give a route a name in the `routes` options while creating the Router instance: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/user/:userId', + name: 'user', + component: User + } + ] +}) +``` + +To link to a named route, you can pass an object to the `router-link` +component's `to` prop: + +``` html +User +``` + +This is the exact same object used programatically with `router.push()`: + +``` js +router.push({ name: 'user', params: { userId: 123 }}) +``` + +In both cases, the router will navigate to the path `/user/123`. + +Full example [here](https://github.com/vuejs/vue-router/blob/dev/examples/named-routes/app.js). diff --git a/docs/fr/essentials/named-views.md b/docs/fr/essentials/named-views.md new file mode 100644 index 000000000..3a28369d7 --- /dev/null +++ b/docs/fr/essentials/named-views.md @@ -0,0 +1,30 @@ +# Named Views (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Sometimes you need to display multiple views at the same time instead of nesting them, e.g. creating a layout with a `sidebar` view and a `main` view. This is where named views came in handy. Instead of having one single outlet in your view, you can have multiple and give each of them a name. A `router-view` without a name will be given `default` as its name. + +``` html + + + +``` + +A view is rendered by using a component, therefore multiple views require multiple components for the same route. Make sure to use the `components` (with +an s) option: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/', + components: { + default: Foo, + a: Bar, + b: Baz + } + } + ] +}) +``` + +A working demo of this example can be found +[here](https://jsfiddle.net/posva/6du90epg/). diff --git a/docs/fr/essentials/navigation.md b/docs/fr/essentials/navigation.md new file mode 100644 index 000000000..af7cd6477 --- /dev/null +++ b/docs/fr/essentials/navigation.md @@ -0,0 +1,71 @@ +# Programmatic Navigation (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Aside from using `` to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods. + +#### `router.push(location, onComplete?, onAbort?)` + +**Note: Inside of a Vue instance, you have access to the router instance as `$router`. You can therefore call `this.$router.push`.** + +To navigate to a different URL, use `router.push`. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL. + +This is the method called internally when you click a ``, so clicking `` is the equivalent of calling `router.push(...)`. + +| Declarative | Programmatic | +|-------------|--------------| +| `` | `router.push(...)` | + +The argument can be a string path, or a location descriptor object. Examples: + +``` js +// literal string path +router.push('home') + +// object +router.push({ path: 'home' }) + +// named route +router.push({ name: 'user', params: { userId: 123 }}) + +// with query, resulting in /register?plan=private +router.push({ path: 'register', query: { plan: 'private' }}) +``` + +In 2.2.0+, optionally provide `onComplete` and `onAbort` callbacks to `router.push` or `router.replace` as the 2nd and 3rd arguments. These callbacks will be called when the navigation either successfully completed (after all async hooks are resolved), or aborted (navigated to the same route, or to a different route before current navigation has finished), respectively. + +#### `router.replace(location, onComplete?, onAbort?)` + +It acts like `router.push`, the only difference is that it navigates without pushing a new history entry, as its name suggests - it replaces the current entry. + +| Declarative | Programmatic | +|-------------|--------------| +| `` | `router.replace(...)` | + + +#### `router.go(n)` + +This method takes a single integer as parameter that indicates by how many steps to go forwards or go backwards in the history stack, similar to `window.history.go(n)`. + +Examples + +``` js +// go forward by one record, the same as history.forward() +router.go(1) + +// go back by one record, the same as history.back() +router.go(-1) + +// go forward by 3 records +router.go(3) + +// fails silently if there aren't that many records. +router.go(-100) +router.go(100) +``` + +#### History Manipulation + +You may have noticed that `router.push`, `router.replace` and `router.go` are counterparts of [`window.history.pushState`, `window.history.replaceState` and `window.history.go`](https://developer.mozilla.org/en-US/docs/Web/API/History), and they do imitate the `window.history` APIs. + +Therefore, if you are already familiar with [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API), manipulating history will be super easy with vue-router. + +It is worth mentioning that vue-router navigation methods (`push`, `replace`, `go`) work consistently in all router modes (`history`, `hash` and `abstract`). diff --git a/docs/fr/essentials/nested-routes.md b/docs/fr/essentials/nested-routes.md new file mode 100644 index 000000000..fc76d4b3c --- /dev/null +++ b/docs/fr/essentials/nested-routes.md @@ -0,0 +1,100 @@ +# Nested Routes (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Real app UIs are usually composed of components that are nested multiple levels deep. It is also very common that the segments of a URL corresponds to a certain structure of nested components, for example: + +``` +/user/foo/profile /user/foo/posts ++------------------+ +-----------------+ +| User | | User | +| +--------------+ | | +-------------+ | +| | Profile | | +------------> | | Posts | | +| | | | | | | | +| +--------------+ | | +-------------+ | ++------------------+ +-----------------+ +``` + +With `vue-router`, it is very simple to express this relationship using nested route configurations. + +Given the app we created in the last chapter: + +``` html +
    + +
    +``` + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} + +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User } + ] +}) +``` + +The `` here is a top-level outlet. It renders the component matched by a top level route. Similarly, a rendered component can also contain its own, nested ``. For example, if we add one inside the `User` component's template: + +``` js +const User = { + template: ` +
    +

    User {{ $route.params.id }}

    + +
    + ` +} +``` + +To render components into this nested outlet, we need to use the `children` +option in `VueRouter` constructor config: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User, + children: [ + { + // UserProfile will be rendered inside User's + // when /user/:id/profile is matched + path: 'profile', + component: UserProfile + }, + { + // UserPosts will be rendered inside User's + // when /user/:id/posts is matched + path: 'posts', + component: UserPosts + } + ] + } + ] +}) +``` + +**Note that nested paths that start with `/` will be treated as a root path. This allows you to leverage the component nesting without having to use a nested URL.** + +As you can see the `children` option is just another Array of route configuration objects like `routes` itself. Therefore, you can keep nesting views as much as you need. + +At this point, with the above configuration, when you visit `/user/foo`, nothing will be rendered inside `User`'s outlet, because no sub route is matched. Maybe you do want to render something there. In such case you can provide an empty subroute path: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/user/:id', component: User, + children: [ + // UserHome will be rendered inside User's + // when /user/:id is matched + { path: '', component: UserHome }, + + // ...other sub routes + ] + } + ] +}) +``` + +A working demo of this example can be found [here](http://jsfiddle.net/yyx990803/L7hscd8h/). diff --git a/docs/fr/essentials/passing-props.md b/docs/fr/essentials/passing-props.md new file mode 100644 index 000000000..6ed2711c3 --- /dev/null +++ b/docs/fr/essentials/passing-props.md @@ -0,0 +1,79 @@ +# Passing Props to Route Components (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +Using `$route` in your component creates a tight coupling with the route which limits the flexibility of the component as it can only be used on certain urls. + +To decouple this component from the router use props: + +**❌ Coupled to $route** + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User } + ] +}) +``` + +**👍 Decoupled with props** + +``` js +const User = { + props: ['id'], + template: '
    User {{ id }}
    ' +} +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User, props: true } + + // for routes with named views, you have to define the props option for each named view: + { + path: '/user/:id', + components: { default: User, sidebar: Sidebar }, + props: { default: true, sidebar: false } + } + ] +}) +``` + +This allows you to use the component anywhere, which makes the component easier to reuse and test. + +### Boolean mode + +When props is set to true, the route.params will be set as the component props. + +### Object mode + +When props is an object, this will be set as the component props as-is. +Useful for when the props are static. + +``` js +const router = new VueRouter({ + routes: [ + { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } + ] +}) +``` + +### Function mode + +You can create a function that returns props. +This allows you to cast the parameter to another type, combine static values with route-based values, etc. + +``` js +const router = new VueRouter({ + routes: [ + { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) } + ] +}) +``` + +The url: `/search?q=vue` would pass `{query: "vue"}` as props to the SearchUser component. + +Try to keep the props function stateless, as it's only evaluated on route changes. +Use a wrapper component if you need state to define the props, that way vue can react to state changes. + + +For advanced usage, checkout the [example](https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js). diff --git a/docs/fr/essentials/redirect-and-alias.md b/docs/fr/essentials/redirect-and-alias.md new file mode 100644 index 000000000..91033aefb --- /dev/null +++ b/docs/fr/essentials/redirect-and-alias.md @@ -0,0 +1,58 @@ +# Redirect and Alias (En)

    *Cette page est en cours de traduction française. Revenez une autre fois pour lire une traduction achevée ou [participez à la traduction française ici](https://github.com/vuejs-fr/vue-router).* + +### Redirect + +Redirecting is also done in the `routes` configuration. To redirect from `/a` to `/b`: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: '/b' } + ] +}) +``` + +The redirect can also be targeting a named route: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: { name: 'foo' }} + ] +}) +``` + +Or even use a function for dynamic redirecting: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: to => { + // the function receives the target route as the argument + // return redirect path/location here. + }} + ] +}) +``` + +For other advanced usage, checkout the [example](https://github.com/vuejs/vue-router/blob/dev/examples/redirect/app.js). + +### Alias + +A redirect means when the user visits `/a`, and URL will be replaced by `/b`, and then matched as `/b`. But what is an alias? + +**An alias of `/a` as `/b` means when the user visits `/b`, the URL remains `/b`, but it will be matched as if the user is visiting `/a`.** + +The above can be expressed in the route configuration as: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', component: A, alias: '/b' } + ] +}) +``` + +An alias gives you the freedom to map a UI structure to an arbitrary URL, instead of being constrained by the configuration's nesting structure. + +For advanced usage, checkout the [example](https://github.com/vuejs/vue-router/blob/dev/examples/route-alias/app.js). diff --git a/docs/fr/installation.md b/docs/fr/installation.md new file mode 100644 index 000000000..b57f2cea6 --- /dev/null +++ b/docs/fr/installation.md @@ -0,0 +1,44 @@ +# Installation + +### Téléchargement direct / CDN + +[https://unpkg.com/vue-router/dist/vue-router.js](https://unpkg.com/vue-router/dist/vue-router.js) + + +[Unpkg.com](https://unpkg.com) fournit des liens CDN basés sur NPM. Le lien ci-dessus pointera toujours vers la dernière release sur NPM. Vous pouvez aussi utiliser un tag ou une version spécifique via une URL comme `https://unpkg.com/vue-router@2.0.0/dist/vue-router.js`. + + +Incluez `vue-router` après Vue et l'installation sera automatique : + +``` html + + +``` + +### NPM + +``` bash +npm install vue-router +``` + +Lorsqu'il est utilisé avec un système de module, vous devez explicitement installer le router via `Vue.use()` : + +``` js +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) +``` + +Vous n'avez pas besoin de faire cela lors de l'utilisation des balises de script globales (` + diff --git a/examples/route-alias/app.js b/examples/route-alias/app.js index 219212a46..d491fe9b5 100644 --- a/examples/route-alias/app.js +++ b/examples/route-alias/app.js @@ -3,6 +3,7 @@ import VueRouter from 'vue-router' Vue.use(VueRouter) +const Root = { template: '
    root
    ' } const Home = { template: '

    Home

    ' } const Foo = { template: '
    foo
    ' } const Bar = { template: '
    bar
    ' } @@ -15,6 +16,7 @@ const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ + { path: '/root', component: Root, alias: '/root-alias' }, { path: '/home', component: Home, children: [ // absolute alias @@ -42,6 +44,10 @@ new Vue({

    Route Alias

      +
    • + /root-alias (renders /root) +
    • +
    • /foo (renders /home/foo)
    • diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index 617ce6a4f..af555e8b5 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -10,7 +10,8 @@ const Bar = {
      bar
      -

      Anchor

      +

      Anchor

      +

      Anchor2

      ` } @@ -29,6 +30,11 @@ const scrollBehavior = (to, from, savedPosition) => { // scroll to anchor by returning the selector if (to.hash) { position.selector = to.hash + + // specify offset of the element + if (to.hash === '#anchor2') { + position.offset = { y: 100 } + } } // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { @@ -64,6 +70,7 @@ new Vue({
    • /foo
    • /bar
    • /bar#anchor
    • +
    • /bar#anchor2
    diff --git a/flow/declarations.js b/flow/declarations.js index e62aeb9f9..003f5846d 100644 --- a/flow/declarations.js +++ b/flow/declarations.js @@ -30,6 +30,7 @@ declare type AfterNavigationHook = (to: Route, from: Route) => any declare type RouterOptions = { routes?: Array; mode?: string; + fallback?: boolean; base?: string; linkActiveClass?: string; parseQuery?: (query: string) => Object; diff --git a/package.json b/package.json index d3bc9a5e2..a14cbe920 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,9 @@ "devDependencies": { "babel-core": "^6.24.1", "babel-eslint": "^7.2.3", - "babel-loader": "^6.2.4", + "babel-loader": "^7.0.0", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-preset-es2015": "^6.24.1", - "babel-preset-es2015-loose": "^8.0.0", "babel-preset-flow-vue": "^1.0.0", "buble": "^0.15.2", "chromedriver": "^2.21.2", @@ -53,7 +52,7 @@ "eslint-plugin-vue-libs": "^1.2.0", "express": "^4.14.0", "express-urlrewrite": "^1.2.0", - "flow-bin": "^0.45.0", + "flow-bin": "^0.48.0", "gitbook-plugin-edit-link": "^2.0.2", "gitbook-plugin-github": "^3.0.0", "jasmine": "2.6.0", @@ -61,16 +60,16 @@ "nightwatch-helpers": "^1.0.0", "path-to-regexp": "^1.5.3", "phantomjs-prebuilt": "^2.1.14", - "rollup": "^0.41.4", + "rollup": "^0.43.0", "rollup-plugin-buble": "^0.15.0", "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-flow-no-whitespace": "^1.0.0", "rollup-plugin-node-resolve": "^3.0.0", "rollup-plugin-replace": "^1.1.1", - "rollup-watch": "^3.2.2", + "rollup-watch": "^4.0.0", "selenium-server": "^2.53.1", "typescript": "^2.0.3", - "uglify-js": "^2.7.0", + "uglify-js": "^3.0.17", "vue": "^2.3.0", "vue-loader": "^12.0.2", "vue-template-compiler": "^2.3.0", diff --git a/src/components/view.js b/src/components/view.js index 299b451dc..1f7fdb21d 100644 --- a/src/components/view.js +++ b/src/components/view.js @@ -23,7 +23,7 @@ export default { // has been toggled inactive but kept-alive. let depth = 0 let inactive = false - while (parent) { + while (parent && parent._routerRoot !== parent) { if (parent.$vnode && parent.$vnode.data.routerView) { depth++ } diff --git a/src/create-route-map.js b/src/create-route-map.js index 20dc5c26f..6e48e683f 100644 --- a/src/create-route-map.js +++ b/src/create-route-map.js @@ -116,7 +116,14 @@ function addRouteRecord ( path: alias, children: route.children } - addRouteRecord(pathList, pathMap, nameMap, aliasRoute, parent, record.path) + addRouteRecord( + pathList, + pathMap, + nameMap, + aliasRoute, + parent, + record.path || '/' // matchAs + ) }) } diff --git a/src/history/base.js b/src/history/base.js index 7228061d3..59efa7ba8 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -188,11 +188,14 @@ export class History { } function normalizeBase (base: ?string): string { + // respect tag if (!base) { if (inBrowser) { // respect tag - const baseEl = document.querySelector('base') - base = (baseEl && baseEl.getAttribute('href')) || '/' + const baseURI = document.baseURI || '/' + const a = document.createElement('a') + a.href = baseURI + base = a.pathname } else { base = '/' } @@ -406,10 +409,10 @@ function flatten (arr) { // return that Promise. function once (fn) { let called = false - return function () { + return function (...args) { if (called) return called = true - return fn.apply(this, arguments) + return fn.apply(this, args) } } diff --git a/src/history/html5.js b/src/history/html5.js index 127570937..37163703b 100644 --- a/src/history/html5.js +++ b/src/history/html5.js @@ -62,16 +62,6 @@ export class HTML5History extends History { export function getLocation (base: string): string { let path = window.location.pathname - - // Special handling for cases where base contains hash ('#') - if (base && base.indexOf('#') > -1) { - path = window.location.href.replace(window.location.origin, '') - if (path.indexOf(base) === 0) { - // Leave the rest of the url as-is - return (path.slice(base.length) || '/') - } - } - if (base && path.indexOf(base) === 0) { path = path.slice(base.length) } diff --git a/src/index.js b/src/index.js index e50c0ea0a..a1a7b8507 100644 --- a/src/index.js +++ b/src/index.js @@ -42,7 +42,7 @@ export default class VueRouter { this.matcher = createMatcher(options.routes || [], this) let mode = options.mode || 'hash' - this.fallback = mode === 'history' && !supportsPushState + this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false if (this.fallback) { mode = 'hash' } diff --git a/src/install.js b/src/install.js index 1c31bfc75..a78c7ff83 100644 --- a/src/install.js +++ b/src/install.js @@ -9,14 +9,6 @@ export function install (Vue) { _Vue = Vue - Object.defineProperty(Vue.prototype, '$router', { - get () { return this.$root._router } - }) - - Object.defineProperty(Vue.prototype, '$route', { - get () { return this.$root._route } - }) - const isDef = v => v !== undefined const registerInstance = (vm, callVal) => { @@ -29,9 +21,12 @@ export function install (Vue) { Vue.mixin({ beforeCreate () { if (isDef(this.$options.router)) { + this._routerRoot = this this._router = this.$options.router this._router.init(this) Vue.util.defineReactive(this, '_route', this._router.history.current) + } else { + this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } registerInstance(this, this) }, @@ -40,6 +35,14 @@ export function install (Vue) { } }) + Object.defineProperty(Vue.prototype, '$router', { + get () { return this._routerRoot._router } + }) + + Object.defineProperty(Vue.prototype, '$route', { + get () { return this._routerRoot._route } + }) + Vue.component('router-view', View) Vue.component('router-link', Link) diff --git a/src/util/location.js b/src/util/location.js index cc2e83cb0..5e482aebe 100644 --- a/src/util/location.js +++ b/src/util/location.js @@ -26,7 +26,7 @@ export function normalizeLocation ( if (current.name) { next.name = current.name next.params = params - } else if (current.matched) { + } else if (current.matched.length) { const rawPath = current.matched[current.matched.length - 1].path next.path = fillParams(rawPath, params, `path ${current.path}`) } else if (process.env.NODE_ENV !== 'production') { diff --git a/src/util/scroll.js b/src/util/scroll.js index c7a6a7805..18b62ee18 100644 --- a/src/util/scroll.js +++ b/src/util/scroll.js @@ -45,7 +45,9 @@ export function handleScroll ( if (isObject && typeof shouldScroll.selector === 'string') { const el = document.querySelector(shouldScroll.selector) if (el) { - position = getElementPosition(el) + let offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {} + offset = normalizeOffset(offset) + position = getElementPosition(el, offset) } else if (isValidPosition(shouldScroll)) { position = normalizePosition(shouldScroll) } @@ -76,13 +78,13 @@ function getScrollPosition (): ?Object { } } -function getElementPosition (el: Element): Object { +function getElementPosition (el: Element, offset: Object): Object { const docEl: any = document.documentElement const docRect = docEl.getBoundingClientRect() const elRect = el.getBoundingClientRect() return { - x: elRect.left - docRect.left, - y: elRect.top - docRect.top + x: elRect.left - docRect.left - offset.x, + y: elRect.top - docRect.top - offset.y } } @@ -97,6 +99,13 @@ function normalizePosition (obj: Object): Object { } } +function normalizeOffset (obj: Object): Object { + return { + x: isNumber(obj.x) ? obj.x : 0, + y: isNumber(obj.y) ? obj.y : 0 + } +} + function isNumber (v: any): boolean { return typeof v === 'number' } diff --git a/test/e2e/specs/nested-router.js b/test/e2e/specs/nested-router.js new file mode 100644 index 000000000..037ea2211 --- /dev/null +++ b/test/e2e/specs/nested-router.js @@ -0,0 +1,28 @@ +module.exports = { + 'basic': function (browser) { + browser + .url('http://localhost:8080/nested-router/') + .waitForElementVisible('#app', 1000) + .assert.count('li a', 3) + + .click('li:nth-child(1) a') + .assert.urlEquals('http://localhost:8080/nested-router/nested-router') + .assert.containsText('.child', 'Child router path: /') + .assert.count('li a', 5) + + .click('.child li:nth-child(1) a') + .assert.containsText('.child', 'Child router path: /foo') + .assert.containsText('.child .foo', 'foo') + + .click('.child li:nth-child(2) a') + .assert.containsText('.child', 'Child router path: /bar') + .assert.containsText('.child .bar', 'bar') + + .click('li:nth-child(2) a') + .assert.urlEquals('http://localhost:8080/nested-router/foo') + .assert.elementNotPresent('.child') + .assert.containsText('#app', 'foo') + .assert.count('li a', 3) + .end() + } +} diff --git a/test/e2e/specs/route-alias.js b/test/e2e/specs/route-alias.js index f6002e5be..9b3cf7c9e 100644 --- a/test/e2e/specs/route-alias.js +++ b/test/e2e/specs/route-alias.js @@ -3,41 +3,46 @@ module.exports = { browser .url('http://localhost:8080/route-alias/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 6) + .assert.count('li a', 7) // assert correct href with base - .assert.attributeContains('li:nth-child(1) a', 'href', '/route-alias/foo') - .assert.attributeContains('li:nth-child(2) a', 'href', '/route-alias/home/bar-alias') - .assert.attributeContains('li:nth-child(3) a', 'href', '/route-alias/baz') - .assert.attributeContains('li:nth-child(4) a', 'href', '/route-alias/home/baz-alias') - .assert.attributeEquals('li:nth-child(5) a', 'href', 'http://localhost:8080/route-alias/home') - .assert.attributeContains('li:nth-child(6) a', 'href', '/route-alias/home/nested-alias/foo') + .assert.attributeContains('li:nth-child(1) a', 'href', '/root-alias') + .assert.attributeContains('li:nth-child(2) a', 'href', '/route-alias/foo') + .assert.attributeContains('li:nth-child(3) a', 'href', '/route-alias/home/bar-alias') + .assert.attributeContains('li:nth-child(4) a', 'href', '/route-alias/baz') + .assert.attributeContains('li:nth-child(5) a', 'href', '/route-alias/home/baz-alias') + .assert.attributeEquals('li:nth-child(6) a', 'href', 'http://localhost:8080/route-alias/home') + .assert.attributeContains('li:nth-child(7) a', 'href', '/route-alias/home/nested-alias/foo') .click('li:nth-child(1) a') + .assert.urlEquals('http://localhost:8080/route-alias/root-alias') + .assert.containsText('.view', 'root') + + .click('li:nth-child(2) a') .assert.urlEquals('http://localhost:8080/route-alias/foo') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'foo') - .click('li:nth-child(2) a') + .click('li:nth-child(3) a') .assert.urlEquals('http://localhost:8080/route-alias/home/bar-alias') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'bar') - .click('li:nth-child(3) a') + .click('li:nth-child(4) a') .assert.urlEquals('http://localhost:8080/route-alias/baz') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'baz') - .click('li:nth-child(4) a') + .click('li:nth-child(5) a') .assert.urlEquals('http://localhost:8080/route-alias/home/baz-alias') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'baz') - .click('li:nth-child(5) a') + .click('li:nth-child(6) a') .assert.urlEquals('http://localhost:8080/route-alias/home') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'default') - .click('li:nth-child(6) a') + .click('li:nth-child(7) a') .assert.urlEquals('http://localhost:8080/route-alias/home/nested-alias/foo') .assert.containsText('.view', 'Home') .assert.containsText('.view', 'nested foo') diff --git a/test/e2e/specs/scroll-behavior.js b/test/e2e/specs/scroll-behavior.js index 4955ef146..7075f681b 100644 --- a/test/e2e/specs/scroll-behavior.js +++ b/test/e2e/specs/scroll-behavior.js @@ -3,7 +3,7 @@ module.exports = { browser .url('http://localhost:8080/scroll-behavior/') .waitForElementVisible('#app', 1000) - .assert.count('li a', 4) + .assert.count('li a', 5) .assert.containsText('.view', 'home') .execute(function () { @@ -47,6 +47,11 @@ module.exports = { .assert.evaluate(function () { return document.getElementById('anchor').getBoundingClientRect().top < 1 }, null, 'scroll to anchor') + + .click('li:nth-child(5) a') + .assert.evaluate(function () { + return document.getElementById('anchor2').getBoundingClientRect().top < 101 + }, null, 'scroll to anchor with offset') .end() } } diff --git a/yarn.lock b/yarn.lock index a5ea3a754..6b73a12ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,10 +43,6 @@ acorn@^5.0.0, acorn@^5.0.1: version "5.0.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" -adm-zip@^0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1" - agent-base@2: version "2.1.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" @@ -77,12 +73,6 @@ alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" -alter@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd" - dependencies: - stable "~0.1.3" - amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -107,8 +97,8 @@ anymatch@^1.3.0: micromatch "^2.1.5" aproba@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" are-we-there-yet@~1.1.2: version "1.1.4" @@ -185,21 +175,9 @@ assertion-error@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.0.tgz#c7f85438fdd466bc7ca16ab90c81513797a5d23b" -ast-traverse@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6" - -ast-types@0.8.12: - version "0.8.12" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" - -ast-types@0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" - ast-types@0.x.x: - version "0.9.11" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.11.tgz#371177bb59232ff5ceaa1d09ee5cad705b1a5aa9" + version "0.9.12" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.12.tgz#b136300d67026625ae15326982ca9918e5db73c9" async-each@^1.0.0: version "1.0.1" @@ -243,19 +221,19 @@ babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: js-tokens "^3.0.0" babel-core@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: babel-code-frame "^6.22.0" - babel-generator "^6.24.1" + babel-generator "^6.25.0" babel-helpers "^6.24.1" babel-messages "^6.23.0" babel-register "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" + babel-template "^6.25.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" convert-source-map "^1.1.0" debug "^2.1.1" json5 "^0.5.0" @@ -275,13 +253,13 @@ babel-eslint@^7.2.3: babel-types "^6.23.0" babylon "^6.17.0" -babel-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" +babel-generator@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" + babel-types "^6.25.0" detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.2.0" @@ -363,14 +341,13 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-loader@^6.2.4: - version "6.4.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" +babel-loader@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.0.0.tgz#2e43a66bee1fff4470533d0402c8a4532fafbaf7" dependencies: find-cache-dir "^0.1.1" - loader-utils "^0.2.16" + loader-utils "^1.0.2" mkdirp "^0.5.1" - object-assign "^4.0.1" babel-messages@^6.23.0: version "6.23.0" @@ -655,47 +632,51 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" +babel-template@^6.24.1, babel-template@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.23.1, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" +babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: babel-code-frame "^6.22.0" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" + babel-types "^6.25.0" + babylon "^6.17.2" debug "^2.2.0" globals "^9.0.0" invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" +babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: babel-runtime "^6.22.0" esutils "^2.0.2" lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.11.0, babylon@^6.15.0, babylon@^6.17.0, babylon@^6.8.4: - version "6.17.2" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.2.tgz#201d25ef5f892c41bae49488b08db0dd476e9f5c" +babylon@^6.17.0, babylon@^6.17.2, babylon@^6.8.4: + version "6.17.3" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.3.tgz#1327d709950b558f204e5352587fd0290f8d8e48" -balanced-match@^0.4.1, balanced-match@^0.4.2: +balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + base64-js@^1.0.2: version "1.2.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" @@ -735,10 +716,10 @@ boom@2.x.x: hoek "2.x.x" brace-expansion@^1.0.0, brace-expansion@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" dependencies: - balanced-match "^0.4.1" + balanced-match "^1.0.0" concat-map "0.0.1" braces@^1.8.2: @@ -749,10 +730,6 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" -breakable@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1" - brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -837,10 +814,6 @@ buble@^0.15.0, buble@^0.15.2: minimist "^1.2.0" os-homedir "^1.0.1" -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - buffer-xor@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -861,6 +834,10 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -871,7 +848,7 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" -camelcase@^1.0.2, camelcase@^1.2.1: +camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" @@ -889,8 +866,8 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000676" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000676.tgz#82ea578237637c8ff34a28acaade373b624c4ea8" + version "1.0.30000686" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000686.tgz#d55b479ed6e6402c1fd3f1fd8f46e694d86ea464" caseless@~0.11.0: version "0.11.0" @@ -924,7 +901,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chokidar@^1.4.3: +chokidar@^1.4.3, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -940,12 +917,13 @@ chokidar@^1.4.3: fsevents "^1.0.0" chromedriver@^2.21.2: - version "2.29.0" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.29.0.tgz#e3fd8b3c08dce2562b80ef1b0b846597659d0cc3" + version "2.30.1" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.30.1.tgz#18cb6c61ca8eb8b32c25dd62a1308e4598d01c26" dependencies: - adm-zip "^0.4.7" + extract-zip "^1.6.5" kew "^0.7.0" mkdirp "^0.5.1" + request "^2.81.0" rimraf "^2.5.4" cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: @@ -959,8 +937,8 @@ circular-json@^0.3.1: resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" clap@^1.0.9: - version "1.1.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.3.tgz#b3bd36e93dd4cbfb395a3c26896352445265c05b" + version "1.2.0" + resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.0.tgz#59c90fe3e137104746ff19469a27a634ff68c857" dependencies: chalk "^1.1.3" @@ -1003,8 +981,8 @@ co@~3.0.6: resolved "https://registry.yarnpkg.com/co/-/co-3.0.6.tgz#1445f226c5eb956138e68c9ac30167ea7d2e6bda" coa@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.2.tgz#2ba9fec3b4aa43d7a49d7e6c3561e92061b6bcec" + version "1.0.3" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.3.tgz#1b54a5e1dcf77c990455d4deea98c564416dc893" dependencies: q "^1.1.2" @@ -1054,7 +1032,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2.9.0, commander@^2.5.0, commander@^2.9.0: +commander@2.9.0, commander@^2.9.0, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: @@ -1064,20 +1042,6 @@ commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -commoner@~0.10.3: - version "0.10.8" - resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" - dependencies: - commander "^2.5.0" - detective "^4.3.1" - glob "^5.0.15" - graceful-fs "^4.1.2" - iconv-lite "^0.4.5" - mkdirp "^0.5.0" - private "^0.1.6" - q "^1.1.2" - recast "^0.11.17" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1090,7 +1054,7 @@ concat-stream@1.5.0: readable-stream "~2.0.0" typedarray "~0.0.5" -concat-stream@^1.5.2: +concat-stream@1.6.0, concat-stream@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1368,22 +1332,7 @@ defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" -defs@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2" - dependencies: - alter "~0.2.0" - ast-traverse "~0.1.1" - breakable "~1.0.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - simple-fmt "~0.1.0" - simple-is "~0.2.0" - stringmap "~0.2.2" - stringset "~0.2.1" - tryor "~0.1.2" - yargs "~3.27.0" - -degenerator@~1.0.0: +degenerator@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" dependencies: @@ -1432,13 +1381,6 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" -detective@^4.3.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" - dependencies: - acorn "^4.0.3" - defined "^1.0.0" - diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" @@ -1514,8 +1456,8 @@ ejs@0.8.3: resolved "https://registry.yarnpkg.com/ejs/-/ejs-0.8.3.tgz#db8aac47ff80a7df82b4c82c126fe8970870626f" electron-to-chromium@^1.2.7: - version "1.3.13" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.13.tgz#1b3a5eace6e087bb5e257a100b0cbfe81b2891fc" + version "1.3.14" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz#64af0f9efd3c3c6acd57d71f83b49ca7ee9c4b43" elliptic@^6.0.0: version "6.4.0" @@ -1563,8 +1505,8 @@ error-ex@^1.2.0: is-arrayish "^0.2.1" es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.22" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.22.tgz#1876c51f990769c112c781ea3ebe89f84fd39071" + version "0.10.23" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" dependencies: es6-iterator "2" es6-symbol "~3.1" @@ -1715,11 +1657,7 @@ espree@^3.4.0: acorn "^5.0.1" acorn-jsx "^3.0.0" -esprima-fb@~15001.1001.0-dev-harmony-fb: - version "15001.1001.0-dev-harmony-fb" - resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659" - -esprima@3.x.x, esprima@^3.1.1, esprima@~3.1.0: +esprima@3.x.x, esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -1855,6 +1793,15 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" +extract-zip@^1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.5.tgz#99a06735b6ea20ea9b705d779acffcc87cff0440" + dependencies: + concat-stream "1.6.0" + debug "2.2.0" + mkdirp "0.5.0" + yauzl "2.4.1" + extract-zip@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.5.0.tgz#92ccf6d81ef70a9fa4c1747114ccef6d8688a6c4" @@ -1954,9 +1901,9 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flow-bin@^0.45.0: - version "0.45.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.45.0.tgz#009dd0f577a3f665c74ca8be827ae8c2dd8fd6b5" +flow-bin@^0.48.0: + version "0.48.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.48.0.tgz#72d075143524358db8901525e3c784dc13a7c7ee" flow-remove-types-no-whitespace@^1.0.3: version "1.0.5" @@ -2008,11 +1955,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" fsevents@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + version "1.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" dependencies: nan "^2.3.0" - node-pre-gyp "^0.6.29" + node-pre-gyp "^0.6.36" fstream-ignore@^1.0.5: version "1.0.5" @@ -2069,9 +2016,9 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" -get-uri@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-1.1.0.tgz#7375d04daf7fcb584b3632679cbdf339b51bb149" +get-uri@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.0.tgz#713e47cbcbaeab38f88af1cdfc85fa7f09b00738" dependencies: data-uri-to-buffer "0" debug "2" @@ -2118,16 +2065,6 @@ glob@7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -2140,8 +2077,8 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: path-is-absolute "^1.0.0" globals@^9.0.0, globals@^9.14.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" globby@^5.0.0: version "5.0.0" @@ -2317,9 +2254,9 @@ https-proxy-agent@1: debug "2" extend "3" -iconv-lite@^0.4.5: - version "0.4.17" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.17.tgz#4fdaa3b38acbc2c031b045d0edcdfe1ecab18c8d" +iconv-lite@0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" icss-replace-symbols@^1.1.0: version "1.1.0" @@ -2402,6 +2339,10 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +ip@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.0.1.tgz#c7e356cdea225ae71b36d70f2e71a92ba4e42590" + ip@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -2491,12 +2432,18 @@ is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: jsonpointer "^4.0.0" xtend "^4.0.0" -is-number@^2.0.2, is-number@^2.1.0: +is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" dependencies: kind-of "^3.0.2" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -2576,8 +2523,8 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" jasmine-core@~2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.2.tgz#74ea1f7cf428691af201107d631234027a09daab" + version "2.6.3" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.6.3.tgz#45072950e4a42b1e322fe55c001100a465d77815" jasmine@2.6.0: version "2.6.0" @@ -2587,12 +2534,6 @@ jasmine@2.6.0: glob "^7.0.6" jasmine-core "~2.6.0" -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - js-base64@^2.1.9: version "2.1.9" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" @@ -2695,6 +2636,12 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.1.5" +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -2899,11 +2846,11 @@ lru-cache@^3.2.0: pseudomap "^1.0.1" lru-cache@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" dependencies: - pseudomap "^1.0.1" - yallist "^2.0.0" + pseudomap "^1.0.2" + yallist "^2.1.2" lru-cache@~2.6.5: version "2.6.5" @@ -3011,18 +2958,18 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - minimatch@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -3102,8 +3049,8 @@ nightwatch-helpers@^1.0.0: resolved "https://registry.yarnpkg.com/nightwatch-helpers/-/nightwatch-helpers-1.2.0.tgz#cdefeb7635074a141825a7b6d1b955b6d7810a0f" nightwatch@^0.9.5: - version "0.9.15" - resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.15.tgz#71a62aa16368e9da09fae800ccb9fb34d036164d" + version "0.9.16" + resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.16.tgz#c4ac3ec711b0ff047c3dca9c6557365ee236519f" dependencies: chai-nightwatch "~0.1.x" ejs "0.8.3" @@ -3144,7 +3091,7 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" -node-pre-gyp@^0.6.29: +node-pre-gyp@^0.6.36: version "0.6.36" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" dependencies: @@ -3291,27 +3238,27 @@ osenv@^0.1.4: os-tmpdir "^1.0.0" pac-proxy-agent@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.0.0.tgz#dcd5b746581367430a236e88eacfd4e5b8d068a5" + version "1.1.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d" dependencies: agent-base "2" debug "2" extend "3" - get-uri "1" + get-uri "2" http-proxy-agent "1" https-proxy-agent "1" - pac-resolver "~1.2.1" + pac-resolver "~2.0.0" + raw-body "2" socks-proxy-agent "2" - stream-to-buffer "0.1.0" -pac-resolver@~1.2.1: - version "1.2.6" - resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-1.2.6.tgz#ed03af0c5b5933505bdd3f07f75175466d5e7cfb" +pac-resolver@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-2.0.0.tgz#99b88d2f193fbdeefc1c9a529c1f3260ab5277cd" dependencies: co "~3.0.6" - degenerator "~1.0.0" + degenerator "~1.0.2" + ip "1.0.1" netmask "~1.0.4" - regenerator "~0.8.13" thunkify "~2.1.1" pako@~0.2.0: @@ -3705,8 +3652,8 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 supports-color "^3.2.3" postcss@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.2.tgz#5c4fea589f0ac3b00caa75b1cbc3a284195b7e5d" dependencies: chalk "^1.1.3" source-map "^0.5.6" @@ -3724,7 +3671,7 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -private@^0.1.6, private@~0.1.5: +private@^0.1.6: version "0.1.7" resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" @@ -3768,7 +3715,7 @@ prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" -pseudomap@^1.0.1: +pseudomap@^1.0.1, pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -3818,20 +3765,30 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" + is-number "^3.0.0" + kind-of "^4.0.0" randombytes@^2.0.0, randombytes@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" + version "2.0.5" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + dependencies: + safe-buffer "^5.1.0" range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" +raw-body@2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.15" + unpipe "1.0.0" + rc@^1.1.7: version "1.2.1" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" @@ -3866,14 +3823,14 @@ readable-stream@1.1.x: string_decoder "~0.10.x" readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6: - version "2.2.9" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" + version "2.2.11" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" dependencies: - buffer-shims "~1.0.0" core-util-is "~1.0.0" inherits "~2.0.1" isarray "~1.0.0" process-nextick-args "~1.0.6" + safe-buffer "~5.0.1" string_decoder "~1.0.0" util-deprecate "~1.0.1" @@ -3905,24 +3862,6 @@ readline2@^1.0.1: is-fullwidth-code-point "^1.0.0" mute-stream "0.0.5" -recast@0.10.33: - version "0.10.33" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" - dependencies: - ast-types "0.8.12" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - -recast@^0.11.17: - version "0.11.23" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" - dependencies: - ast-types "0.9.6" - esprima "~3.1.0" - private "~0.1.5" - source-map "~0.5.0" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -3951,10 +3890,6 @@ regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" -regenerator-runtime@~0.9.5: - version "0.9.6" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" - regenerator-transform@0.9.11: version "0.9.11" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" @@ -3963,18 +3898,6 @@ regenerator-transform@0.9.11: babel-types "^6.19.0" private "^0.1.6" -regenerator@~0.8.13: - version "0.8.46" - resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.46.tgz#154c327686361ed52cad69b2545efc53a3d07696" - dependencies: - commoner "~0.10.3" - defs "~1.1.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - recast "0.10.33" - regenerator-runtime "~0.9.5" - through "~2.3.8" - regex-cache@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" @@ -4009,8 +3932,8 @@ regjsparser@^0.1.4: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + version "1.0.2" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" repeat-element@^1.1.2: version "1.1.2" @@ -4202,15 +4125,16 @@ rollup-pluginutils@^2.0.1: estree-walker "^0.3.0" micromatch "^2.3.11" -rollup-watch@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/rollup-watch/-/rollup-watch-3.2.2.tgz#5e574232e9ef36da9177f46946d8080cb267354b" +rollup-watch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/rollup-watch/-/rollup-watch-4.0.0.tgz#309051b9403b9e5445c5746c9eba9a466951d39e" dependencies: + chokidar "^1.7.0" require-relative "0.8.7" -rollup@^0.41.4: - version "0.41.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" +rollup@^0.43.0: + version "0.43.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.43.0.tgz#b36bdb75fa5e0823b6de8aee18ff7b5655520543" dependencies: source-map-support "^0.4.0" @@ -4224,7 +4148,11 @@ rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.0.tgz#fe4c8460397f9eaaaa58e73be46273408a45e223" + +safe-buffer@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" @@ -4304,8 +4232,8 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" shelljs@^0.7.5: - version "0.7.7" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -4319,14 +4247,6 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -simple-fmt@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b" - -simple-is@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0" - slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -4346,8 +4266,8 @@ sntp@1.x.x: hoek "2.x.x" socks-proxy-agent@2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.0.tgz#ddfb01b5dbea5fc879490ca38a25fe87d3d15912" + version "2.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3" dependencies: agent-base "2" extend "3" @@ -4380,7 +4300,7 @@ source-map-support@^0.4.0, source-map-support@^0.4.2: dependencies: source-map "^0.5.6" -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -4409,8 +4329,8 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -4419,14 +4339,9 @@ sshpk@^1.7.0: optionalDependencies: bcrypt-pbkdf "^1.0.0" ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" jsbn "~0.1.0" tweetnacl "~0.14.0" -stable@~0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" - "statuses@>= 1.3.1 < 2", statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" @@ -4439,8 +4354,8 @@ stream-browserify@^2.0.1: readable-stream "^2.0.2" stream-http@^2.3.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.1.tgz#546a51741ad5a6b07e9e31b0b10441a917df528a" + version "2.7.2" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" @@ -4448,16 +4363,6 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-to-buffer@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" - dependencies: - stream-to "~0.2.0" - -stream-to@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" - strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -4482,18 +4387,10 @@ string_decoder@^0.10.25, string_decoder@~0.10.x: resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" string_decoder@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.1.tgz#62e200f039955a6810d8df0a33ffc0f013662d98" + version "1.0.2" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" dependencies: - safe-buffer "^5.0.1" - -stringmap@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1" - -stringset@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5" + safe-buffer "~5.0.1" stringstream@~0.0.4: version "0.0.5" @@ -4591,7 +4488,7 @@ throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" -through@^2.3.6, through@~2.3.8: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -4627,10 +4524,6 @@ tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" -tryor@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b" - tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -4671,18 +4564,25 @@ typedarray@^0.0.6, typedarray@~0.0.5: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" typescript@^2.0.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.4.tgz#3d38321828231e434f287514959c37a82b629f42" + version "2.4.0" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.0.tgz#aef5a8d404beba36ad339abf079ddddfffba86dd" -uglify-js@^2.7.0, uglify-js@^2.8.27: - version "2.8.27" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.27.tgz#47787f912b0f242e5b984343be8e35e95f694c9c" +uglify-js@^2.8.27: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: source-map "~0.5.1" yargs "~3.10.0" optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^3.0.17: + version "3.0.17" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.17.tgz#d228cd55c2df9b3d2f53f147568cb4cc4a72cc06" + dependencies: + commander "~2.9.0" + source-map "~0.5.1" + uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" @@ -4705,7 +4605,7 @@ uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" -unpipe@~1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -4737,8 +4637,8 @@ utils-merge@1.0.0: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" uuid@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" validate-npm-package-license@^3.0.1: version "3.0.1" @@ -4801,8 +4701,8 @@ vue-style-loader@^3.0.0: loader-utils "^1.0.2" vue-template-compiler@^2.3.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.3.3.tgz#b5bab9ec57309c906b82a78c81a02179dbc2f470" + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.3.4.tgz#5a88ac2c5e4d5d6218e6aa80e7e221fb7e67894c" dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -4812,8 +4712,8 @@ vue-template-es2015-compiler@^1.2.2: resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.5.2.tgz#a0a6c50c941d2a4abda963f2f42c337ac450ee95" vue@^2.3.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.3.tgz#d1eaa8fde5240735a4563e74f2c7fead9cbb064c" + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.4.tgz#5ec3b87a191da8090bbef56b7cfabd4158038171" watchpack@^1.3.1: version "1.3.1" @@ -4889,10 +4789,6 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -window-size@^0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" - wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -4930,11 +4826,11 @@ xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" -y18n@^3.2.0, y18n@^3.2.1: +y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" -yallist@^2.0.0: +yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -4971,17 +4867,6 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" -yargs@~3.27.0: - version "3.27.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40" - dependencies: - camelcase "^1.2.1" - cliui "^2.1.0" - decamelize "^1.0.0" - os-locale "^1.4.0" - window-size "^0.1.2" - y18n "^3.2.0" - yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"