{"action":"created","comment":{"url":"https://api.github.com/repos/dojo/routing/pulls/comments/122428178","pull_request_review_id":44543406,"id":122428178,"diff_hunk":"@@ -54,6 +63,403 @@ npm install @dojo/shim\n \n The examples below are provided in TypeScript syntax. The package does work under JavaScript, but for clarity, the examples will only include one syntax.\n \n+### Widget Routing\n+\n+Widgets are a fundamental concept for any Dojo 2 application and as such Dojo 2 Routing provides collection of components that integrate directly with existing widgets within an application.\n+\n+These components enable widgets to be registered against a route _without_ requiring any knowledge of the `Router` or `Routes`.\n+\n+#### Outlets\n+\n+The primary concept for the routing integration is an `outlet`, this is a unique identifier associated with registered application route. Dojo 2 Widgets can then be configured with these outlet identifiers using the `Outlet` higher order component. `Outlet` returns a \"new\" Widget that can be used like any other widget within a `render` method e.g. `w(MyFooOutlet, { })`.\n+\n+Properties can be passed to an `Outlet` widget, in the same way as if the original widget was being used, however all properties are made optional in order to allow the properties to be injected using the [mapParams](#mapParams) function described below.\n+\n+The number of widgets that can be mapped to a single outlet identifier is not restricted. All the configured widgets for a single outlet will be rendered when the route associated to the outlet is matched by the `router` and they are part of the current widget hierarchy.\n+\n+The following example configures a stateless widget with an outlet called `foo`, the resulting `FooOutlet` can be used in a widgets `render` in the same way as any other Dojo 2 Widget.\n+\n+```ts\n+import { Outlet } from '@dojo/routing/Outlet';\n+import { MyViewWidget } from './MyViewWidget';\n+\n+const FooOutlet = Outlet(MyViewWidget, 'foo');\n+```\n+\n+Example usage of `FooOutlet`, where the widget will only be rendered when the route registered against outlet `foo` is matched.\n+\n+```ts\n+class App extends WidgetBase {\n+\tprotected render(): DNode {\n+\t\treturn v('div', [\n+\t\t\tw(MyViewWidget, {})\n+\t\t]);\n+\t}\n+}\n+```\n+\n+#### Outlet Component Types\n+\n+When registering an outlet a different widget can be configure for each `MatchType` of a route:\n+\n+| Type              | Description |\n+| ----------------- | ---------------------------------------------------- |\n+|`MatchType.INDEX`  | This is an exact match for the registered route. E.g. Navigating to `foo/bar` with a registered route `foo/bar`.   |\n+|`MatchType.PARTIAL`| Any match other than an exact match, for example `foo/bar` would partially match `foo/bar/qux` but only if `foo/bar/qux` was also a registered route. Otherwise it would be an `ERROR` match. |\n+|`MatchType.ERROR`  | An error match occurs when a partial match occurs but there is no match for the next section of the route. |","path":"README.md","position":63,"original_position":63,"commit_id":"c98313ad35994fe9b4679168c7f68aa65629d772","original_commit_id":"c98313ad35994fe9b4679168c7f68aa65629d772","user":{"login":"dylans","id":97291,"avatar_url":"https://avatars2.githubusercontent.com/u/97291?v=3","gravatar_id":"","url":"https://api.github.com/users/dylans","html_url":"https://github.com/dylans","followers_url":"https://api.github.com/users/dylans/followers","following_url":"https://api.github.com/users/dylans/following{/other_user}","gists_url":"https://api.github.com/users/dylans/gists{/gist_id}","starred_url":"https://api.github.com/users/dylans/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dylans/subscriptions","organizations_url":"https://api.github.com/users/dylans/orgs","repos_url":"https://api.github.com/users/dylans/repos","events_url":"https://api.github.com/users/dylans/events{/privacy}","received_events_url":"https://api.github.com/users/dylans/received_events","type":"User","site_admin":false},"body":"\"An error match occurs when a partial match occurs but there is no match for the next section of the route.\" -> \"When a partial match occurs but there is no match for the next section of the route.\"","created_at":"2017-06-16T12:17:17Z","updated_at":"2017-06-16T12:39:32Z","html_url":"https://github.com/dojo/routing/pull/90#discussion_r122428178","pull_request_url":"https://api.github.com/repos/dojo/routing/pulls/90","_links":{"self":{"href":"https://api.github.com/repos/dojo/routing/pulls/comments/122428178"},"html":{"href":"https://github.com/dojo/routing/pull/90#discussion_r122428178"},"pull_request":{"href":"https://api.github.com/repos/dojo/routing/pulls/90"}}},"pull_request":{"url":"https://api.github.com/repos/dojo/routing/pulls/90","id":124445707,"html_url":"https://github.com/dojo/routing/pull/90","diff_url":"https://github.com/dojo/routing/pull/90.diff","patch_url":"https://github.com/dojo/routing/pull/90.patch","issue_url":"https://api.github.com/repos/dojo/routing/issues/90","number":90,"state":"open","locked":false,"title":"Dojo 2 Component Routing","user":{"login":"agubler","id":1982678,"avatar_url":"https://avatars0.githubusercontent.com/u/1982678?v=3","gravatar_id":"","url":"https://api.github.com/users/agubler","html_url":"https://github.com/agubler","followers_url":"https://api.github.com/users/agubler/followers","following_url":"https://api.github.com/users/agubler/following{/other_user}","gists_url":"https://api.github.com/users/agubler/gists{/gist_id}","starred_url":"https://api.github.com/users/agubler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agubler/subscriptions","organizations_url":"https://api.github.com/users/agubler/orgs","repos_url":"https://api.github.com/users/agubler/repos","events_url":"https://api.github.com/users/agubler/events{/privacy}","received_events_url":"https://api.github.com/users/agubler/received_events","type":"User","site_admin":false},"body":"**Type:** feature\r\n\r\nThe following has been addressed in the PR:\r\n\r\n* [x] There is a related issue\r\n* [x] All code matches the [style guide](https://github.com/dojo/meta/blob/master/STYLE.md)\r\n* [x] Unit or Functional tests are included in the PR\r\n\r\n**Description:**\r\n\r\nIntegrated routing support for Dojo 2 widgets; routing is controlled by registering a `RouteConfig`, that defines the routing hierarchy and associated `outlet` identifiers. Standard Dojo 2 components can then be associated with an `outlet` identifier by using the `Outlet` higher order component.\r\n\r\n*Registering Routing Configuration:*\r\n\r\n```ts\r\nconst routeConfig = [\r\n    { path: 'foo', outlet: 'foo' }\r\n];\r\n\r\nconst router = new Router(routeConfig);\r\n\r\nregistry.define(routerKey, Injector(RouterInjector, router));\r\n```\r\n\r\nA Dojo 2 widget can just be associated to the registered `outlet` by utilising the `Outlet` higher order component.\r\n\r\n```ts\r\ninterface MyWidgetProperties {\r\n    label: string;\r\n}\r\n\r\nclass MyWidget extends WidgetBase<MyWidgetProperties> {\r\n    render() {\r\n        return v('div', [ this.properties.label ]);\r\n    }\r\n}\r\n\r\nconst MyWidgetOutlet = Outlet(MyWidget, 'foo');\r\n```\r\n\r\nFor each `Outlet` a component can be registered for an exact route match (known as `index`), partial route match and a route error. \r\n\r\nRouting also supports path and query params, these along with the route location and match type might need to be used by the wrapped component for which a `mapParams` function can be defined when registering the `Outlet` that will be used to map them to the widgets properties.\r\n\r\n```ts\r\nOutlet({ component: MyWidget, error: ErrorWidget }, 'foo', (params, type, location) => {\r\n    return { label: params.label };\r\n});\r\n```\r\n\r\nTodo: \r\n* [x] Update README\r\n* [x] Link Component\r\n\r\nResolves #88\r\n","created_at":"2017-06-07T15:11:34Z","updated_at":"2017-06-16T12:39:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"62b5482926d6d7c56f27eedec8620d75c98de811","assignee":null,"assignees":[],"requested_reviewers":[{"login":"rishson","id":468596,"avatar_url":"https://avatars2.githubusercontent.com/u/468596?v=3","gravatar_id":"","url":"https://api.github.com/users/rishson","html_url":"https://github.com/rishson","followers_url":"https://api.github.com/users/rishson/followers","following_url":"https://api.github.com/users/rishson/following{/other_user}","gists_url":"https://api.github.com/users/rishson/gists{/gist_id}","starred_url":"https://api.github.com/users/rishson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rishson/subscriptions","organizations_url":"https://api.github.com/users/rishson/orgs","repos_url":"https://api.github.com/users/rishson/repos","events_url":"https://api.github.com/users/rishson/events{/privacy}","received_events_url":"https://api.github.com/users/rishson/received_events","type":"User","site_admin":false},{"login":"rorticus","id":2008858,"avatar_url":"https://avatars1.githubusercontent.com/u/2008858?v=3","gravatar_id":"","url":"https://api.github.com/users/rorticus","html_url":"https://github.com/rorticus","followers_url":"https://api.github.com/users/rorticus/followers","following_url":"https://api.github.com/users/rorticus/following{/other_user}","gists_url":"https://api.github.com/users/rorticus/gists{/gist_id}","starred_url":"https://api.github.com/users/rorticus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rorticus/subscriptions","organizations_url":"https://api.github.com/users/rorticus/orgs","repos_url":"https://api.github.com/users/rorticus/repos","events_url":"https://api.github.com/users/rorticus/events{/privacy}","received_events_url":"https://api.github.com/users/rorticus/received_events","type":"User","site_admin":false},{"login":"matt-gadd","id":2183490,"avatar_url":"https://avatars3.githubusercontent.com/u/2183490?v=3","gravatar_id":"","url":"https://api.github.com/users/matt-gadd","html_url":"https://github.com/matt-gadd","followers_url":"https://api.github.com/users/matt-gadd/followers","following_url":"https://api.github.com/users/matt-gadd/following{/other_user}","gists_url":"https://api.github.com/users/matt-gadd/gists{/gist_id}","starred_url":"https://api.github.com/users/matt-gadd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matt-gadd/subscriptions","organizations_url":"https://api.github.com/users/matt-gadd/orgs","repos_url":"https://api.github.com/users/matt-gadd/repos","events_url":"https://api.github.com/users/matt-gadd/events{/privacy}","received_events_url":"https://api.github.com/users/matt-gadd/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/dojo/routing/milestones/17","html_url":"https://github.com/dojo/routing/milestone/17","labels_url":"https://api.github.com/repos/dojo/routing/milestones/17/labels","id":2480677,"number":17,"title":"2017.06","description":"","creator":{"login":"dylans","id":97291,"avatar_url":"https://avatars2.githubusercontent.com/u/97291?v=3","gravatar_id":"","url":"https://api.github.com/users/dylans","html_url":"https://github.com/dylans","followers_url":"https://api.github.com/users/dylans/followers","following_url":"https://api.github.com/users/dylans/following{/other_user}","gists_url":"https://api.github.com/users/dylans/gists{/gist_id}","starred_url":"https://api.github.com/users/dylans/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dylans/subscriptions","organizations_url":"https://api.github.com/users/dylans/orgs","repos_url":"https://api.github.com/users/dylans/repos","events_url":"https://api.github.com/users/dylans/events{/privacy}","received_events_url":"https://api.github.com/users/dylans/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":1,"state":"open","created_at":"2017-04-25T15:52:49Z","updated_at":"2017-06-12T13:02:23Z","due_on":"2017-06-30T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/dojo/routing/pulls/90/commits","review_comments_url":"https://api.github.com/repos/dojo/routing/pulls/90/comments","review_comment_url":"https://api.github.com/repos/dojo/routing/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dojo/routing/issues/90/comments","statuses_url":"https://api.github.com/repos/dojo/routing/statuses/c98313ad35994fe9b4679168c7f68aa65629d772","head":{"label":"agubler:issue-88-in-router","ref":"issue-88-in-router","sha":"c98313ad35994fe9b4679168c7f68aa65629d772","user":{"login":"agubler","id":1982678,"avatar_url":"https://avatars0.githubusercontent.com/u/1982678?v=3","gravatar_id":"","url":"https://api.github.com/users/agubler","html_url":"https://github.com/agubler","followers_url":"https://api.github.com/users/agubler/followers","following_url":"https://api.github.com/users/agubler/following{/other_user}","gists_url":"https://api.github.com/users/agubler/gists{/gist_id}","starred_url":"https://api.github.com/users/agubler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agubler/subscriptions","organizations_url":"https://api.github.com/users/agubler/orgs","repos_url":"https://api.github.com/users/agubler/repos","events_url":"https://api.github.com/users/agubler/events{/privacy}","received_events_url":"https://api.github.com/users/agubler/received_events","type":"User","site_admin":false},"repo":{"id":61368232,"name":"routing","full_name":"agubler/routing","owner":{"login":"agubler","id":1982678,"avatar_url":"https://avatars0.githubusercontent.com/u/1982678?v=3","gravatar_id":"","url":"https://api.github.com/users/agubler","html_url":"https://github.com/agubler","followers_url":"https://api.github.com/users/agubler/followers","following_url":"https://api.github.com/users/agubler/following{/other_user}","gists_url":"https://api.github.com/users/agubler/gists{/gist_id}","starred_url":"https://api.github.com/users/agubler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agubler/subscriptions","organizations_url":"https://api.github.com/users/agubler/orgs","repos_url":"https://api.github.com/users/agubler/repos","events_url":"https://api.github.com/users/agubler/events{/privacy}","received_events_url":"https://api.github.com/users/agubler/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/agubler/routing","description":"Dojo 2 Routing","fork":true,"url":"https://api.github.com/repos/agubler/routing","forks_url":"https://api.github.com/repos/agubler/routing/forks","keys_url":"https://api.github.com/repos/agubler/routing/keys{/key_id}","collaborators_url":"https://api.github.com/repos/agubler/routing/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/agubler/routing/teams","hooks_url":"https://api.github.com/repos/agubler/routing/hooks","issue_events_url":"https://api.github.com/repos/agubler/routing/issues/events{/number}","events_url":"https://api.github.com/repos/agubler/routing/events","assignees_url":"https://api.github.com/repos/agubler/routing/assignees{/user}","branches_url":"https://api.github.com/repos/agubler/routing/branches{/branch}","tags_url":"https://api.github.com/repos/agubler/routing/tags","blobs_url":"https://api.github.com/repos/agubler/routing/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/agubler/routing/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/agubler/routing/git/refs{/sha}","trees_url":"https://api.github.com/repos/agubler/routing/git/trees{/sha}","statuses_url":"https://api.github.com/repos/agubler/routing/statuses/{sha}","languages_url":"https://api.github.com/repos/agubler/routing/languages","stargazers_url":"https://api.github.com/repos/agubler/routing/stargazers","contributors_url":"https://api.github.com/repos/agubler/routing/contributors","subscribers_url":"https://api.github.com/repos/agubler/routing/subscribers","subscription_url":"https://api.github.com/repos/agubler/routing/subscription","commits_url":"https://api.github.com/repos/agubler/routing/commits{/sha}","git_commits_url":"https://api.github.com/repos/agubler/routing/git/commits{/sha}","comments_url":"https://api.github.com/repos/agubler/routing/comments{/number}","issue_comment_url":"https://api.github.com/repos/agubler/routing/issues/comments{/number}","contents_url":"https://api.github.com/repos/agubler/routing/contents/{+path}","compare_url":"https://api.github.com/repos/agubler/routing/compare/{base}...{head}","merges_url":"https://api.github.com/repos/agubler/routing/merges","archive_url":"https://api.github.com/repos/agubler/routing/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/agubler/routing/downloads","issues_url":"https://api.github.com/repos/agubler/routing/issues{/number}","pulls_url":"https://api.github.com/repos/agubler/routing/pulls{/number}","milestones_url":"https://api.github.com/repos/agubler/routing/milestones{/number}","notifications_url":"https://api.github.com/repos/agubler/routing/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/agubler/routing/labels{/name}","releases_url":"https://api.github.com/repos/agubler/routing/releases{/id}","deployments_url":"https://api.github.com/repos/agubler/routing/deployments","created_at":"2016-06-17T11:12:18Z","updated_at":"2016-06-17T11:12:19Z","pushed_at":"2017-06-15T17:40:27Z","git_url":"git://github.com/agubler/routing.git","ssh_url":"git@github.com:agubler/routing.git","clone_url":"https://github.com/agubler/routing.git","svn_url":"https://github.com/agubler/routing","homepage":null,"size":970,"stargazers_count":0,"watchers_count":0,"language":"TypeScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dojo:master","ref":"master","sha":"6ac04e4a4311f30448bde0bf6c36ff5fea18a863","user":{"login":"dojo","id":86896,"avatar_url":"https://avatars1.githubusercontent.com/u/86896?v=3","gravatar_id":"","url":"https://api.github.com/users/dojo","html_url":"https://github.com/dojo","followers_url":"https://api.github.com/users/dojo/followers","following_url":"https://api.github.com/users/dojo/following{/other_user}","gists_url":"https://api.github.com/users/dojo/gists{/gist_id}","starred_url":"https://api.github.com/users/dojo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dojo/subscriptions","organizations_url":"https://api.github.com/users/dojo/orgs","repos_url":"https://api.github.com/users/dojo/repos","events_url":"https://api.github.com/users/dojo/events{/privacy}","received_events_url":"https://api.github.com/users/dojo/received_events","type":"Organization","site_admin":false},"repo":{"id":35429260,"name":"routing","full_name":"dojo/routing","owner":{"login":"dojo","id":86896,"avatar_url":"https://avatars1.githubusercontent.com/u/86896?v=3","gravatar_id":"","url":"https://api.github.com/users/dojo","html_url":"https://github.com/dojo","followers_url":"https://api.github.com/users/dojo/followers","following_url":"https://api.github.com/users/dojo/following{/other_user}","gists_url":"https://api.github.com/users/dojo/gists{/gist_id}","starred_url":"https://api.github.com/users/dojo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dojo/subscriptions","organizations_url":"https://api.github.com/users/dojo/orgs","repos_url":"https://api.github.com/users/dojo/repos","events_url":"https://api.github.com/users/dojo/events{/privacy}","received_events_url":"https://api.github.com/users/dojo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dojo/routing","description":":rocket: Dojo 2 - routing library.","fork":false,"url":"https://api.github.com/repos/dojo/routing","forks_url":"https://api.github.com/repos/dojo/routing/forks","keys_url":"https://api.github.com/repos/dojo/routing/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dojo/routing/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dojo/routing/teams","hooks_url":"https://api.github.com/repos/dojo/routing/hooks","issue_events_url":"https://api.github.com/repos/dojo/routing/issues/events{/number}","events_url":"https://api.github.com/repos/dojo/routing/events","assignees_url":"https://api.github.com/repos/dojo/routing/assignees{/user}","branches_url":"https://api.github.com/repos/dojo/routing/branches{/branch}","tags_url":"https://api.github.com/repos/dojo/routing/tags","blobs_url":"https://api.github.com/repos/dojo/routing/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dojo/routing/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dojo/routing/git/refs{/sha}","trees_url":"https://api.github.com/repos/dojo/routing/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dojo/routing/statuses/{sha}","languages_url":"https://api.github.com/repos/dojo/routing/languages","stargazers_url":"https://api.github.com/repos/dojo/routing/stargazers","contributors_url":"https://api.github.com/repos/dojo/routing/contributors","subscribers_url":"https://api.github.com/repos/dojo/routing/subscribers","subscription_url":"https://api.github.com/repos/dojo/routing/subscription","commits_url":"https://api.github.com/repos/dojo/routing/commits{/sha}","git_commits_url":"https://api.github.com/repos/dojo/routing/git/commits{/sha}","comments_url":"https://api.github.com/repos/dojo/routing/comments{/number}","issue_comment_url":"https://api.github.com/repos/dojo/routing/issues/comments{/number}","contents_url":"https://api.github.com/repos/dojo/routing/contents/{+path}","compare_url":"https://api.github.com/repos/dojo/routing/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dojo/routing/merges","archive_url":"https://api.github.com/repos/dojo/routing/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dojo/routing/downloads","issues_url":"https://api.github.com/repos/dojo/routing/issues{/number}","pulls_url":"https://api.github.com/repos/dojo/routing/pulls{/number}","milestones_url":"https://api.github.com/repos/dojo/routing/milestones{/number}","notifications_url":"https://api.github.com/repos/dojo/routing/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dojo/routing/labels{/name}","releases_url":"https://api.github.com/repos/dojo/routing/releases{/id}","deployments_url":"https://api.github.com/repos/dojo/routing/deployments","created_at":"2015-05-11T14:31:49Z","updated_at":"2017-04-11T09:56:46Z","pushed_at":"2017-06-15T17:40:29Z","git_url":"git://github.com/dojo/routing.git","ssh_url":"git@github.com:dojo/routing.git","clone_url":"https://github.com/dojo/routing.git","svn_url":"https://github.com/dojo/routing","homepage":"http://dojo.io","size":946,"stargazers_count":10,"watchers_count":10,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":14,"mirror_url":null,"open_issues_count":6,"forks":14,"open_issues":6,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dojo/routing/pulls/90"},"html":{"href":"https://github.com/dojo/routing/pull/90"},"issue":{"href":"https://api.github.com/repos/dojo/routing/issues/90"},"comments":{"href":"https://api.github.com/repos/dojo/routing/issues/90/comments"},"review_comments":{"href":"https://api.github.com/repos/dojo/routing/pulls/90/comments"},"review_comment":{"href":"https://api.github.com/repos/dojo/routing/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dojo/routing/pulls/90/commits"},"statuses":{"href":"https://api.github.com/repos/dojo/routing/statuses/c98313ad35994fe9b4679168c7f68aa65629d772"}}}}
{"actor":{"display_login":"dylans"}}