├── .github
├── stale.yml
└── workflows
│ ├── ci.yml
│ └── update_dependencies.yml
├── .gitignore
├── .mergify.yml
├── .npmignore
├── .prettierignore
├── .prettierrc.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── downstream_projects.json
├── examples
├── angular-cli
│ ├── .editorconfig
│ ├── .gitignore
│ ├── README.md
│ ├── angular.json
│ ├── cypress.json
│ ├── cypress
│ │ └── integration
│ │ │ └── example_spec.js
│ ├── package.json
│ ├── src
│ │ ├── app
│ │ │ ├── about.component.ts
│ │ │ ├── app.component.ts
│ │ │ ├── app.module.ts
│ │ │ ├── continentList.component.ts
│ │ │ ├── countryDetail.component.ts
│ │ │ ├── countryList.component.ts
│ │ │ ├── data.api.ts
│ │ │ └── data.json
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main.ts
│ │ ├── polyfills.ts
│ │ ├── styles.css
│ │ ├── test.ts
│ │ ├── tsconfig.app.json
│ │ ├── tsconfig.spec.json
│ │ └── typings.d.ts
│ ├── tsconfig.json
│ └── tslint.json
├── angularjs-bower-script-tags
│ ├── README.md
│ ├── app
│ │ ├── about.component.js
│ │ ├── continentList.component.js
│ │ ├── countryDetail.component.js
│ │ ├── countryList.component.js
│ │ ├── data.json
│ │ ├── index.js
│ │ └── router.config.js
│ ├── bower.json
│ ├── cypress.json
│ ├── cypress
│ │ └── integration
│ │ │ └── example_spec.js
│ ├── index.html
│ ├── index.js
│ ├── package.json
│ └── styles.css
├── angularjs-npm-script-tags
│ ├── README.md
│ ├── app
│ │ ├── about.component.js
│ │ ├── continentList.component.js
│ │ ├── countryDetail.component.js
│ │ ├── countryList.component.js
│ │ ├── data.json
│ │ ├── index.js
│ │ └── router.config.js
│ ├── cypress.json
│ ├── cypress
│ │ └── integration
│ │ │ └── example_spec.js
│ ├── index.html
│ ├── index.js
│ ├── package.json
│ └── styles.css
├── angularjs-webpack
│ ├── README.md
│ ├── app
│ │ ├── about.component.js
│ │ ├── app.module.js
│ │ ├── continentList.component.js
│ │ ├── countryDetail.component.js
│ │ ├── countryList.component.js
│ │ ├── data.api.js
│ │ ├── data.json
│ │ ├── index.js
│ │ └── router.config.js
│ ├── cypress.json
│ ├── cypress
│ │ └── integration
│ │ │ └── example_spec.js
│ ├── index.html
│ ├── index.js
│ ├── package.json
│ ├── styles.css
│ └── webpack.config.js
└── create-react-app
│ ├── README.md
│ ├── cypress.json
│ ├── cypress
│ └── integration
│ │ └── example_spec.js
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
│ └── src
│ ├── About.jsx
│ ├── App.css
│ ├── App.jsx
│ ├── ContinentList.jsx
│ ├── CountryDetail.jsx
│ ├── CountryList.jsx
│ ├── data.api.js
│ ├── data.json
│ └── index.js
├── jest.config.js
├── karma.conf.js
├── package.json
├── rollup.config.js
├── src
├── DSRDataStore.ts
├── dsr.ts
├── index.ts
└── interface.ts
├── test
├── deepStateRedirectSpec.ts
├── index.js
└── util.ts
├── tsconfig.json
└── yarn.lock
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 90
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 14
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - notstale
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: stale
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: |
13 | This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
14 |
15 | This does not mean that the issue is invalid. Valid issues may be reopened.
16 |
17 | Thank you for your contributions.
18 | # Comment to post when closing a stale issue. Set to `false` to disable
19 | closeComment: false
20 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: 'CI'
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 |
9 | jobs:
10 | ci:
11 | needs: [test, downstream]
12 | runs-on: ubuntu-latest
13 | steps:
14 | - run: true
15 | test:
16 | name: yarn test
17 | runs-on: ubuntu-latest
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Install Dependencies
21 | run: yarn install --pure-lockfile
22 | - name: Check Peer Dependencies
23 | run: npx check-peer-dependencies
24 | - name: Run Tests
25 | run: yarn test
26 |
27 | downstream:
28 | name: Test downstream ${{ matrix.group }} projects
29 | runs-on: ubuntu-latest
30 | strategy:
31 | matrix:
32 | group: ['angular', 'angularjs', 'react']
33 | steps:
34 | - uses: actions/checkout@v2
35 | - name: Prepare to Test Downstream Projects
36 | run: |
37 | npm config set scripts-prepend-node-path auto
38 | git config --global user.email uirouter@github.actions
39 | git config --global user.name uirouter_github_actions
40 | - name: Install Dependencies
41 | run: yarn install --pure-lockfile
42 | - name: Test Downstream Projects
43 | run: yarn test:downstream --group ${{ matrix.group }}
44 |
--------------------------------------------------------------------------------
/.github/workflows/update_dependencies.yml:
--------------------------------------------------------------------------------
1 | # This workflow requires a personal access token for uirouterbot
2 | name: Weekly Dependency Bumps
3 | on:
4 | repository_dispatch:
5 | types: [update_dependencies]
6 | schedule:
7 | - cron: '0 21 * * 0'
8 |
9 | jobs:
10 | upgrade-dependencies:
11 | runs-on: ubuntu-latest
12 | name: Update dependencies
13 | strategy:
14 | matrix:
15 | excludes: ['']
16 | deptype: ['dependencies', 'devDependencies']
17 | latest: [true]
18 | steps:
19 | - uses: actions/checkout@v2
20 | - run: |
21 | git config user.name uirouterbot
22 | git config user.password ${{ secrets.UIROUTERBOT_PAT }}
23 | git remote set-url origin $(git remote get-url origin | sed -e 's/ui-router/uirouterbot/')
24 | git fetch --unshallow -p origin
25 | - name: Update dependencies
26 | id: upgrade
27 | uses: ui-router/publish-scripts/actions/upgrade@actions-upgrade-v1.0.3
28 | with:
29 | excludes: ${{ matrix.excludes }}
30 | deptype: ${{ matrix.deptype }}
31 | latest: ${{ matrix.latest }}
32 | - name: Create Pull Request
33 | id: cpr
34 | if: ${{ steps.upgrade.outputs.upgrades != '' }}
35 | # the following hash is from https://github.com/peter-evans/create-pull-request/releases/tag/v2.7.0
36 | uses: peter-evans/create-pull-request@340e629d2f63059fb3e3f15437e92cfbc7acd85b
37 | with:
38 | token: ${{ secrets.UIROUTERBOT_PAT }}
39 | request-to-parent: true
40 | branch-suffix: 'random'
41 | commit-message: 'chore(package): Update ${{ steps.upgrade.outputs.upgradecount }} ${{ matrix.deptype }} to ${{ steps.upgrade.outputs.upgradestrategy }}'
42 | title: 'chore(package): Update ${{ steps.upgrade.outputs.upgradecount }} ${{ matrix.deptype }} to ${{ steps.upgrade.outputs.upgradestrategy }}'
43 | body: |
44 | chore(package): Update ${{ steps.upgrade.outputs.upgradecount }} ${{ matrix.deptype }} to ${{ steps.upgrade.outputs.upgradestrategy }}
45 |
46 | ```
47 | ${{ steps.upgrade.outputs.upgrades }}
48 | ```
49 |
50 | Auto-generated by [create-pull-request][1]
51 |
52 | [1]: https://github.com/peter-evans/create-pull-request
53 | - name: Apply Merge Label
54 | if: ${{ steps.cpr.outputs.pr_number != '' }}
55 | uses: actions/github-script@0.9.0
56 | with:
57 | github-token: ${{ secrets.UIROUTERBOT_PAT }}
58 | script: |
59 | await github.issues.addLabels({
60 | owner: context.repo.owner,
61 | repo: context.repo.repo,
62 | issue_number: ${{ steps.cpr.outputs.pr_number }},
63 | labels: ['ready to squash and merge']
64 | });
65 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # master only
2 | build
3 | bundles
4 | build_packages
5 | site
6 | yarn-error.log
7 |
8 | # common
9 | **/.*
10 | *~
11 | node_modules
12 | bower_components
13 | lib
14 | lib-esm
15 | _bundles
16 |
17 | # webstorm files
18 | .idea
19 | idea-out
20 | *.iml
21 | *.ipr
22 | *.iws
23 |
24 | # generate doc to _doc; copy to proper gh-pages dir
25 | _doc
26 |
27 | !.github
28 |
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | pull_request_rules:
2 | - name: Auto Squash and Merge
3 | conditions:
4 | - base=master
5 | - status-success=ci
6 | - 'label=ready to squash and merge'
7 | actions:
8 | delete_head_branch: {}
9 | merge:
10 | method: squash
11 | strict: smart
12 | - name: Auto Rebase and Merge
13 | conditions:
14 | - base=master
15 | - status-success=ci
16 | - 'label=ready to rebase and merge'
17 | actions:
18 | delete_head_branch: {}
19 | merge:
20 | method: rebase
21 | strict: smart
22 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Any hidden files
2 | **/.*
3 | .*
4 | *.iml
5 | *.ipr
6 | *.iws
7 |
8 | src
9 | test
10 | scripts
11 |
12 | node_modules
13 |
14 | tslint.json
15 | tsconfig.json
16 | tsconfig.**.json
17 | webpack.config.js
18 | rollup.config.js
19 | karma.conf.js
20 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "es5",
4 | "printWidth": 120
5 | }
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.2.0 (2019-12-26)
2 |
3 | [Compare `@uirouter/dsr` versions 1.1.1 and 1.2.0](https://github.com/ui-router/dsr/compare/1.1.1...1.2.0)
4 |
5 | ### Bug Fixes
6 |
7 | - **params:** When performing DSR with param criteria, only consider the parameters listed in the dsr configuration block ([d073218](https://github.com/ui-router/dsr/commit/d073218))
8 |
9 | ## 1.1.1 (2019-10-08)
10 |
11 | [Compare `@uirouter/dsr` versions 1.1.0 and 1.1.1](https://github.com/ui-router/dsr/compare/1.1.0...1.1.1)
12 |
13 | ### Bug Fixes
14 |
15 | - **examples:** update angular-cli example to uirouter/angular 4.x ([2c0388c](https://github.com/ui-router/dsr/commit/2c0388c))
16 | - **package:** Change peerDependency on uirouter/core from '^5.0.1' to '>=5.0.1' ([d039187](https://github.com/ui-router/dsr/commit/d039187))
17 | - **travis:** use service: xvfb instead of launching it manually. install libgconf debian package ([fb48a4a](https://github.com/ui-router/dsr/commit/fb48a4a))
18 |
19 | # 1.1.0 (2019-01-16)
20 |
21 | [Compare `@uirouter/dsr` versions 1.0.3 and 1.1.0](https://github.com/ui-router/dsr/compare/1.0.3...1.1.0)
22 |
23 | ### Features
24 |
25 | - **dataSource:** Added pluggable dataSource ability and created LocalStorageDataSource ([1a934b4](https://github.com/ui-router/dsr/commit/1a934b4)), closes [#90](https://github.com/ui-router/dsr/issues/90)
26 | - **dataSource:** Create SessionStorageDataSource ([a26579c](https://github.com/ui-router/dsr/commit/a26579c))
27 |
28 | ## 1.0.3 (2018-03-31)
29 |
30 | [Compare `@uirouter/dsr` versions 1.0.2 and 1.0.3](https://github.com/ui-router/dsr/compare/1.0.2...1.0.3)
31 |
32 | ### Bug Fixes
33 |
34 | - **typings:** Augment StateDeclaration using deep path ([#3](https://github.com/ui-router/dsr/issues/3)) ([e582bc3](https://github.com/ui-router/dsr/commit/e582bc3)), closes [#2](https://github.com/ui-router/dsr/issues/2)
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2013-2015 The AngularUI Team, Karsten Sperling
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deep State Redirect
2 |
3 | ### DSR for UI-Router 1.0 [](https://github.com/ui-router/dsr/actions?query=workflow%3A%22CI%3A+Deep+State+Redirect+for+UIRouter%22)
4 |
5 | With Deep State Redirect, a parent state remembers whatever child state was last activated.
6 | When the user directly reactivates the parent state, they are redirected to the nested state (which was previously activated).
7 |
8 | ## Overview and Use Case
9 |
10 | Deep State Redirect (DSR) is a marker you can add to a state definition.
11 |
12 | When a child state of the DSR marked state is activated, UI-Router Extras remembers the child and its parameters.
13 | The most-recently-activate child is remembered no matter where the user navigates in the state tree.
14 | When the DSR marked state is directly activated, UI-Router Extras will redirect to the remembered child state and parameters.
15 |
16 | One use case for DSR is a tabbed application.
17 | Each tab might contain an application module.
18 | Each tabs' state is marked as deepStateRedirect.
19 | When the user navigates into the tab, and drills down to a substate, DSR will remember the substate.
20 | The user can then navigate to other tabs (or somewhere else completely).
21 | When they click the original tab again, it will transition to the remembered ehild state and parameters of that tab, making it appear that the tab was never destructed.
22 |
23 | Deep State Redirect can be used with StickyStates, or on its own.
24 | If used with a Sticky State, the states will be reactivated, and the DOM will be unchanged (as opposed to the states being re-entered and controllers re-initialized)
25 |
26 | ## Using
27 |
28 | See: http://christopherthielen.github.io/ui-router-extras/#/dsr
29 |
30 | TODO: Move docs here
31 |
32 | ### Using a custom DataStore
33 |
34 | By default DSR stores the most recent redirects in memory.
35 | Alternatively, you can store the redirects in Local Storage using
36 | [LocalStorageDataStore](https://github.com/ui-router/dsr/blob/master/src/DSRDataStore.ts)
37 | or create your own DataStore.
38 |
39 | When registering the DSRPlugin, pass an options object with a `dataStore` property, i.e.:
40 |
41 | ```js
42 | router.plugin(DSRPlugin, { dataStore: new LocalStorageDataStore() });
43 | ```
44 |
45 | ## Example Builds
46 |
47 | The [`/examples` directory](https://github.com/ui-router/dsr/tree/master/examples) contains example setups for:
48 |
49 | - Angular-CLI
50 | - AngularJS + bower + script tags
51 | - AngularJS + npm + script tags
52 | - AngularJS + webpack
53 | - Create-React-App
54 |
--------------------------------------------------------------------------------
/downstream_projects.json:
--------------------------------------------------------------------------------
1 | {
2 | "angular": {
3 | "angular-cli": "./examples/angular-cli"
4 | },
5 | "angularjs": {
6 | "angularjs-webpack": "./examples/angularjs-webpack"
7 | },
8 | "react": {
9 | "create-react-app": "./examples/create-react-app"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/angular-cli/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/examples/angular-cli/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | /.idea
13 | .project
14 | .classpath
15 | .c9/
16 | *.launch
17 | .settings/
18 | *.sublime-workspace
19 |
20 | # IDE - VSCode
21 | .vscode/*
22 | !.vscode/settings.json
23 | !.vscode/tasks.json
24 | !.vscode/launch.json
25 | !.vscode/extensions.json
26 |
27 | # misc
28 | /.sass-cache
29 | /connect.lock
30 | /coverage
31 | /libpeerconnection.log
32 | npm-debug.log
33 | testem.log
34 | /typings
35 |
36 | # e2e
37 | /e2e/*.js
38 | /e2e/*.map
39 |
40 | # System Files
41 | .DS_Store
42 | Thumbs.db
43 |
44 |
--------------------------------------------------------------------------------
/examples/angular-cli/README.md:
--------------------------------------------------------------------------------
1 | # Angular-CLI
2 |
3 | Example showing sticky states installed in an Angular-CLI app.
4 |
5 | ## Running
6 |
7 | ```
8 | npm install
9 | npm start
10 | ```
--------------------------------------------------------------------------------
/examples/angular-cli/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "angular-cli": {
7 | "root": "",
8 | "sourceRoot": "src",
9 | "projectType": "application",
10 | "architect": {
11 | "build": {
12 | "builder": "@angular-devkit/build-angular:browser",
13 | "options": {
14 | "outputPath": "dist",
15 | "index": "src/index.html",
16 | "main": "src/main.ts",
17 | "tsConfig": "src/tsconfig.app.json",
18 | "polyfills": "src/polyfills.ts",
19 | "assets": ["src/assets", "src/favicon.ico"],
20 | "styles": ["src/styles.css"],
21 | "scripts": []
22 | },
23 | "configurations": {
24 | "production": {
25 | "optimization": true,
26 | "outputHashing": "all",
27 | "sourceMap": false,
28 | "extractCss": true,
29 | "namedChunks": false,
30 | "aot": true,
31 | "extractLicenses": true,
32 | "vendorChunk": false,
33 | "buildOptimizer": true,
34 | "fileReplacements": [
35 | {
36 | "replace": "src/environments/environment.ts",
37 | "with": "src/environments/environment.prod.ts"
38 | }
39 | ]
40 | }
41 | }
42 | },
43 | "serve": {
44 | "builder": "@angular-devkit/build-angular:dev-server",
45 | "options": {
46 | "browserTarget": "angular-cli:build"
47 | },
48 | "configurations": {
49 | "production": {
50 | "browserTarget": "angular-cli:build:production"
51 | }
52 | }
53 | },
54 | "extract-i18n": {
55 | "builder": "@angular-devkit/build-angular:extract-i18n",
56 | "options": {
57 | "browserTarget": "angular-cli:build"
58 | }
59 | },
60 | "test": {
61 | "builder": "@angular-devkit/build-angular:karma",
62 | "options": {
63 | "main": "src/test.ts",
64 | "karmaConfig": "./karma.conf.js",
65 | "polyfills": "src/polyfills.ts",
66 | "tsConfig": "src/tsconfig.spec.json",
67 | "scripts": [],
68 | "styles": ["src/styles.css"],
69 | "assets": ["src/assets", "src/favicon.ico"]
70 | }
71 | },
72 | "lint": {
73 | "builder": "@angular-devkit/build-angular:tslint",
74 | "options": {
75 | "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
76 | "exclude": ["**/node_modules/**"]
77 | }
78 | }
79 | }
80 | },
81 | "angular-cli-e2e": {
82 | "root": "e2e",
83 | "sourceRoot": "e2e",
84 | "projectType": "application",
85 | "architect": {
86 | "e2e": {
87 | "builder": "@angular-devkit/build-angular:protractor",
88 | "options": {
89 | "protractorConfig": "./protractor.conf.js",
90 | "devServerTarget": "angular-cli:serve"
91 | }
92 | },
93 | "lint": {
94 | "builder": "@angular-devkit/build-angular:tslint",
95 | "options": {
96 | "tsConfig": ["e2e/tsconfig.e2e.json"],
97 | "exclude": ["**/node_modules/**"]
98 | }
99 | }
100 | }
101 | }
102 | },
103 | "defaultProject": "angular-cli",
104 | "schematics": {
105 | "@schematics/angular:component": {
106 | "prefix": "app",
107 | "styleext": "css"
108 | },
109 | "@schematics/angular:directive": {
110 | "prefix": "app"
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/examples/angular-cli/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:4000",
3 | "video": false
4 | }
5 |
--------------------------------------------------------------------------------
/examples/angular-cli/cypress/integration/example_spec.js:
--------------------------------------------------------------------------------
1 | describe('example app', () => {
2 | it('loads', () => {
3 | cy.visit('');
4 | });
5 |
6 | it('renders links', () => {
7 | cy.visit('/');
8 | cy.get('a').contains('about');
9 | cy.get('a').contains('continentlist');
10 | });
11 |
12 | it('renders about by default', () => {
13 | cy.visit('/');
14 | cy.contains('This is a trivial Deep State Redirect example app');
15 | });
16 |
17 | it('can navigate to continentlist', () => {
18 | cy.visit('');
19 | cy
20 | .get('a')
21 | .contains('continentlist')
22 | .click();
23 |
24 | cy.contains('Africa');
25 | cy.contains('America');
26 | cy.contains('Oceania');
27 | });
28 |
29 | it('can navigate to belize', () => {
30 | cy.visit('');
31 | cy
32 | .get('a')
33 | .contains('continentlist')
34 | .click();
35 | cy
36 | .get('a')
37 | .contains('America')
38 | .click();
39 | cy
40 | .get('a')
41 | .contains('Belize')
42 | .click();
43 | cy.get('h3').contains('Belize');
44 | });
45 |
46 | it('can navigate to belize and back', () => {
47 | cy.visit('');
48 | cy
49 | .get('a')
50 | .contains('continentlist')
51 | .click();
52 | cy
53 | .get('a')
54 | .contains('America')
55 | .click();
56 | cy.url().should('include', '/America');
57 |
58 | cy
59 | .get('a')
60 | .contains('Belize')
61 | .click();
62 | cy.get('h3').contains('Belize');
63 | cy.url().should('include', '/America/Belize');
64 |
65 | cy
66 | .get('a')
67 | .contains('about')
68 | .click();
69 | cy.contains('This is a trivial Deep State Redirect example app');
70 | });
71 |
72 | it('dsr sends you back to belize', () => {
73 | cy.visit('');
74 | cy
75 | .get('a')
76 | .contains('continentlist')
77 | .click();
78 | cy
79 | .get('a')
80 | .contains('America')
81 | .click();
82 | cy.url().should('include', '/America');
83 |
84 | cy
85 | .get('a')
86 | .contains('Belize')
87 | .click();
88 | cy.url().should('include', '/America/Belize');
89 | cy.get('h3').contains('Belize');
90 |
91 | cy
92 | .get('a')
93 | .contains('about')
94 | .click();
95 | cy.url().should('include', '/about');
96 | cy.contains('This is a trivial Deep State Redirect example app');
97 |
98 | cy
99 | .get('a')
100 | .contains('continentlist')
101 | .click();
102 | cy.url().should('include', '/America/Belize');
103 | cy.get('h3').contains('Belize');
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/examples/angular-cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-cli",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "build": "ng build --prod",
9 | "test": "npm run build && cypress-runner run --path dist",
10 | "test:open": "npm run build && cypress-runner open --path dist",
11 | "lint": "ng lint",
12 | "e2e": "ng e2e"
13 | },
14 | "private": true,
15 | "dependencies": {
16 | "@angular/animations": "^7.2.0",
17 | "@angular/common": "^7.2.0",
18 | "@angular/compiler": "^7.2.0",
19 | "@angular/core": "^7.2.0",
20 | "@angular/forms": "^7.2.0",
21 | "@angular/http": "^7.2.0",
22 | "@angular/platform-browser": "^7.2.0",
23 | "@angular/platform-browser-dynamic": "^7.2.0",
24 | "@angular/router": "^7.2.0",
25 | "@uirouter/angular": "^4.0.0",
26 | "@uirouter/dsr": "^1.0.2",
27 | "@uirouter/visualizer": "^6.0.0",
28 | "core-js": "^2.4.1",
29 | "rxjs": "^6.3.3",
30 | "tslib": "^1.9.0",
31 | "zone.js": "^0.8.14",
32 | "rxjs-compat": "^6.0.0-rc.0"
33 | },
34 | "devDependencies": {
35 | "@angular-devkit/build-angular": "~0.12.0",
36 | "@angular/cli": "^7.2.1",
37 | "@angular/compiler-cli": "^7.2.0",
38 | "@angular/language-service": "^7.2.0",
39 | "@types/jasmine": "~2.8.6",
40 | "@types/jasminewd2": "~2.0.2",
41 | "@types/node": "~9.6.1",
42 | "@uirouter/cypress-runner": "^1.0.2",
43 | "codelyzer": "^4.0.1",
44 | "jasmine-core": "~3.1.0",
45 | "jasmine-spec-reporter": "~4.2.1",
46 | "karma": "~2.0.0",
47 | "karma-chrome-launcher": "~2.2.0",
48 | "karma-cli": "~1.0.1",
49 | "karma-coverage-istanbul-reporter": "^1.2.1",
50 | "karma-jasmine": "~1.1.0",
51 | "karma-jasmine-html-reporter": "^1.0.0",
52 | "protractor": "~5.3.0",
53 | "ts-node": "~5.0.1",
54 | "tslint": "~5.9.1",
55 | "typescript": "~3.2.2"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/about.component.ts:
--------------------------------------------------------------------------------
1 | import { Input, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'generic-cmp',
5 | template: `
6 |
This is a trivial Deep State Redirect example app
7 |
8 | Active the continentlist state
9 | Select a continent
10 | Select a country
11 | Reactivate this state (about )
12 |
13 | Active the continents state again.
14 | You are redirected to the previously active substate of continentlist
(including parameters).
15 | You should see the country you chose in the previous step.
16 |
17 |
18 | `,
19 | })
20 | export class AboutComponent {
21 | }
22 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { StateService } from '@uirouter/core';
3 |
4 | @Component({
5 | selector: 'app-root',
6 | template: `
7 | about
8 | continentlist
9 |
10 |
11 | `,
12 | styles: [`
13 | .active { font-weight: bold }
14 | `]
15 | })
16 | export class AppComponent {
17 | constructor(public $state: StateService) {
18 |
19 | }
20 | isActive(stateName: string) {
21 | return this.$state.includes(stateName)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { FormsModule } from '@angular/forms';
4 |
5 | import { UIRouterModule } from '@uirouter/angular';
6 | import { UIRouter } from '@uirouter/core';
7 | import { DSRPlugin } from '@uirouter/dsr';
8 | import { Visualizer } from '@uirouter/visualizer';
9 |
10 | import { AppComponent } from './app.component';
11 | import { CountryDetailComponent } from './countryDetail.component';
12 | import { CountryListComponent } from './countryList.component';
13 | import { getContinents, getCountries } from './data.api';
14 | import { ContinentListComponent } from './continentList.component';
15 | import { AboutComponent } from './about.component';
16 |
17 | export const states = [
18 | {
19 | name: 'continentlist',
20 | url: '/continents',
21 | dsr: true,
22 | component: ContinentListComponent,
23 | resolve: {
24 | 'continents': () => getContinents() },
25 | },
26 |
27 | {
28 | name: 'continentlist.countrylist',
29 | url: '/:continent',
30 | component: CountryListComponent,
31 | resolve: {
32 | 'countries': ['$transition$', ($transition$) => getCountries($transition$.params().continent)],
33 | },
34 | },
35 |
36 | {
37 | name: 'continentlist.countrylist.countrydetail',
38 | url: '/:country',
39 | component: CountryDetailComponent,
40 | resolve: {
41 | 'country': ['$transition$', ($transition$) => $transition$.params().country],
42 | },
43 | },
44 |
45 | {
46 | name: 'about',
47 | url: '/about',
48 | component: AboutComponent,
49 | }
50 | ];
51 |
52 | export function configFn(router: UIRouter) {
53 | states.forEach(state => router.stateRegistry.register(state));
54 | router.urlService.rules.initial({ state: 'about' });
55 | router.plugin(DSRPlugin);
56 | router.plugin(Visualizer);
57 | }
58 |
59 | @NgModule({
60 | declarations: [
61 | AboutComponent,
62 | AppComponent,
63 | ContinentListComponent,
64 | CountryDetailComponent,
65 | CountryListComponent,
66 | ],
67 | entryComponents: [
68 | AboutComponent,
69 | AppComponent,
70 | ContinentListComponent,
71 | CountryDetailComponent,
72 | CountryListComponent,
73 | ],
74 | imports: [
75 | BrowserModule,
76 | FormsModule,
77 | UIRouterModule.forRoot({
78 | config: configFn,
79 | })
80 | ],
81 | bootstrap: [AppComponent]
82 | })
83 | export class AppModule { }
84 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/continentList.component.ts:
--------------------------------------------------------------------------------
1 | import { Input, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'continent-list-cmp',
5 | template: `
6 | Continents
7 |
8 |
9 | {{ continent }}
10 |
11 |
12 |
13 | `,
14 | })
15 | export class ContinentListComponent {
16 | @Input() continents: string[];
17 | }
18 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/countryDetail.component.ts:
--------------------------------------------------------------------------------
1 | import { Input, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'country-detail-cmp',
5 | template: `
6 | {{ country }}
7 |
8 |
9 |
10 | `,
11 | })
12 | export class CountryDetailComponent {
13 | @Input() country: string;
14 |
15 | imageSrc() {
16 | if (!this.country) { return ''; }
17 | const prefix = 'http://www.randomlists.com/img/national-flags/';
18 | const imageName = this.country.toLowerCase().replace(/ /g, '_');
19 | return `${prefix}${imageName}.gif`;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/countryList.component.ts:
--------------------------------------------------------------------------------
1 | import { Input, Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'country-list-cmp',
5 | template: `
6 |
7 |
8 |
17 |
18 | `,
19 | styles: [`
20 | .container {
21 | display: flex;
22 | flex-flow: row wrap;
23 | }
24 | .container > * {
25 | border: 1px solid;
26 | padding: 0.5em;
27 | margin: 0.5em;
28 | flex: 1 1 75px;
29 | }
30 | .container > a.active {
31 | background: lightgray;
32 | }
33 | `]
34 | })
35 | export class CountryListComponent {
36 | @Input() countries: string[];
37 | }
38 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/data.api.ts:
--------------------------------------------------------------------------------
1 | declare var require;
2 |
3 | function getContinents(): Promise {
4 | return Promise.resolve(require('./data.json'))
5 | .then(countries => countries.map(country => country.continent))
6 | .then(continents => continents.reduce((acc, continent) => acc.includes(continent) ? acc : acc.concat(continent), []))
7 | }
8 |
9 | function getCountries(continent: string): Promise {
10 | return Promise.resolve(require('./data.json'))
11 | .then(countries => countries.filter(country => country.continent === continent))
12 | .then(countries => countries.map(country => country.name));
13 | }
14 |
15 | export { getContinents, getCountries };
16 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/app/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Afghanistan",
4 | "continent": "Asia"
5 | },
6 | {
7 | "name": "Albania",
8 | "continent": "Europe"
9 | },
10 | {
11 | "name": "Algeria",
12 | "continent": "Africa"
13 | },
14 | {
15 | "name": "Andorra",
16 | "continent": "Europe"
17 | },
18 | {
19 | "name": "Angola",
20 | "continent": "Africa"
21 | },
22 | {
23 | "name": "Antigua and Barbuda",
24 | "continent": "America"
25 | },
26 | {
27 | "name": "Argentina",
28 | "continent": "America"
29 | },
30 | {
31 | "name": "Armenia",
32 | "continent": "Asia"
33 | },
34 | {
35 | "name": "Australia",
36 | "continent": "Oceania"
37 | },
38 | {
39 | "name": "Austria",
40 | "continent": "Europe"
41 | },
42 | {
43 | "name": "Azerbaijan",
44 | "continent": "Asia"
45 | },
46 | {
47 | "name": "Bahamas",
48 | "continent": "America"
49 | },
50 | {
51 | "name": "Bahrain",
52 | "continent": "Asia"
53 | },
54 | {
55 | "name": "Bangladesh",
56 | "continent": "Asia"
57 | },
58 | {
59 | "name": "Barbados",
60 | "continent": "America"
61 | },
62 | {
63 | "name": "Belarus",
64 | "continent": "Europe"
65 | },
66 | {
67 | "name": "Belgium",
68 | "continent": "Europe"
69 | },
70 | {
71 | "name": "Belize",
72 | "continent": "America"
73 | },
74 | {
75 | "name": "Benin",
76 | "continent": "Africa"
77 | },
78 | {
79 | "name": "Bhutan",
80 | "continent": "Asia"
81 | },
82 | {
83 | "name": "Bolivia",
84 | "continent": "America"
85 | },
86 | {
87 | "name": "Bosnia and Herzegovina",
88 | "continent": "Europe"
89 | },
90 | {
91 | "name": "Botswana",
92 | "continent": "Africa"
93 | },
94 | {
95 | "name": "Brazil",
96 | "continent": "America"
97 | },
98 | {
99 | "name": "Brunei",
100 | "continent": "Asia"
101 | },
102 | {
103 | "name": "Bulgaria",
104 | "continent": "Europe"
105 | },
106 | {
107 | "name": "Burkina Faso",
108 | "continent": "Africa"
109 | },
110 | {
111 | "name": "Myanmar",
112 | "continent": "Asia"
113 | },
114 | {
115 | "name": "Burundi",
116 | "continent": "Africa"
117 | },
118 | {
119 | "name": "Cambodia",
120 | "continent": "Asia"
121 | },
122 | {
123 | "name": "Cameroon",
124 | "continent": "Africa"
125 | },
126 | {
127 | "name": "Canada",
128 | "continent": "America"
129 | },
130 | {
131 | "name": "Cape Verde",
132 | "continent": "Africa"
133 | },
134 | {
135 | "name": "Central African Republic",
136 | "continent": "Africa"
137 | },
138 | {
139 | "name": "Chad",
140 | "continent": "Africa"
141 | },
142 | {
143 | "name": "Chile",
144 | "continent": "America"
145 | },
146 | {
147 | "name": "China",
148 | "continent": "Asia"
149 | },
150 | {
151 | "name": "Colombia",
152 | "continent": "America"
153 | },
154 | {
155 | "name": "Comoros",
156 | "continent": "Africa"
157 | },
158 | {
159 | "name": "Congo",
160 | "continent": "Africa"
161 | },
162 | {
163 | "name": "Costa Rica",
164 | "continent": "America"
165 | },
166 | {
167 | "name": "Croatia",
168 | "continent": "Europe"
169 | },
170 | {
171 | "name": "Cuba",
172 | "continent": "America"
173 | },
174 | {
175 | "name": "Cyprus",
176 | "continent": "Europe"
177 | },
178 | {
179 | "name": "Czech Republic",
180 | "continent": "Europe"
181 | },
182 | {
183 | "name": "Denmark",
184 | "continent": "Europe"
185 | },
186 | {
187 | "name": "Djibouti",
188 | "continent": "Africa"
189 | },
190 | {
191 | "name": "Dominica",
192 | "continent": "America"
193 | },
194 | {
195 | "name": "Dominican Republic",
196 | "continent": "America"
197 | },
198 | {
199 | "name": "East Timor",
200 | "continent": "Asia"
201 | },
202 | {
203 | "name": "Ecuador",
204 | "continent": "America"
205 | },
206 | {
207 | "name": "Egypt",
208 | "continent": "Africa"
209 | },
210 | {
211 | "name": "El Salvador",
212 | "continent": "America"
213 | },
214 | {
215 | "name": "England",
216 | "continent": "Europe"
217 | },
218 | {
219 | "name": "Equatorial Guinea",
220 | "continent": "Africa"
221 | },
222 | {
223 | "name": "Eritrea",
224 | "continent": "Africa"
225 | },
226 | {
227 | "name": "Estonia",
228 | "continent": "Europe"
229 | },
230 | {
231 | "name": "Ethiopia",
232 | "continent": "Africa"
233 | },
234 | {
235 | "name": "Fiji",
236 | "continent": "Oceania"
237 | },
238 | {
239 | "name": "Finland",
240 | "continent": "Europe"
241 | },
242 | {
243 | "name": "France",
244 | "continent": "Europe"
245 | },
246 | {
247 | "name": "Gabon",
248 | "continent": "Africa"
249 | },
250 | {
251 | "name": "Gambia",
252 | "continent": "Africa"
253 | },
254 | {
255 | "name": "Georgia",
256 | "continent": "Asia"
257 | },
258 | {
259 | "name": "Germany",
260 | "continent": "Europe"
261 | },
262 | {
263 | "name": "Ghana",
264 | "continent": "Africa"
265 | },
266 | {
267 | "name": "Greece",
268 | "continent": "Europe"
269 | },
270 | {
271 | "name": "Grenada",
272 | "continent": "America"
273 | },
274 | {
275 | "name": "Guatemala",
276 | "continent": "America"
277 | },
278 | {
279 | "name": "Guinea",
280 | "continent": "Africa"
281 | },
282 | {
283 | "name": "Guinea-Bissau",
284 | "continent": "Africa"
285 | },
286 | {
287 | "name": "Guyana",
288 | "continent": "America"
289 | },
290 | {
291 | "name": "Haiti",
292 | "continent": "America"
293 | },
294 | {
295 | "name": "Honduras",
296 | "continent": "America"
297 | },
298 | {
299 | "name": "Hong Kong",
300 | "continent": "Asia"
301 | },
302 | {
303 | "name": "Hungary",
304 | "continent": "Europe"
305 | },
306 | {
307 | "name": "Iceland",
308 | "continent": "Europe"
309 | },
310 | {
311 | "name": "India",
312 | "continent": "Asia"
313 | },
314 | {
315 | "name": "Indonesia",
316 | "continent": "Asia"
317 | },
318 | {
319 | "name": "Iran",
320 | "continent": "Asia"
321 | },
322 | {
323 | "name": "Iraq",
324 | "continent": "Asia"
325 | },
326 | {
327 | "name": "Ireland",
328 | "continent": "Europe"
329 | },
330 | {
331 | "name": "Isle of Man",
332 | "continent": "Europe"
333 | },
334 | {
335 | "name": "Israel",
336 | "continent": "Asia"
337 | },
338 | {
339 | "name": "Italy",
340 | "continent": "Europe"
341 | },
342 | {
343 | "name": "Jamaica",
344 | "continent": "America"
345 | },
346 | {
347 | "name": "Japan",
348 | "continent": "Asia"
349 | },
350 | {
351 | "name": "Jordan",
352 | "continent": "Asia"
353 | },
354 | {
355 | "name": "Kazakhstan",
356 | "continent": "Asia"
357 | },
358 | {
359 | "name": "Kenya",
360 | "continent": "Africa"
361 | },
362 | {
363 | "name": "Kiribati",
364 | "continent": "Oceania"
365 | },
366 | {
367 | "name": "North Korea",
368 | "continent": "Asia"
369 | },
370 | {
371 | "name": "South Korea",
372 | "continent": "Asia"
373 | },
374 | {
375 | "name": "Kosovo",
376 | "continent": "Europe"
377 | },
378 | {
379 | "name": "Kuwait",
380 | "continent": "Asia"
381 | },
382 | {
383 | "name": "Kyrgyzstan",
384 | "continent": "Asia"
385 | },
386 | {
387 | "name": "Laos",
388 | "continent": "Asia"
389 | },
390 | {
391 | "name": "Latvia",
392 | "continent": "Europe"
393 | },
394 | {
395 | "name": "Lebanon",
396 | "continent": "Asia"
397 | },
398 | {
399 | "name": "Lesotho",
400 | "continent": "Africa"
401 | },
402 | {
403 | "name": "Liberia",
404 | "continent": "Africa"
405 | },
406 | {
407 | "name": "Libya",
408 | "continent": "Africa"
409 | },
410 | {
411 | "name": "Liechtenstein",
412 | "continent": "Europe"
413 | },
414 | {
415 | "name": "Lithuania",
416 | "continent": "Europe"
417 | },
418 | {
419 | "name": "Luxembourg",
420 | "continent": "Europe"
421 | },
422 | {
423 | "name": "Macau",
424 | "continent": "Asia"
425 | },
426 | {
427 | "name": "Macedonia",
428 | "continent": "Europe"
429 | },
430 | {
431 | "name": "Madagascar",
432 | "continent": "Africa"
433 | },
434 | {
435 | "name": "Malawi",
436 | "continent": "Africa"
437 | },
438 | {
439 | "name": "Malaysia",
440 | "continent": "Asia"
441 | },
442 | {
443 | "name": "Maldives",
444 | "continent": "Asia"
445 | },
446 | {
447 | "name": "Mali",
448 | "continent": "Africa"
449 | },
450 | {
451 | "name": "Malta",
452 | "continent": "Europe"
453 | },
454 | {
455 | "name": "Marshall Islands",
456 | "continent": "Oceania"
457 | },
458 | {
459 | "name": "Mauritania",
460 | "continent": "Africa"
461 | },
462 | {
463 | "name": "Mauritius",
464 | "continent": "Africa"
465 | },
466 | {
467 | "name": "Mexico",
468 | "continent": "America"
469 | },
470 | {
471 | "name": "Micronesia",
472 | "continent": "Oceania"
473 | },
474 | {
475 | "name": "Moldova",
476 | "continent": "Europe"
477 | },
478 | {
479 | "name": "Monaco",
480 | "continent": "Europe"
481 | },
482 | {
483 | "name": "Mongolia",
484 | "continent": "Asia"
485 | },
486 | {
487 | "name": "Montenegro",
488 | "continent": "Europe"
489 | },
490 | {
491 | "name": "Morocco",
492 | "continent": "Africa"
493 | },
494 | {
495 | "name": "Mozambique",
496 | "continent": "Africa"
497 | },
498 | {
499 | "name": "Namibia",
500 | "continent": "Africa"
501 | },
502 | {
503 | "name": "Nauru",
504 | "continent": "Oceania"
505 | },
506 | {
507 | "name": "Nepal",
508 | "continent": "Asia"
509 | },
510 | {
511 | "name": "Netherlands",
512 | "continent": "Europe"
513 | },
514 | {
515 | "name": "New Zealand",
516 | "continent": "Oceania"
517 | },
518 | {
519 | "name": "Nicaragua",
520 | "continent": "America"
521 | },
522 | {
523 | "name": "Niger",
524 | "continent": "Africa"
525 | },
526 | {
527 | "name": "Nigeria",
528 | "continent": "Africa"
529 | },
530 | {
531 | "name": "Norway",
532 | "continent": "Europe"
533 | },
534 | {
535 | "name": "Oman",
536 | "continent": "Asia"
537 | },
538 | {
539 | "name": "Pakistan",
540 | "continent": "Asia"
541 | },
542 | {
543 | "name": "Palau",
544 | "continent": "Oceania"
545 | },
546 | {
547 | "name": "Panama",
548 | "continent": "America"
549 | },
550 | {
551 | "name": "Papua New Guinea",
552 | "continent": "Oceania"
553 | },
554 | {
555 | "name": "Paraguay",
556 | "continent": "America"
557 | },
558 | {
559 | "name": "Peru",
560 | "continent": "America"
561 | },
562 | {
563 | "name": "Philippines",
564 | "continent": "Asia"
565 | },
566 | {
567 | "name": "Poland",
568 | "continent": "Europe"
569 | },
570 | {
571 | "name": "Portugal",
572 | "continent": "Europe"
573 | },
574 | {
575 | "name": "Puerto Rico",
576 | "continent": "America"
577 | },
578 | {
579 | "name": "Qatar",
580 | "continent": "Asia"
581 | },
582 | {
583 | "name": "Romania",
584 | "continent": "Europe"
585 | },
586 | {
587 | "name": "Russia",
588 | "continent": "Europe"
589 | },
590 | {
591 | "name": "Rwanda",
592 | "continent": "Africa"
593 | },
594 | {
595 | "name": "Saint Kitts and Nevis",
596 | "continent": "America"
597 | },
598 | {
599 | "name": "Saint Lucia",
600 | "continent": "America"
601 | },
602 | {
603 | "name": "Saint Vincent and the Grenadines",
604 | "continent": "America"
605 | },
606 | {
607 | "name": "Samoa",
608 | "continent": "Oceania"
609 | },
610 | {
611 | "name": "San Marino",
612 | "continent": "Europe"
613 | },
614 | {
615 | "name": "Saudi Arabia",
616 | "continent": "Asia"
617 | },
618 | {
619 | "name": "Scotland",
620 | "continent": "Europe"
621 | },
622 | {
623 | "name": "Senegal",
624 | "continent": "Africa"
625 | },
626 | {
627 | "name": "Serbia",
628 | "continent": "Europe"
629 | },
630 | {
631 | "name": "Seychelles",
632 | "continent": "Africa"
633 | },
634 | {
635 | "name": "Sierra Leone",
636 | "continent": "Africa"
637 | },
638 | {
639 | "name": "Singapore",
640 | "continent": "Asia"
641 | },
642 | {
643 | "name": "Slovakia",
644 | "continent": "Europe"
645 | },
646 | {
647 | "name": "Slovenia",
648 | "continent": "Europe"
649 | },
650 | {
651 | "name": "Solomon Islands",
652 | "continent": "Oceania"
653 | },
654 | {
655 | "name": "Somalia",
656 | "continent": "Africa"
657 | },
658 | {
659 | "name": "South Africa",
660 | "continent": "Africa"
661 | },
662 | {
663 | "name": "Spain",
664 | "continent": "Europe"
665 | },
666 | {
667 | "name": "Sri Lanka",
668 | "continent": "Asia"
669 | },
670 | {
671 | "name": "Sudan",
672 | "continent": "Africa"
673 | },
674 | {
675 | "name": "Suriname",
676 | "continent": "America"
677 | },
678 | {
679 | "name": "Swaziland",
680 | "continent": "Africa"
681 | },
682 | {
683 | "name": "Sweden",
684 | "continent": "Europe"
685 | },
686 | {
687 | "name": "Switzerland",
688 | "continent": "Europe"
689 | },
690 | {
691 | "name": "Syria",
692 | "continent": "Asia"
693 | },
694 | {
695 | "name": "Taiwan",
696 | "continent": "Asia"
697 | },
698 | {
699 | "name": "Tajikistan",
700 | "continent": "Asia"
701 | },
702 | {
703 | "name": "Tanzania",
704 | "continent": "Africa"
705 | },
706 | {
707 | "name": "Thailand",
708 | "continent": "Asia"
709 | },
710 | {
711 | "name": "Togo",
712 | "continent": "Africa"
713 | },
714 | {
715 | "name": "Tonga",
716 | "continent": "Oceania"
717 | },
718 | {
719 | "name": "Trinidad and Tobago",
720 | "continent": "America"
721 | },
722 | {
723 | "name": "Tunisia",
724 | "continent": "Africa"
725 | },
726 | {
727 | "name": "Turkey",
728 | "continent": "Asia"
729 | },
730 | {
731 | "name": "Turkmenistan",
732 | "continent": "Asia"
733 | },
734 | {
735 | "name": "Tuvalu",
736 | "continent": "Oceania"
737 | },
738 | {
739 | "name": "Uganda",
740 | "continent": "Africa"
741 | },
742 | {
743 | "name": "Ukraine",
744 | "continent": "Europe"
745 | },
746 | {
747 | "name": "United Arab Emirates",
748 | "continent": "Asia"
749 | },
750 | {
751 | "name": "United Kingdom",
752 | "continent": "Europe"
753 | },
754 | {
755 | "name": "United States of America",
756 | "continent": "America"
757 | },
758 | {
759 | "name": "Uruguay",
760 | "continent": "America"
761 | },
762 | {
763 | "name": "USSR",
764 | "continent": "Europe"
765 | },
766 | {
767 | "name": "Uzbekistan",
768 | "continent": "Asia"
769 | },
770 | {
771 | "name": "Vanuatu",
772 | "continent": "Oceania"
773 | },
774 | {
775 | "name": "Vatican City",
776 | "continent": "Europe"
777 | },
778 | {
779 | "name": "Venezuela",
780 | "continent": "America"
781 | },
782 | {
783 | "name": "Vietnam",
784 | "continent": "Asia"
785 | },
786 | {
787 | "name": "Wales",
788 | "continent": "Europe"
789 | },
790 | {
791 | "name": "Yemen",
792 | "continent": "Asia"
793 | },
794 | {
795 | "name": "Zambia",
796 | "continent": "Africa"
797 | },
798 | {
799 | "name": "Zimbabwe",
800 | "continent": "Africa"
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ui-router/dsr/faf4ac097655375f2d1804ef706b3836b73597d3/examples/angular-cli/src/favicon.ico
--------------------------------------------------------------------------------
/examples/angular-cli/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AngularCli
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following for the Reflect API. */
41 | // import 'core-js/es6/reflect';
42 |
43 | /** Evergreen browsers require these. **/
44 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
45 |
46 | /**
47 | * Required to support Web Animations `@angular/platform-browser/animations`.
48 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
49 | **/
50 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
51 |
52 | /***************************************************************************************************
53 | * Zone JS is required by default for Angular itself.
54 | */
55 | import 'zone.js/dist/zone'; // Included with Angular CLI.
56 |
57 | /***************************************************************************************************
58 | * APPLICATION IMPORTS
59 | */
60 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
3 | .active {
4 | font-weight: bold;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare const __karma__: any;
17 | declare const require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | const context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "es2015",
7 | "types": []
8 | },
9 | "exclude": [
10 | "test.ts",
11 | "**/*.spec.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["jasmine", "node"]
9 | },
10 | "files": ["test.ts", "polyfills.ts"],
11 | "include": ["**/*.spec.ts", "**/*.d.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/examples/angular-cli/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/angular-cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "importHelpers": true,
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "moduleResolution": "node",
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "target": "es5",
12 | "typeRoots": ["node_modules/@types"],
13 | "lib": ["es2017", "dom"],
14 | "module": "es2015",
15 | "baseUrl": "./"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/angular-cli/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": ["node_modules/codelyzer"],
3 | "rules": {
4 | "arrow-return-shorthand": true,
5 | "callable-types": true,
6 | "class-name": true,
7 | "comment-format": [true, "check-space"],
8 | "curly": true,
9 | "deprecation": {
10 | "severity": "warn"
11 | },
12 | "eofline": true,
13 | "forin": true,
14 | "import-blacklist": [true, "rxjs/Rx"],
15 | "import-spacing": true,
16 | "indent": [true, "spaces"],
17 | "interface-over-type-literal": true,
18 | "label-position": true,
19 | "max-line-length": [true, 140],
20 | "member-access": false,
21 | "member-ordering": [
22 | true,
23 | {
24 | "order": ["static-field", "instance-field", "static-method", "instance-method"]
25 | }
26 | ],
27 | "no-arg": true,
28 | "no-bitwise": true,
29 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
30 | "no-construct": true,
31 | "no-debugger": true,
32 | "no-duplicate-super": true,
33 | "no-empty": false,
34 | "no-empty-interface": true,
35 | "no-eval": true,
36 | "no-inferrable-types": [true, "ignore-params"],
37 | "no-misused-new": true,
38 | "no-non-null-assertion": true,
39 | "no-shadowed-variable": true,
40 | "no-string-literal": false,
41 | "no-string-throw": true,
42 | "no-switch-case-fall-through": true,
43 | "no-trailing-whitespace": true,
44 | "no-unnecessary-initializer": true,
45 | "no-unused-expression": true,
46 | "no-use-before-declare": true,
47 | "no-var-keyword": true,
48 | "object-literal-sort-keys": false,
49 | "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
50 | "prefer-const": true,
51 | "quotemark": [true, "single"],
52 | "radix": true,
53 | "semicolon": [true, "always"],
54 | "triple-equals": [true, "allow-null-check"],
55 | "typedef-whitespace": [
56 | true,
57 | {
58 | "call-signature": "nospace",
59 | "index-signature": "nospace",
60 | "parameter": "nospace",
61 | "property-declaration": "nospace",
62 | "variable-declaration": "nospace"
63 | }
64 | ],
65 | "typeof-compare": true,
66 | "unified-signatures": true,
67 | "variable-name": false,
68 | "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
69 | "directive-selector": [true, "attribute", "app", "camelCase"],
70 | "component-selector": [true, "element", "app", "kebab-case"],
71 | "no-output-on-prefix": true,
72 | "use-input-property-decorator": true,
73 | "use-output-property-decorator": true,
74 | "use-host-property-decorator": true,
75 | "no-input-rename": true,
76 | "no-output-rename": true,
77 | "use-life-cycle-interface": true,
78 | "use-pipe-transform-interface": true,
79 | "component-class-suffix": true,
80 | "directive-class-suffix": true
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/README.md:
--------------------------------------------------------------------------------
1 | # bower + script tags
2 |
3 | Example showing sticky states installed via hybrid npm and bower packages.
4 | Scripts are added using script tags in index.html.
5 |
6 | ## Running
7 |
8 | ```
9 | npm install
10 | npm start
11 | ```
12 |
13 | ## Info
14 |
15 | This example uses `angular` and `angular-ui-router` from bower.
16 | Because sticky states and visualizer are not published to bower, they are added to the `package.json` instead.
17 |
18 | Sticky states requires a reference to ui-router core.
19 | We're using the monolithic `angular-ui-router.js` bundle (which also bundles ui-router core).
20 | To expose ui-router core, we add a shim via a script tag:
21 |
22 | ```
23 |
24 |
25 |
29 |
30 |
31 |
32 | ```
33 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/about.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('about', {
2 | template: `
3 | This is a trivial Deep State Redirect example app
4 |
5 | Active the continentlist state
6 | Select a continent
7 | Select a country
8 | Reactivate this state (about )
9 |
10 | Active the continents state again.
11 | You are redirected to the previously active substate of continentlist
(including parameters).
12 | You should see the country you chose in the previous step.
13 |
14 |
15 | `,
16 | });
17 |
18 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/continentList.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('continentList', {
2 | template: `
3 | Continents
4 |
5 |
6 | {{ continent }}
7 |
8 |
9 |
10 | `,
11 | bindings: {
12 | continents: '<',
13 | },
14 | });
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/countryDetail.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('countryDetail', {
2 | template: `
3 | {{ $ctrl.country }}
4 |
5 |
6 |
7 | `,
8 | controller: function () {
9 | this.imageSrc = function() {
10 | if (!this.country) { return ''; }
11 | const prefix = 'http://www.randomlists.com/img/national-flags/';
12 | const imageName = this.country.toLowerCase().replace(/ /g, '_');
13 | return `${prefix}${imageName}.gif`;
14 | };
15 | },
16 | bindings: {
17 | country: '<',
18 | },
19 | });
20 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/countryList.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('countryList', {
2 | template: `
3 |
4 |
5 |
13 | `,
14 | bindings: {
15 | countries: '<',
16 | },
17 | });
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Afghanistan",
4 | "continent": "Asia"
5 | },
6 | {
7 | "name": "Albania",
8 | "continent": "Europe"
9 | },
10 | {
11 | "name": "Algeria",
12 | "continent": "Africa"
13 | },
14 | {
15 | "name": "Andorra",
16 | "continent": "Europe"
17 | },
18 | {
19 | "name": "Angola",
20 | "continent": "Africa"
21 | },
22 | {
23 | "name": "Antigua and Barbuda",
24 | "continent": "America"
25 | },
26 | {
27 | "name": "Argentina",
28 | "continent": "America"
29 | },
30 | {
31 | "name": "Armenia",
32 | "continent": "Asia"
33 | },
34 | {
35 | "name": "Australia",
36 | "continent": "Oceania"
37 | },
38 | {
39 | "name": "Austria",
40 | "continent": "Europe"
41 | },
42 | {
43 | "name": "Azerbaijan",
44 | "continent": "Asia"
45 | },
46 | {
47 | "name": "Bahamas",
48 | "continent": "America"
49 | },
50 | {
51 | "name": "Bahrain",
52 | "continent": "Asia"
53 | },
54 | {
55 | "name": "Bangladesh",
56 | "continent": "Asia"
57 | },
58 | {
59 | "name": "Barbados",
60 | "continent": "America"
61 | },
62 | {
63 | "name": "Belarus",
64 | "continent": "Europe"
65 | },
66 | {
67 | "name": "Belgium",
68 | "continent": "Europe"
69 | },
70 | {
71 | "name": "Belize",
72 | "continent": "America"
73 | },
74 | {
75 | "name": "Benin",
76 | "continent": "Africa"
77 | },
78 | {
79 | "name": "Bhutan",
80 | "continent": "Asia"
81 | },
82 | {
83 | "name": "Bolivia",
84 | "continent": "America"
85 | },
86 | {
87 | "name": "Bosnia and Herzegovina",
88 | "continent": "Europe"
89 | },
90 | {
91 | "name": "Botswana",
92 | "continent": "Africa"
93 | },
94 | {
95 | "name": "Brazil",
96 | "continent": "America"
97 | },
98 | {
99 | "name": "Brunei",
100 | "continent": "Asia"
101 | },
102 | {
103 | "name": "Bulgaria",
104 | "continent": "Europe"
105 | },
106 | {
107 | "name": "Burkina Faso",
108 | "continent": "Africa"
109 | },
110 | {
111 | "name": "Myanmar",
112 | "continent": "Asia"
113 | },
114 | {
115 | "name": "Burundi",
116 | "continent": "Africa"
117 | },
118 | {
119 | "name": "Cambodia",
120 | "continent": "Asia"
121 | },
122 | {
123 | "name": "Cameroon",
124 | "continent": "Africa"
125 | },
126 | {
127 | "name": "Canada",
128 | "continent": "America"
129 | },
130 | {
131 | "name": "Cape Verde",
132 | "continent": "Africa"
133 | },
134 | {
135 | "name": "Central African Republic",
136 | "continent": "Africa"
137 | },
138 | {
139 | "name": "Chad",
140 | "continent": "Africa"
141 | },
142 | {
143 | "name": "Chile",
144 | "continent": "America"
145 | },
146 | {
147 | "name": "China",
148 | "continent": "Asia"
149 | },
150 | {
151 | "name": "Colombia",
152 | "continent": "America"
153 | },
154 | {
155 | "name": "Comoros",
156 | "continent": "Africa"
157 | },
158 | {
159 | "name": "Congo",
160 | "continent": "Africa"
161 | },
162 | {
163 | "name": "Costa Rica",
164 | "continent": "America"
165 | },
166 | {
167 | "name": "Croatia",
168 | "continent": "Europe"
169 | },
170 | {
171 | "name": "Cuba",
172 | "continent": "America"
173 | },
174 | {
175 | "name": "Cyprus",
176 | "continent": "Europe"
177 | },
178 | {
179 | "name": "Czech Republic",
180 | "continent": "Europe"
181 | },
182 | {
183 | "name": "Denmark",
184 | "continent": "Europe"
185 | },
186 | {
187 | "name": "Djibouti",
188 | "continent": "Africa"
189 | },
190 | {
191 | "name": "Dominica",
192 | "continent": "America"
193 | },
194 | {
195 | "name": "Dominican Republic",
196 | "continent": "America"
197 | },
198 | {
199 | "name": "East Timor",
200 | "continent": "Asia"
201 | },
202 | {
203 | "name": "Ecuador",
204 | "continent": "America"
205 | },
206 | {
207 | "name": "Egypt",
208 | "continent": "Africa"
209 | },
210 | {
211 | "name": "El Salvador",
212 | "continent": "America"
213 | },
214 | {
215 | "name": "England",
216 | "continent": "Europe"
217 | },
218 | {
219 | "name": "Equatorial Guinea",
220 | "continent": "Africa"
221 | },
222 | {
223 | "name": "Eritrea",
224 | "continent": "Africa"
225 | },
226 | {
227 | "name": "Estonia",
228 | "continent": "Europe"
229 | },
230 | {
231 | "name": "Ethiopia",
232 | "continent": "Africa"
233 | },
234 | {
235 | "name": "Fiji",
236 | "continent": "Oceania"
237 | },
238 | {
239 | "name": "Finland",
240 | "continent": "Europe"
241 | },
242 | {
243 | "name": "France",
244 | "continent": "Europe"
245 | },
246 | {
247 | "name": "Gabon",
248 | "continent": "Africa"
249 | },
250 | {
251 | "name": "Gambia",
252 | "continent": "Africa"
253 | },
254 | {
255 | "name": "Georgia",
256 | "continent": "Asia"
257 | },
258 | {
259 | "name": "Germany",
260 | "continent": "Europe"
261 | },
262 | {
263 | "name": "Ghana",
264 | "continent": "Africa"
265 | },
266 | {
267 | "name": "Greece",
268 | "continent": "Europe"
269 | },
270 | {
271 | "name": "Grenada",
272 | "continent": "America"
273 | },
274 | {
275 | "name": "Guatemala",
276 | "continent": "America"
277 | },
278 | {
279 | "name": "Guinea",
280 | "continent": "Africa"
281 | },
282 | {
283 | "name": "Guinea-Bissau",
284 | "continent": "Africa"
285 | },
286 | {
287 | "name": "Guyana",
288 | "continent": "America"
289 | },
290 | {
291 | "name": "Haiti",
292 | "continent": "America"
293 | },
294 | {
295 | "name": "Honduras",
296 | "continent": "America"
297 | },
298 | {
299 | "name": "Hong Kong",
300 | "continent": "Asia"
301 | },
302 | {
303 | "name": "Hungary",
304 | "continent": "Europe"
305 | },
306 | {
307 | "name": "Iceland",
308 | "continent": "Europe"
309 | },
310 | {
311 | "name": "India",
312 | "continent": "Asia"
313 | },
314 | {
315 | "name": "Indonesia",
316 | "continent": "Asia"
317 | },
318 | {
319 | "name": "Iran",
320 | "continent": "Asia"
321 | },
322 | {
323 | "name": "Iraq",
324 | "continent": "Asia"
325 | },
326 | {
327 | "name": "Ireland",
328 | "continent": "Europe"
329 | },
330 | {
331 | "name": "Isle of Man",
332 | "continent": "Europe"
333 | },
334 | {
335 | "name": "Israel",
336 | "continent": "Asia"
337 | },
338 | {
339 | "name": "Italy",
340 | "continent": "Europe"
341 | },
342 | {
343 | "name": "Jamaica",
344 | "continent": "America"
345 | },
346 | {
347 | "name": "Japan",
348 | "continent": "Asia"
349 | },
350 | {
351 | "name": "Jordan",
352 | "continent": "Asia"
353 | },
354 | {
355 | "name": "Kazakhstan",
356 | "continent": "Asia"
357 | },
358 | {
359 | "name": "Kenya",
360 | "continent": "Africa"
361 | },
362 | {
363 | "name": "Kiribati",
364 | "continent": "Oceania"
365 | },
366 | {
367 | "name": "North Korea",
368 | "continent": "Asia"
369 | },
370 | {
371 | "name": "South Korea",
372 | "continent": "Asia"
373 | },
374 | {
375 | "name": "Kosovo",
376 | "continent": "Europe"
377 | },
378 | {
379 | "name": "Kuwait",
380 | "continent": "Asia"
381 | },
382 | {
383 | "name": "Kyrgyzstan",
384 | "continent": "Asia"
385 | },
386 | {
387 | "name": "Laos",
388 | "continent": "Asia"
389 | },
390 | {
391 | "name": "Latvia",
392 | "continent": "Europe"
393 | },
394 | {
395 | "name": "Lebanon",
396 | "continent": "Asia"
397 | },
398 | {
399 | "name": "Lesotho",
400 | "continent": "Africa"
401 | },
402 | {
403 | "name": "Liberia",
404 | "continent": "Africa"
405 | },
406 | {
407 | "name": "Libya",
408 | "continent": "Africa"
409 | },
410 | {
411 | "name": "Liechtenstein",
412 | "continent": "Europe"
413 | },
414 | {
415 | "name": "Lithuania",
416 | "continent": "Europe"
417 | },
418 | {
419 | "name": "Luxembourg",
420 | "continent": "Europe"
421 | },
422 | {
423 | "name": "Macau",
424 | "continent": "Asia"
425 | },
426 | {
427 | "name": "Macedonia",
428 | "continent": "Europe"
429 | },
430 | {
431 | "name": "Madagascar",
432 | "continent": "Africa"
433 | },
434 | {
435 | "name": "Malawi",
436 | "continent": "Africa"
437 | },
438 | {
439 | "name": "Malaysia",
440 | "continent": "Asia"
441 | },
442 | {
443 | "name": "Maldives",
444 | "continent": "Asia"
445 | },
446 | {
447 | "name": "Mali",
448 | "continent": "Africa"
449 | },
450 | {
451 | "name": "Malta",
452 | "continent": "Europe"
453 | },
454 | {
455 | "name": "Marshall Islands",
456 | "continent": "Oceania"
457 | },
458 | {
459 | "name": "Mauritania",
460 | "continent": "Africa"
461 | },
462 | {
463 | "name": "Mauritius",
464 | "continent": "Africa"
465 | },
466 | {
467 | "name": "Mexico",
468 | "continent": "America"
469 | },
470 | {
471 | "name": "Micronesia",
472 | "continent": "Oceania"
473 | },
474 | {
475 | "name": "Moldova",
476 | "continent": "Europe"
477 | },
478 | {
479 | "name": "Monaco",
480 | "continent": "Europe"
481 | },
482 | {
483 | "name": "Mongolia",
484 | "continent": "Asia"
485 | },
486 | {
487 | "name": "Montenegro",
488 | "continent": "Europe"
489 | },
490 | {
491 | "name": "Morocco",
492 | "continent": "Africa"
493 | },
494 | {
495 | "name": "Mozambique",
496 | "continent": "Africa"
497 | },
498 | {
499 | "name": "Namibia",
500 | "continent": "Africa"
501 | },
502 | {
503 | "name": "Nauru",
504 | "continent": "Oceania"
505 | },
506 | {
507 | "name": "Nepal",
508 | "continent": "Asia"
509 | },
510 | {
511 | "name": "Netherlands",
512 | "continent": "Europe"
513 | },
514 | {
515 | "name": "New Zealand",
516 | "continent": "Oceania"
517 | },
518 | {
519 | "name": "Nicaragua",
520 | "continent": "America"
521 | },
522 | {
523 | "name": "Niger",
524 | "continent": "Africa"
525 | },
526 | {
527 | "name": "Nigeria",
528 | "continent": "Africa"
529 | },
530 | {
531 | "name": "Norway",
532 | "continent": "Europe"
533 | },
534 | {
535 | "name": "Oman",
536 | "continent": "Asia"
537 | },
538 | {
539 | "name": "Pakistan",
540 | "continent": "Asia"
541 | },
542 | {
543 | "name": "Palau",
544 | "continent": "Oceania"
545 | },
546 | {
547 | "name": "Panama",
548 | "continent": "America"
549 | },
550 | {
551 | "name": "Papua New Guinea",
552 | "continent": "Oceania"
553 | },
554 | {
555 | "name": "Paraguay",
556 | "continent": "America"
557 | },
558 | {
559 | "name": "Peru",
560 | "continent": "America"
561 | },
562 | {
563 | "name": "Philippines",
564 | "continent": "Asia"
565 | },
566 | {
567 | "name": "Poland",
568 | "continent": "Europe"
569 | },
570 | {
571 | "name": "Portugal",
572 | "continent": "Europe"
573 | },
574 | {
575 | "name": "Puerto Rico",
576 | "continent": "America"
577 | },
578 | {
579 | "name": "Qatar",
580 | "continent": "Asia"
581 | },
582 | {
583 | "name": "Romania",
584 | "continent": "Europe"
585 | },
586 | {
587 | "name": "Russia",
588 | "continent": "Europe"
589 | },
590 | {
591 | "name": "Rwanda",
592 | "continent": "Africa"
593 | },
594 | {
595 | "name": "Saint Kitts and Nevis",
596 | "continent": "America"
597 | },
598 | {
599 | "name": "Saint Lucia",
600 | "continent": "America"
601 | },
602 | {
603 | "name": "Saint Vincent and the Grenadines",
604 | "continent": "America"
605 | },
606 | {
607 | "name": "Samoa",
608 | "continent": "Oceania"
609 | },
610 | {
611 | "name": "San Marino",
612 | "continent": "Europe"
613 | },
614 | {
615 | "name": "Saudi Arabia",
616 | "continent": "Asia"
617 | },
618 | {
619 | "name": "Scotland",
620 | "continent": "Europe"
621 | },
622 | {
623 | "name": "Senegal",
624 | "continent": "Africa"
625 | },
626 | {
627 | "name": "Serbia",
628 | "continent": "Europe"
629 | },
630 | {
631 | "name": "Seychelles",
632 | "continent": "Africa"
633 | },
634 | {
635 | "name": "Sierra Leone",
636 | "continent": "Africa"
637 | },
638 | {
639 | "name": "Singapore",
640 | "continent": "Asia"
641 | },
642 | {
643 | "name": "Slovakia",
644 | "continent": "Europe"
645 | },
646 | {
647 | "name": "Slovenia",
648 | "continent": "Europe"
649 | },
650 | {
651 | "name": "Solomon Islands",
652 | "continent": "Oceania"
653 | },
654 | {
655 | "name": "Somalia",
656 | "continent": "Africa"
657 | },
658 | {
659 | "name": "South Africa",
660 | "continent": "Africa"
661 | },
662 | {
663 | "name": "Spain",
664 | "continent": "Europe"
665 | },
666 | {
667 | "name": "Sri Lanka",
668 | "continent": "Asia"
669 | },
670 | {
671 | "name": "Sudan",
672 | "continent": "Africa"
673 | },
674 | {
675 | "name": "Suriname",
676 | "continent": "America"
677 | },
678 | {
679 | "name": "Swaziland",
680 | "continent": "Africa"
681 | },
682 | {
683 | "name": "Sweden",
684 | "continent": "Europe"
685 | },
686 | {
687 | "name": "Switzerland",
688 | "continent": "Europe"
689 | },
690 | {
691 | "name": "Syria",
692 | "continent": "Asia"
693 | },
694 | {
695 | "name": "Taiwan",
696 | "continent": "Asia"
697 | },
698 | {
699 | "name": "Tajikistan",
700 | "continent": "Asia"
701 | },
702 | {
703 | "name": "Tanzania",
704 | "continent": "Africa"
705 | },
706 | {
707 | "name": "Thailand",
708 | "continent": "Asia"
709 | },
710 | {
711 | "name": "Togo",
712 | "continent": "Africa"
713 | },
714 | {
715 | "name": "Tonga",
716 | "continent": "Oceania"
717 | },
718 | {
719 | "name": "Trinidad and Tobago",
720 | "continent": "America"
721 | },
722 | {
723 | "name": "Tunisia",
724 | "continent": "Africa"
725 | },
726 | {
727 | "name": "Turkey",
728 | "continent": "Asia"
729 | },
730 | {
731 | "name": "Turkmenistan",
732 | "continent": "Asia"
733 | },
734 | {
735 | "name": "Tuvalu",
736 | "continent": "Oceania"
737 | },
738 | {
739 | "name": "Uganda",
740 | "continent": "Africa"
741 | },
742 | {
743 | "name": "Ukraine",
744 | "continent": "Europe"
745 | },
746 | {
747 | "name": "United Arab Emirates",
748 | "continent": "Asia"
749 | },
750 | {
751 | "name": "United Kingdom",
752 | "continent": "Europe"
753 | },
754 | {
755 | "name": "United States of America",
756 | "continent": "America"
757 | },
758 | {
759 | "name": "Uruguay",
760 | "continent": "America"
761 | },
762 | {
763 | "name": "USSR",
764 | "continent": "Europe"
765 | },
766 | {
767 | "name": "Uzbekistan",
768 | "continent": "Asia"
769 | },
770 | {
771 | "name": "Vanuatu",
772 | "continent": "Oceania"
773 | },
774 | {
775 | "name": "Vatican City",
776 | "continent": "Europe"
777 | },
778 | {
779 | "name": "Venezuela",
780 | "continent": "America"
781 | },
782 | {
783 | "name": "Vietnam",
784 | "continent": "Asia"
785 | },
786 | {
787 | "name": "Wales",
788 | "continent": "Europe"
789 | },
790 | {
791 | "name": "Yemen",
792 | "continent": "Asia"
793 | },
794 | {
795 | "name": "Zambia",
796 | "continent": "Africa"
797 | },
798 | {
799 | "name": "Zimbabwe",
800 | "continent": "Africa"
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/index.js:
--------------------------------------------------------------------------------
1 | import './router.config';
2 |
3 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/app/router.config.js:
--------------------------------------------------------------------------------
1 | console.log(window['@uirouter/visualizer'])
2 | var Visualizer = window['@uirouter/visualizer'].Visualizer;
3 | var DSRPlugin = window['@uirouter/dsr'].DSRPlugin;
4 |
5 | var states = [
6 | {
7 | name: 'continentlist',
8 | url: '/continents',
9 | dsr: true,
10 | component: 'continentList',
11 | resolve: {
12 | 'continents': () => getContinents(),
13 | },
14 | },
15 |
16 | {
17 | name: 'continentlist.countrylist',
18 | url: '/:continent',
19 | component: 'countryList',
20 | resolve: {
21 | 'countries': ($transition$) => getCountries($transition$.params().continent),
22 | },
23 | },
24 |
25 | {
26 | name: 'continentlist.countrylist.countrydetail',
27 | url: '/:country',
28 | component: 'countryDetail',
29 | resolve: {
30 | 'country': ($transition$) => $transition$.params().country,
31 | },
32 | },
33 |
34 | {
35 | name: 'about',
36 | url: '/about',
37 | component: 'about',
38 | },
39 | ];
40 |
41 | angular.module('app', ['ui.router']).config(function ($uiRouterProvider) {
42 | $uiRouterProvider.plugin(DSRPlugin);
43 | $uiRouterProvider.plugin(Visualizer);
44 |
45 | // Add states
46 | states.forEach(state => $uiRouterProvider.stateRegistry.register(state));
47 |
48 | // Set initial state
49 | $uiRouterProvider.urlService.rules.initial({ state: 'about' });
50 | });
51 |
52 |
53 | function getContinents() {
54 | return fetch('app/data.json').then(res => res.json())
55 | .then(countries => countries.map(country => country.continent))
56 | .then(continents => continents.reduce((acc, continent) => acc.includes(continent) ? acc : acc.concat(continent), []))
57 | }
58 |
59 | function getCountries(continent) {
60 | return fetch('app/data.json').then(res => res.json())
61 | .then(countries => countries.filter(country => country.continent === continent))
62 | .then(countries => countries.map(country => country.name));
63 | }
64 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-bower",
3 | "description": "AngularJS/bower sticky states example",
4 | "main": "index.js",
5 | "authors": [
6 | "Chris Thielen "
7 | ],
8 | "license": "MIT",
9 | "homepage": "https://github.com/ui-router/sticky-states",
10 | "private": true,
11 | "resolvers": [
12 | "bower-npm-resolver"
13 | ],
14 | "ignore": [
15 | "**/.*",
16 | "node_modules",
17 | "bower_components",
18 | "test",
19 | "tests"
20 | ],
21 | "dependencies": {
22 | "angular-ui-router": "^1.0.13",
23 | "angular": "^1.6.8"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:4000",
3 | "video": false
4 | }
5 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/cypress/integration/example_spec.js:
--------------------------------------------------------------------------------
1 | describe('example app', () => {
2 | it('loads', () => {
3 | cy.visit('');
4 | });
5 |
6 | it('renders links', () => {
7 | cy.visit('/');
8 | cy.get('a').contains('about');
9 | cy.get('a').contains('continentlist');
10 | });
11 |
12 | it('renders about by default', () => {
13 | cy.visit('/');
14 | cy.contains('This is a trivial Deep State Redirect example app');
15 | });
16 |
17 | it('can navigate to continentlist', () => {
18 | cy.visit('');
19 | cy
20 | .get('a')
21 | .contains('continentlist')
22 | .click();
23 |
24 | cy.contains('Africa');
25 | cy.contains('America');
26 | cy.contains('Oceania');
27 | });
28 |
29 | it('can navigate to belize', () => {
30 | cy.visit('');
31 | cy
32 | .get('a')
33 | .contains('continentlist')
34 | .click();
35 | cy
36 | .get('a')
37 | .contains('America')
38 | .click();
39 | cy
40 | .get('a')
41 | .contains('Belize')
42 | .click();
43 | cy.get('h3').contains('Belize');
44 | });
45 |
46 | it('can navigate to belize and back', () => {
47 | cy.visit('');
48 | cy
49 | .get('a')
50 | .contains('continentlist')
51 | .click();
52 | cy
53 | .get('a')
54 | .contains('America')
55 | .click();
56 | cy.url().should('include', '/America');
57 |
58 | cy
59 | .get('a')
60 | .contains('Belize')
61 | .click();
62 | cy.get('h3').contains('Belize');
63 | cy.url().should('include', '/America/Belize');
64 |
65 | cy
66 | .get('a')
67 | .contains('about')
68 | .click();
69 | cy.contains('This is a trivial Deep State Redirect example app');
70 | });
71 |
72 | it('dsr sends you back to belize', () => {
73 | cy.visit('');
74 | cy
75 | .get('a')
76 | .contains('continentlist')
77 | .click();
78 | cy
79 | .get('a')
80 | .contains('America')
81 | .click();
82 | cy.url().should('include', '/America');
83 |
84 | cy
85 | .get('a')
86 | .contains('Belize')
87 | .click();
88 | cy.url().should('include', '/America/Belize');
89 | cy.get('h3').contains('Belize');
90 |
91 | cy
92 | .get('a')
93 | .contains('about')
94 | .click();
95 | cy.url().should('include', '/about');
96 | cy.contains('This is a trivial Deep State Redirect example app');
97 |
98 | cy
99 | .get('a')
100 | .contains('continentlist')
101 | .click();
102 | cy.url().should('include', '/America/Belize');
103 | cy.get('h3').contains('Belize');
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/index.js:
--------------------------------------------------------------------------------
1 | var StickyStatesPlugin = window['@uirouter/sticky-states'].StickyStatesPlugin;
2 | var Visualizer = (window['@uirouter/visualizer'] || window['ui-router-visualizer']).Visualizer;
3 |
4 | // Create the module where our functionality can attach to
5 | var APP_MODULE = angular.module('app', ['ui.router']);
6 |
7 | APP_MODULE.config(function ($uiRouterProvider) {
8 | $uiRouterProvider.plugin(StickyStatesPlugin);
9 | $uiRouterProvider.plugin(Visualizer);
10 |
11 | // Add states
12 | var stateRegistry = $uiRouterProvider.stateRegistry;
13 |
14 | stateRegistry.register({
15 | name: 'home',
16 | url: '/home',
17 | sticky: true,
18 | views: {
19 | home: 'generic',
20 | },
21 | });
22 |
23 | stateRegistry.register({
24 | name: 'about',
25 | url: '/about',
26 | sticky: true,
27 | views: {
28 | about: 'generic',
29 | },
30 | });
31 |
32 | // Set initial state
33 | var urlService = $uiRouterProvider.urlService;
34 | urlService.rules.initial({ state: 'home' })
35 | });
36 |
37 | // Generic component
38 | APP_MODULE.component('generic', {
39 | template: `
40 | {{ $ctrl.$state$.name }} state loaded
41 |
42 | `,
43 | controller: function() {
44 | this.text = "Text entered here is not lost";
45 | },
46 | bindings: { '$state$': '<' },
47 | });
48 |
49 | APP_MODULE.run(function ($state, $rootScope) {
50 | $rootScope.$state = $state;
51 | });
52 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-bower-script-tags",
3 | "version": "1.0.0",
4 | "description": "AngularJS/bower sticky states example",
5 | "main": "index.js",
6 | "scripts": {
7 | "postinstall": "bower install",
8 | "test": "cypress-runner run --path .",
9 | "test:open": "cypress-runner open --path .",
10 | "start": "lite-server"
11 | },
12 | "author": "",
13 | "license": "MIT",
14 | "devDependencies": {
15 | "bower": "^1.8.2",
16 | "lite-server": "^2.3.0"
17 | },
18 | "dependencies": {
19 | "@uirouter/cypress-runner": "^1.0.2",
20 | "@uirouter/dsr": "^1.0.2",
21 | "@uirouter/visualizer": "^6"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/angularjs-bower-script-tags/styles.css:
--------------------------------------------------------------------------------
1 | .active {
2 | font-weight: bold;
3 | }
4 | .container {
5 | display: flex;
6 | flex-flow: row wrap;
7 | }
8 | .container > * {
9 | border: 1px solid;
10 | padding: 0.5em;
11 | margin: 0.5em;
12 | flex: 1 1 75px;
13 | }
14 | .container > a.active {
15 | background: lightgray;
16 | }
17 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/README.md:
--------------------------------------------------------------------------------
1 | # npm + script tags
2 |
3 | Example showing sticky states installed via npm packages.
4 | Scripts are added using script tags in index.html.
5 |
6 | ## Running
7 |
8 | ```
9 | npm install
10 | npm start
11 | ```
12 |
13 | ## Info
14 |
15 | This example has separate script tags for `ui-router-core.js` from the `@uirouter/core` package and `ui-router-angularjs.js` from `@uirouter/angularjs` package.
16 |
17 | ```
18 |
19 |
20 |
21 |
22 |
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/about.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('about', {
2 | template: `
3 | This is a trivial Deep State Redirect example app
4 |
5 | Active the continentlist state
6 | Select a continent
7 | Select a country
8 | Reactivate this state (about )
9 |
10 | Active the continents state again.
11 | You are redirected to the previously active substate of continentlist
(including parameters).
12 | You should see the country you chose in the previous step.
13 |
14 |
15 | `,
16 | });
17 |
18 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/continentList.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('continentList', {
2 | template: `
3 | Continents
4 |
5 |
6 | {{ continent }}
7 |
8 |
9 |
10 | `,
11 | bindings: {
12 | continents: '<',
13 | },
14 | });
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/countryDetail.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('countryDetail', {
2 | template: `
3 | {{ $ctrl.country }}
4 |
5 |
6 |
7 | `,
8 | controller: function () {
9 | this.imageSrc = function() {
10 | if (!this.country) { return ''; }
11 | const prefix = 'http://www.randomlists.com/img/national-flags/';
12 | const imageName = this.country.toLowerCase().replace(/ /g, '_');
13 | return `${prefix}${imageName}.gif`;
14 | };
15 | },
16 | bindings: {
17 | country: '<',
18 | },
19 | });
20 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/countryList.component.js:
--------------------------------------------------------------------------------
1 | angular.module('app').component('countryList', {
2 | template: `
3 |
4 |
5 |
13 | `,
14 | bindings: {
15 | countries: '<',
16 | },
17 | });
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Afghanistan",
4 | "continent": "Asia"
5 | },
6 | {
7 | "name": "Albania",
8 | "continent": "Europe"
9 | },
10 | {
11 | "name": "Algeria",
12 | "continent": "Africa"
13 | },
14 | {
15 | "name": "Andorra",
16 | "continent": "Europe"
17 | },
18 | {
19 | "name": "Angola",
20 | "continent": "Africa"
21 | },
22 | {
23 | "name": "Antigua and Barbuda",
24 | "continent": "America"
25 | },
26 | {
27 | "name": "Argentina",
28 | "continent": "America"
29 | },
30 | {
31 | "name": "Armenia",
32 | "continent": "Asia"
33 | },
34 | {
35 | "name": "Australia",
36 | "continent": "Oceania"
37 | },
38 | {
39 | "name": "Austria",
40 | "continent": "Europe"
41 | },
42 | {
43 | "name": "Azerbaijan",
44 | "continent": "Asia"
45 | },
46 | {
47 | "name": "Bahamas",
48 | "continent": "America"
49 | },
50 | {
51 | "name": "Bahrain",
52 | "continent": "Asia"
53 | },
54 | {
55 | "name": "Bangladesh",
56 | "continent": "Asia"
57 | },
58 | {
59 | "name": "Barbados",
60 | "continent": "America"
61 | },
62 | {
63 | "name": "Belarus",
64 | "continent": "Europe"
65 | },
66 | {
67 | "name": "Belgium",
68 | "continent": "Europe"
69 | },
70 | {
71 | "name": "Belize",
72 | "continent": "America"
73 | },
74 | {
75 | "name": "Benin",
76 | "continent": "Africa"
77 | },
78 | {
79 | "name": "Bhutan",
80 | "continent": "Asia"
81 | },
82 | {
83 | "name": "Bolivia",
84 | "continent": "America"
85 | },
86 | {
87 | "name": "Bosnia and Herzegovina",
88 | "continent": "Europe"
89 | },
90 | {
91 | "name": "Botswana",
92 | "continent": "Africa"
93 | },
94 | {
95 | "name": "Brazil",
96 | "continent": "America"
97 | },
98 | {
99 | "name": "Brunei",
100 | "continent": "Asia"
101 | },
102 | {
103 | "name": "Bulgaria",
104 | "continent": "Europe"
105 | },
106 | {
107 | "name": "Burkina Faso",
108 | "continent": "Africa"
109 | },
110 | {
111 | "name": "Myanmar",
112 | "continent": "Asia"
113 | },
114 | {
115 | "name": "Burundi",
116 | "continent": "Africa"
117 | },
118 | {
119 | "name": "Cambodia",
120 | "continent": "Asia"
121 | },
122 | {
123 | "name": "Cameroon",
124 | "continent": "Africa"
125 | },
126 | {
127 | "name": "Canada",
128 | "continent": "America"
129 | },
130 | {
131 | "name": "Cape Verde",
132 | "continent": "Africa"
133 | },
134 | {
135 | "name": "Central African Republic",
136 | "continent": "Africa"
137 | },
138 | {
139 | "name": "Chad",
140 | "continent": "Africa"
141 | },
142 | {
143 | "name": "Chile",
144 | "continent": "America"
145 | },
146 | {
147 | "name": "China",
148 | "continent": "Asia"
149 | },
150 | {
151 | "name": "Colombia",
152 | "continent": "America"
153 | },
154 | {
155 | "name": "Comoros",
156 | "continent": "Africa"
157 | },
158 | {
159 | "name": "Congo",
160 | "continent": "Africa"
161 | },
162 | {
163 | "name": "Costa Rica",
164 | "continent": "America"
165 | },
166 | {
167 | "name": "Croatia",
168 | "continent": "Europe"
169 | },
170 | {
171 | "name": "Cuba",
172 | "continent": "America"
173 | },
174 | {
175 | "name": "Cyprus",
176 | "continent": "Europe"
177 | },
178 | {
179 | "name": "Czech Republic",
180 | "continent": "Europe"
181 | },
182 | {
183 | "name": "Denmark",
184 | "continent": "Europe"
185 | },
186 | {
187 | "name": "Djibouti",
188 | "continent": "Africa"
189 | },
190 | {
191 | "name": "Dominica",
192 | "continent": "America"
193 | },
194 | {
195 | "name": "Dominican Republic",
196 | "continent": "America"
197 | },
198 | {
199 | "name": "East Timor",
200 | "continent": "Asia"
201 | },
202 | {
203 | "name": "Ecuador",
204 | "continent": "America"
205 | },
206 | {
207 | "name": "Egypt",
208 | "continent": "Africa"
209 | },
210 | {
211 | "name": "El Salvador",
212 | "continent": "America"
213 | },
214 | {
215 | "name": "England",
216 | "continent": "Europe"
217 | },
218 | {
219 | "name": "Equatorial Guinea",
220 | "continent": "Africa"
221 | },
222 | {
223 | "name": "Eritrea",
224 | "continent": "Africa"
225 | },
226 | {
227 | "name": "Estonia",
228 | "continent": "Europe"
229 | },
230 | {
231 | "name": "Ethiopia",
232 | "continent": "Africa"
233 | },
234 | {
235 | "name": "Fiji",
236 | "continent": "Oceania"
237 | },
238 | {
239 | "name": "Finland",
240 | "continent": "Europe"
241 | },
242 | {
243 | "name": "France",
244 | "continent": "Europe"
245 | },
246 | {
247 | "name": "Gabon",
248 | "continent": "Africa"
249 | },
250 | {
251 | "name": "Gambia",
252 | "continent": "Africa"
253 | },
254 | {
255 | "name": "Georgia",
256 | "continent": "Asia"
257 | },
258 | {
259 | "name": "Germany",
260 | "continent": "Europe"
261 | },
262 | {
263 | "name": "Ghana",
264 | "continent": "Africa"
265 | },
266 | {
267 | "name": "Greece",
268 | "continent": "Europe"
269 | },
270 | {
271 | "name": "Grenada",
272 | "continent": "America"
273 | },
274 | {
275 | "name": "Guatemala",
276 | "continent": "America"
277 | },
278 | {
279 | "name": "Guinea",
280 | "continent": "Africa"
281 | },
282 | {
283 | "name": "Guinea-Bissau",
284 | "continent": "Africa"
285 | },
286 | {
287 | "name": "Guyana",
288 | "continent": "America"
289 | },
290 | {
291 | "name": "Haiti",
292 | "continent": "America"
293 | },
294 | {
295 | "name": "Honduras",
296 | "continent": "America"
297 | },
298 | {
299 | "name": "Hong Kong",
300 | "continent": "Asia"
301 | },
302 | {
303 | "name": "Hungary",
304 | "continent": "Europe"
305 | },
306 | {
307 | "name": "Iceland",
308 | "continent": "Europe"
309 | },
310 | {
311 | "name": "India",
312 | "continent": "Asia"
313 | },
314 | {
315 | "name": "Indonesia",
316 | "continent": "Asia"
317 | },
318 | {
319 | "name": "Iran",
320 | "continent": "Asia"
321 | },
322 | {
323 | "name": "Iraq",
324 | "continent": "Asia"
325 | },
326 | {
327 | "name": "Ireland",
328 | "continent": "Europe"
329 | },
330 | {
331 | "name": "Isle of Man",
332 | "continent": "Europe"
333 | },
334 | {
335 | "name": "Israel",
336 | "continent": "Asia"
337 | },
338 | {
339 | "name": "Italy",
340 | "continent": "Europe"
341 | },
342 | {
343 | "name": "Jamaica",
344 | "continent": "America"
345 | },
346 | {
347 | "name": "Japan",
348 | "continent": "Asia"
349 | },
350 | {
351 | "name": "Jordan",
352 | "continent": "Asia"
353 | },
354 | {
355 | "name": "Kazakhstan",
356 | "continent": "Asia"
357 | },
358 | {
359 | "name": "Kenya",
360 | "continent": "Africa"
361 | },
362 | {
363 | "name": "Kiribati",
364 | "continent": "Oceania"
365 | },
366 | {
367 | "name": "North Korea",
368 | "continent": "Asia"
369 | },
370 | {
371 | "name": "South Korea",
372 | "continent": "Asia"
373 | },
374 | {
375 | "name": "Kosovo",
376 | "continent": "Europe"
377 | },
378 | {
379 | "name": "Kuwait",
380 | "continent": "Asia"
381 | },
382 | {
383 | "name": "Kyrgyzstan",
384 | "continent": "Asia"
385 | },
386 | {
387 | "name": "Laos",
388 | "continent": "Asia"
389 | },
390 | {
391 | "name": "Latvia",
392 | "continent": "Europe"
393 | },
394 | {
395 | "name": "Lebanon",
396 | "continent": "Asia"
397 | },
398 | {
399 | "name": "Lesotho",
400 | "continent": "Africa"
401 | },
402 | {
403 | "name": "Liberia",
404 | "continent": "Africa"
405 | },
406 | {
407 | "name": "Libya",
408 | "continent": "Africa"
409 | },
410 | {
411 | "name": "Liechtenstein",
412 | "continent": "Europe"
413 | },
414 | {
415 | "name": "Lithuania",
416 | "continent": "Europe"
417 | },
418 | {
419 | "name": "Luxembourg",
420 | "continent": "Europe"
421 | },
422 | {
423 | "name": "Macau",
424 | "continent": "Asia"
425 | },
426 | {
427 | "name": "Macedonia",
428 | "continent": "Europe"
429 | },
430 | {
431 | "name": "Madagascar",
432 | "continent": "Africa"
433 | },
434 | {
435 | "name": "Malawi",
436 | "continent": "Africa"
437 | },
438 | {
439 | "name": "Malaysia",
440 | "continent": "Asia"
441 | },
442 | {
443 | "name": "Maldives",
444 | "continent": "Asia"
445 | },
446 | {
447 | "name": "Mali",
448 | "continent": "Africa"
449 | },
450 | {
451 | "name": "Malta",
452 | "continent": "Europe"
453 | },
454 | {
455 | "name": "Marshall Islands",
456 | "continent": "Oceania"
457 | },
458 | {
459 | "name": "Mauritania",
460 | "continent": "Africa"
461 | },
462 | {
463 | "name": "Mauritius",
464 | "continent": "Africa"
465 | },
466 | {
467 | "name": "Mexico",
468 | "continent": "America"
469 | },
470 | {
471 | "name": "Micronesia",
472 | "continent": "Oceania"
473 | },
474 | {
475 | "name": "Moldova",
476 | "continent": "Europe"
477 | },
478 | {
479 | "name": "Monaco",
480 | "continent": "Europe"
481 | },
482 | {
483 | "name": "Mongolia",
484 | "continent": "Asia"
485 | },
486 | {
487 | "name": "Montenegro",
488 | "continent": "Europe"
489 | },
490 | {
491 | "name": "Morocco",
492 | "continent": "Africa"
493 | },
494 | {
495 | "name": "Mozambique",
496 | "continent": "Africa"
497 | },
498 | {
499 | "name": "Namibia",
500 | "continent": "Africa"
501 | },
502 | {
503 | "name": "Nauru",
504 | "continent": "Oceania"
505 | },
506 | {
507 | "name": "Nepal",
508 | "continent": "Asia"
509 | },
510 | {
511 | "name": "Netherlands",
512 | "continent": "Europe"
513 | },
514 | {
515 | "name": "New Zealand",
516 | "continent": "Oceania"
517 | },
518 | {
519 | "name": "Nicaragua",
520 | "continent": "America"
521 | },
522 | {
523 | "name": "Niger",
524 | "continent": "Africa"
525 | },
526 | {
527 | "name": "Nigeria",
528 | "continent": "Africa"
529 | },
530 | {
531 | "name": "Norway",
532 | "continent": "Europe"
533 | },
534 | {
535 | "name": "Oman",
536 | "continent": "Asia"
537 | },
538 | {
539 | "name": "Pakistan",
540 | "continent": "Asia"
541 | },
542 | {
543 | "name": "Palau",
544 | "continent": "Oceania"
545 | },
546 | {
547 | "name": "Panama",
548 | "continent": "America"
549 | },
550 | {
551 | "name": "Papua New Guinea",
552 | "continent": "Oceania"
553 | },
554 | {
555 | "name": "Paraguay",
556 | "continent": "America"
557 | },
558 | {
559 | "name": "Peru",
560 | "continent": "America"
561 | },
562 | {
563 | "name": "Philippines",
564 | "continent": "Asia"
565 | },
566 | {
567 | "name": "Poland",
568 | "continent": "Europe"
569 | },
570 | {
571 | "name": "Portugal",
572 | "continent": "Europe"
573 | },
574 | {
575 | "name": "Puerto Rico",
576 | "continent": "America"
577 | },
578 | {
579 | "name": "Qatar",
580 | "continent": "Asia"
581 | },
582 | {
583 | "name": "Romania",
584 | "continent": "Europe"
585 | },
586 | {
587 | "name": "Russia",
588 | "continent": "Europe"
589 | },
590 | {
591 | "name": "Rwanda",
592 | "continent": "Africa"
593 | },
594 | {
595 | "name": "Saint Kitts and Nevis",
596 | "continent": "America"
597 | },
598 | {
599 | "name": "Saint Lucia",
600 | "continent": "America"
601 | },
602 | {
603 | "name": "Saint Vincent and the Grenadines",
604 | "continent": "America"
605 | },
606 | {
607 | "name": "Samoa",
608 | "continent": "Oceania"
609 | },
610 | {
611 | "name": "San Marino",
612 | "continent": "Europe"
613 | },
614 | {
615 | "name": "Saudi Arabia",
616 | "continent": "Asia"
617 | },
618 | {
619 | "name": "Scotland",
620 | "continent": "Europe"
621 | },
622 | {
623 | "name": "Senegal",
624 | "continent": "Africa"
625 | },
626 | {
627 | "name": "Serbia",
628 | "continent": "Europe"
629 | },
630 | {
631 | "name": "Seychelles",
632 | "continent": "Africa"
633 | },
634 | {
635 | "name": "Sierra Leone",
636 | "continent": "Africa"
637 | },
638 | {
639 | "name": "Singapore",
640 | "continent": "Asia"
641 | },
642 | {
643 | "name": "Slovakia",
644 | "continent": "Europe"
645 | },
646 | {
647 | "name": "Slovenia",
648 | "continent": "Europe"
649 | },
650 | {
651 | "name": "Solomon Islands",
652 | "continent": "Oceania"
653 | },
654 | {
655 | "name": "Somalia",
656 | "continent": "Africa"
657 | },
658 | {
659 | "name": "South Africa",
660 | "continent": "Africa"
661 | },
662 | {
663 | "name": "Spain",
664 | "continent": "Europe"
665 | },
666 | {
667 | "name": "Sri Lanka",
668 | "continent": "Asia"
669 | },
670 | {
671 | "name": "Sudan",
672 | "continent": "Africa"
673 | },
674 | {
675 | "name": "Suriname",
676 | "continent": "America"
677 | },
678 | {
679 | "name": "Swaziland",
680 | "continent": "Africa"
681 | },
682 | {
683 | "name": "Sweden",
684 | "continent": "Europe"
685 | },
686 | {
687 | "name": "Switzerland",
688 | "continent": "Europe"
689 | },
690 | {
691 | "name": "Syria",
692 | "continent": "Asia"
693 | },
694 | {
695 | "name": "Taiwan",
696 | "continent": "Asia"
697 | },
698 | {
699 | "name": "Tajikistan",
700 | "continent": "Asia"
701 | },
702 | {
703 | "name": "Tanzania",
704 | "continent": "Africa"
705 | },
706 | {
707 | "name": "Thailand",
708 | "continent": "Asia"
709 | },
710 | {
711 | "name": "Togo",
712 | "continent": "Africa"
713 | },
714 | {
715 | "name": "Tonga",
716 | "continent": "Oceania"
717 | },
718 | {
719 | "name": "Trinidad and Tobago",
720 | "continent": "America"
721 | },
722 | {
723 | "name": "Tunisia",
724 | "continent": "Africa"
725 | },
726 | {
727 | "name": "Turkey",
728 | "continent": "Asia"
729 | },
730 | {
731 | "name": "Turkmenistan",
732 | "continent": "Asia"
733 | },
734 | {
735 | "name": "Tuvalu",
736 | "continent": "Oceania"
737 | },
738 | {
739 | "name": "Uganda",
740 | "continent": "Africa"
741 | },
742 | {
743 | "name": "Ukraine",
744 | "continent": "Europe"
745 | },
746 | {
747 | "name": "United Arab Emirates",
748 | "continent": "Asia"
749 | },
750 | {
751 | "name": "United Kingdom",
752 | "continent": "Europe"
753 | },
754 | {
755 | "name": "United States of America",
756 | "continent": "America"
757 | },
758 | {
759 | "name": "Uruguay",
760 | "continent": "America"
761 | },
762 | {
763 | "name": "USSR",
764 | "continent": "Europe"
765 | },
766 | {
767 | "name": "Uzbekistan",
768 | "continent": "Asia"
769 | },
770 | {
771 | "name": "Vanuatu",
772 | "continent": "Oceania"
773 | },
774 | {
775 | "name": "Vatican City",
776 | "continent": "Europe"
777 | },
778 | {
779 | "name": "Venezuela",
780 | "continent": "America"
781 | },
782 | {
783 | "name": "Vietnam",
784 | "continent": "Asia"
785 | },
786 | {
787 | "name": "Wales",
788 | "continent": "Europe"
789 | },
790 | {
791 | "name": "Yemen",
792 | "continent": "Asia"
793 | },
794 | {
795 | "name": "Zambia",
796 | "continent": "Africa"
797 | },
798 | {
799 | "name": "Zimbabwe",
800 | "continent": "Africa"
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/index.js:
--------------------------------------------------------------------------------
1 | import './router.config';
2 |
3 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/app/router.config.js:
--------------------------------------------------------------------------------
1 | console.log(window['@uirouter/visualizer'])
2 | var Visualizer = window['@uirouter/visualizer'].Visualizer;
3 | var DSRPlugin = window['@uirouter/dsr'].DSRPlugin;
4 |
5 | var states = [
6 | {
7 | name: 'continentlist',
8 | url: '/continents',
9 | dsr: true,
10 | component: 'continentList',
11 | resolve: {
12 | 'continents': () => getContinents(),
13 | },
14 | },
15 |
16 | {
17 | name: 'continentlist.countrylist',
18 | url: '/:continent',
19 | component: 'countryList',
20 | resolve: {
21 | 'countries': ($transition$) => getCountries($transition$.params().continent),
22 | },
23 | },
24 |
25 | {
26 | name: 'continentlist.countrylist.countrydetail',
27 | url: '/:country',
28 | component: 'countryDetail',
29 | resolve: {
30 | 'country': ($transition$) => $transition$.params().country,
31 | },
32 | },
33 |
34 | {
35 | name: 'about',
36 | url: '/about',
37 | component: 'about',
38 | },
39 | ];
40 |
41 | angular.module('app', ['ui.router']).config(function ($uiRouterProvider) {
42 | $uiRouterProvider.plugin(DSRPlugin);
43 | $uiRouterProvider.plugin(Visualizer);
44 |
45 | // Add states
46 | states.forEach(state => $uiRouterProvider.stateRegistry.register(state));
47 |
48 | // Set initial state
49 | $uiRouterProvider.urlService.rules.initial({ state: 'about' });
50 | });
51 |
52 |
53 | function getContinents() {
54 | return fetch('app/data.json').then(res => res.json())
55 | .then(countries => countries.map(country => country.continent))
56 | .then(continents => continents.reduce((acc, continent) => acc.includes(continent) ? acc : acc.concat(continent), []))
57 | }
58 |
59 | function getCountries(continent) {
60 | return fetch('app/data.json').then(res => res.json())
61 | .then(countries => countries.filter(country => country.continent === continent))
62 | .then(countries => countries.map(country => country.name));
63 | }
64 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:4000",
3 | "video": false
4 | }
5 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/cypress/integration/example_spec.js:
--------------------------------------------------------------------------------
1 | describe('example app', () => {
2 | it('loads', () => {
3 | cy.visit('');
4 | });
5 |
6 | it('renders links', () => {
7 | cy.visit('/');
8 | cy.get('a').contains('about');
9 | cy.get('a').contains('continentlist');
10 | });
11 |
12 | it('renders about by default', () => {
13 | cy.visit('/');
14 | cy.contains('This is a trivial Deep State Redirect example app');
15 | });
16 |
17 | it('can navigate to continentlist', () => {
18 | cy.visit('');
19 | cy
20 | .get('a')
21 | .contains('continentlist')
22 | .click();
23 |
24 | cy.contains('Africa');
25 | cy.contains('America');
26 | cy.contains('Oceania');
27 | });
28 |
29 | it('can navigate to belize', () => {
30 | cy.visit('');
31 | cy
32 | .get('a')
33 | .contains('continentlist')
34 | .click();
35 | cy
36 | .get('a')
37 | .contains('America')
38 | .click();
39 | cy
40 | .get('a')
41 | .contains('Belize')
42 | .click();
43 | cy.get('h3').contains('Belize');
44 | });
45 |
46 | it('can navigate to belize and back', () => {
47 | cy.visit('');
48 | cy
49 | .get('a')
50 | .contains('continentlist')
51 | .click();
52 | cy
53 | .get('a')
54 | .contains('America')
55 | .click();
56 | cy.url().should('include', '/America');
57 |
58 | cy
59 | .get('a')
60 | .contains('Belize')
61 | .click();
62 | cy.get('h3').contains('Belize');
63 | cy.url().should('include', '/America/Belize');
64 |
65 | cy
66 | .get('a')
67 | .contains('about')
68 | .click();
69 | cy.contains('This is a trivial Deep State Redirect example app');
70 | });
71 |
72 | it('dsr sends you back to belize', () => {
73 | cy.visit('');
74 | cy
75 | .get('a')
76 | .contains('continentlist')
77 | .click();
78 | cy
79 | .get('a')
80 | .contains('America')
81 | .click();
82 | cy.url().should('include', '/America');
83 |
84 | cy
85 | .get('a')
86 | .contains('Belize')
87 | .click();
88 | cy.url().should('include', '/America/Belize');
89 | cy.get('h3').contains('Belize');
90 |
91 | cy
92 | .get('a')
93 | .contains('about')
94 | .click();
95 | cy.url().should('include', '/about');
96 | cy.contains('This is a trivial Deep State Redirect example app');
97 |
98 | cy
99 | .get('a')
100 | .contains('continentlist')
101 | .click();
102 | cy.url().should('include', '/America/Belize');
103 | cy.get('h3').contains('Belize');
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/index.js:
--------------------------------------------------------------------------------
1 | var StickyStatesPlugin = window['@uirouter/sticky-states'].StickyStatesPlugin;
2 | var Visualizer = (window['@uirouter/visualizer'] || window['ui-router-visualizer']).Visualizer;
3 |
4 | // Create the module where our functionality can attach to
5 | var APP_MODULE = angular.module('app', ['ui.router']);
6 |
7 | APP_MODULE.config(function ($uiRouterProvider) {
8 | $uiRouterProvider.plugin(StickyStatesPlugin);
9 | $uiRouterProvider.plugin(Visualizer);
10 |
11 | // Add states
12 | var stateRegistry = $uiRouterProvider.stateRegistry;
13 |
14 | stateRegistry.register({
15 | name: 'home',
16 | url: '/home',
17 | sticky: true,
18 | views: {
19 | home: 'generic',
20 | },
21 | });
22 |
23 | stateRegistry.register({
24 | name: 'about',
25 | url: '/about',
26 | sticky: true,
27 | views: {
28 | about: 'generic',
29 | },
30 | });
31 |
32 | // Set initial state
33 | var urlService = $uiRouterProvider.urlService;
34 | urlService.rules.initial({ state: 'home' })
35 | });
36 |
37 | // Generic component
38 | APP_MODULE.component('generic', {
39 | template: `
40 | {{ $ctrl.$state$.name }} state loaded
41 |
42 | `,
43 | controller: function() {
44 | this.text = "Text entered here is not lost";
45 | },
46 | bindings: { '$state$': '<' },
47 | });
48 |
49 | APP_MODULE.run(function ($state, $rootScope) {
50 | $rootScope.$state = $state;
51 | });
52 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-npm-script-tags",
3 | "version": "1.0.0",
4 | "description": "AngularJS/bower sticky states example",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "cypress-runner run --path dist",
8 | "test:open": "cypress-runner open --path dist",
9 | "start": "lite-server"
10 | },
11 | "author": "",
12 | "license": "MIT",
13 | "devDependencies": {
14 | "@uirouter/cypress-runner": "^1.0.2"
15 | },
16 | "dependencies": {
17 | "@uirouter/angularjs": "^1.0.13",
18 | "@uirouter/dsr": "^1.0.2",
19 | "@uirouter/sticky-states": "^1.4.1",
20 | "@uirouter/visualizer": "^6",
21 | "angular": "^1.6.8"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/angularjs-npm-script-tags/styles.css:
--------------------------------------------------------------------------------
1 | .active {
2 | font-weight: bold;
3 | }
4 | .container {
5 | display: flex;
6 | flex-flow: row wrap;
7 | }
8 | .container > * {
9 | border: 1px solid;
10 | padding: 0.5em;
11 | margin: 0.5em;
12 | flex: 1 1 75px;
13 | }
14 | .container > a.active {
15 | background: lightgray;
16 | }
17 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/README.md:
--------------------------------------------------------------------------------
1 | # bower + script tags
2 |
3 | Example showing sticky states installed via npm packages.
4 | The app is bundled using webpack.
5 |
6 | ## Running
7 |
8 | ```
9 | npm install
10 | npm start
11 | ```
12 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/about.component.js:
--------------------------------------------------------------------------------
1 | import { APP_MODULE } from './app.module';
2 | APP_MODULE.component('about', {
3 | template: `
4 | This is a trivial Deep State Redirect example app
5 |
6 | Active the continentlist state
7 | Select a continent
8 | Select a country
9 | Reactivate this state (about )
10 |
11 | Active the continents state again.
12 | You are redirected to the previously active substate of continentlist
(including parameters).
13 | You should see the country you chose in the previous step.
14 |
15 |
16 | `,
17 | });
18 |
19 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/app.module.js:
--------------------------------------------------------------------------------
1 | import angular from 'angular';
2 | import UIROUTER from '@uirouter/angularjs';
3 |
4 | // Create the module where our functionality can attach to
5 | export const APP_MODULE = angular.module('app', [UIROUTER]);
6 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/continentList.component.js:
--------------------------------------------------------------------------------
1 | import { APP_MODULE } from './app.module';
2 | APP_MODULE.component('continentList', {
3 | template: `
4 | Continents
5 |
6 |
7 | {{ continent }}
8 |
9 |
10 |
11 | `,
12 | bindings: {
13 | continents: '<',
14 | },
15 | });
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/countryDetail.component.js:
--------------------------------------------------------------------------------
1 | import { APP_MODULE } from './app.module';
2 | APP_MODULE.component('countryDetail', {
3 | template: `
4 | {{ $ctrl.country }}
5 |
6 |
7 |
8 | `,
9 | controller: function () {
10 | this.imageSrc = function() {
11 | if (!this.country) { return ''; }
12 | const prefix = 'http://www.randomlists.com/img/national-flags/';
13 | const imageName = this.country.toLowerCase().replace(/ /g, '_');
14 | return `${prefix}${imageName}.gif`;
15 | };
16 | },
17 | bindings: {
18 | country: '<',
19 | },
20 | });
21 |
22 |
23 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/countryList.component.js:
--------------------------------------------------------------------------------
1 | import { APP_MODULE } from './app.module';
2 | APP_MODULE.component('countryList', {
3 | template: `
4 |
5 |
6 |
14 | `,
15 | bindings: {
16 | countries: '<',
17 | },
18 | });
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/data.api.js:
--------------------------------------------------------------------------------
1 | function getContinents() {
2 | return Promise.resolve(require('./data.json'))
3 | .then(countries => countries.map(country => country.continent))
4 | .then(continents => continents.reduce((acc, continent) => acc.includes(continent) ? acc : acc.concat(continent), []))
5 | }
6 |
7 | function getCountries(continent) {
8 | return Promise.resolve(require('./data.json'))
9 | .then(countries => countries.filter(country => country.continent === continent))
10 | .then(countries => countries.map(country => country.name));
11 | }
12 |
13 | export { getContinents, getCountries };
14 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Afghanistan",
4 | "continent": "Asia"
5 | },
6 | {
7 | "name": "Albania",
8 | "continent": "Europe"
9 | },
10 | {
11 | "name": "Algeria",
12 | "continent": "Africa"
13 | },
14 | {
15 | "name": "Andorra",
16 | "continent": "Europe"
17 | },
18 | {
19 | "name": "Angola",
20 | "continent": "Africa"
21 | },
22 | {
23 | "name": "Antigua and Barbuda",
24 | "continent": "America"
25 | },
26 | {
27 | "name": "Argentina",
28 | "continent": "America"
29 | },
30 | {
31 | "name": "Armenia",
32 | "continent": "Asia"
33 | },
34 | {
35 | "name": "Australia",
36 | "continent": "Oceania"
37 | },
38 | {
39 | "name": "Austria",
40 | "continent": "Europe"
41 | },
42 | {
43 | "name": "Azerbaijan",
44 | "continent": "Asia"
45 | },
46 | {
47 | "name": "Bahamas",
48 | "continent": "America"
49 | },
50 | {
51 | "name": "Bahrain",
52 | "continent": "Asia"
53 | },
54 | {
55 | "name": "Bangladesh",
56 | "continent": "Asia"
57 | },
58 | {
59 | "name": "Barbados",
60 | "continent": "America"
61 | },
62 | {
63 | "name": "Belarus",
64 | "continent": "Europe"
65 | },
66 | {
67 | "name": "Belgium",
68 | "continent": "Europe"
69 | },
70 | {
71 | "name": "Belize",
72 | "continent": "America"
73 | },
74 | {
75 | "name": "Benin",
76 | "continent": "Africa"
77 | },
78 | {
79 | "name": "Bhutan",
80 | "continent": "Asia"
81 | },
82 | {
83 | "name": "Bolivia",
84 | "continent": "America"
85 | },
86 | {
87 | "name": "Bosnia and Herzegovina",
88 | "continent": "Europe"
89 | },
90 | {
91 | "name": "Botswana",
92 | "continent": "Africa"
93 | },
94 | {
95 | "name": "Brazil",
96 | "continent": "America"
97 | },
98 | {
99 | "name": "Brunei",
100 | "continent": "Asia"
101 | },
102 | {
103 | "name": "Bulgaria",
104 | "continent": "Europe"
105 | },
106 | {
107 | "name": "Burkina Faso",
108 | "continent": "Africa"
109 | },
110 | {
111 | "name": "Myanmar",
112 | "continent": "Asia"
113 | },
114 | {
115 | "name": "Burundi",
116 | "continent": "Africa"
117 | },
118 | {
119 | "name": "Cambodia",
120 | "continent": "Asia"
121 | },
122 | {
123 | "name": "Cameroon",
124 | "continent": "Africa"
125 | },
126 | {
127 | "name": "Canada",
128 | "continent": "America"
129 | },
130 | {
131 | "name": "Cape Verde",
132 | "continent": "Africa"
133 | },
134 | {
135 | "name": "Central African Republic",
136 | "continent": "Africa"
137 | },
138 | {
139 | "name": "Chad",
140 | "continent": "Africa"
141 | },
142 | {
143 | "name": "Chile",
144 | "continent": "America"
145 | },
146 | {
147 | "name": "China",
148 | "continent": "Asia"
149 | },
150 | {
151 | "name": "Colombia",
152 | "continent": "America"
153 | },
154 | {
155 | "name": "Comoros",
156 | "continent": "Africa"
157 | },
158 | {
159 | "name": "Congo",
160 | "continent": "Africa"
161 | },
162 | {
163 | "name": "Costa Rica",
164 | "continent": "America"
165 | },
166 | {
167 | "name": "Croatia",
168 | "continent": "Europe"
169 | },
170 | {
171 | "name": "Cuba",
172 | "continent": "America"
173 | },
174 | {
175 | "name": "Cyprus",
176 | "continent": "Europe"
177 | },
178 | {
179 | "name": "Czech Republic",
180 | "continent": "Europe"
181 | },
182 | {
183 | "name": "Denmark",
184 | "continent": "Europe"
185 | },
186 | {
187 | "name": "Djibouti",
188 | "continent": "Africa"
189 | },
190 | {
191 | "name": "Dominica",
192 | "continent": "America"
193 | },
194 | {
195 | "name": "Dominican Republic",
196 | "continent": "America"
197 | },
198 | {
199 | "name": "East Timor",
200 | "continent": "Asia"
201 | },
202 | {
203 | "name": "Ecuador",
204 | "continent": "America"
205 | },
206 | {
207 | "name": "Egypt",
208 | "continent": "Africa"
209 | },
210 | {
211 | "name": "El Salvador",
212 | "continent": "America"
213 | },
214 | {
215 | "name": "England",
216 | "continent": "Europe"
217 | },
218 | {
219 | "name": "Equatorial Guinea",
220 | "continent": "Africa"
221 | },
222 | {
223 | "name": "Eritrea",
224 | "continent": "Africa"
225 | },
226 | {
227 | "name": "Estonia",
228 | "continent": "Europe"
229 | },
230 | {
231 | "name": "Ethiopia",
232 | "continent": "Africa"
233 | },
234 | {
235 | "name": "Fiji",
236 | "continent": "Oceania"
237 | },
238 | {
239 | "name": "Finland",
240 | "continent": "Europe"
241 | },
242 | {
243 | "name": "France",
244 | "continent": "Europe"
245 | },
246 | {
247 | "name": "Gabon",
248 | "continent": "Africa"
249 | },
250 | {
251 | "name": "Gambia",
252 | "continent": "Africa"
253 | },
254 | {
255 | "name": "Georgia",
256 | "continent": "Asia"
257 | },
258 | {
259 | "name": "Germany",
260 | "continent": "Europe"
261 | },
262 | {
263 | "name": "Ghana",
264 | "continent": "Africa"
265 | },
266 | {
267 | "name": "Greece",
268 | "continent": "Europe"
269 | },
270 | {
271 | "name": "Grenada",
272 | "continent": "America"
273 | },
274 | {
275 | "name": "Guatemala",
276 | "continent": "America"
277 | },
278 | {
279 | "name": "Guinea",
280 | "continent": "Africa"
281 | },
282 | {
283 | "name": "Guinea-Bissau",
284 | "continent": "Africa"
285 | },
286 | {
287 | "name": "Guyana",
288 | "continent": "America"
289 | },
290 | {
291 | "name": "Haiti",
292 | "continent": "America"
293 | },
294 | {
295 | "name": "Honduras",
296 | "continent": "America"
297 | },
298 | {
299 | "name": "Hong Kong",
300 | "continent": "Asia"
301 | },
302 | {
303 | "name": "Hungary",
304 | "continent": "Europe"
305 | },
306 | {
307 | "name": "Iceland",
308 | "continent": "Europe"
309 | },
310 | {
311 | "name": "India",
312 | "continent": "Asia"
313 | },
314 | {
315 | "name": "Indonesia",
316 | "continent": "Asia"
317 | },
318 | {
319 | "name": "Iran",
320 | "continent": "Asia"
321 | },
322 | {
323 | "name": "Iraq",
324 | "continent": "Asia"
325 | },
326 | {
327 | "name": "Ireland",
328 | "continent": "Europe"
329 | },
330 | {
331 | "name": "Isle of Man",
332 | "continent": "Europe"
333 | },
334 | {
335 | "name": "Israel",
336 | "continent": "Asia"
337 | },
338 | {
339 | "name": "Italy",
340 | "continent": "Europe"
341 | },
342 | {
343 | "name": "Jamaica",
344 | "continent": "America"
345 | },
346 | {
347 | "name": "Japan",
348 | "continent": "Asia"
349 | },
350 | {
351 | "name": "Jordan",
352 | "continent": "Asia"
353 | },
354 | {
355 | "name": "Kazakhstan",
356 | "continent": "Asia"
357 | },
358 | {
359 | "name": "Kenya",
360 | "continent": "Africa"
361 | },
362 | {
363 | "name": "Kiribati",
364 | "continent": "Oceania"
365 | },
366 | {
367 | "name": "North Korea",
368 | "continent": "Asia"
369 | },
370 | {
371 | "name": "South Korea",
372 | "continent": "Asia"
373 | },
374 | {
375 | "name": "Kosovo",
376 | "continent": "Europe"
377 | },
378 | {
379 | "name": "Kuwait",
380 | "continent": "Asia"
381 | },
382 | {
383 | "name": "Kyrgyzstan",
384 | "continent": "Asia"
385 | },
386 | {
387 | "name": "Laos",
388 | "continent": "Asia"
389 | },
390 | {
391 | "name": "Latvia",
392 | "continent": "Europe"
393 | },
394 | {
395 | "name": "Lebanon",
396 | "continent": "Asia"
397 | },
398 | {
399 | "name": "Lesotho",
400 | "continent": "Africa"
401 | },
402 | {
403 | "name": "Liberia",
404 | "continent": "Africa"
405 | },
406 | {
407 | "name": "Libya",
408 | "continent": "Africa"
409 | },
410 | {
411 | "name": "Liechtenstein",
412 | "continent": "Europe"
413 | },
414 | {
415 | "name": "Lithuania",
416 | "continent": "Europe"
417 | },
418 | {
419 | "name": "Luxembourg",
420 | "continent": "Europe"
421 | },
422 | {
423 | "name": "Macau",
424 | "continent": "Asia"
425 | },
426 | {
427 | "name": "Macedonia",
428 | "continent": "Europe"
429 | },
430 | {
431 | "name": "Madagascar",
432 | "continent": "Africa"
433 | },
434 | {
435 | "name": "Malawi",
436 | "continent": "Africa"
437 | },
438 | {
439 | "name": "Malaysia",
440 | "continent": "Asia"
441 | },
442 | {
443 | "name": "Maldives",
444 | "continent": "Asia"
445 | },
446 | {
447 | "name": "Mali",
448 | "continent": "Africa"
449 | },
450 | {
451 | "name": "Malta",
452 | "continent": "Europe"
453 | },
454 | {
455 | "name": "Marshall Islands",
456 | "continent": "Oceania"
457 | },
458 | {
459 | "name": "Mauritania",
460 | "continent": "Africa"
461 | },
462 | {
463 | "name": "Mauritius",
464 | "continent": "Africa"
465 | },
466 | {
467 | "name": "Mexico",
468 | "continent": "America"
469 | },
470 | {
471 | "name": "Micronesia",
472 | "continent": "Oceania"
473 | },
474 | {
475 | "name": "Moldova",
476 | "continent": "Europe"
477 | },
478 | {
479 | "name": "Monaco",
480 | "continent": "Europe"
481 | },
482 | {
483 | "name": "Mongolia",
484 | "continent": "Asia"
485 | },
486 | {
487 | "name": "Montenegro",
488 | "continent": "Europe"
489 | },
490 | {
491 | "name": "Morocco",
492 | "continent": "Africa"
493 | },
494 | {
495 | "name": "Mozambique",
496 | "continent": "Africa"
497 | },
498 | {
499 | "name": "Namibia",
500 | "continent": "Africa"
501 | },
502 | {
503 | "name": "Nauru",
504 | "continent": "Oceania"
505 | },
506 | {
507 | "name": "Nepal",
508 | "continent": "Asia"
509 | },
510 | {
511 | "name": "Netherlands",
512 | "continent": "Europe"
513 | },
514 | {
515 | "name": "New Zealand",
516 | "continent": "Oceania"
517 | },
518 | {
519 | "name": "Nicaragua",
520 | "continent": "America"
521 | },
522 | {
523 | "name": "Niger",
524 | "continent": "Africa"
525 | },
526 | {
527 | "name": "Nigeria",
528 | "continent": "Africa"
529 | },
530 | {
531 | "name": "Norway",
532 | "continent": "Europe"
533 | },
534 | {
535 | "name": "Oman",
536 | "continent": "Asia"
537 | },
538 | {
539 | "name": "Pakistan",
540 | "continent": "Asia"
541 | },
542 | {
543 | "name": "Palau",
544 | "continent": "Oceania"
545 | },
546 | {
547 | "name": "Panama",
548 | "continent": "America"
549 | },
550 | {
551 | "name": "Papua New Guinea",
552 | "continent": "Oceania"
553 | },
554 | {
555 | "name": "Paraguay",
556 | "continent": "America"
557 | },
558 | {
559 | "name": "Peru",
560 | "continent": "America"
561 | },
562 | {
563 | "name": "Philippines",
564 | "continent": "Asia"
565 | },
566 | {
567 | "name": "Poland",
568 | "continent": "Europe"
569 | },
570 | {
571 | "name": "Portugal",
572 | "continent": "Europe"
573 | },
574 | {
575 | "name": "Puerto Rico",
576 | "continent": "America"
577 | },
578 | {
579 | "name": "Qatar",
580 | "continent": "Asia"
581 | },
582 | {
583 | "name": "Romania",
584 | "continent": "Europe"
585 | },
586 | {
587 | "name": "Russia",
588 | "continent": "Europe"
589 | },
590 | {
591 | "name": "Rwanda",
592 | "continent": "Africa"
593 | },
594 | {
595 | "name": "Saint Kitts and Nevis",
596 | "continent": "America"
597 | },
598 | {
599 | "name": "Saint Lucia",
600 | "continent": "America"
601 | },
602 | {
603 | "name": "Saint Vincent and the Grenadines",
604 | "continent": "America"
605 | },
606 | {
607 | "name": "Samoa",
608 | "continent": "Oceania"
609 | },
610 | {
611 | "name": "San Marino",
612 | "continent": "Europe"
613 | },
614 | {
615 | "name": "Saudi Arabia",
616 | "continent": "Asia"
617 | },
618 | {
619 | "name": "Scotland",
620 | "continent": "Europe"
621 | },
622 | {
623 | "name": "Senegal",
624 | "continent": "Africa"
625 | },
626 | {
627 | "name": "Serbia",
628 | "continent": "Europe"
629 | },
630 | {
631 | "name": "Seychelles",
632 | "continent": "Africa"
633 | },
634 | {
635 | "name": "Sierra Leone",
636 | "continent": "Africa"
637 | },
638 | {
639 | "name": "Singapore",
640 | "continent": "Asia"
641 | },
642 | {
643 | "name": "Slovakia",
644 | "continent": "Europe"
645 | },
646 | {
647 | "name": "Slovenia",
648 | "continent": "Europe"
649 | },
650 | {
651 | "name": "Solomon Islands",
652 | "continent": "Oceania"
653 | },
654 | {
655 | "name": "Somalia",
656 | "continent": "Africa"
657 | },
658 | {
659 | "name": "South Africa",
660 | "continent": "Africa"
661 | },
662 | {
663 | "name": "Spain",
664 | "continent": "Europe"
665 | },
666 | {
667 | "name": "Sri Lanka",
668 | "continent": "Asia"
669 | },
670 | {
671 | "name": "Sudan",
672 | "continent": "Africa"
673 | },
674 | {
675 | "name": "Suriname",
676 | "continent": "America"
677 | },
678 | {
679 | "name": "Swaziland",
680 | "continent": "Africa"
681 | },
682 | {
683 | "name": "Sweden",
684 | "continent": "Europe"
685 | },
686 | {
687 | "name": "Switzerland",
688 | "continent": "Europe"
689 | },
690 | {
691 | "name": "Syria",
692 | "continent": "Asia"
693 | },
694 | {
695 | "name": "Taiwan",
696 | "continent": "Asia"
697 | },
698 | {
699 | "name": "Tajikistan",
700 | "continent": "Asia"
701 | },
702 | {
703 | "name": "Tanzania",
704 | "continent": "Africa"
705 | },
706 | {
707 | "name": "Thailand",
708 | "continent": "Asia"
709 | },
710 | {
711 | "name": "Togo",
712 | "continent": "Africa"
713 | },
714 | {
715 | "name": "Tonga",
716 | "continent": "Oceania"
717 | },
718 | {
719 | "name": "Trinidad and Tobago",
720 | "continent": "America"
721 | },
722 | {
723 | "name": "Tunisia",
724 | "continent": "Africa"
725 | },
726 | {
727 | "name": "Turkey",
728 | "continent": "Asia"
729 | },
730 | {
731 | "name": "Turkmenistan",
732 | "continent": "Asia"
733 | },
734 | {
735 | "name": "Tuvalu",
736 | "continent": "Oceania"
737 | },
738 | {
739 | "name": "Uganda",
740 | "continent": "Africa"
741 | },
742 | {
743 | "name": "Ukraine",
744 | "continent": "Europe"
745 | },
746 | {
747 | "name": "United Arab Emirates",
748 | "continent": "Asia"
749 | },
750 | {
751 | "name": "United Kingdom",
752 | "continent": "Europe"
753 | },
754 | {
755 | "name": "United States of America",
756 | "continent": "America"
757 | },
758 | {
759 | "name": "Uruguay",
760 | "continent": "America"
761 | },
762 | {
763 | "name": "USSR",
764 | "continent": "Europe"
765 | },
766 | {
767 | "name": "Uzbekistan",
768 | "continent": "Asia"
769 | },
770 | {
771 | "name": "Vanuatu",
772 | "continent": "Oceania"
773 | },
774 | {
775 | "name": "Vatican City",
776 | "continent": "Europe"
777 | },
778 | {
779 | "name": "Venezuela",
780 | "continent": "America"
781 | },
782 | {
783 | "name": "Vietnam",
784 | "continent": "Asia"
785 | },
786 | {
787 | "name": "Wales",
788 | "continent": "Europe"
789 | },
790 | {
791 | "name": "Yemen",
792 | "continent": "Asia"
793 | },
794 | {
795 | "name": "Zambia",
796 | "continent": "Africa"
797 | },
798 | {
799 | "name": "Zimbabwe",
800 | "continent": "Africa"
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/index.js:
--------------------------------------------------------------------------------
1 | import './router.config';
2 |
3 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/app/router.config.js:
--------------------------------------------------------------------------------
1 | import { Visualizer } from '@uirouter/visualizer';
2 | import { DSRPlugin } from '@uirouter/dsr';
3 |
4 | import { APP_MODULE } from './app.module';
5 | import { getContinents, getCountries } from './data.api';
6 |
7 | import './about.component';
8 | import './continentList.component';
9 | import './countryDetail.component';
10 | import './countryList.component';
11 |
12 | export const states = [
13 | {
14 | name: 'continentlist',
15 | url: '/continents',
16 | dsr: true,
17 | component: 'continentList',
18 | resolve: {
19 | 'continents': () => getContinents(),
20 | },
21 | },
22 |
23 | {
24 | name: 'continentlist.countrylist',
25 | url: '/:continent',
26 | component: 'countryList',
27 | resolve: {
28 | 'countries': ($transition$) => getCountries($transition$.params().continent),
29 | },
30 | },
31 |
32 | {
33 | name: 'continentlist.countrylist.countrydetail',
34 | url: '/:country',
35 | component: 'countryDetail',
36 | resolve: {
37 | 'country': ($transition$) => $transition$.params().country,
38 | },
39 | },
40 |
41 | {
42 | name: 'about',
43 | url: '/about',
44 | component: 'about',
45 | },
46 | ];
47 |
48 | APP_MODULE.config(function ($uiRouterProvider) {
49 | $uiRouterProvider.plugin(DSRPlugin);
50 | $uiRouterProvider.plugin(Visualizer);
51 |
52 | // Add states
53 | states.forEach(state => $uiRouterProvider.stateRegistry.register(state));
54 |
55 | // Set initial state
56 | $uiRouterProvider.urlService.rules.initial({ state: 'about' });
57 | });
58 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:4000",
3 | "video": false
4 | }
5 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/cypress/integration/example_spec.js:
--------------------------------------------------------------------------------
1 | describe('example app', () => {
2 | it('loads', () => {
3 | cy.visit('');
4 | });
5 |
6 | it('renders links', () => {
7 | cy.visit('/');
8 | cy.get('a').contains('about');
9 | cy.get('a').contains('continentlist');
10 | });
11 |
12 | it('renders about by default', () => {
13 | cy.visit('/');
14 | cy.contains('This is a trivial Deep State Redirect example app');
15 | });
16 |
17 | it('can navigate to continentlist', () => {
18 | cy.visit('');
19 | cy
20 | .get('a')
21 | .contains('continentlist')
22 | .click();
23 |
24 | cy.contains('Africa');
25 | cy.contains('America');
26 | cy.contains('Oceania');
27 | });
28 |
29 | it('can navigate to belize', () => {
30 | cy.visit('');
31 | cy
32 | .get('a')
33 | .contains('continentlist')
34 | .click();
35 | cy
36 | .get('a')
37 | .contains('America')
38 | .click();
39 | cy
40 | .get('a')
41 | .contains('Belize')
42 | .click();
43 | cy.get('h3').contains('Belize');
44 | });
45 |
46 | it('can navigate to belize and back', () => {
47 | cy.visit('');
48 | cy
49 | .get('a')
50 | .contains('continentlist')
51 | .click();
52 | cy
53 | .get('a')
54 | .contains('America')
55 | .click();
56 | cy.url().should('include', '/America');
57 |
58 | cy
59 | .get('a')
60 | .contains('Belize')
61 | .click();
62 | cy.get('h3').contains('Belize');
63 | cy.url().should('include', '/America/Belize');
64 |
65 | cy
66 | .get('a')
67 | .contains('about')
68 | .click();
69 | cy.contains('This is a trivial Deep State Redirect example app');
70 | });
71 |
72 | it('dsr sends you back to belize', () => {
73 | cy.visit('');
74 | cy
75 | .get('a')
76 | .contains('continentlist')
77 | .click();
78 | cy
79 | .get('a')
80 | .contains('America')
81 | .click();
82 | cy.url().should('include', '/America');
83 |
84 | cy
85 | .get('a')
86 | .contains('Belize')
87 | .click();
88 | cy.url().should('include', '/America/Belize');
89 | cy.get('h3').contains('Belize');
90 |
91 | cy
92 | .get('a')
93 | .contains('about')
94 | .click();
95 | cy.url().should('include', '/about');
96 | cy.contains('This is a trivial Deep State Redirect example app');
97 |
98 | cy
99 | .get('a')
100 | .contains('continentlist')
101 | .click();
102 | cy.url().should('include', '/America/Belize');
103 | cy.get('h3').contains('Belize');
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/index.js:
--------------------------------------------------------------------------------
1 | import './app/index';
2 |
3 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-webpack",
3 | "version": "1.0.0",
4 | "description": "AngularJS/webpack sticky states example",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "npm run build && cypress-runner run --path .",
8 | "test:open": "npm run build && cypress-runner open --path .",
9 | "build": "webpack --progress",
10 | "start": "webpack-dev-server --progress --open"
11 | },
12 | "author": "",
13 | "license": "MIT",
14 | "dependencies": {
15 | "@uirouter/angularjs": "^1.0.13",
16 | "@uirouter/dsr": "^1.0.2",
17 | "@uirouter/visualizer": "^5.1.3",
18 | "angular": "^1.6.8"
19 | },
20 | "devDependencies": {
21 | "@uirouter/cypress-runner": "^1.0.2",
22 | "babel-core": "^6.26.0",
23 | "babel-loader": "^7.1.2",
24 | "webpack": "^3.10.0",
25 | "webpack-dev-server": "^2.10.1"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/styles.css:
--------------------------------------------------------------------------------
1 | .active {
2 | font-weight: bold;
3 | }
4 | .container {
5 | display: flex;
6 | flex-flow: row wrap;
7 | }
8 | .container > * {
9 | border: 1px solid;
10 | padding: 0.5em;
11 | margin: 0.5em;
12 | flex: 1 1 75px;
13 | }
14 | .container > a.active {
15 | background: lightgray;
16 | }
17 |
--------------------------------------------------------------------------------
/examples/angularjs-webpack/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: "./index.js",
3 | output: {
4 | filename: "bundle.js",
5 | },
6 | module: {
7 | loaders: [ { test: /\.js?$/, loader: "babel-loader", } ]
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/examples/create-react-app/README.md:
--------------------------------------------------------------------------------
1 | # create-react-app
2 |
3 | Example showing sticky states installed in a create-react-app app.
4 |
5 | ## Running
6 |
7 | ```
8 | yarn install
9 | yarn start
10 | ```
11 |
--------------------------------------------------------------------------------
/examples/create-react-app/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:4000",
3 | "video": false
4 | }
5 |
--------------------------------------------------------------------------------
/examples/create-react-app/cypress/integration/example_spec.js:
--------------------------------------------------------------------------------
1 | describe('example app', () => {
2 | it('loads', () => {
3 | cy.visit('');
4 | });
5 |
6 | it('renders links', () => {
7 | cy.visit('/');
8 | cy.get('a').contains('about');
9 | cy.get('a').contains('continentlist');
10 | });
11 |
12 | it('renders about by default', () => {
13 | cy.visit('/');
14 | cy.contains('This is a trivial Deep State Redirect example app');
15 | });
16 |
17 | it('can navigate to continentlist', () => {
18 | cy.visit('');
19 | cy
20 | .get('a')
21 | .contains('continentlist')
22 | .click();
23 |
24 | cy.contains('Africa');
25 | cy.contains('America');
26 | cy.contains('Oceania');
27 | });
28 |
29 | it('can navigate to belize', () => {
30 | cy.visit('');
31 | cy
32 | .get('a')
33 | .contains('continentlist')
34 | .click();
35 | cy
36 | .get('a')
37 | .contains('America')
38 | .click();
39 | cy
40 | .get('a')
41 | .contains('Belize')
42 | .click();
43 | cy.get('h3').contains('Belize');
44 | });
45 |
46 | it('can navigate to belize and back', () => {
47 | cy.visit('');
48 | cy
49 | .get('a')
50 | .contains('continentlist')
51 | .click();
52 | cy
53 | .get('a')
54 | .contains('America')
55 | .click();
56 | cy.url().should('include', '/America');
57 |
58 | cy
59 | .get('a')
60 | .contains('Belize')
61 | .click();
62 | cy.get('h3').contains('Belize');
63 | cy.url().should('include', '/America/Belize');
64 |
65 | cy
66 | .get('a')
67 | .contains('about')
68 | .click();
69 | cy.contains('This is a trivial Deep State Redirect example app');
70 | });
71 |
72 | it('dsr sends you back to belize', () => {
73 | cy.visit('');
74 | cy
75 | .get('a')
76 | .contains('continentlist')
77 | .click();
78 | cy
79 | .get('a')
80 | .contains('America')
81 | .click();
82 | cy.url().should('include', '/America');
83 |
84 | cy
85 | .get('a')
86 | .contains('Belize')
87 | .click();
88 | cy.url().should('include', '/America/Belize');
89 | cy.get('h3').contains('Belize');
90 |
91 | cy
92 | .get('a')
93 | .contains('about')
94 | .click();
95 | cy.url().should('include', '/about');
96 | cy.contains('This is a trivial Deep State Redirect example app');
97 |
98 | cy
99 | .get('a')
100 | .contains('continentlist')
101 | .click();
102 | cy.url().should('include', '/America/Belize');
103 | cy.get('h3').contains('Belize');
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/examples/create-react-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-react-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@uirouter/react": "^0.6.2",
7 | "@uirouter/dsr": "^1.0.2",
8 | "@uirouter/visualizer": "^6.0.0",
9 | "react": "^16.2.0",
10 | "react-dom": "^16.2.0"
11 | },
12 | "devDependencies": {
13 | "@uirouter/cypress-runner": "^1.0.2",
14 | "react-scripts": "1.1.1"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "npm run build && cypress-runner run --path build",
20 | "test:open": "npm run build && cypress-runner open --path build",
21 | "eject": "react-scripts eject"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/create-react-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ui-router/dsr/faf4ac097655375f2d1804ef706b3836b73597d3/examples/create-react-app/public/favicon.ico
--------------------------------------------------------------------------------
/examples/create-react-app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/examples/create-react-app/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/About.jsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { UISref } from '@uirouter/react';
3 |
4 | export class About extends React.Component {
5 | render() {
6 | return (
7 |
8 |
This is a trivial Deep State Redirect example app
9 |
10 | Active the continentlist state
11 | Select a continent
12 | Select a country
13 | Reactivate this state (about )
14 |
15 | Active the continents state again.
16 | You are redirected to the previously active substate of
17 | continentlist
(including parameters).
18 | You should see the country you chose in the previous step.
19 |
20 |
21 |
22 | );
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/App.css:
--------------------------------------------------------------------------------
1 | .active {
2 | font-weight: bold;
3 | }
4 | .container {
5 | display: flex;
6 | flex-flow: row wrap;
7 | }
8 | .container > * {
9 | border: 1px solid;
10 | padding: 0.5em;
11 | margin: 0.5em;
12 | flex: 1 1 75px;
13 | }
14 | .container > a.active {
15 | background: lightgray;
16 | }
17 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { UIRouter, UISref, UISrefActive, UIView } from '@uirouter/react';
3 | import { pushStateLocationPlugin } from '@uirouter/core';
4 | import { Visualizer } from '@uirouter/visualizer';
5 | import { DSRPlugin } from "@uirouter/dsr";
6 |
7 | import { ContinentList } from "./ContinentList";
8 | import { CountryList } from "./CountryList";
9 | import { About } from "./About";
10 | import { CountryDetail } from "./CountryDetail";
11 |
12 | import { getContinents, getCountries } from "./data.api";
13 |
14 | import './App.css';
15 |
16 | const plugins = [
17 | pushStateLocationPlugin,
18 | Visualizer,
19 | DSRPlugin,
20 | ];
21 |
22 | export const states = [
23 | {
24 | name: 'continentlist',
25 | url: '/continents',
26 | dsr: true,
27 | component: ContinentList,
28 | resolve: {
29 | 'continents': () => getContinents(),
30 | },
31 | },
32 |
33 | {
34 | name: 'continentlist.countrylist',
35 | url: '/:continent',
36 | component: CountryList,
37 | resolve: {
38 | 'countries': ['$transition$', ($transition$) => getCountries($transition$.params().continent)],
39 | },
40 | },
41 |
42 | {
43 | name: 'continentlist.countrylist.countrydetail',
44 | url: '/:country',
45 | component: CountryDetail,
46 | resolve: {
47 | 'country': ['$transition$', ($transition$) => $transition$.params().country],
48 | },
49 | },
50 |
51 | {
52 | name: 'about',
53 | url: '/about',
54 | component: About,
55 | },
56 | ];
57 |
58 | function routerConfig(router) {
59 | // Set initial state
60 | router.urlService.rules.initial({ state: 'about' });
61 | }
62 |
63 | class App extends Component {
64 | render() {
65 | return (
66 |
67 |
78 |
79 | );
80 | }
81 | }
82 |
83 | export default App;
84 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/ContinentList.jsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { UISref, UISrefActive, UIView } from '@uirouter/react';
3 |
4 | export class ContinentList extends React.Component {
5 | render() {
6 | const { continents } = this.props;
7 | return (
8 |
9 |
Continents
10 |
11 | {continents.map(continent => {
12 | return (
13 |
14 |
15 |
16 | {continent}
17 |
18 |
19 |
20 | );
21 | })}
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/CountryDetail.jsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export class CountryDetail extends React.Component {
4 | render() {
5 | const { country } = this.props;
6 | if (!country) return null;
7 |
8 | const prefix = '//www.randomlists.com/img/national-flags/';
9 | const imageName = country.toLowerCase().replace(/ /g, '_');
10 | const imgSrc = `${prefix}${imageName}.gif`;
11 | const alt = `flag of ${country}}`;
12 |
13 | return (
14 |
15 |
{country}
16 |
17 |
18 |
19 |
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/CountryList.jsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { UISref, UISrefActive, UIView } from '@uirouter/react';
3 |
4 | export class CountryList extends React.Component {
5 | render() {
6 | const { countries } = this.props;
7 |
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | {countries.map(country => {
15 | return (
16 |
17 |
18 | {country}
19 |
20 |
21 | )
22 | })}
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/data.api.js:
--------------------------------------------------------------------------------
1 | function getContinents() {
2 | return Promise.resolve(require('./data.json'))
3 | .then(countries => countries.map(country => country.continent))
4 | .then(continents => continents.reduce((acc, continent) => acc.includes(continent) ? acc : acc.concat(continent), []))
5 | }
6 |
7 | function getCountries(continent) {
8 | return Promise.resolve(require('./data.json'))
9 | .then(countries => countries.filter(country => country.continent === continent))
10 | .then(countries => countries.map(country => country.name));
11 | }
12 |
13 | export { getContinents, getCountries };
14 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Afghanistan",
4 | "continent": "Asia"
5 | },
6 | {
7 | "name": "Albania",
8 | "continent": "Europe"
9 | },
10 | {
11 | "name": "Algeria",
12 | "continent": "Africa"
13 | },
14 | {
15 | "name": "Andorra",
16 | "continent": "Europe"
17 | },
18 | {
19 | "name": "Angola",
20 | "continent": "Africa"
21 | },
22 | {
23 | "name": "Antigua and Barbuda",
24 | "continent": "America"
25 | },
26 | {
27 | "name": "Argentina",
28 | "continent": "America"
29 | },
30 | {
31 | "name": "Armenia",
32 | "continent": "Asia"
33 | },
34 | {
35 | "name": "Australia",
36 | "continent": "Oceania"
37 | },
38 | {
39 | "name": "Austria",
40 | "continent": "Europe"
41 | },
42 | {
43 | "name": "Azerbaijan",
44 | "continent": "Asia"
45 | },
46 | {
47 | "name": "Bahamas",
48 | "continent": "America"
49 | },
50 | {
51 | "name": "Bahrain",
52 | "continent": "Asia"
53 | },
54 | {
55 | "name": "Bangladesh",
56 | "continent": "Asia"
57 | },
58 | {
59 | "name": "Barbados",
60 | "continent": "America"
61 | },
62 | {
63 | "name": "Belarus",
64 | "continent": "Europe"
65 | },
66 | {
67 | "name": "Belgium",
68 | "continent": "Europe"
69 | },
70 | {
71 | "name": "Belize",
72 | "continent": "America"
73 | },
74 | {
75 | "name": "Benin",
76 | "continent": "Africa"
77 | },
78 | {
79 | "name": "Bhutan",
80 | "continent": "Asia"
81 | },
82 | {
83 | "name": "Bolivia",
84 | "continent": "America"
85 | },
86 | {
87 | "name": "Bosnia and Herzegovina",
88 | "continent": "Europe"
89 | },
90 | {
91 | "name": "Botswana",
92 | "continent": "Africa"
93 | },
94 | {
95 | "name": "Brazil",
96 | "continent": "America"
97 | },
98 | {
99 | "name": "Brunei",
100 | "continent": "Asia"
101 | },
102 | {
103 | "name": "Bulgaria",
104 | "continent": "Europe"
105 | },
106 | {
107 | "name": "Burkina Faso",
108 | "continent": "Africa"
109 | },
110 | {
111 | "name": "Myanmar",
112 | "continent": "Asia"
113 | },
114 | {
115 | "name": "Burundi",
116 | "continent": "Africa"
117 | },
118 | {
119 | "name": "Cambodia",
120 | "continent": "Asia"
121 | },
122 | {
123 | "name": "Cameroon",
124 | "continent": "Africa"
125 | },
126 | {
127 | "name": "Canada",
128 | "continent": "America"
129 | },
130 | {
131 | "name": "Cape Verde",
132 | "continent": "Africa"
133 | },
134 | {
135 | "name": "Central African Republic",
136 | "continent": "Africa"
137 | },
138 | {
139 | "name": "Chad",
140 | "continent": "Africa"
141 | },
142 | {
143 | "name": "Chile",
144 | "continent": "America"
145 | },
146 | {
147 | "name": "China",
148 | "continent": "Asia"
149 | },
150 | {
151 | "name": "Colombia",
152 | "continent": "America"
153 | },
154 | {
155 | "name": "Comoros",
156 | "continent": "Africa"
157 | },
158 | {
159 | "name": "Congo",
160 | "continent": "Africa"
161 | },
162 | {
163 | "name": "Costa Rica",
164 | "continent": "America"
165 | },
166 | {
167 | "name": "Croatia",
168 | "continent": "Europe"
169 | },
170 | {
171 | "name": "Cuba",
172 | "continent": "America"
173 | },
174 | {
175 | "name": "Cyprus",
176 | "continent": "Europe"
177 | },
178 | {
179 | "name": "Czech Republic",
180 | "continent": "Europe"
181 | },
182 | {
183 | "name": "Denmark",
184 | "continent": "Europe"
185 | },
186 | {
187 | "name": "Djibouti",
188 | "continent": "Africa"
189 | },
190 | {
191 | "name": "Dominica",
192 | "continent": "America"
193 | },
194 | {
195 | "name": "Dominican Republic",
196 | "continent": "America"
197 | },
198 | {
199 | "name": "East Timor",
200 | "continent": "Asia"
201 | },
202 | {
203 | "name": "Ecuador",
204 | "continent": "America"
205 | },
206 | {
207 | "name": "Egypt",
208 | "continent": "Africa"
209 | },
210 | {
211 | "name": "El Salvador",
212 | "continent": "America"
213 | },
214 | {
215 | "name": "England",
216 | "continent": "Europe"
217 | },
218 | {
219 | "name": "Equatorial Guinea",
220 | "continent": "Africa"
221 | },
222 | {
223 | "name": "Eritrea",
224 | "continent": "Africa"
225 | },
226 | {
227 | "name": "Estonia",
228 | "continent": "Europe"
229 | },
230 | {
231 | "name": "Ethiopia",
232 | "continent": "Africa"
233 | },
234 | {
235 | "name": "Fiji",
236 | "continent": "Oceania"
237 | },
238 | {
239 | "name": "Finland",
240 | "continent": "Europe"
241 | },
242 | {
243 | "name": "France",
244 | "continent": "Europe"
245 | },
246 | {
247 | "name": "Gabon",
248 | "continent": "Africa"
249 | },
250 | {
251 | "name": "Gambia",
252 | "continent": "Africa"
253 | },
254 | {
255 | "name": "Georgia",
256 | "continent": "Asia"
257 | },
258 | {
259 | "name": "Germany",
260 | "continent": "Europe"
261 | },
262 | {
263 | "name": "Ghana",
264 | "continent": "Africa"
265 | },
266 | {
267 | "name": "Greece",
268 | "continent": "Europe"
269 | },
270 | {
271 | "name": "Grenada",
272 | "continent": "America"
273 | },
274 | {
275 | "name": "Guatemala",
276 | "continent": "America"
277 | },
278 | {
279 | "name": "Guinea",
280 | "continent": "Africa"
281 | },
282 | {
283 | "name": "Guinea-Bissau",
284 | "continent": "Africa"
285 | },
286 | {
287 | "name": "Guyana",
288 | "continent": "America"
289 | },
290 | {
291 | "name": "Haiti",
292 | "continent": "America"
293 | },
294 | {
295 | "name": "Honduras",
296 | "continent": "America"
297 | },
298 | {
299 | "name": "Hong Kong",
300 | "continent": "Asia"
301 | },
302 | {
303 | "name": "Hungary",
304 | "continent": "Europe"
305 | },
306 | {
307 | "name": "Iceland",
308 | "continent": "Europe"
309 | },
310 | {
311 | "name": "India",
312 | "continent": "Asia"
313 | },
314 | {
315 | "name": "Indonesia",
316 | "continent": "Asia"
317 | },
318 | {
319 | "name": "Iran",
320 | "continent": "Asia"
321 | },
322 | {
323 | "name": "Iraq",
324 | "continent": "Asia"
325 | },
326 | {
327 | "name": "Ireland",
328 | "continent": "Europe"
329 | },
330 | {
331 | "name": "Isle of Man",
332 | "continent": "Europe"
333 | },
334 | {
335 | "name": "Israel",
336 | "continent": "Asia"
337 | },
338 | {
339 | "name": "Italy",
340 | "continent": "Europe"
341 | },
342 | {
343 | "name": "Jamaica",
344 | "continent": "America"
345 | },
346 | {
347 | "name": "Japan",
348 | "continent": "Asia"
349 | },
350 | {
351 | "name": "Jordan",
352 | "continent": "Asia"
353 | },
354 | {
355 | "name": "Kazakhstan",
356 | "continent": "Asia"
357 | },
358 | {
359 | "name": "Kenya",
360 | "continent": "Africa"
361 | },
362 | {
363 | "name": "Kiribati",
364 | "continent": "Oceania"
365 | },
366 | {
367 | "name": "North Korea",
368 | "continent": "Asia"
369 | },
370 | {
371 | "name": "South Korea",
372 | "continent": "Asia"
373 | },
374 | {
375 | "name": "Kosovo",
376 | "continent": "Europe"
377 | },
378 | {
379 | "name": "Kuwait",
380 | "continent": "Asia"
381 | },
382 | {
383 | "name": "Kyrgyzstan",
384 | "continent": "Asia"
385 | },
386 | {
387 | "name": "Laos",
388 | "continent": "Asia"
389 | },
390 | {
391 | "name": "Latvia",
392 | "continent": "Europe"
393 | },
394 | {
395 | "name": "Lebanon",
396 | "continent": "Asia"
397 | },
398 | {
399 | "name": "Lesotho",
400 | "continent": "Africa"
401 | },
402 | {
403 | "name": "Liberia",
404 | "continent": "Africa"
405 | },
406 | {
407 | "name": "Libya",
408 | "continent": "Africa"
409 | },
410 | {
411 | "name": "Liechtenstein",
412 | "continent": "Europe"
413 | },
414 | {
415 | "name": "Lithuania",
416 | "continent": "Europe"
417 | },
418 | {
419 | "name": "Luxembourg",
420 | "continent": "Europe"
421 | },
422 | {
423 | "name": "Macau",
424 | "continent": "Asia"
425 | },
426 | {
427 | "name": "Macedonia",
428 | "continent": "Europe"
429 | },
430 | {
431 | "name": "Madagascar",
432 | "continent": "Africa"
433 | },
434 | {
435 | "name": "Malawi",
436 | "continent": "Africa"
437 | },
438 | {
439 | "name": "Malaysia",
440 | "continent": "Asia"
441 | },
442 | {
443 | "name": "Maldives",
444 | "continent": "Asia"
445 | },
446 | {
447 | "name": "Mali",
448 | "continent": "Africa"
449 | },
450 | {
451 | "name": "Malta",
452 | "continent": "Europe"
453 | },
454 | {
455 | "name": "Marshall Islands",
456 | "continent": "Oceania"
457 | },
458 | {
459 | "name": "Mauritania",
460 | "continent": "Africa"
461 | },
462 | {
463 | "name": "Mauritius",
464 | "continent": "Africa"
465 | },
466 | {
467 | "name": "Mexico",
468 | "continent": "America"
469 | },
470 | {
471 | "name": "Micronesia",
472 | "continent": "Oceania"
473 | },
474 | {
475 | "name": "Moldova",
476 | "continent": "Europe"
477 | },
478 | {
479 | "name": "Monaco",
480 | "continent": "Europe"
481 | },
482 | {
483 | "name": "Mongolia",
484 | "continent": "Asia"
485 | },
486 | {
487 | "name": "Montenegro",
488 | "continent": "Europe"
489 | },
490 | {
491 | "name": "Morocco",
492 | "continent": "Africa"
493 | },
494 | {
495 | "name": "Mozambique",
496 | "continent": "Africa"
497 | },
498 | {
499 | "name": "Namibia",
500 | "continent": "Africa"
501 | },
502 | {
503 | "name": "Nauru",
504 | "continent": "Oceania"
505 | },
506 | {
507 | "name": "Nepal",
508 | "continent": "Asia"
509 | },
510 | {
511 | "name": "Netherlands",
512 | "continent": "Europe"
513 | },
514 | {
515 | "name": "New Zealand",
516 | "continent": "Oceania"
517 | },
518 | {
519 | "name": "Nicaragua",
520 | "continent": "America"
521 | },
522 | {
523 | "name": "Niger",
524 | "continent": "Africa"
525 | },
526 | {
527 | "name": "Nigeria",
528 | "continent": "Africa"
529 | },
530 | {
531 | "name": "Norway",
532 | "continent": "Europe"
533 | },
534 | {
535 | "name": "Oman",
536 | "continent": "Asia"
537 | },
538 | {
539 | "name": "Pakistan",
540 | "continent": "Asia"
541 | },
542 | {
543 | "name": "Palau",
544 | "continent": "Oceania"
545 | },
546 | {
547 | "name": "Panama",
548 | "continent": "America"
549 | },
550 | {
551 | "name": "Papua New Guinea",
552 | "continent": "Oceania"
553 | },
554 | {
555 | "name": "Paraguay",
556 | "continent": "America"
557 | },
558 | {
559 | "name": "Peru",
560 | "continent": "America"
561 | },
562 | {
563 | "name": "Philippines",
564 | "continent": "Asia"
565 | },
566 | {
567 | "name": "Poland",
568 | "continent": "Europe"
569 | },
570 | {
571 | "name": "Portugal",
572 | "continent": "Europe"
573 | },
574 | {
575 | "name": "Puerto Rico",
576 | "continent": "America"
577 | },
578 | {
579 | "name": "Qatar",
580 | "continent": "Asia"
581 | },
582 | {
583 | "name": "Romania",
584 | "continent": "Europe"
585 | },
586 | {
587 | "name": "Russia",
588 | "continent": "Europe"
589 | },
590 | {
591 | "name": "Rwanda",
592 | "continent": "Africa"
593 | },
594 | {
595 | "name": "Saint Kitts and Nevis",
596 | "continent": "America"
597 | },
598 | {
599 | "name": "Saint Lucia",
600 | "continent": "America"
601 | },
602 | {
603 | "name": "Saint Vincent and the Grenadines",
604 | "continent": "America"
605 | },
606 | {
607 | "name": "Samoa",
608 | "continent": "Oceania"
609 | },
610 | {
611 | "name": "San Marino",
612 | "continent": "Europe"
613 | },
614 | {
615 | "name": "Saudi Arabia",
616 | "continent": "Asia"
617 | },
618 | {
619 | "name": "Scotland",
620 | "continent": "Europe"
621 | },
622 | {
623 | "name": "Senegal",
624 | "continent": "Africa"
625 | },
626 | {
627 | "name": "Serbia",
628 | "continent": "Europe"
629 | },
630 | {
631 | "name": "Seychelles",
632 | "continent": "Africa"
633 | },
634 | {
635 | "name": "Sierra Leone",
636 | "continent": "Africa"
637 | },
638 | {
639 | "name": "Singapore",
640 | "continent": "Asia"
641 | },
642 | {
643 | "name": "Slovakia",
644 | "continent": "Europe"
645 | },
646 | {
647 | "name": "Slovenia",
648 | "continent": "Europe"
649 | },
650 | {
651 | "name": "Solomon Islands",
652 | "continent": "Oceania"
653 | },
654 | {
655 | "name": "Somalia",
656 | "continent": "Africa"
657 | },
658 | {
659 | "name": "South Africa",
660 | "continent": "Africa"
661 | },
662 | {
663 | "name": "Spain",
664 | "continent": "Europe"
665 | },
666 | {
667 | "name": "Sri Lanka",
668 | "continent": "Asia"
669 | },
670 | {
671 | "name": "Sudan",
672 | "continent": "Africa"
673 | },
674 | {
675 | "name": "Suriname",
676 | "continent": "America"
677 | },
678 | {
679 | "name": "Swaziland",
680 | "continent": "Africa"
681 | },
682 | {
683 | "name": "Sweden",
684 | "continent": "Europe"
685 | },
686 | {
687 | "name": "Switzerland",
688 | "continent": "Europe"
689 | },
690 | {
691 | "name": "Syria",
692 | "continent": "Asia"
693 | },
694 | {
695 | "name": "Taiwan",
696 | "continent": "Asia"
697 | },
698 | {
699 | "name": "Tajikistan",
700 | "continent": "Asia"
701 | },
702 | {
703 | "name": "Tanzania",
704 | "continent": "Africa"
705 | },
706 | {
707 | "name": "Thailand",
708 | "continent": "Asia"
709 | },
710 | {
711 | "name": "Togo",
712 | "continent": "Africa"
713 | },
714 | {
715 | "name": "Tonga",
716 | "continent": "Oceania"
717 | },
718 | {
719 | "name": "Trinidad and Tobago",
720 | "continent": "America"
721 | },
722 | {
723 | "name": "Tunisia",
724 | "continent": "Africa"
725 | },
726 | {
727 | "name": "Turkey",
728 | "continent": "Asia"
729 | },
730 | {
731 | "name": "Turkmenistan",
732 | "continent": "Asia"
733 | },
734 | {
735 | "name": "Tuvalu",
736 | "continent": "Oceania"
737 | },
738 | {
739 | "name": "Uganda",
740 | "continent": "Africa"
741 | },
742 | {
743 | "name": "Ukraine",
744 | "continent": "Europe"
745 | },
746 | {
747 | "name": "United Arab Emirates",
748 | "continent": "Asia"
749 | },
750 | {
751 | "name": "United Kingdom",
752 | "continent": "Europe"
753 | },
754 | {
755 | "name": "United States of America",
756 | "continent": "America"
757 | },
758 | {
759 | "name": "Uruguay",
760 | "continent": "America"
761 | },
762 | {
763 | "name": "USSR",
764 | "continent": "Europe"
765 | },
766 | {
767 | "name": "Uzbekistan",
768 | "continent": "Asia"
769 | },
770 | {
771 | "name": "Vanuatu",
772 | "continent": "Oceania"
773 | },
774 | {
775 | "name": "Vatican City",
776 | "continent": "Europe"
777 | },
778 | {
779 | "name": "Venezuela",
780 | "continent": "America"
781 | },
782 | {
783 | "name": "Vietnam",
784 | "continent": "Asia"
785 | },
786 | {
787 | "name": "Wales",
788 | "continent": "Europe"
789 | },
790 | {
791 | "name": "Yemen",
792 | "continent": "Asia"
793 | },
794 | {
795 | "name": "Zambia",
796 | "continent": "Africa"
797 | },
798 | {
799 | "name": "Zimbabwe",
800 | "continent": "Africa"
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/examples/create-react-app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(React.createElement(App), document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testEnvironment: 'jsdom',
4 | roots: ['src', 'test'],
5 | testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)', '**/?*Spec.[jt]s'],
6 | };
7 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file
2 | var karma = require('karma');
3 |
4 | module.exports = function(karma) {
5 | var config = {
6 | singleRun: true,
7 | autoWatch: false,
8 | autoWatchInterval: 0,
9 |
10 | // level of logging
11 | // possible values: LOG_DISABLE, LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG
12 | logLevel: 'warn',
13 |
14 | reporters: ['super-dots', 'mocha'],
15 | colors: true,
16 | mochaReporter: {
17 | output: 'minimal',
18 | },
19 |
20 | port: 8080,
21 |
22 | // base path, that will be used to resolve files and exclude
23 | basePath: '.',
24 |
25 | browsers: ['ChromeHeadlessNoSandbox'],
26 | customLaunchers: {
27 | ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', flags: ['--no-sandbox'] },
28 | },
29 |
30 | frameworks: ['jasmine'],
31 |
32 | plugins: [
33 | require('karma-webpack'),
34 | require('karma-sourcemap-loader'),
35 | require('karma-super-dots-reporter'),
36 | require('karma-mocha-reporter'),
37 | require('karma-jasmine'),
38 | require('karma-chrome-launcher'),
39 | ],
40 |
41 | webpack: {
42 | mode: 'development',
43 | devtool: 'inline-source-map',
44 |
45 | resolve: {
46 | extensions: ['.js', '.ts'],
47 | },
48 |
49 | module: {
50 | rules: [{ test: /\.ts$/, use: 'ts-loader' }],
51 | },
52 | },
53 |
54 | webpackMiddleware: {
55 | stats: 'minimal',
56 | },
57 |
58 | files: ['test/index.js'],
59 |
60 | preprocessors: {
61 | 'test/index.js': ['webpack', 'sourcemap'],
62 | },
63 | };
64 |
65 | karma.set(config);
66 | };
67 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@uirouter/dsr",
3 | "description": "UI-Router Deep State Redirect: redirect to the most recently activated child state",
4 | "version": "1.2.0",
5 | "scripts": {
6 | "clean": "shx rm -rf lib lib-esm _bundles",
7 | "build": "npm run compile && rollup -c && rollup -c --environment MINIFY",
8 | "compile": "npm run clean && tsc && tsc -m es6 --outDir lib-esm",
9 | "test": "jest",
10 | "test:downstream": "test_downstream_projects",
11 | "watch": "run-p watch:*",
12 | "watch:buildjs": "tsc -w",
13 | "watch:test": "jest --watch",
14 | "debug": "node --inspect ./node_modules/.bin/jest --runInBand --watch",
15 | "changelog": "update_changelog",
16 | "release": "release",
17 | "prepublishOnly": "npm run build"
18 | },
19 | "homepage": "https://ui-router.github.io",
20 | "contributors": [
21 | {
22 | "name": "Chris Thielen",
23 | "web": "https://github.com/christopherthielen"
24 | }
25 | ],
26 | "maintainers": [
27 | {
28 | "name": "UIRouter Team",
29 | "web": "https://github.com/ui-router?tab=members"
30 | }
31 | ],
32 | "repository": {
33 | "type": "git",
34 | "url": "https://github.com/ui-router/dsr.git"
35 | },
36 | "bugs": {
37 | "url": "https://github.com/ui-router/dsr/issues"
38 | },
39 | "engines": {
40 | "node": ">=4.0.0"
41 | },
42 | "jsnext:main": "lib-esm/index.js",
43 | "main": "lib/index.js",
44 | "typings": "lib/index.d.ts",
45 | "license": "MIT",
46 | "peerDependencies": {
47 | "@uirouter/core": ">=5.0.0"
48 | },
49 | "devDependencies": {
50 | "@types/jest": "^26.0.14",
51 | "@types/jquery": "^3.3.38",
52 | "@types/lodash": "^4.14.152",
53 | "@typescript-eslint/eslint-plugin": "^4.1.1",
54 | "@typescript-eslint/parser": "^4.1.1",
55 | "@uirouter/core": "^6.0.5",
56 | "@uirouter/publish-scripts": "^2.5.4",
57 | "bufferutil": "^4.0.1",
58 | "canvas": "^2.5.0",
59 | "eslint": "^7.9.0",
60 | "eslint-config-prettier": "^6.11.0",
61 | "eslint-plugin-prettier": "^3.1.4",
62 | "husky": "^4.2.5",
63 | "jest": "^26.4.2",
64 | "lodash": "^4.17.11",
65 | "prettier": "^2.0.5",
66 | "pretty-quick": "^2.0.1",
67 | "rollup": "^2.10.9",
68 | "rollup-plugin-node-resolve": "^5.2.0",
69 | "rollup-plugin-sourcemaps": "^0.6.2",
70 | "rollup-plugin-uglify": "^6.0.1",
71 | "ts-jest": "^26.4.0",
72 | "typescript": "^3.9.3",
73 | "utf-8-validate": "^5.0.2"
74 | },
75 | "husky": {
76 | "hooks": {
77 | "pre-commit": "pretty-quick --staged"
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import nodeResolve from 'rollup-plugin-node-resolve';
2 | import { uglify } from 'rollup-plugin-uglify';
3 | import sourcemaps from 'rollup-plugin-sourcemaps';
4 |
5 | var MINIFY = process.env.MINIFY;
6 |
7 | var pkg = require('./package.json');
8 | var banner = `/**
9 | * ${pkg.description}
10 | * @version v${pkg.version}
11 | * @link ${pkg.homepage}
12 | * @license MIT License, http://www.opensource.org/licenses/MIT
13 | */`;
14 |
15 | var uglifyOpts = { output: {} };
16 | // retain multiline comment with @license
17 | uglifyOpts.output.comments = (node, comment) => comment.type === 'comment2' && /@license/i.test(comment.value);
18 |
19 | var plugins = [nodeResolve({ jsnext: true }), sourcemaps()];
20 |
21 | if (MINIFY) plugins.push(uglify(uglifyOpts));
22 |
23 | var extension = MINIFY ? '.min.js' : '.js';
24 |
25 | export default {
26 | input: 'lib-esm/index.js',
27 | output: {
28 | name: pkg.name,
29 | globals: { '@uirouter/core': '@uirouter/core' },
30 | sourcemap: true,
31 | format: 'umd',
32 | exports: 'named',
33 | banner: banner,
34 | file: '_bundles/ui-router-dsr' + extension,
35 | },
36 | external: '@uirouter/core',
37 | plugins: plugins,
38 | };
39 |
--------------------------------------------------------------------------------
/src/DSRDataStore.ts:
--------------------------------------------------------------------------------
1 | import { StateOrName, UIRouter } from '@uirouter/core';
2 | import { RecordedDSR } from './interface';
3 |
4 | export interface DSRDataStore {
5 | init(router: UIRouter): void;
6 | // Gets the remembered DSR target state for a given state and params
7 | get(state: StateOrName): RecordedDSR[];
8 | // Sets the remembered DSR target state for a given state and params
9 | set(state: StateOrName, recordedDSR: RecordedDSR[] | undefined): void;
10 | }
11 |
12 | export class StateObjectDataStore implements DSRDataStore {
13 | private router: UIRouter;
14 |
15 | private getState(stateOrName: StateOrName) {
16 | const state = this.router.stateService.get(stateOrName);
17 | return state && state.$$state();
18 | }
19 |
20 | public init(router: UIRouter): void {
21 | this.router = router;
22 | }
23 |
24 | public get(stateOrName: StateOrName): RecordedDSR[] {
25 | return this.getState(stateOrName).$dsr || [];
26 | }
27 |
28 | public set(stateOrName: StateOrName, recordedDsr: RecordedDSR[]): void {
29 | const state = this.getState(stateOrName);
30 | if (recordedDsr) {
31 | state.$dsr = recordedDsr;
32 | } else {
33 | delete state.$dsr;
34 | }
35 | }
36 | }
37 |
38 | export class LocalStorageDataStore implements DSRDataStore {
39 | private router: UIRouter;
40 | private key = 'uiRouterDeepStateRedirect';
41 | private _storage: Storage = localStorage;
42 |
43 | constructor(storage?: Storage) {
44 | this._storage = storage || localStorage;
45 | }
46 |
47 | private getStore() {
48 | const item = this._storage.getItem(this.key);
49 | return JSON.parse(item || '{}');
50 | }
51 |
52 | private setStore(contents: any) {
53 | if (contents) {
54 | try {
55 | this._storage.setItem(this.key, JSON.stringify(contents));
56 | } catch (err) {
57 | console.error(
58 | 'UI-Router Deep State Redirect: cannot store object in LocalStorage. Is there a circular reference?',
59 | contents
60 | );
61 | console.error(err);
62 | }
63 | } else {
64 | this._storage.removeItem(this.key);
65 | }
66 | }
67 |
68 | private getStateName(stateOrName: StateOrName) {
69 | const state = this.router.stateService.get(stateOrName);
70 | return state && state.name;
71 | }
72 |
73 | public init(router: UIRouter): void {
74 | this.router = router;
75 | }
76 |
77 | public get(stateOrName: StateOrName): RecordedDSR[] {
78 | const stateName = this.getStateName(stateOrName);
79 | const store = this.getStore();
80 | return store[stateName] || [];
81 | }
82 |
83 | public set(stateOrName: StateOrName, recordedDsr: RecordedDSR[]): void {
84 | const stateName = this.getStateName(stateOrName);
85 | const store = this.getStore();
86 | store[stateName] = recordedDsr;
87 | this.setStore(store);
88 | }
89 | }
90 |
91 | export class SessionStorageDataStore extends LocalStorageDataStore {
92 | constructor() {
93 | super(sessionStorage);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/dsr.ts:
--------------------------------------------------------------------------------
1 | import {
2 | StateObject,
3 | StateDeclaration,
4 | Param,
5 | UIRouter,
6 | RawParams,
7 | StateOrName,
8 | TargetState,
9 | Transition,
10 | UIRouterPlugin,
11 | TransitionService,
12 | StateService,
13 | } from '@uirouter/core';
14 |
15 | import { DSRDataStore, StateObjectDataStore } from './DSRDataStore';
16 | import { _DSRConfig, DSRConfigObj, DSRFunction, DSRProp, ParamPredicate, RecordedDSR } from './interface';
17 |
18 | class DSRPlugin implements UIRouterPlugin {
19 | name = 'deep-state-redirect';
20 |
21 | dataStore: DSRDataStore;
22 | $transitions: TransitionService;
23 | $state: StateService;
24 | hookDeregFns = [];
25 |
26 | constructor($uiRouter: UIRouter, options: { dataStore: DSRDataStore }) {
27 | this.$transitions = $uiRouter.transitionService;
28 | this.$state = $uiRouter.stateService;
29 | this.dataStore = (options && options.dataStore) || new StateObjectDataStore();
30 | this.dataStore.init($uiRouter);
31 |
32 | this.hookDeregFns.push(
33 | this.$transitions.onRetain(
34 | { retained: (state) => !!this.getDsrProp(state.self) },
35 | this.recordDeepState.bind(this)
36 | )
37 | );
38 | this.hookDeregFns.push(
39 | this.$transitions.onEnter({ entering: (state) => !!this.getDsrProp(state.self) }, this.recordDeepState.bind(this))
40 | );
41 | this.hookDeregFns.push(
42 | this.$transitions.onBefore({ to: (state) => !!this.getDsrProp(state.self) }, this.deepStateRedirect.bind(this))
43 | );
44 | }
45 |
46 | dispose(_router: UIRouter): void {
47 | this.hookDeregFns.forEach((fn) => fn());
48 | }
49 |
50 | /**
51 | * Resets deep state redirect
52 | *
53 | * A deep state is recorded for each DSR state.
54 | * This function resets recorded deep state redirect(s) to the initial value.
55 | *
56 | * If called with no parameters, the redirects for all states are reset.
57 | *
58 | * If called with a `state` parameter, the redirect for that state is reset.
59 | *
60 | * If called with `state` and `params` parameters, the redirect for that state and set of parameter values is reset.
61 | *
62 | * @param state (optional) the redirect for this state will be reset
63 | * @param params (optional) the redirect for the state and parameters will be reset
64 | */
65 | reset(state?: StateOrName, params?: RawParams): void {
66 | const { $state } = this;
67 | if (!state) {
68 | $state.get().forEach((_state) => this.dataStore.set(_state, undefined));
69 | } else if (!params) {
70 | this.dataStore.set(state, undefined);
71 | } else {
72 | const currentDSRS = this.dataStore.get(state);
73 | const $$state = $state.get(state).$$state();
74 | this.dataStore.set(state, currentDSRS.filter(this.paramsEqual($$state, params, undefined, true)));
75 | }
76 | }
77 |
78 | /**
79 | * Returns the recorded redirect
80 | *
81 | * Returns the recorded redirect for a given DSR `state` (and optionally `params`).
82 | *
83 | * @param state the DSR state
84 | * @param params (optional) the parameter values
85 | *
86 | * @returns the recorded redirect `TargetState`
87 | */
88 | getRedirect(state: StateOrName, params?: RawParams): TargetState {
89 | return this.getDeepStateRedirect(state, params);
90 | }
91 |
92 | private getDsrProp(state: StateDeclaration): DSRProp {
93 | return state.deepStateRedirect || state.dsr;
94 | }
95 |
96 | public getConfig(state: StateDeclaration): _DSRConfig {
97 | const { $state } = this;
98 | const dsrProp: DSRProp = this.getDsrProp(state);
99 | if (typeof dsrProp === 'undefined') return;
100 |
101 | let params: ParamPredicate;
102 | let defaultTarget: TargetState = typeof dsrProp === 'string' ? $state.target(dsrProp) : undefined;
103 | let fn: DSRFunction = typeof dsrProp === 'function' ? dsrProp : undefined;
104 |
105 | if (typeof dsrProp === 'object') {
106 | fn = dsrProp.fn;
107 | if (typeof dsrProp.default === 'object') {
108 | defaultTarget = $state.target(dsrProp.default.state, dsrProp.default.params, dsrProp.default.options);
109 | } else if (typeof dsrProp.default === 'string') {
110 | defaultTarget = $state.target(dsrProp.default);
111 | }
112 |
113 | const paramsProp = (dsrProp as DSRConfigObj).params;
114 |
115 | if (paramsProp === true) {
116 | params = () => true;
117 | } else if (Array.isArray(paramsProp)) {
118 | params = (param: Param) => paramsProp.indexOf(param.id) !== -1;
119 | }
120 | }
121 |
122 | fn = fn || (((transition: Transition, target: TargetState) => target) as DSRFunction);
123 |
124 | return { default: defaultTarget, params, fn };
125 | }
126 |
127 | public paramsEqual(
128 | state: StateObject,
129 | transParams: RawParams,
130 | paramPredicate: ParamPredicate = () => true,
131 | negate = false
132 | ): (redirect: RecordedDSR) => boolean {
133 | const schema = state.parameters({ inherit: true }).filter(paramPredicate);
134 |
135 | return (redirect: RecordedDSR) => {
136 | const equals = Param.equals(schema, redirect.triggerParams, transParams);
137 | return negate ? !equals : equals;
138 | };
139 | }
140 |
141 | private recordDeepState(transition: Transition, state: StateDeclaration): void {
142 | const { $state } = this;
143 | const hasParamsConfig = !!this.getConfig(state).params;
144 | const _state: StateObject = state.$$state();
145 |
146 | transition.promise.then(() => {
147 | const transTo = transition.to();
148 | const triggerParams = transition.params();
149 | const target: TargetState = $state.target(transTo, triggerParams);
150 | const targetStateName = target.name();
151 | const targetParams = target.params();
152 | const recordedDSR: RecordedDSR = { triggerParams, targetStateName, targetParams };
153 |
154 | if (hasParamsConfig) {
155 | const currentDSRS: RecordedDSR[] = this.dataStore.get(_state);
156 | const predicate = this.paramsEqual(transTo.$$state(), triggerParams, this.getConfig(state).params, true);
157 | const updatedDSRS = currentDSRS.filter(predicate).concat(recordedDSR);
158 | this.dataStore.set(_state, updatedDSRS);
159 | } else {
160 | this.dataStore.set(_state, [recordedDSR]);
161 | }
162 | });
163 | }
164 |
165 | private deepStateRedirect(transition: Transition): TargetState | undefined {
166 | const opts = transition.options();
167 | if (opts['ignoreDsr'] || (opts.custom && opts.custom.ignoreDsr)) return;
168 |
169 | const config: _DSRConfig = this.getConfig(transition.to());
170 | let redirect: TargetState = this.getDeepStateRedirect(transition.to(), transition.params());
171 |
172 | redirect = config.fn(transition, redirect);
173 |
174 | if (redirect && redirect.state() === transition.to()) return;
175 |
176 | return redirect;
177 | }
178 |
179 | private getTargetState(dsr: RecordedDSR): TargetState {
180 | return this.$state.target(dsr.targetStateName, dsr.targetParams);
181 | }
182 |
183 | private getDeepStateRedirect(stateOrName: StateOrName, params: RawParams): TargetState {
184 | const { $state } = this;
185 | const _state = $state.get(stateOrName);
186 | const state = _state && _state.$$state();
187 | const config: _DSRConfig = this.getConfig(_state);
188 | const currentDSRS = this.dataStore.get(stateOrName);
189 | let recordedDSR: RecordedDSR;
190 |
191 | if (config.params) {
192 | const predicate = this.paramsEqual(state, params, config.params, false);
193 | const match = currentDSRS.find(predicate);
194 | recordedDSR = match && match;
195 | } else {
196 | recordedDSR = currentDSRS[0] && currentDSRS[0];
197 | }
198 |
199 | let dsrTarget = recordedDSR ? this.getTargetState(recordedDSR) : config.default;
200 |
201 | if (dsrTarget) {
202 | // merge original params with deep state redirect params
203 | const targetParams = Object.assign({}, params, dsrTarget.params());
204 | dsrTarget = $state.target(dsrTarget.state(), targetParams, dsrTarget.options());
205 | }
206 |
207 | return dsrTarget;
208 | }
209 | }
210 |
211 | export { DSRPlugin };
212 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './dsr';
2 |
--------------------------------------------------------------------------------
/src/interface.ts:
--------------------------------------------------------------------------------
1 | import { Param, RawParams, StateOrName, TargetState, Transition, TransitionOptions } from '@uirouter/core';
2 |
3 | declare module '@uirouter/core/lib/state/interface' {
4 | interface StateDeclaration {
5 | dsr?: DSRProp;
6 | deepStateRedirect?: DSRProp;
7 | }
8 | }
9 |
10 | declare module '@uirouter/core/lib/state/stateObject' {
11 | interface StateObject {
12 | $dsr: RecordedDSR[];
13 | }
14 | }
15 |
16 | export type ParamPredicate = (param: Param) => boolean;
17 | export type DSRProp = boolean | string | DSRFunction | DSRConfigObj;
18 | export type DSRFunction = (...args) => boolean | DSRTarget;
19 | export interface DSRTarget {
20 | state?: StateOrName;
21 | params?: RawParams;
22 | options?: TransitionOptions;
23 | }
24 |
25 | export interface DSRConfigObj {
26 | default?: string | DSRTarget;
27 | params?: boolean | string[];
28 | fn?: DSRFunction;
29 | }
30 |
31 | export interface _DSRConfig {
32 | default?: TargetState;
33 | params?: ParamPredicate;
34 | fn?: (transition: Transition, something: any) => any;
35 | }
36 |
37 | export interface RecordedDSR {
38 | targetStateName: string;
39 | targetParams: RawParams;
40 | triggerParams: Record;
41 | }
42 |
--------------------------------------------------------------------------------
/test/deepStateRedirectSpec.ts:
--------------------------------------------------------------------------------
1 | import { memoryLocationPlugin, servicesPlugin, StateDeclaration, StateService, UIRouter } from '@uirouter/core';
2 | import { DSRPlugin } from '../src/dsr';
3 | import { addCallbacks, getTestGoFn, pathFrom, resetTransitionLog } from './util';
4 |
5 | // const equalityTester = (first, second) =>
6 | // Object.keys(second).reduce((acc, key) => first[key] == second[key] && acc, true);
7 | //
8 | function getDSRStates(): StateDeclaration[] {
9 | // This function effectively returns the default DSR state at runtime
10 | function p7DSRFunction(transition, pendingRedirect) {
11 | // allow standard DSR behavior by returning pendingRedirect $dsr$.redirect has a state set
12 | if (pendingRedirect && pendingRedirect.state()) return pendingRedirect;
13 |
14 | // Otherwise, return a redirect object {state: "foo", params: {} }
15 | const redirectState = transition.params().param === '2' ? 'p7.child2' : 'p7.child1';
16 | return transition.router.stateService.target(redirectState);
17 | }
18 |
19 | return [
20 | { name: 'other' },
21 | { name: 'tabs' },
22 | { name: 'tabs.tabs1', deepStateRedirect: true },
23 | { name: 'tabs.tabs1.deep' },
24 | { name: 'tabs.tabs1.deep.nest' },
25 | { name: 'tabs.tabs2', deepStateRedirect: true },
26 | { name: 'tabs.tabs2.deep' },
27 | { name: 'tabs.tabs2.deep.nest' },
28 | {
29 | name: 'p1',
30 | url: '/p1/:param1/:param2',
31 | deepStateRedirect: { params: ['param1'] },
32 | params: { param1: null, param2: null },
33 | },
34 | { name: 'p1.child' },
35 | { name: 'p2', url: '/p2/:param1/:param2', deepStateRedirect: { params: true } },
36 | { name: 'p2.child' },
37 | { name: 'p3', url: '/p3/:param1', deepStateRedirect: { params: true } },
38 | { name: 'p3.child' },
39 | { name: 'p4', url: '/p4', dsr: { default: 'p4.child' } },
40 | { name: 'p4.child' },
41 | { name: 'p4.child2' },
42 | { name: 'p5', url: '/p5', dsr: { default: { state: 'p5.child', params: { p5param: '1' } } } },
43 | { name: 'p5.child', url: '/child/:p5param' },
44 | { name: 'p6', url: '/p6/:param', dsr: { params: true, default: 'p6.child1' }, params: { param: null } },
45 | { name: 'p6.child1' },
46 | { name: 'p6.child2' },
47 | { name: 'p6.child3' },
48 | { name: 'p7', url: '/p7/:param', dsr: { default: {}, fn: p7DSRFunction }, params: { param: null } },
49 | { name: 'p7.child1' },
50 | { name: 'p7.child2' },
51 | { name: 'p8', dsr: true },
52 | { name: 'p8child1', parent: 'p8' },
53 | { name: 'p8child2', parent: 'p8' },
54 | ];
55 | }
56 |
57 | function dsrReset(newStates) {
58 | addCallbacks(newStates);
59 | resetTransitionLog();
60 | }
61 |
62 | let router: UIRouter = undefined;
63 | let $state: StateService = undefined;
64 | let $deepStateRedirect = undefined;
65 | let testGo = undefined;
66 |
67 | describe('deepStateRedirect', function () {
68 | beforeEach(async function (done) {
69 | router = new UIRouter();
70 | router.plugin(servicesPlugin);
71 | router.plugin(memoryLocationPlugin);
72 | $deepStateRedirect = router.plugin(DSRPlugin);
73 |
74 | router.urlService.rules.otherwise('/');
75 | $state = router.stateService;
76 |
77 | testGo = getTestGoFn(router);
78 |
79 | const newStates = getDSRStates();
80 | dsrReset(newStates);
81 | newStates.forEach((state) => router.stateRegistry.register(state));
82 |
83 | done();
84 | });
85 |
86 | describe(' - ', function () {
87 | it('should toggle between tab states', async function (done) {
88 | await testGo('tabs', { entered: 'tabs' });
89 | await testGo('tabs.tabs2', { entered: 'tabs.tabs2' });
90 | await testGo('tabs.tabs1', { entered: 'tabs.tabs1', exited: 'tabs.tabs2' });
91 |
92 | done();
93 | });
94 |
95 | it('should redirect to tabs.tabs1.deep.nest', async function (done) {
96 | await testGo('tabs', { entered: 'tabs' });
97 | await testGo('tabs.tabs2.deep.nest', { entered: ['tabs.tabs2', 'tabs.tabs2.deep', 'tabs.tabs2.deep.nest'] });
98 | await testGo('tabs.tabs1', {
99 | entered: 'tabs.tabs1',
100 | exited: ['tabs.tabs2.deep.nest', 'tabs.tabs2.deep', 'tabs.tabs2'],
101 | });
102 | await testGo(
103 | 'tabs.tabs2',
104 | {
105 | entered: ['tabs.tabs2', 'tabs.tabs2.deep', 'tabs.tabs2.deep.nest'],
106 | exited: 'tabs.tabs1',
107 | },
108 | { redirect: 'tabs.tabs2.deep.nest' }
109 | );
110 |
111 | done();
112 | });
113 |
114 | it('should forget a previous redirect to tabs.tabs2.deep.nest', async function (done) {
115 | await testGo('tabs', { entered: 'tabs' });
116 | await testGo('tabs.tabs2.deep.nest', { entered: ['tabs.tabs2', 'tabs.tabs2.deep', 'tabs.tabs2.deep.nest'] });
117 | await testGo('tabs.tabs1.deep.nest', {
118 | entered: ['tabs.tabs1', 'tabs.tabs1.deep', 'tabs.tabs1.deep.nest'],
119 | exited: ['tabs.tabs2.deep.nest', 'tabs.tabs2.deep', 'tabs.tabs2'],
120 | });
121 | await testGo(
122 | 'tabs.tabs2',
123 | {
124 | entered: ['tabs.tabs2', 'tabs.tabs2.deep', 'tabs.tabs2.deep.nest'],
125 | exited: ['tabs.tabs1.deep.nest', 'tabs.tabs1.deep', 'tabs.tabs1'],
126 | },
127 | { redirect: 'tabs.tabs2.deep.nest' }
128 | );
129 | await testGo(
130 | 'tabs.tabs1',
131 | {
132 | entered: ['tabs.tabs1', 'tabs.tabs1.deep', 'tabs.tabs1.deep.nest'],
133 | exited: ['tabs.tabs2.deep.nest', 'tabs.tabs2.deep', 'tabs.tabs2'],
134 | },
135 | { redirect: 'tabs.tabs1.deep.nest' }
136 | );
137 |
138 | $deepStateRedirect.reset('tabs.tabs2');
139 |
140 | await testGo('tabs.tabs2', {
141 | entered: ['tabs.tabs2'],
142 | exited: ['tabs.tabs1.deep.nest', 'tabs.tabs1.deep', 'tabs.tabs1'],
143 | });
144 | await testGo(
145 | 'tabs.tabs1',
146 | {
147 | entered: ['tabs.tabs1', 'tabs.tabs1.deep', 'tabs.tabs1.deep.nest'],
148 | exited: ['tabs.tabs2'],
149 | },
150 | { redirect: 'tabs.tabs1.deep.nest' }
151 | );
152 |
153 | $deepStateRedirect.reset();
154 |
155 | await testGo('tabs.tabs2', {
156 | entered: 'tabs.tabs2',
157 | exited: ['tabs.tabs1.deep.nest', 'tabs.tabs1.deep', 'tabs.tabs1'],
158 | });
159 | await testGo('tabs.tabs1', { entered: 'tabs.tabs1', exited: ['tabs.tabs2'] });
160 |
161 | done();
162 | });
163 | });
164 |
165 | describe('with child substates configured using {parent: parentState}', function () {
166 | it('should remember and redirect to the last deepest state', async function (done) {
167 | await testGo('p8child1');
168 | await testGo('other');
169 | await testGo('p8', undefined, { redirect: 'p8child1' });
170 |
171 | done();
172 | });
173 | });
174 |
175 | describe('with configured params', function () {
176 | it('should redirect only when params match', async function (done) {
177 | await $state.go('p1', { param1: 'foo', param2: 'foo2' });
178 | expect($state.current.name).toEqual('p1');
179 | expect($state.params).toEqual({ '#': null, param1: 'foo', param2: 'foo2' } as any);
180 |
181 | await $state.go('.child');
182 | expect($state.current.name).toEqual('p1.child');
183 |
184 | await $state.go('p1', { param1: 'bar' });
185 | expect($state.current.name).toEqual('p1');
186 |
187 | await $state.go('p1', { param1: 'foo', param2: 'somethingelse' });
188 | expect($state.current.name).toEqual('p1.child'); // DSR
189 |
190 | done();
191 | });
192 |
193 | // Test for issue #184 getRedirect()
194 | it('should be returned from getRedirect() for matching DSR params', async function (done) {
195 | await $state.go('p1', { param1: 'foo', param2: 'foo2' });
196 | await $state.go('.child');
197 |
198 | expect($deepStateRedirect.getRedirect('p1', { param1: 'foo' }).state().name).toBe('p1.child');
199 | expect($deepStateRedirect.getRedirect('p1', { param1: 'bar' })).toBeUndefined();
200 |
201 | done();
202 | });
203 |
204 | // Test for PR #165
205 | it('should consider only the params from the dsr configuration', async function (done) {
206 | router.stateRegistry.register({
207 | name: 'rootState1',
208 | url: '/rootstate1/:rootstate1param',
209 | deepStateRedirect: {
210 | params: ['rootstate1param'],
211 | },
212 | });
213 | router.stateRegistry.register({ name: 'rootState2', url: '/rootstate2/:rootstate2param' });
214 | router.stateRegistry.register({ name: 'rootState1.sub1', url: '/sub1' });
215 | router.stateRegistry.register({ name: 'rootState1.sub2', url: '/sub2/:sub2param' });
216 |
217 | await $state.go('rootState1.sub1', { rootstate1param: 'rootstate1param' });
218 | await $state.go('rootState1.sub2', { rootstate1param: 'rootstate1param', sub2param: 'sub2param' });
219 | await $state.go('rootState2', { rootstate2param: 'rootstate2param' });
220 | await $state.go('rootState1', { rootstate1param: 'rootstate1param' });
221 |
222 | const targetState = $deepStateRedirect.getRedirect('rootState1', { rootstate1param: 'rootstate1param' });
223 | expect(targetState.state().name).toBe('rootState1.sub2');
224 |
225 | done();
226 | });
227 |
228 | it('should not redirect if a param is resetted', async function (done) {
229 | await $state.go('p3', { param1: 'foo' });
230 | await $state.go('.child');
231 | await $state.go('p3', { param1: 'bar' });
232 | await $state.go('.child');
233 |
234 | $deepStateRedirect.reset('p3', { param1: 'foo' });
235 |
236 | await $state.go('p3', { param1: 'foo' });
237 | expect($state.current.name).toEqual('p3'); // DSR
238 |
239 | await $state.go('p3', { param1: 'bar' });
240 | expect($state.current.name).toEqual('p3.child'); // DSR
241 |
242 | done();
243 | });
244 |
245 | it("should redirect only when all params match if 'params: true'", async function (done) {
246 | await $state.go('p2', { param1: 'foo', param2: 'foo2' });
247 |
248 | expect($state.current.name).toEqual('p2');
249 | expect($state.params).toEqual({ param1: 'foo', param2: 'foo2', '#': null } as any);
250 |
251 | await $state.go('.child');
252 | expect($state.current.name).toEqual('p2.child');
253 |
254 | await $state.go('p2', { param1: 'bar' });
255 | expect($state.current.name).toEqual('p2');
256 |
257 | await $state.go('p2', { param1: 'foo', param2: 'somethingelse' });
258 | expect($state.current.name).toEqual('p2');
259 |
260 | await $state.go('p2', { param1: 'foo', param2: 'foo2' });
261 | expect($state.current.name).toEqual('p2.child'); // DSR
262 |
263 | done();
264 | });
265 | });
266 |
267 | describe('ignoreDsr option', function () {
268 | it('should not redirect to tabs.tabs2.deep.nest when options are: { ignoreDsr: true }', async function (done) {
269 | await testGo('tabs', { entered: 'tabs' });
270 | await testGo('tabs.tabs2.deep.nest', { entered: pathFrom('tabs.tabs2', 'tabs.tabs2.deep.nest') });
271 | await testGo('tabs.tabs1.deep.nest', {
272 | entered: pathFrom('tabs.tabs1', 'tabs.tabs1.deep.nest'),
273 | exited: pathFrom('tabs.tabs2.deep.nest', 'tabs.tabs2'),
274 | });
275 | await $state.go('tabs.tabs2', {}, { custom: { ignoreDsr: true } });
276 |
277 | expect($state.current.name).toBe('tabs.tabs2');
278 |
279 | done();
280 | });
281 |
282 | it('should redirect to tabs.tabs2.deep.nest after a previous ignoreDsr transition', async function (done) {
283 | await testGo('tabs', { entered: 'tabs' });
284 | await testGo('tabs.tabs2.deep.nest', { entered: pathFrom('tabs.tabs2', 'tabs.tabs2.deep.nest') });
285 | await testGo('tabs.tabs1.deep.nest', {
286 | entered: pathFrom('tabs.tabs1', 'tabs.tabs1.deep.nest'),
287 | exited: pathFrom('tabs.tabs2.deep.nest', 'tabs.tabs2'),
288 | });
289 |
290 | await $state.go('tabs.tabs2', {}, { custom: { ignoreDsr: true } });
291 |
292 | expect($state.current.name).toBe('tabs.tabs2');
293 |
294 | resetTransitionLog();
295 | await testGo(
296 | 'tabs.tabs1',
297 | {
298 | exited: 'tabs.tabs2',
299 | entered: pathFrom('tabs.tabs1', 'tabs.tabs1.deep.nest'),
300 | },
301 | { redirect: 'tabs.tabs1.deep.nest' }
302 | );
303 |
304 | done();
305 | });
306 |
307 | it('should remember the DSR state itself when transitioned to using ignoreDsr ', async function (done) {
308 | await testGo('tabs.tabs1.deep', { entered: pathFrom('tabs', 'tabs.tabs1.deep') });
309 | await testGo('tabs.tabs2', { entered: 'tabs.tabs2', exited: pathFrom('tabs.tabs1.deep', 'tabs.tabs1') });
310 |
311 | await $state.go('tabs.tabs1', {}, { custom: { ignoreDsr: true } });
312 |
313 | expect($state.current.name).toBe('tabs.tabs1');
314 | await $state.go('tabs.tabs2', {}, {});
315 |
316 | expect($state.current.name).toBe('tabs.tabs2');
317 | await $state.go('tabs.tabs1', {}, {});
318 |
319 | expect($state.current.name).toBe('tabs.tabs1');
320 |
321 | done();
322 | });
323 | });
324 |
325 | describe('default substates', function () {
326 | // Test for issue #184 getRedirect()
327 | it('should be returned by getRedirect', function () {
328 | expect($deepStateRedirect.getRedirect('p4').state().name).toBe('p4.child');
329 | });
330 |
331 | it('should affect the first transition to the DSR state', async function (done) {
332 | await testGo('p4', undefined, { redirect: 'p4.child' });
333 | await testGo('p4.child2');
334 | await testGo('p4', undefined, { redirect: 'p4.child2' });
335 |
336 | done();
337 | });
338 |
339 | it('should provide default parameters', async function (done) {
340 | await testGo('p5', undefined, { redirect: 'p5.child' });
341 | expect($state.params).toEqual({ p5param: '1', '#': null } as any);
342 |
343 | done();
344 | });
345 |
346 | it('should redirect to the default state when params: true and transition to DSR with un-seen param values', async function (done) {
347 | await testGo('p6', undefined, { params: { param: '1' }, redirect: 'p6.child1' });
348 | await testGo('p6.child2');
349 | await testGo('p6', undefined, { params: { param: '1' }, redirect: 'p6.child2' });
350 | // await testGo("p6", undefined, { params: { param: "2" }, redirect: 'p6.child1' });
351 |
352 | done();
353 | });
354 |
355 | describe('in conjunction with a dsr fn', function () {
356 | it('should still invoke the dsr fn and use the result', async function (done) {
357 | // This effectively allows a function to determine DSR default
358 | await testGo('p7', undefined, { params: { param: '2' }, redirect: 'p7.child2' });
359 | await testGo('p7.child1');
360 | await testGo('p7', undefined, { params: { param: '2' }, redirect: 'p7.child1' });
361 |
362 | done();
363 | });
364 |
365 | it('should still invoke the dsr fn and use the result', async function (done) {
366 | // This effectively allows the default DSR to be determined by a fn
367 | await testGo('p7', undefined, { redirect: 'p7.child1' });
368 | await testGo('p1');
369 | await testGo('p7', undefined, { params: { param: '2' }, redirect: 'p7.child1' });
370 |
371 | done();
372 | });
373 | });
374 | });
375 | });
376 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | // require all source files ending in "Spec" from the
2 | // current directory and all subdirectories
3 |
4 | require('@uirouter/core');
5 | require('@uirouter/core/lib/vanilla');
6 | require('../src/dsr');
7 |
8 | var testsContext = require.context('.', true, /Spec$/);
9 | testsContext.keys().forEach(testsContext);
10 |
--------------------------------------------------------------------------------
/test/util.ts:
--------------------------------------------------------------------------------
1 | var tLog, tExpected;
2 | import * as _ from 'lodash';
3 |
4 | var TransitionAudit = function() {
5 | this.entered = [];
6 | this.exited = [];
7 | this.reactivated = [];
8 | this.inactivated = [];
9 | this.views = [];
10 |
11 | // this.toString = angular.bind(this,
12 | // function toString() {
13 | // var copy = {};
14 | // angular.forEach(this, function(value, key) {
15 | // if (key === 'inactivated' || key === 'reactivated' ||
16 | // key === 'entered' || key === 'exited') {
17 | // copy[key] = value;
18 | // }
19 | // });
20 | // return angular.toJson(copy);
21 | // }
22 | // );
23 | };
24 |
25 | // Add callbacks to each
26 | export function addCallbacks(basicStates) {
27 | basicStates.forEach(function(state) {
28 | function deregisterView(state, cause) {
29 | var views = _.keys(state.$$state().views);
30 | tLog.views = _.difference(tLog.views, views);
31 | // console.log(cause + ":Deregistered Inactive view " + views + " for state " + state.name + ": ", tLog.views);
32 | }
33 | function registerView(state, cause) {
34 | var views = _.keys(state.$$state().views);
35 | tLog.views = _.union(tLog.views, views);
36 | // console.log(cause + ": Registered Inactive view " + views + " for state " + state.name + ": ", tLog.views);
37 | }
38 |
39 | state.onInactivate = function() {
40 | tLog.inactivated.push(state.name);
41 | registerView(state, 'Inactivate');
42 | };
43 | state.onReactivate = function() {
44 | tLog.reactivated.push(state.name);
45 | deregisterView(state, 'Reactivate');
46 | };
47 | state.onEnter = function() {
48 | tLog.entered.push(state.name);
49 | deregisterView(state, 'Enter ');
50 | };
51 | state.onExit = function() {
52 | tLog.exited.push(state.name);
53 | deregisterView(state, 'Exit ');
54 | };
55 | });
56 | }
57 |
58 | export function pathFrom(start, end) {
59 | var startNodes = start.split('.');
60 | var endNodes = end.split('.');
61 | var reverse = startNodes.length > endNodes.length;
62 | if (reverse) {
63 | var tmp = startNodes;
64 | startNodes = endNodes;
65 | endNodes = tmp;
66 | }
67 |
68 | var common = _.intersection(endNodes, startNodes);
69 | var difference = _.difference(endNodes, startNodes);
70 | difference.splice(0, 0, common.pop());
71 |
72 | var name = common.join('.');
73 | var path = _.map(difference, function(segment) {
74 | name = (name ? name + '.' : '') + segment;
75 | return name;
76 | });
77 | if (reverse) path.reverse();
78 | return path;
79 | }
80 |
81 | export function getTestGoFn($uiRouter) {
82 | var $state = $uiRouter.stateService;
83 |
84 | /**
85 | * This test function does the following:
86 | * - Go to a state `state`.
87 | * - Flush transition
88 | * - Expect the current state to be the target state, or the expected redirect state
89 | * - analyse the transition log and expect
90 | * - The entered states to match tAdditional.entered
91 | * - The exited states to match tAdditional.exited
92 | * - The inactivated states to match tAdditional.inactivated
93 | * - The reactivated states to match tAdditional.reactivated
94 | * - Expect the active+inactive states to match the active+inactive views
95 | *
96 | * @param state: The target state
97 | * @param tAdditional: An object with the expected transitions
98 | * {
99 | * entered: statename or [ statenamearray ],
100 | * exited: statename or [ statenamearray ],
101 | * inactivated: statename or [ statenamearray ],
102 | * reactivated: statename or [ statenamearray ]
103 | * }
104 | * note: statenamearray may be built using the pathFrom helper function
105 | * @param options: options which modify the expected transition behavior
106 | * { redirect: redirectstatename }
107 | */
108 | async function testGo(state, tAdditional, options) {
109 | await $state.go(state, options && options.params, options);
110 |
111 | var expectRedirect = options && options.redirect;
112 | if (!expectRedirect) expect($state.current.name).toBe(state);
113 | else expect($state.current.name).toBe(expectRedirect);
114 |
115 | // var root = $state.$current.path[0].parent;
116 | // var __inactives = root.parent;
117 |
118 | // If ct.ui.router.extras.sticky module is included, then root.parent holds the inactive states/views
119 | // if (__inactives) {
120 | // var __inactiveViews = _.keys(__inactives.locals);
121 | // var extra = _.difference(__inactiveViews, tLog.views);
122 | // var missing = _.difference(tLog.views, __inactiveViews);
123 | //
124 | // expect("Extra Views: " + extra).toEqual("Extra Views: " + []);
125 | // expect("Missing Views: " + missing).toEqual("Missing Views: " + []);
126 | // }
127 |
128 | if (tExpected && tAdditional) {
129 | // append all arrays in tAdditional to arrays in tExpected
130 | Object.keys(tAdditional).forEach(key => (tExpected[key] = tExpected[key].concat(tAdditional[key])));
131 | // angular.forEach(tAdditional, function (value, key) {
132 | // tExpected[key] = tExpected[key].concat(tAdditional[key]);
133 | // });
134 |
135 | Object.keys(tLog)
136 | .filter(x => x !== 'views')
137 | .forEach(key => {
138 | // angular.forEach(_.without(_.keys(tLog), 'views'), function(key) {
139 | var left = key + ': ' + JSON.stringify(tLog[key]);
140 | var right = key + ': ' + JSON.stringify(tExpected[key]);
141 | expect(left).toBe(right);
142 | });
143 | }
144 |
145 | return Promise.resolve();
146 | }
147 |
148 | return testGo;
149 | }
150 |
151 | export function resetTransitionLog() {
152 | tLog = new TransitionAudit();
153 | tExpected = new TransitionAudit();
154 | }
155 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "emitDecoratorMetadata": true,
4 | "experimentalDecorators": true,
5 | "moduleResolution": "node",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "lib": ["es6", "dom"],
9 | "allowSyntheticDefaultImports": true,
10 | "outDir": "lib",
11 | "declaration": true,
12 | "sourceMap": true
13 | },
14 | "files": ["src/index.ts"]
15 | }
16 |
--------------------------------------------------------------------------------