GithubHelp home page GithubHelp logo

visionmedia / page.js Goto Github PK

View Code? Open in Web Editor NEW
7.7K 7.7K 687.0 817 KB

Micro client-side router inspired by the Express router

Home Page: http://visionmedia.github.com/page.js

JavaScript 97.91% HTML 1.73% Makefile 0.36%

page.js's People

Contributors

5im-0n avatar a avatar andyburke avatar boreplusplus avatar chevett avatar christianalfoni avatar devote avatar fisch42 avatar flootr avatar gianlucaguarini avatar hheiskanen avatar hugomrdias avatar jonathanong avatar kaisermann avatar kethinov avatar matthewp avatar matthewpblog avatar mclotworthy avatar nwmcsween avatar pahans avatar paulmaly avatar paulocoghi avatar rstacruz avatar samccone avatar seminice avatar tj avatar victorb avatar wesleydrobinson avatar woodlandhunter avatar zoomzhao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

page.js's Issues

Non-node ajax example

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?

pluggable history junk

for old shitty browsers. I dont want any of that in this lib itself but we should facilitate it

maintainer

haven't had much time for client-side work, any takers? all I ask is:

  • keep page.js small and focused (potentially leverage components to shrink more)
  • maintain similar code style
  • follow semver ;D

Metabug for tests

This is a meta bug for tests that need to be created at sometime.

Examples

Seems to still be an issue with the examples

Load params on page enter?

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!

bind to page exit ?

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.

Have "onClick" verify if "event.defaultPrevented" is set.

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.

Use page.js offline without a server

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?

TypeError: Arguments to path.join must be strings

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)

Anchors are ignored in start()

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?

We need a plan

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?

remove ctx

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

Doc seems to be missing a few words.

I am definitely missing something...

  1. Is this a node application or a client side browser app?
  2. Is this a meteor client side app or meteor server side app?
  3. What is it that is being loaded, JSON, javascript, html?

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.

window.addEventListener !== document.addEventListener // true

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!

Support for mapping "vanity" URL paths

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.

refactor for multiple Page instances

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...

Parameter parsing appears not to work chrome 32.0

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.

click and dom context

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 ?

pushState Error

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();

Navigate pages by options

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

Bootstrap conflict?

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.

page.js support for hybrid apps (e.g. phonegap native apps)

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).

sprintf-ish

maybe..:

page('/user/:name/:op', 'tobi', 'edit')

"param" handler ร  la express

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?

Support redirection?

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?

Click event interception doesn't work with custom elements / shadow DOM

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).

Weird behavior when used with RequireJS

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?

Using a query string in combination with base fails to dispatch to root

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.

Redirect from '/' to '/Home' gets reset on Context#save()

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?

AMD support

Any chance to add AMD support? Would be great, thx!

Redirect/refresh loop for unhandled urls

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.

Stop Making Great Software

I have a problem of having to rewrite parts of my apps every time you release something new. Please stop.. thanks

easy to get caught in an infinite loop

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).

Is it possible to intercept change of url requests

There are two common use cases for this:

  1. Some routes require login (or require certain user role)
  2. There might be unsaved date on the current page.

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.