Socket
Socket
Sign inDemoInstall

director

Package Overview
Dependencies
Maintainers
2
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

director - npm Package Compare versions

Comparing version 1.0.11 to 1.1.0

test/browser/backend/backend.js

75

lib/director/browser.js

@@ -33,2 +33,3 @@

hash: dloc.hash,
history: false,

@@ -45,3 +46,3 @@ check: function () {

if (this.mode === 'modern') {
window.onhashchange();
this.history === true ? window.onpopstate() : window.onhashchange();
}

@@ -53,4 +54,5 @@ else {

init: function (fn) {
init: function (fn, history) {
var self = this;
this.history = history;

@@ -61,5 +63,5 @@ if (!window.Router.listeners) {

function onchange() {
function onchange(onChangeEvent) {
for (var i = 0, l = window.Router.listeners.length; i < l; i++) {
window.Router.listeners[i]();
window.Router.listeners[i](onChangeEvent);
}

@@ -71,3 +73,16 @@ }

|| document.documentMode > 7)) {
window.onhashchange = onchange;
// At least for now HTML5 history is available for 'modern' browsers only
if (this.history === true) {
// There is an old bug in Chrome that causes onpopstate to fire even
// upon initial page load. Since the handler is run manually in init(),
// this would cause Chrome to run it twise. Currently the only
// workaround seems to be to set the handler after the initial page load
// http://code.google.com/p/chromium/issues/detail?id=63040
setTimeout(function() {
window.onpopstate = onchange;
}, 500);
}
else {
window.onhashchange = onchange;
}
this.mode = 'modern';

@@ -124,3 +139,10 @@ }

dloc.hash = (s[0] === '/') ? s : '/' + s;
if (this.history === true) {
window.history.pushState({}, document.title, s);
// Fire an onpopstate event manually since pushing does not obviously
// trigger the pop event.
this.fire();
} else {
dloc.hash = (s[0] === '/') ? s : '/' + s;
}
return this;

@@ -161,2 +183,4 @@ },

this.historySupport = (window.history != null ? window.history.pushState : null) != null
this.configure();

@@ -168,16 +192,29 @@ this.mount(routes || {});

var self = this;
this.handler = function() {
var hash = dloc.hash.replace(/^#/, '');
self.dispatch('on', hash);
this.handler = function(onChangeEvent) {
var url = self.history === true ? self.getPath() : onChangeEvent.newURL.replace(/.*#/, '');
self.dispatch('on', url);
};
if (dloc.hash === '' && r) {
dloc.hash = r;
listener.init(this.handler, this.history);
if (this.history === false) {
if (dloc.hash === '' && r) {
dloc.hash = r;
} else if (dloc.hash.length > 0) {
self.dispatch('on', dloc.hash.replace(/^#/, ''));
}
}
else {
routeTo = dloc.hash === '' && r ? r : dloc.hash.length > 0 ? dloc.hash.replace(/^#/, '') : null;
if (routeTo) {
window.history.replaceState({}, document.title, routeTo);
}
if (dloc.hash.length > 0) {
this.handler();
// Router has been initialized, but due to the chrome bug it will not
// yet actually route HTML5 history state changes. Thus, decide if should route.
if (routeTo || this.run_in_init === true) {
this.handler();
}
}
listener.init(this.handler);
return this;

@@ -187,3 +224,3 @@ };

Router.prototype.explode = function () {
var v = dloc.hash;
var v = this.history === true ? this.getPath() : dloc.hash;
if (v[1] === '/') { v=v.slice(1) }

@@ -254,1 +291,9 @@ return v.slice(1, v.length).split("/");

};
Router.prototype.getPath = function () {
var path = window.location.pathname;
if (path.substr(0, 1) !== '/') {
path = '/' + path;
}
return path;
};

4

lib/director/router.js

@@ -147,2 +147,6 @@ /*

// Client only, but browser.js does not include a super implementation
this.history = (options.html5history && this.historySupport) || false;
this.run_in_init = (this.history === true && options.run_handler_in_init !== false);
//

@@ -149,0 +153,0 @@ // TODO: Global once

@@ -5,3 +5,3 @@ {

"author": "Nodejitsu Inc. <info@nodejitsu.com>",
"version": "1.0.11",
"version": "1.1.0",
"maintainers": [

@@ -8,0 +8,0 @@ "hij1nx <paolo@nodejitsu.com>",

@@ -29,3 +29,3 @@ <img src="https://github.com/flatiron/director/raw/master/img/director.png" />

Client-side routing (aka hash-routing) allows you to specify some information about the state of the application using the URL. So that when the user visits a specific URL, the application can be transformed accordingly.
Client-side routing (aka hash-routing) allows you to specify some information about the state of the application using the URL. So that when the user visits a specific URL, the application can be transformed accordingly.

@@ -137,3 +137,3 @@ <img src="https://github.com/flatiron/director/raw/master/img/hashRoute.png" />

Director handles routing for HTTP requests similar to `journey` or `express`:
Director handles routing for HTTP requests similar to `journey` or `express`:

@@ -166,3 +166,3 @@ ```js

// setup a server and when there is a request, dispatch the
// route that was requestd in the request object.
// route that was requested in the request object.
//

@@ -198,9 +198,9 @@ var server = http.createServer(function (req, res) {

var director = require('director');
var router = new director.cli.Router();
router.on('create', function () {
console.log('create something');
});
router.on(/destroy/, function () {

@@ -237,2 +237,3 @@ console.log('destroy something');

* [Resources](#resources)
* [History API](#history-api)
* [Instance Methods](#instance-methods)

@@ -258,3 +259,3 @@ * [Attach Properties to `this`](#attach-to-this)

//
var routes = {
var routes = {
//

@@ -273,3 +274,3 @@ // a route which assigns the function `bark`.

//
var router = Router(routes);
var router = Router(routes);
```

@@ -286,3 +287,3 @@

var router = new Router().init();
router.on('/some/resource', function () {

@@ -299,6 +300,6 @@ //

var router = new director.http.Router();
router.get(/\/some\/resource/, function () {
//
// Do something on an GET to `/some/resource`
// Do something on an GET to `/some/resource`
//

@@ -315,3 +316,3 @@ });

var router = new director.http.Router();
//

@@ -325,3 +326,3 @@ // Create routes inside the `/users` scope.

//
this.post(function (id) {

@@ -332,3 +333,3 @@ //

});
this.get(function (id) {

@@ -339,3 +340,3 @@ //

});
this.get(/\/friends/, function (id) {

@@ -373,3 +374,3 @@ //

* **recurse:** Controls [route recursion](#route-recursion). Use `forward`, `backward`, or `false`. Default is `false` Client-side, and `backward` Server-side.
* **recurse:** Controls [route recursion](#route-recursion). Use `forward`, `backward`, or `false`. Default is `false` Client-side, and `backward` Server-side.
* **strict:** If set to `false`, then trailing slashes (or other delimiters) are allowed in routes. Default is `true`.

@@ -386,2 +387,4 @@ * **async:** Controls [async routing](#async-routing). Use `true` or `false`. Default is `false`.

* **after:** A function (or list of functions) to call when a given route is no longer the active route.
* **html5history:** If set to `true` and client supports `pushState()`, then uses HTML5 History API instead of hash fragments. See [History API](#history-api) for more information.
* **run_handler_in_init:** If `html5history` is enabled, the route handler by default is executed upon `Router.init()` since with real URIs the router can not know if it should call a route handler or not. Setting this to `false` disables the route handler initial execution.

@@ -410,3 +413,3 @@ <a name="url-matching"></a>

``` js
var router = Router({
var router = Router({
//

@@ -442,11 +445,11 @@ // given the route '/hello/world'.

When you are using the same route fragments it is more descriptive to define these fragments by name and then use them in your [Routing Table](#routing-table) or [Adhoc Routes](#adhoc-routing). Consider a simple example where a `userId` is used repeatedly.
When you are using the same route fragments it is more descriptive to define these fragments by name and then use them in your [Routing Table](#routing-table) or [Adhoc Routes](#adhoc-routing). Consider a simple example where a `userId` is used repeatedly.
``` js
//
// Create a router. This could also be director.cli.Router() or
// Create a router. This could also be director.cli.Router() or
// director.http.Router().
//
var router = new director.Router();
//

@@ -456,3 +459,3 @@ // A route could be defined using the `userId` explicitly.

router.on(/([\w-_]+)/, function (userId) { });
//

@@ -462,3 +465,3 @@ // Define a shorthand for this fragment called `userId`.

router.param('userId', /([\\w\\-]+)/);
//

@@ -504,3 +507,3 @@ // Now multiple routes can be defined with the same

//
on: growl
on: growl
},

@@ -547,3 +550,3 @@ //

//
on: function() { return false; }
on: function() { return false; }
},

@@ -553,6 +556,6 @@ //

//
on: bark
on: bark
}
};
//

@@ -567,3 +570,3 @@ // This feature works in reverse with recursion set to true.

Before diving into how Director exposes async routing, you should understand [Route Recursion](#route-recursion). At it's core route recursion is about evaluating a series of functions gathered when traversing the [Routing Table](#routing-table).
Before diving into how Director exposes async routing, you should understand [Route Recursion](#route-recursion). At it's core route recursion is about evaluating a series of functions gathered when traversing the [Routing Table](#routing-table).

@@ -581,3 +584,3 @@ Normally this series of functions is evaluated synchronously. In async routing, these functions are evaluated asynchronously. Async routing can be extremely useful both on the client-side and the server-side:

var router = new director.Router();
router.on('/:foo/:bar/:bazz', function (foo, bar, bazz) {

@@ -594,3 +597,3 @@ //

var router = new director.http.Router().configure({ async: true });
router.on('/:foo/:bar/:bazz', function (foo, bar, bazz, next) {

@@ -627,2 +630,11 @@ //

<a name="history-api"></a>
## History API
**Available on the Client-side only.** Director supports using HTML5 History API instead of hash fragments for navigation. To use the API, pass `{html5history: true}` to `configure()`. Use of the API is enabled only if the client supports `pushState()`.
Using the API gives you cleaner URIs but they come with a cost. Unlike with hash fragments your route URIs must exist. When the client enters a page, say http://foo.com/bar/baz, the web server must respond with something meaningful. Usually this means that your web server checks the URI points to something that, in a sense, exists, and then serves the client the JavaScript application.
If you're after a single-page application you can not use plain old `<a href="/bar/baz">` tags for navigation anymore. When such link is clicked, web browsers try to ask for the resource from server which is not of course desired for a single-page application. Instead you need to use e.g. click handlers and call the `setRoute()` method yourself.
<a name="attach-to-this"></a>

@@ -665,6 +677,6 @@ ## Attach Properties To `this`

* Buffer the request body and parse it according to the `Content-Type` header (usually `application/json` or `application/x-www-form-urlencoded`).
* Buffer the request body and parse it according to the `Content-Type` header (usually `application/json` or `application/x-www-form-urlencoded`).
* Stream the request body by manually calling `.pipe` or listening to the `data` and `end` events.
By default `director.http.Router()` will attempt to parse either the `.chunks` or `.body` properties set on the request parameter passed to `router.dispatch(request, response, callback)`. The router instance will also wait for the `end` event before firing any routes.
By default `director.http.Router()` will attempt to parse either the `.chunks` or `.body` properties set on the request parameter passed to `router.dispatch(request, response, callback)`. The router instance will also wait for the `end` event before firing any routes.

@@ -675,3 +687,3 @@ **Default Behavior**

var director = require('director');
var router = new director.http.Router();

@@ -682,3 +694,3 @@

// This will not work, because all of the data
// events and the end event have already fired.
// events and the end event have already fired.
//

@@ -696,3 +708,3 @@ this.req.on('data', function (chunk) {

director = require('director');
var router = new director.http.Router();

@@ -705,3 +717,3 @@

});
router.dispatch(req, res, function (err) {

@@ -712,7 +724,7 @@ if (err) {

}
console.log('Served ' + req.url);
});
});
router.post('/', function () {

@@ -724,3 +736,3 @@ this.res.writeHead(200, { 'Content-Type': 'application/json' })

**Streaming Support**
**Streaming Support**

@@ -736,4 +748,4 @@ If you wish to get access to the request stream before the `end` event is fired, you can pass the `{ stream: true }` options to the route.

//
// This will work because the route handler is invoked
// immediately without waiting for the `end` event.
// This will work because the route handler is invoked
// immediately without waiting for the `end` event.
//

@@ -765,3 +777,3 @@ this.req.on('data', function (chunk) {

Adds the `route` handler for the specified `method` and `path` within the [Routing Table](#routing-table).
Adds the `route` handler for the specified `method` and `path` within the [Routing Table](#routing-table).

@@ -795,3 +807,3 @@ ### path(path, routesFn)

### getRoute([index])
* `index` {Number}: The hash value is divided by forward slashes, each section then has an index, if this is provided, only that section of the route will be returned.
* `index` {Number}: The hash value is divided by forward slashes, each section then has an index, if this is provided, only that section of the route will be returned.

@@ -801,6 +813,6 @@ Returns the entire route or just a section of it.

### setRoute(route)
* `route` {String}: Supply a route value, such as `home/stats`.
* `route` {String}: Supply a route value, such as `home/stats`.
Set the current route.
### setRoute(start, length)

@@ -807,0 +819,0 @@ * `start` {Number} - The position at which to start removing items.

@@ -5,2 +5,9 @@ module("Director.js", {

shared = {};
// Init needed keys earlier because of in HTML5 mode the route handler
// is executed upon Router.init() and due to that setting shared.fired
// in the param test of createTest is too late
if (HTML5TEST) {
shared.fired = [];
shared.fired_count = 0;
}
},

@@ -15,3 +22,3 @@ teardown: function() {

function createTest(name, config, use, test) {
function createTest(name, config, use, test, initialRoute) {
if (typeof use === 'function') {

@@ -21,2 +28,17 @@ test = use;

}
if (HTML5TEST) {
if (use === undefined) {
use = {};
}
if (use.run_handler_in_init === undefined) {
use.run_handler_in_init = false;
}
use.html5history = true;
}
// Because of the use of setTimeout when defining onpopstate
var innerTimeout = HTML5TEST === true ? 500 : 0;
asyncTest(name, function() {

@@ -31,19 +53,25 @@ setTimeout(function() {

router.init();
router.init(initialRoute);
test.call(context = {
router: router,
navigate: function(url, callback) {
window.location.hash = url;
setTimeout(function() {
callback.call(context);
}, 14);
},
finish: function() {
router.destroy();
start();
}
});
setTimeout(function() {
test.call(context = {
router: router,
navigate: function(url, callback) {
if (HTML5TEST) {
router.setRoute(url);
} else {
window.location.hash = url;
}
setTimeout(function() {
callback.call(context);
}, 14);
},
finish: function() {
router.destroy();
start();
}
})
}, innerTimeout);
}, 14);
});
};

@@ -648,1 +648,48 @@

createTest('initializing with a default route should only result in one route handling', {
'/': {
on: function root() {
if (!shared.init){
shared.init = 0;
}
shared.init++;
}
},
'/test': {
on: function root() {
if (!shared.test){
shared.test = 0;
}
shared.test++;
}
}
}, function() {
this.navigate('/test', function root() {
equal(shared.init, 1);
equal(shared.test, 1);
this.finish();
});
},
null,
'/');
createTest('changing the hash twice should call each route once', {
'/hash1': {
on: function root() {
shared.fired.push('hash1');
}
},
'/hash2': {
on: function root() {
shared.fired.push('hash2');
}
}
}, function() {
shared.fired = [];
this.navigate('/hash1', function(){});
this.navigate('/hash2', function(){
deepEqual(shared.fired, ['hash1', 'hash2']);
this.finish();
});
}
);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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