GithubHelp home page GithubHelp logo

riot / route Goto Github PK

View Code? Open in Web Editor NEW
211.0 9.0 40.0 2.05 MB

Simple isomorphic router

License: MIT License

JavaScript 85.60% Riot 14.40%
route router riotjs components minimal simple isomorphic

route's Issues

Roadmap

Now it's time to think about the next :-)

  • server-side support #18
  • replaceState #47
  • prepare to make it optional for Riot.js 2.4
  • rewrite into ES6

Other candidates:

  • next()? #25
  • route deconstructor #36
  • decode URI #29

Note: #36 would be nice, but I'd like to keep it small, too. #29 breaks specs.

Remove /

Hi,
i have a route.base('/translations)
and when i click on link with href="/translations/login" my url becoming /translationslogin.
How i can create translations/login?

Isomorphic examples

I see that the docs mention riot-route is capable of isomorphic operation.

Is it possible to run two routers at once?

Dev branch tests failing

I wanted to make a new riot-route release but it seems that the tests keep failing in the dev branch. @cognitom any clue about what's the issue? The master branch does not have any problem

should decode URI

The router should call decodeURIComponent on parameters before providing them to the callbacks, so that the callbacks receive the intended values rather than the URI-encoded values.

Template literals break IE

Do you want to request a feature or report a bug?
This is a bug

What is the current behavior?
The page does not open in ie11. I get an error: Invalid character

What is the expected behavior?
No error

IE is breaking when it tries to evaluate the template literal here:
https://github.com/riot/route/blob/master/dist/cjs.route.js#L59

Per the MDN it doesn't look like those are supported in IE at all.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Steps to reproduce:
Try to use the router in an application loaded into IE11

Default base path

I've found this doesn't work out of the box without setting riot.route.base('/')
Since this now uses history.pushState shouldn't the default base be '/' instead of '#'?

riot-route-tag: tag based router for Riot.js

I'm thinking about tag-based router as a new feature. I'm now working on feature/route-tag branch and I'd like to share my current idea here. Nothing was decided yet. Any feedback is welcome!

Todos

  • for the first release
    • implement riot-route-tag (draft)
    • write tests
    • 2 packages in 1 repo 2 builds in 1 repo
    • adjust api specs (gathering ideas)
    • write documents
  • for the second release
    • fix some logic on riot-route
    • maybe a little fix on riot, too

Specs (proposal)

<app>
  <router>
    <route path="fruit/apple"><p>Apple</p></route>
    <route path="fruit/banana"><p>Banana</p></route>
    <route path="fruit/*"><inner-tag /></route>
  </router>
</app>

<inner-tag>
  <p>{ name } is not found</p>
  <script>
    this.on('route', name => this.name = name)
  </script>
</inner-tag>
  • <router>
    • it can contains multiple routes
    • it has base attribute (optional) maybe later
    • equivalent to const r = route.create() so it creates subrouter
  • <route>
    • it has path attribute
    • <route path="fruit/apple"> is equivalent to r('fruit/apple', () => { ... })
    • when the route has selected, it triggers route event on its children and passes some arguments to them

Two builds:

We could import them like this:

import route from 'riot-route'
// or
import route from 'riot-route/lib/tag' // note that it's not same as cjs below
const route = require('riot-route')
// or
const route = require('riot-route/tag')

Q&A

  • Q: What is packages dir?
    • A: to provide 2 packages in one repo
  • Q: Why not making a separated repo?
    • A: riot-route-tag is tightly coupled with riot-route
  • Q: Why two npm packages?
    • A: because of ES6 and CJS modules handling. We have no general way to provide submodules in both at this point: require('riot-route/tag') is not compatible with import 'riot-route/tag'.
  • Q: Why now?
    • A: Riot v3 has got much better if implementation πŸ˜„

Related informations:

Routing bug after `riot.route('some/path')`

I discovered strange behavior that I believe can't be right. I'm seeing this on

  • windows 7
  • IE 11.0.9600.18449
  • riotjs 2.6.2
  • riot-route 2.5.0

Have a look at the plunkr here and click the links one after the other:
https://plnkr.co/edit/bGUkr1sueLDtcFrxd9sj

The problem is that the last click actually does change the url but no events are triggered (hashchange, popstate), also the riot handler is not run as in the steps before.

Also, I noticed that step 3 doesn't seem to add state. Perhaps this is why IE thinks that the current fragment is already "#a/b" so there is no event to trigger?

Any ideas?

Roadmap and todos

See also the discussion on riot/riot#1063.

v2.0.0

v2.3.0

  • support HTML5 history API
  • base url option: router.base('/foo')
  • click event override: to avoid page reloading
  • url match: router('/bar/*', function(id) { ... }) (allow only wild card)
  • 2-4x smaller than page.js
  • documentation
  • 100% coverage - now 99% Thanks! @GianlucaGuarini

Any feedback is appreciated πŸ˜„

Riot routing and links within a page

If the route base is # how do I link to a specific spot within a page? Normally you'd do something like some-page/#target but that would trigger the Router. Any help here would be appreciated! :)

Introduces WebdriverIO

For testing this library, I'd like to introduce WebdriverIO. We're using Karma now, but even if it's a simple unit test, it can't handle page transition. It makes the tests difficult, especially for the libraries like riot-route.

I've done the most part of the research. But some points are still open. Your feedback is welcome.

  • WebdriveIO research (ver4 is awsome, actually)
  • makes Java free environment locally
  • creates phantomjs lanucher for WebdriveIO
  • how to measure the coverage
  • how to live together with Karma tests

Saucelabs widget doesn't support multiple test in one repo, IFIK...

Routing priority broken

Previously, when a match is found, no other routes are triggered. Now multiple routes are firing.

I noticed this updating from riot 2.3.18 -> 2.5.0.
It appears to be caused by changes in riot observable, because it works correctly if I roll that back. Nothing in this route repo has changed in a while.


Example:

route('/post/*.amp.html', function() { /* */ })
route('/post/*', function() { /* */ })

Given the url: /post/title-of-my-post
The expected result is for the second route to trigger.
The actual result is both get triggered, and also appears to be a race condition of which one gets triggered first.

Add standalone route release

Currently the dist folder contains route.js that is meant to be used in nodejs but actually there is no way to use a standalone release that could be directly included in a browser environment without riot or an additional build step. Probably the package.json should point to the lib/index.js file and the dist/route.js should contain a build release including riot-observable as well.

Routing without hash !

Hi guys (@cognitom @GianlucaGuarini ), is it possible to have routes without hash ?

I tried this :

riot.route.base('/')

It's working for /first but it can't get the second one in /first/second and I get this error :

capture d ecran 2016-02-10 a 00 47 04

I get the same error with just adding trailing slash like that /first/

It's the way used here https://github.com/riot/examples/blob/gh-pages/router-complex/index.html#L28 but it seems not working.

As I said on Gitter :

In fact the riot.route.base can’t be the same as parser

#/first/second is working
/first#second is working
/first/second is not working

Obviously, this bug appears only when we enter the adress directly in the adress bar. I get almost the same bug with every version of superstatic.

Add Middleware to Routes

It would be interesting to have the option of middlewares on routes, executing before they get properly handled. E.g.

riot.route('/products/new', function() {
    // show view
}, ['UserController.isLogged']);

The idea is that middleware would always return a boolean. true firing the route callback, false preventing it from being handled.

There is also the .next() approach, discussed on Issue #25. Maybe we could define which approach would be the more interesting.

Mapping routes to tags

Does anyone have a best practice or nice way to show/hide tags on a per-route basis? Ideally it would be mounting/unmounting the tag from the DOM entirely over simply showing/hiding, but I'm interested to see what others are doing.

regression Bug of the router API?

riot/riot#1385

    /**
     * Disable the default riot route parser
     */
    riot.route.parser(function(path) {
    console.info("parser",path);
        return path; // return the path "as-is"
    });

    /**
     * Handle route change event
     */
    riot.route(function (path) {
        console.info("route is change to",path);
    });

    riot.route.start(true);

I expect that my callback is called on every change of the url (as in the version 2.3.4)

But it is not true in case the route is changed from index.html#blog to index.html#
The callback in the route.parser is invoked with empty path, and the riot.route callback is not called

PS: I don't know how to generate route problem with plunker

subRoute.stop() doesn't work (stop is undefined)

I need to load and unload sub-components dynamically and they have inner routes themselves.
I wanted to stop subRoute when component is unmounting, so the handlers wouldn't accumulate.

The code from router API doesn't work. I've tried in in playground and the error is same.

var subRoute = riot.route.create()
subRoute('/fruit/apple', function() { /* */ })
subRoute.stop()

Version bump / dev branch

Could riot/route get a patch version bump and be updated in the next riot release?
There are a couple bug fixes that would be nice to include along with riot.
Also, the dev branch needs to be merged into master.

route & route.base functions allow regex

I'm starting to create an app for one client using Riot and one of the use cases is that the base route can change due localization, so I tried to use a regular expression in riot.route.base method and it worked as a charm even though the docs don't mention it.

I've been inspecting the code to see if that's expected or not, because I wanted to make sure that it won't stop to work in path/minor version and I've clearly seen that method comments (api docs) specify that the parameters can be a string or RegExp, so I make the assumption that's a feature.

If you can assert all of this, I will send a PR with an update of the docs.

Only route registered routes

Note: Using Riot 2.3.1
So I was rewriting my webapp which used:
http://example.com#media/id

In the new version the base by default is '#' but it affects every link in the webpage, using or not using '#' so I couldn't click any links because it didn't do anything at all. I really needed to get it working so I finally changed the base to '/' and then the url in the adressbar started to change as I clicked the links but, It does nothing, just works with registered routes, in my case '/media...' after changing the base.

To get it working I needed to register '/..' and then redirect by javascript if the destiny was different from the origin. Here is the code (Which right now doesn't think in queries) I used to get this working If it is of any help:

getUrl = ->
  "#{window.location.protocol}//#{window.location.host}#{window.location.pathname}"

oldMediaId = null
baseUrlForRouter = getUrl()

$(document).ready ->
  riot.route.base('/')

  riot.route 'media/*', (mediaid)->
    if mediaid? and oldMediaId != mediaid
      mediaPopupExec(mediaid)
      oldMediaId = mediaid

  riot.route '/..', () ->
    tUrl = getUrl()
    if tUrl != baseUrlForRouter
      window.location.replace(tUrl)

  riot.route.start(true)

So I can't find anything to solve it in a more official way. Usually in ExpressJS (Node.js) routes are like (req, res, next), and the next param is to call the next registered route which fits the actual route with his filter. If it doesn't have any other, it makes the default move, which in Express usually would be 404 because It doen't find any route, but here would be to send it to the clicked url.

In less words: When any route doesn't satisfy the asked route, it ""shouldn't do event.preventDefault()"" (Just as an example XD)

Sorry if there is an official way to do this, but I couldn't find it :S

click back button on browser doesn't go back to the last state?

Hi guys, with the riot-router, when I click the back button on the browser, the page address did change back to the previous one but the page was not reloaded. Is this a bug or designed like this? if expected, how should I make the content also change back? Regards!

Cannot pass options to routed tags

Hello

I created a basic app with Riot 3.1.0, and the latest router (I built it from sources, as riot+route.min.js doesn't seem to be available on jsdelivr).

The app contains three files:

hello.tag:

<hello>
  <span>Hello { opts.name }!</span>
</hello>

app.tag:

<app>
    <router>
      <route path="">
        <hello name={ name }></hello>
      </route>
    </router>
    <script>
        this.name = "World"
    </script>
</app>

index.html:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>

    <app></app>

    <script type="text/javascript" src="riot+compiler.min.js"></script>
    <script src="route+tag.min.js"></script>
    <script type="riot/tag" data-src="./app.tag"></script>
    <script type="riot/tag" data-src="./hello.tag"></script>

    <script type="text/javascript">
      riot.mount('app')
    </script>

  </body>
</html>

I expected this to display "Hello World!" but the result is "Hello!".
In hello.tag, this.opts.name is an empty string.

Did I miss something, or is there a real problem?

Is change routing in routing callback supported?

Hi, my scenario is like this:

  • When there is no path in the url, I want to change the url to some default path

My code is now like this (v2.3):

studyRoute(view, id) {
    switch(view) {
    case 'news':
      require('./views/news-view.html')
      self.loadView('news-view', id)
      break
    default:
      riot.route('news/1')     // is this supported?
    }
  }
  riot.route(self.studyRoute)
  riot.route.start()
  riot.route.exec()

If I start with empty path url, it will bring me to /#news/1, which is correct. However after changing the url, the studyRoute is not called again, thus my actual logic is not executed.

I am not sure if it is due to I am not writing the correct code, or a bug. Please advise :)

Unexpected behaviour of route.start(true)

I have faced with strange behaviour of single page application built with riot.js . Its rendering was delayed until loading of all external js libraries finishes. It includes async externals, iframes content, etc. After investigation it became clear that route.start(true) calls appropriate route handler only after 'load' event browser trgiggers.

It was not trivial to find the reason, a lot of time was spent. I suggest to describe this behaviour in documentation and suggest to explicitly call of route.exec() where it`s possible. My problem was solved as follows:

riot.route.start() // call of start(true) delays route processing before 'onload' event raises
riot.route.exec() // so need call exec() in place

Route match action should receive parsed segments

There's very little point in having a route matcher that does not (1) regard the values obtained by riot.parser.fn1 and (2) inconsistently produces callback function parameters.

Eg:

riot.route('/fruit/*', function(name) { /* */ })
riot.route('/fruit/apple', function() { /* */ })
riot.route('/fruit/orange', function() { /* */ })

Not only is there a name parameter JUST for wildcard matching, but this setup requires fruit as the bare minimum abstraction.

Expectedly, all route callbacks should plug into the values obtained by parser.fn1. In the default scenario, this looks like:

riot.route('/fruit/*', function(collection, id, action) { /* */ })
riot.route('/fruit/apple', function(collection, id, action){ /* */ })
riot.route('/fruit/orange', function(collection, id, action) { /* */ })

Of course, some parameters may still be undefined, but at least you can always expect a set of parameters in the callback.

My second point: We have to have a full set of routes just for fruit, and will have to repeat the same set for cars and another for trees, etc.

This practice only makes sense when you're designating routes for a specific tag or a specific set of tags. This same practice prevent you from having a succinct, global level routes declaration.

The same solution allows for:

// (1)
riot.route('..', function (collection, id, action) {
  // ..
});

// (2)
riot.route('fruit/apple/..', function (custom, parser, args) {
  // .. long-tail url, read it
});

(1): While this isn't a recommended only solution, it allows for a nice last resort/"catch-all" which has the power to run its own logic based on params

(2): Dependent on our desired URL structure (and appropriate parser fn), we can allow for deep, complex URLs and handle them all at once without having to declare multiple blocks, repeating boilerplate.

Anyway, Issue getting a bit long here. If this is approved, I have the matching PR ready to be opened. It's a simple 2-line fix

Coveralls doesn't work

After repo name changed (riot-router --> riot-route), coveralls seems not working. I've already changed the source and synced it. There's something buggy. Some issues like this is reported on coveralls' repo.
lemurheavy/coveralls-public#603

Unable to include lib/index.js in the new riot 2.3.0 build

I have tried including the new router in the new riot build https://github.com/riot/riot/blob/2.3.0/lib/riot.js but it does not pass the old router tests. Do I need to test a build script with esperanto or do we stick with smash? In case we want to use smash the router code should be wrapped in its own IIFE avoiding to pollute the global scope. What do you recommend?

Is there a CDN release of this

I'm playing around with the 3.0 version of Riot and the router has been removed. I'm wondering if there is a release of the stand alone router on a CDN someplace?

I've checked a few including cdn.jsdelivr.net (where I'm grabbing the 3.0 riot from) but I cant seem to locate the router code.

I'm using https://cdn.rawgit.com/riot/route/master/dist/route.js for now, but a released version on CDN would be much better.

route.query() not working as expected when using # base

When using # as the base, route.query() for these URLs is not behaving correctly:

  • index.html?param=xyz#/search => { param: "xyz#/search" }
  • index.html?param=xyz#/search?q=keyword => { param: "xyz#/search?q=keyword" }

Where ?param=xyz are query params for the server rather than the router.

It's not entirely clear how it should behave. The docs don't address it and the specs only test with '/' base. My expectation is that if using a # base, the router should only consider query params after the #. Which would look like this:

  • index.html?param=xyz#/search => {}
  • index.html?param=xyz#/search?q=keyword => { q: "keyword" }

When using '/' as the base, the issue doesn't exist because there's only one set of query params which is shared between server and router.

I didn't manage to write a spec to show this failing because the code behaves differently when running in the test suite (it doesn't use location.href).

Partial server-side support

We should simply allow something like the exec method to work server-side. This way, you can pass it the request path and let your route handlers do any rendering they normally would do on the client side.

I can work on a PR if you agree with the idea.

Open in new window/tab?

I'm used to link with a CTRL+click opening in a new tab/window. Is there a way to do that with the riot.route?
Or replace my riot.route with a href that the router picks up?

Thanks!

riot.route not working in ie for 2.3.1

I have this setup for riot routing -

var router = function(page,id) {
function change_page(current_page){
RiotControl.trigger('page_changed', current_page, xmenu.last_page)
xmenu.last_page = current_page;
}
page = !page ? 'home' : page;
change_page(page);
}
// Riot router
riot.route(router)
// Execute router function once for rendering the items
riot.route.exec(router);

when I click a link with href="#home" or set location.hash the callback function 'router' is never called in ie11 works fine in chrome and ff.

Makes route.exec() callable without callback

@tipiirai can't we change the API of route.exec()?

v2.2 allowed a custom callback for this function, but I'd like to make it callable without a callback.

// v2.2
riot.exec(callback)

// v2.3
riot.exec()

I often use it this manner in v2.2, but it looks redundant:

// v2.2
var callback = function(id) {
  /* do something */
}
riot(callback)
riot.exec(callback)

And if there're multiple routings, we have no way to exec. Any advice or thought?
(At this time, this would be the only point which is not compatible with v2.2)

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.