visionmedia / page.js Goto Github PK
View Code? Open in Web Editor NEWMicro client-side router inspired by the Express router
Home Page: http://visionmedia.github.com/page.js
Micro client-side router inspired by the Express router
Home Page: http://visionmedia.github.com/page.js
maybe..:
page('/user/:name/:op', 'tobi', 'edit')
The following code demonstrates the problem
page.base('/example')
page.page('/', function() { console.log("example root"); })
page('/example') // works OK
page('/example?foo=bar') // does not find the route
I traced it back to this line in Context
initialization
this.path = path.replace(base, '') || '/';
Without a query string, path
is correctly initialized to "/", but if the base is followed by a query string, the result of replace is not empty.
I managed to work around this in my application by changing pathname
initialization in Route.prototype.match
to
pathname = ~qsIndex ? path.slice(0, qsIndex) || '/' : path
but I'm not sure if this is the correct way to fix this.
when present
TJ I am using page click option to handle click event
my links have data attributes
<a href="/some-path" data-transition="slide-left">my link</a>
So would it make sense to add a reference to the dom element in the state object
so I can use data attributes? Or Should I write my own custom onClick method for that ?
Please add a licence to the project.
Yeah, it is really behaving weird. Every first time I visit my page after restarting server, it returns 404 when loading page.js via RequireJS. But after that, when I hit reload, all goes smooth. No further 404s.
Only for the first time. Has anybody a clue what this could be?
I am definitely missing something...
Your documentation does not seem to make these things clear. While I can take my novice self and attempt to ferret out this information from the code, it would be nice to have orienting words or two occur in the ReadMe.
In many apps including mine usernames are used to secure "vanity URLs" e.g http://facebook.com/{user_username}, http://facebook.com/{page_username}. A username can be bound to different types of objects (e.g. users, pages) and the type of object associated with a particular username determines what sub-resource are supported (e.g. {user_username}/messages, {page_username}/fans.)
It looks like I can handle this in page.js by defining a * wildcard route and working with the full path string passed to context.params[0]. It all gets pretty low-level from there. I'm wondering if it might be possible to provide better support for this use-case in the library. I don't have any implementation ideas yet myself, but wanted to go ahead and report the use case.
Thanks for a nice library.
npm install does not install the examples and devDependencies. According to the docs;
$ npm install
$ node examples
This does not work( Ubuntu 13.04, latest Node.js )
Hi,
I'd run into an annoying issue using last versions of Page.js and I think I've found the source of it.
I randomly run this line of code into chrome 26 console:
> window.addEventListener !== document.addEventListener
> true
I'm not sure why, but this makes my application break by leading Page.js into not listening to click
events on the document:
page.start = function(options){
// ...
if (false !== options.click) window.addEventListener('click', onclick, false);
// ...
};
I'd like to know if this was made intentional in order to know if I should find a workaround or wait for a fix.
Thanks!
onclick in index.js should detect target attribute
if target attribute == '_blank' return
Hi,
Your library looks fantastic and that too at 1200bytes its almost unbelievable!
I was trying to get it to use but could not do so.
Your nodejs based examples work fine. But I could not understand why my examples could not work.
I was simply trying to host a couple of pages say main.html and child.html. And I wanted to click on a link in the page say #/child
which should map to a function which will get child.html via ajax (say via $.ajax). Could not make this simple usecase to work (without node.js)
Could you help me via some code snippets?
Is there any reason why #anchors
are ignored in the start()
method (see)?
I can work around that "problem" by calling start()
with { dispatch: false }
and dispatch it myself. But it looks like a bug to me. I'd say hash
is a legitimate part of the URL, wouldn't you?
Had a peak around the code as well as #30 , but couldn't figure it out. Here's an example:
boot.js:
page('/note/:slug', function() {
note.select();
});
// ...
page();
noteview.js:
NoteView.prototype.select = function(note) {
// ...
page('/note/' + note.slug); // INFINITE LOOP
};
I feel like before page redirects it should check if the pathname
is the same. It looks like it does that in the unhandled
function, but that function isn't getting called from page('/note/' + note.slug)
.
Hi -- is it possible to bind to the exit from a page or route ?
In a classic HTML page there's no need since one renders everything at once, but in a single page app, one often needs to unbind or remove certain elements.
so that self-contained modules may invoke it without undefined behaviour
I experimented with adding page.js to the little test app here: https://github.com/kdonald/graceworks. It works fine when served to a HTML 5 browser such as Chrome (using something like serve running on localhost:3000, for example). However, the app doesn't work when wrapped in a Apache Cordova (phonegap) project and targeted at the iPhone simulator or an iPhone device. Specifically, it looks like the default ("/") route is never firing so no content ever gets rendered for the user to interact with.
I've found very little docs on the web about IOS's/Phonegap's support for the HTML5 history API. Previously, I was using path.js for navigation with #/fragments and it was working for the most part; however, window.history.back() did not work consistently in a native Phonegap environment and that's why I wanted to try out page.js (specifically, users were unable to navigate back to the #/home or root page of the app ("default route"), while window.history.back did work as expected when navigating from a child page to a parent that was not the root).
What are your thoughts for supporting multi-page hybrid (phonegap) apps? jQuery Mobile appears to maintain its own url history stack and does not rely on HTML 5 by default. I'm intentionally not using JQuery Mobile's navigation support in my app though as I wanted more control (I've built my own page navigator/router abstraction on-top of page js that routes URLs to MVC objects that handle page interactions... would love to see page.js just working when running on a native HTML container like in a Phonegap environment).
I'm getting this exception in IE9 on this line: https://github.com/visionmedia/page.js/blob/master/index.js#L228
Wouldn't this lib provide some fallbacks to pushState APIs for older browsers? Or is this library not for production use? I'm only using page.js as a router to handle client-side code execution; I'm not using it as a push state lib.
Suppose we have several urls defined for news articles:
page("/news", listNews);
page("/news/:item", showNewsItem);
page("/news/:item/edit", editNewsItem);
If the user then clicks on a link to "/news/draft"
, a url for which no handler has been defined, page.js will trigger the unhandled handler. This will change window.location and cause a page refresh at which point the link will still be unhandled causing a refresh loop.
Solution:
unhandled
should compare ctx.canonicalPath
to window.location
before triggering a page change.
Caveat:
I'm not sure about the exact logic required here considering potential url fragments and query parameters.
After unzipping the ZIP file: https://github.com/visionmedia/page.js/archive/master.zip
and running the three comands
$ npm install
$ node examples
$ open http://localhost:3000
(actually it was port 4000!)
I get the following error:
TypeError: Arguments to path.join must be strings
at path.js:360:15
at Array.filter (native)
at exports.join (path.js:358:36)
at exports.send (/...../page.js/node_modules/express/node_modules/connect/lib/middleware/static.js:141:20)
at ServerResponse.res.sendfile (/...../page.js/node_modules/express/lib/response.js:243:3)
at /...../page.js/examples/index.js:72:7
at callbacks (/...../page.js/node_modules/express/lib/router/index.js:171:11)
at param (/...../page.js/node_modules/express/lib/router/index.js:145:11)
at param (/...../page.js/node_modules/express/lib/router/index.js:142:11)
at pass (/...../page.js/node_modules/express/lib/router/index.js:152:5)
Seems to still be an issue with the examples
I have defined paths as follows:
page.base('/');
page('/managetask/:number', handle1);
page('*', handle2);
page.start();
I make a call of /managetask/0002
what happens is that handle1 never gets called at all and handle2 receives the full path of "/managetask/0002" and there are no paramaters present in ctx.params.
I have a custom element which contains links inside its shadow dom. Page.js should intercept clicks to these links and prevent the default action. The problem is e.target
is the custom element, as the browser doesn't give the webpage insight into the element's DOM tree.
e.srcElement
on the other hand is the anchor element. But that might be a quirk/bug in the custom element polyfill (I'm using the one from polymer).
haven't had much time for client-side work, any takers? all I ask is:
add an option to page() / page.start()
Any chance to add AMD support? Would be great, thx!
for old shitty browsers. I dont want any of that in this lib itself but we should facilitate it
Hello. I am looking to use page.js for a project. I have to have this project as a downloadable file that runs locally from the html file on the user's desktop.
Although this is a client side routing solution all of the examples get caught in an infinite loop when I run them. Is it because page.js relies on pushstate? If so, what are my options for client side routing without a server.... angular.js?
I'm finding that page.js stops working if jquery and bootstrap are included in the page. I've tried this with the basic example. It seems to be bootstrap rather than jquery that's causing the problem though it didn't appear there was a namespace conflict.
I'd love to have a way to navigate URL strings like this to keep things DRYer.
page('/user/:id', { id: 24 });
Bonus: a fantasticly-free unintended upside to this is you kinda get named routes support:
urls = {
listUsers: '/user',
showUser: '/user/:id'
}
page(urls.showUser, app.showUser); // create a route
page(urls.showUser, { id: 24 }); // navigate to a route
as plugin
this is subjective, but IMHO if you have a basepath of "/admin" and you do page('/settings')
it should be /admin/settings
Is there to way to prevent the handling of routing for specific anchors?
It would be interesting to have a page.param(paramName, handler);
that would behave identically to express' app.param
.
Would reduce redundancy in the route handler definitions in some cases.
What do you think?
implementation-wise it'll be a little bit hacky but referencing page.path
etc and changing the (ctx, next)
signature to (next)
might be worth it
There are two common use cases for this:
In both cases, a common solution is to intercept requests to change the page, and warn the user that the requested page 1) requires different credentials, or 2) moving to the request page will cause loosing all unsaved data. Depending on the user feedback, one can either continue with the request action and change to the new URL anyway, or abort the navigation.
I know crossroads.js provides callbacks for this, and durandal's router requires usage of objects that support lifecycle (i.e. assumes callbacks have properties for canActivate, canDeactivate, etc.. which are called when jumping from one page to another). I believe sammy.js has similar functionality through its before and after callbacks, and so does Flatiron's director.
What is the right way to deal with this in page.js?
PS: I am looking for a small routing solution that does what is supposed to do an stays out of the way, it seems the only real contenders are page.js and crossroads.js, but crossroads.js hasn't seen a commit in a year, so I was hoping to use page.js. Suggestions for other alternatives are welcome.
If i have the following code--
page.base('/Actions');
page("#:id", Controller.init);
page("*", Controller.init);
page();
And i load the page like /Actions#/12 it doesnt load 12 into the params-- am i doing someting wrong? I've tried a few different setups to no avail.
I would like to be able to pass the params in via the url.
Thanks!
This is a meta bug for tests that need to be created at sometime.
how to redirect with page.js ?
like i've access a url
this url create a uuid and insert a model to mongodb and return that _id
then redirect to
http://localhost:3000/id here ?
At this moment, the onClick
handler in page.js will call page.show
even if event.preventDefault()
was called on the link click event beforeHand.
Browsers normally don't push new history states when event.preventDefault()
is called on a link click events. I think that page.js should behave the same and wrap transparently the browser history system in that regard.
This is most useful for web-apps and single page apps when some links are just actions that don't really point to new pages. At this moment, a link such as <a href='#'>toggle visibility</a>
that is cancelled will still make the router go through its motions and call the route code.
I have a problem of having to rewrite parts of my apps every time you release something new. Please stop.. thanks
Why doesn't this use component/path-to-regexp?
Currently, I want to redirect to a default url by
page('/default', function(context, next){
// show but quickly back to /
})
page('/', function(context, next){
// redirect to '/default'
page('/default');
})
page();
I think the problem come from
page.replace = function(path, state, init, dispatch){
var ctx = new Context(path, state);
ctx.init = init;
if (null == dispatch) dispatch = true;
if (dispatch) page.dispatch(ctx);
ctx.save();
return ctx;
};
which do ctx.save(); before page.dispatch
Shall we save ctx first?
Multiple Page
objects could be used with basepaths and operate independently, but the existing API will be left as-is, this would make testing a bit easier since the routes would reset etc...
Unsure of the error, or solution.
Error - Uncaught DataCloneError: An object could not be cloned. main.js:10026
main.js:10026
Context.prototype.pushState = function(){
history.pushState(this.state, this.title, this.canonicalPath);
};
main.js
indexView = function() {
console.log('indexView rendered');
return document.getElementById('index').style.display = 'block';
};
aboutView = function() {
return console.log('aboutView rendered');
};
projectsView = function() {
return console.log('projectsView rendered');
};
notfoundView = function() {
return console.log('404 page rendered');
};
page.base('/');
page('/', index);
page('/about', aboutView);
page('/projects', projectsView);
page('*', notfoundView);
page();
Hi.
I have two routes, '/' and '/:title'. In the '/' route I want to redirect to '/Home' but this instantly gets reset back to '/'.
page('/', function() {
console.log('index!');
page('/Home');
});
page('/:title', function() {
console.log('titled page!');
});
page();
When I run this, I think because of https://github.com/visionmedia/page.js/blob/master/index.js#L145, my output is 'index!' and 'titled page!' but I see '/Home' in the URL for a split second and then the URL is '/' again.
Putting the page('/Home'); in a setTimeout 0 'fixes' it, but i'd rather not. I'm making a small wiki app, so I want to redirect to a page named Home instantly. How do I achieve this behaviour?
I'm just curious.
I think that we need to plan our actions. May be we start from minor release 1.4.0
?
I suggest to include in the package this things:
@nwmcsween what do you think about it? Any additions?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.