Prototype for routing proposal #8

merged 55 commits into from May 17, 2016


None yet

3 participants

novemberborn commented Apr 22, 2016 edited

After discussions with @kitsonk I've arrived at an approach to routing that would work with with the Dojo 2 Application architecture.

There's a Google Doc to discuss the proposal in prose, this PR is to discuss the code 😄

Please note that this is still a prototype. I'll be updating this PR as I go along. I'll be looking at:

  • index routes
  • fall-through routes
  • search component matching
  • navigationStart event and deferring navigation
  • History management
  • Link widget

Since other parts of the Dojo 2 toolkit are still in flux they're included here as "bundled" dependencies.

novemberborn added some commits Apr 21, 2016
@novemberborn novemberborn update boilerplate 3b953e1
@novemberborn novemberborn indent package.json using spaces da16a45
@novemberborn novemberborn bump typescript 74bd825
@novemberborn novemberborn ignore .vscode 41633c1
@novemberborn novemberborn bump tslint fcc545a
@novemberborn novemberborn bump intern, istanbul and remap-istanbul deps 1d917a2
@kitsonk kitsonk self-assigned this Apr 27, 2016
@kitsonk kitsonk added this to the 2016.05 milestone Apr 27, 2016
novemberborn added some commits Apr 21, 2016
@novemberborn novemberborn include dependencies bc8f0be
@novemberborn novemberborn node typings in tests clash with dojo-loader 38f657b
@novemberborn novemberborn implement createRoute 77e7c6a
@novemberborn novemberborn make pathname option optional 3c9a878
@novemberborn novemberborn refactor path handling
Change parse() to deconstruct(), redo the interface.

Change matched in MatchResult to isMatch.

Properly reject empty parameter names, and names that are just the colon
@novemberborn novemberborn initial router implementation 5c19393
@novemberborn novemberborn fix type errors 223082e
@novemberborn novemberborn reorder imports, definitions, etc caeb74f
@novemberborn novemberborn provide stub implementations of exec and guard
The optionality confuses TypeScript, and it's no fun writing guards for them either.
@novemberborn novemberborn support hierarchical routes 72de9a6
@novemberborn novemberborn only allow params() if the path contains parameters 7a29ee6
@novemberborn novemberborn path option when creating routes
Move search and hash component rejection into createRoute. This can be loosened once support is added.
@novemberborn novemberborn improve path deconstruct
Throw TypeErrors. Remove unnecessary if-condition.
@novemberborn novemberborn add tests d303d7d
@novemberborn novemberborn make Router#dispatch() return a boolean
Useful for checking whether anything was routed.
@novemberborn novemberborn change path matching to ignore search and hash components
Also fixes : matching (by not tokenizing colons).
@novemberborn novemberborn support index routes 0049642
@novemberborn novemberborn support fallback routes b2c3079
@novemberborn novemberborn support router-level fallback a1b623a
@novemberborn novemberborn ensure parameters have unique names ed6c94b
@novemberborn novemberborn use switch/case when executing routes for better code coverage
/* istanbul ignore else */ didn't seem to work.
@novemberborn novemberborn present parameter values from path as a single argument
This lets us use a second argument for the UrlSearchParams.
@novemberborn novemberborn use braces to name parameters
Braces have better forward compatibility and make more sense when naming parameters in the search component.
@novemberborn novemberborn support search parameters
Each route can specify search parameters in its path argument. No values can be
provided and the parameters do not have to be provided for the route to match.

Only the specified parameters are extracted from the dispatched path, and only
if they're provided. These are passed to the params() handler as a
UrlSearchParams object (from dojo-core).

The default params() handler adds the *first* value from each specified and
provided search parameter to the return object.

Search parameters must be unique across the entire path, including the pathname

When multiple routes are matched, each route receives its specified search
@novemberborn novemberborn tweak interfaces and class properties 736e263
@novemberborn novemberborn implement navstart event and routing deferral/cancelation 7a086ba
@novemberborn novemberborn implement history managers 426e828
@novemberborn novemberborn avoid unnecessary promise allocation when disptaching b3baf7b
@novemberborn novemberborn router dispatch returns a task
Routing may be asynchronous. Cancel the task if new navigation occurs to prevent interleaving.
@novemberborn novemberborn use 'literal' property in LiteralSegment interface cd55a9b
@novemberborn novemberborn require trailing slashes to match route declarations 12bac44
@novemberborn novemberborn allow trailing slash matching behavior to be disabled ff1c136
@novemberborn novemberborn document library dadf6fb

I've finished the initial implementation. The README describes the current features and how to use them.

I'm confident the code does not currently meet the style guide. Let's not nitpick this yet. Ideally we update the tslint config so a machine can find the issues.

We should bikeshed about the different modules, interfaces, naming, and exports. It might be good to first try and integrate this with the application factory, widgets and stores so we have a better idea of how the pieces should fit together.

Currently the various dependencies (dojo-actions, dojo-compose, dojo-core and dojo-widgets) are directly committed to this PR. We need to list them as dependencies and let npm install deal with it.

I'd still like to:

  • Implement the Link widget
  • Make createHistory take a base argument, or detect it from the document, so that its path value can be relative to that base
  • Be able to easily navigate from route guard() functions, rather than preventing a route from being selected

Meanwhile I'll try and document some of the internals.

novemberborn and others added some commits Apr 29, 2016
@novemberborn novemberborn code comments for createRouter da57595
@kitsonk @novemberborn kitsonk Small tweaks to prototype 9c79446
@novemberborn novemberborn clean up UrlSearchParams access
Null values may be returned, so just guard against them. That makes the has()
check redundant.
@novemberborn novemberborn remove unnecessary casting f5a36d2
@novemberborn novemberborn improve match bailing and guard calling 93f57c0
@novemberborn novemberborn code comments for createRoute b9c5f49
@novemberborn novemberborn code comments for interfaces d434870
@novemberborn novemberborn move interfaces around
* Don't export interfaces that are not needed in other modules
* Move DefaultParameters to the interfaces module
* Reorder interface declarations within the modules
@novemberborn novemberborn refactor Segment type
Use a union type rather than subinterfaces and optional properties. Add a type
guard to figure out which type is present.
@novemberborn novemberborn better edge-case handling for paths
Reject repeated slashes and ampersands when creating routes. Ignore repeated
slashes when dispatching.
@novemberborn novemberborn catch duplicate search parameter names bd434d4
@novemberborn novemberborn refactor and document path util b2206d8
@novemberborn novemberborn reorganize src layout
Prefix internal modules with an underscore.
@novemberborn novemberborn export routing factories from main
createRoute() and createRouter(), as well as associated interfaces, are now
exported from the main `dojo-routing` module. History is left in
@novemberborn novemberborn code comments for history managers b6abeb3

Did some refactoring, added documentation, and fixed some minor bugs.

@novemberborn novemberborn tslint updates ae64450
kitsonk commented May 17, 2016

I am going to merge this so we can start iterating on it.

@kitsonk kitsonk merged commit 57630f5 into dojo:master May 17, 2016

1 check passed

jQuery Foundation CLA All authors have signed the CLA
@novemberborn novemberborn deleted the novemberborn:prototype branch May 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment