Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

flux-router-component

Package Overview
Dependencies
Maintainers
5
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flux-router-component - npm Package Compare versions

Comparing version 0.5.0 to 0.5.1

12

lib/History.js

@@ -50,2 +50,10 @@ /**

/**
* @method getState
* @return {Object|null} The state object in history
*/
getState: function () {
return (this.win.history && this.win.history.state) || null;
},
/**
* Gets the path string, including the pathname and search query (if it exists).

@@ -71,3 +79,3 @@ * @method getUrl

win.history.pushState(state, title, url);
} else {
} else if (url) {
win.location.href = url;

@@ -88,3 +96,3 @@ }

win.history.replaceState(state, title, url);
} else {
} else if (url) {
win.location.replace(url);

@@ -91,0 +99,0 @@ }

@@ -5,2 +5,3 @@ /**

*/
/*global window */
'use strict';

@@ -11,2 +12,3 @@

var History = require('./History');
var EVT_CLICK = 'click';
var EVT_PAGELOAD = 'pageload';

@@ -24,2 +26,9 @@ var EVT_POPSTATE = 'popstate';

function saveScrollPosition(e, history) {
var historyState = (history.getState && history.getState()) || {};
historyState.scroll = {x: window.scrollX, y: window.scrollY};
debug('remember scroll position', historyState.scroll);
history.replaceState(historyState);
}
RouterMixin = {

@@ -33,2 +42,3 @@ componentDidMount: function() {

self._history = ('function' === typeof self.props.historyCreator) ? self.props.historyCreator() : new History();
self._enableScroll = (self.props.enableScroll !== false);

@@ -61,3 +71,3 @@ if (self.props.checkRouteOnPageLoad) {

if (url !== self.state.route.url) {
context.executeAction(navigateAction, {type: EVT_POPSTATE, url: url, params: e.state});
context.executeAction(navigateAction, {type: EVT_POPSTATE, url: url, params: (e.state && e.state.params)});
}

@@ -67,2 +77,13 @@ }

self._history.on(self._historyListener);
if (self._enableScroll) {
var scrollTimer;
self._scrollListener = function (e) {
if (scrollTimer) {
window.clearTimeout(scrollTimer);
}
scrollTimer = window.setTimeout(saveScrollPosition.bind(self, e, self._history), 150);
};
window.addEventListener('scroll', self._scrollListener);
}
},

@@ -72,2 +93,8 @@ componentWillUnmount: function() {

this._historyListener = null;
if (this._enableScroll) {
window.removeEventListener('scroll', this._scrollListener);
this._scrollListener = null;
}
this._history = null;

@@ -84,4 +111,22 @@ },

var nav = newState.route.navigate;
if (nav.type !== EVT_POPSTATE && nav.type !== EVT_PAGELOAD) {
this._history.pushState(nav.params || null, null, newState.route.url);
var historyState;
switch (nav.type) {
case EVT_CLICK:
historyState = {params: (nav.params || {})};
if (this._enableScroll) {
window.scrollTo(0, 0);
historyState.scroll = {x: 0, y: 0};
debug('on click navigation, reset scroll position to (0, 0)');
}
this._history.pushState(historyState, null, newState.route.url);
break;
case EVT_POPSTATE:
if (this._enableScroll) {
historyState = (this._history.getState && this._history.getState()) || {};
var scroll = (historyState && historyState.scroll) || {};
debug('on popstate navigation, restore scroll position to ', scroll);
window.scrollTo(scroll.x || 0, scroll.y || 0);
}
break;
}

@@ -88,0 +133,0 @@ }

2

package.json
{
"name": "flux-router-component",
"version": "0.5.0",
"version": "0.5.1",
"description": "Router-related React component and mixin for applications with Flux architecture",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -15,3 +15,13 @@ # flux-router-component

### Example Usage
Example of using `NavLink` with `href` property defined:
Here are two examples of generating `NavLink` using `href` property, and using `routeName` property. Using `href` property is better than using `routeName`, because:
* Using `href` makes your code more readible, as it shows exactly how the `href` is generated.
* Using `routeName` assumes `this.prop.context` has a `makePath()` function, which will be used to generate the `href` from the `routeName` and `navParams` props.
* Using `routeName` could be more limited, especially when it comes to query string and hash fragment, if the `makePath()` function does not support query string and hash fragment.
#### Example of Using `href` Property (Recommended)
If the url is static, or you can generate the url outside of `Navlink`, you can simply pass the url to `NavLink` as a prop. Here is an example:
```js

@@ -24,3 +34,3 @@ var NavLink = require('flux-router-component').NavLink;

links,
context = this.props.context; // this should have a router instance and an executeAction function
context = this.props.context; // context should provide executeAction()
pages = [

@@ -57,4 +67,59 @@ {

We also have another more sophisticated example application, [routing](https://github.com/yahoo/flux-examples/tree/master/routing), that uses `NavLink` with `routeName` property defined.
#### Example of Using `routeName` Property
Before you continue with this example, you should know that you can always generate the url yourself outside of `NavLink` and pass it to `NavLink` as `href` prop just like the example above. Your code will be more straight-forward that way, and you will have more control over how to generate `href` (see more explanations in [the Example Usage section](#example-usage)).
If you choose not to generate `href` yourself and the `context` prop you pass to `NavLink` provides `makePath(routeName, routeParams)`, you can also use the `routeName` prop (and the optional `navParams` prop). If the `href` prop is not present, `NavLink` will use `this.props.context.makePath(this.props.routeName, this.props.navParams)` to generate the `href` for the anchor element. The `navParams` prop is useful for dynamic routes. It should be a hash object containing the route parameters and their values.
An example of such context is the `ComponentContext` provided by [fluxible-plugin-routr](https://github.com/yahoo/fluxible-plugin-routr/blob/master/lib/routr-plugin.js#L36), which is a plugin for [fluxible-app](https://github.com/yahoo/fluxible-app). We have a more sophisticated example application, [routing](https://github.com/yahoo/flux-examples/tree/master/routing), showing how everything works together.
Here is a quick example code showcasing how to use `routeName` prop along with `navParams` prop:
```js
// assume routes are defined somewhere like this:
// var routes = {
// home: {
// path: '/',
// page: 'home'
// },
// article: {
// path: '/article/:id',
// page: 'article'
// }
// };
var pages = [
{
routeName: 'home',
text: 'Home'
},
{
routeName: 'article',
routeParams: {
id: 'a'
}
text: 'Article A'
}
];
var Nav = React.createClass({
render: function () {
var context = this.props.context; // context should provide executeAction() and makePath()
var links = pages.map(function (page) {
return (
<li className="navItem">
<NavLink routeName={page.routeName} navParams={page.routeParams} context={context}>
{page.text}
</NavLink>
</li>
);
});
return (
<ul className="nav">
{links}
</ul>
);
}
});
```
## RouterMixin

@@ -65,4 +130,4 @@ `RouterMixin` is a React mixin to be used by application's top level React component to:

* execute navigate action and then dispatch `CHANGE_ROUTE_START` and `CHANGE_ROUTE_SUCCESS` or `CHANGE_ROUTE_FAILURE` events via flux dispatcher on window `popstate` events
* [manage scroll position](#scroll-position-management) when navigating between pages
### Example Usage

@@ -128,4 +193,8 @@ ```js

return new HistoryWithHash({
useHashRoute: true, // optional
hashRouteTransformer: { // optional transformer for custom hash route syntax
// optional. Defaults to true if browser does not support pushState; false otherwise.
useHashRoute: true,
// optional. Defaults to '/'. Used when url has no hash fragment
defaultHashRoute: '/default',
// optional. Transformer for custom hash route syntax
hashRouteTransformer: {
transform: function (original) {

@@ -157,2 +226,3 @@ // transform url hash fragment from '/new/path' to 'new-path'

* getUrl()
* getState()
* pushState(state, title, url)

@@ -181,3 +251,27 @@ * replaceState(state, title, url)

## Scroll Position Management
`RouterMixin` has a built-in mechanism for managing scroll position upon page navigation, for modern browsers that support native history state:
* reset scroll position to `(0, 0)` when user clicks on a link and navigates to a new page, and
* restore scroll position to last visited state when user clicks forward and back buttons to navigate between pages.
If you want to disable this behavior, you can set `enableScroll` prop to `false` for `RouterMixin`. This is an example of how it can be done:
```js
var RouterMixin = require('flux-router-component').RouterMixin;
var Application = React.createClass({
mixins: [RouterMixin],
...
});
var appComponent = Application({
...
enableScroll: false
});
```
## Polyfills

@@ -184,0 +278,0 @@ `addEventListener` and `removeEventListener` polyfills are provided by:

@@ -16,2 +16,4 @@ /**

* is not available in the window object's history object; false otherwise.
* @param {String} [options.defaultHashRoute='/'] Only used when options.useHashRoute is enabled and
the location url does not have any hash fragment.
* @param {Object} [options.hashRouteTransformer] A custom transformer can be provided

@@ -40,2 +42,3 @@ * to transform the hash to the desired syntax.

}
this._defaultHashRoute = options.defaultHashRoute || '/';

@@ -71,7 +74,7 @@ // allow custom syntax for hash

* Returns the hash fragment in current window location.
* @method _getHash
* @method _getHashRoute
* @return {String} The hash fragment string (without the # prefix).
* @private
*/
_getHash: function () {
_getHashRoute: function () {
var hash = this.win.location.hash,

@@ -81,3 +84,3 @@ transformer = this._hashRouteTransformer;

// remove the '#' prefix
hash = hash.substring(1) || '';
hash = hash.substring(1) || this._defaultHashRoute;

@@ -88,2 +91,10 @@ return (transformer && transformer.reverse) ? transformer.reverse(hash) : hash;

/**
* @method getState
* @return {Object|null} The state object in history
*/
getState: function () {
return (this.win.history && this.win.history.state) || null;
},
/**
* Gets the path string (or hash fragment if the history object is

@@ -100,3 +111,3 @@ * configured to use hash for routing),

if (this._useHashRoute) {
return this._getHash() || path;
return this._getHashRoute();
}

@@ -126,4 +137,5 @@ return path;

if (this._hasPushState) {
history.pushState(state, title, location.pathname + location.search + hash);
} else {
url = hash ? location.pathname + location.search + hash : null;
history.pushState(state, title, url);
} else if (hash) {
location.hash = hash;

@@ -134,3 +146,3 @@ }

history.pushState(state, title, url);
} else {
} else if (url) {
location.href = url;

@@ -160,6 +172,7 @@ }

}
url = location.pathname + location.search + hash;
if (this._hasPushState) {
url = hash ? (location.pathname + location.search + hash) : null;
history.replaceState(state, title, url);
} else {
} else if (url) {
url = location.pathname + location.search + hash;
location.replace(url);

@@ -170,3 +183,3 @@ }

history.replaceState(state, title, url);
} else {
} else if (url) {
location.replace(url);

@@ -173,0 +186,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc