diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c0967bb --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +src/__tests__/** diff --git a/.eslintrc b/.eslintrc index b36f846..7cbc65a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,54 +1,168 @@ { - "env": { - "browser": true, - "node": true, - "mocha": true, - "es6": true + "parser": "babel-eslint", // https://github.com/babel/babel-eslint + "env": { // http://eslint.org/docs/user-guide/configuring.html#specifying-environments + "browser": true, // browser global variables + "node": true // Node.js global variables and Node.js-specific rules }, - "globals": { - "angular": true, - "moment": true, - "R": true, - "inject": true, - "Q": true, - "sinon": true, - "getService": true, - "expect": true, - "xit": true, - "dealoc": true, - "require": true + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true }, "rules": { - "camelcase": 2, - "curly": 2, - "brace-style": [2, "1tbs"], - "quotes": [2, "single"], - "semi": [2, "always"], - "object-curly-spacing": [2, "always"], - "array-bracket-spacing": [2, "never"], - "computed-property-spacing": [2, "never"], - "space-infix-ops": 2, - "space-after-keywords": [2, "always"], - "dot-notation": 2, - "eqeqeq": [2, "smart"], - "no-use-before-define": 2, - "no-redeclare": 2, - "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], - "no-floating-decimal": 2, - "no-spaced-func": 2, - "no-extra-parens": 1, - "no-underscore-dangle": 0, - "valid-jsdoc": 1, - "space-after-keywords": 2, - "max-len": [2, 120], - "no-use-before-define": [2, "nofunc"], - "no-warning-comments": 0, - "new-cap": 0, - "strict": 0, - "eol-last": 0, - "semi": 2 - }, - "ecmaFeatures": { - "modules": true + "no-undef": 0, +/** + * Strict mode + */ + "strict": [2, "never"], // http://eslint.org/docs/rules/strict + +/** + * ES6 + */ + "no-var": 2, // http://eslint.org/docs/rules/no-var + "prefer-const": 2, // http://eslint.org/docs/rules/prefer-const + +/** + * Variables + */ + "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow + "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names + "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars + "vars": "local", + "args": "after-used" + }], + "no-use-before-define": 0, // http://eslint.org/docs/rules/no-use-before-define + +/** + * Possible errors + */ + "comma-dangle": [2, "always-multiline"], // http://eslint.org/docs/rules/comma-dangle + "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign + "no-console": 1, // http://eslint.org/docs/rules/no-console + "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger + "no-alert": 1, // http://eslint.org/docs/rules/no-alert + "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition + "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys + "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case + "no-empty": 2, // http://eslint.org/docs/rules/no-empty + "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign + "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast + "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi + "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign + "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations + "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp + "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace + "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls + "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays + "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable + "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan + "block-scoped-var": 0, // http://eslint.org/docs/rules/block-scoped-var + +/** + * Best practices + */ + "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return + "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly + "default-case": 2, // http://eslint.org/docs/rules/default-case + "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation + "allowKeywords": true + }], + "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq + "guard-for-in": 0, // http://eslint.org/docs/rules/guard-for-in + "no-caller": 2, // http://eslint.org/docs/rules/no-caller + "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return + "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null + "no-eval": 2, // http://eslint.org/docs/rules/no-eval + "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native + "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind + "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough + "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal + "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval + "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks + "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func + "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str + "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign + "no-new": 2, // http://eslint.org/docs/rules/no-new + "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func + "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers + "no-octal": 2, // http://eslint.org/docs/rules/no-octal + "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape + "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign + "no-proto": 2, // http://eslint.org/docs/rules/no-proto + "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare + "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign + "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url + "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare + "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences + "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal + "no-with": 2, // http://eslint.org/docs/rules/no-with + "radix": 2, // http://eslint.org/docs/rules/radix + "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top + "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife + "yoda": 2, // http://eslint.org/docs/rules/yoda + +/** + * Style + */ + "indent": [2, 2], // http://eslint.org/docs/rules/indent + "brace-style": [2, // http://eslint.org/docs/rules/brace-style + "1tbs", { + "allowSingleLine": true + }], + "quotes": [ + 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes + ], + "camelcase": [2, { // http://eslint.org/docs/rules/camelcase + "properties": "never" + }], + "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing + "before": false, + "after": true + }], + "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style + "eol-last": 2, // http://eslint.org/docs/rules/eol-last + "func-names": 1, // http://eslint.org/docs/rules/func-names + "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing + "beforeColon": false, + "afterColon": true + }], + "new-cap": [2, { // http://eslint.org/docs/rules/new-cap + "newIsCap": true, + "capIsNew": false + }], + "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines + "max": 2 + }], + "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary + "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object + "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func + "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces + "no-extra-parens": [2, "functions"], // http://eslint.org/docs/rules/no-extra-parens + "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle + "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var + "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks + "semi": [2, "always"], // http://eslint.org/docs/rules/semi + "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing + "before": false, + "after": true + }], + "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords + "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks + "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren + "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops + "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case + "spaced-comment": 2 // http://eslint.org/docs/rules/spaced-comment } } diff --git a/example/index.js b/example/index.js index b2a05c0..b971c5b 100644 --- a/example/index.js +++ b/example/index.js @@ -48,6 +48,7 @@ export default angular
  • Child View 1
  • Child View 2
  • Child View 3
  • +
  • Child View 4 (prohibited)
  • @@ -129,6 +130,20 @@ export default angular } } }) + .state('app.child4', { + url: '/child4', + prohibited: true, + views: { + child: { + template: ` +
    +

    Child View 4

    +
    This state is prohibited. You should've been redirected to the root.
    +
    + ` + } + } + }) }) .config(($ngReduxProvider) => { const logger = createLogger({ @@ -142,4 +157,25 @@ export default angular $ngReduxProvider.createStoreWith(reducers, ['ngUiRouterMiddleware', logger, thunk]); }) + .run(($rootScope, $state, $ngRedux, $urlRouter) => { + + // If save something to the store, dispatch will force state change update + console.log('will do dispatch'); + $ngRedux.dispatch({type: 'SOME_ACTION'}); + console.log('did dispatch'); + + $rootScope.$on('$stateChangeStart', function(evt, to, params) { + if (to.prohibited) { + evt.preventDefault(); + console.log('prohibited state change cancelled'); + $state.go('app'); + } + }); + + console.log('$stateChangeStart callback is ready'); + console.log('enable $urlRouter listening'); + + $urlRouter.sync(); + $urlRouter.listen(); + }) .name; diff --git a/package.json b/package.json index fc577e9..fb125ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redux-ui-router", - "version": "0.4.3", + "version": "0.4.4", "description": "Redux middleware for use with Angular UI Router", "main": "./lib/index.js", "scripts": { diff --git a/src/index.js b/src/index.js index 8a1d1a7..24c9cae 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ import stateChangeActions from './state-change-actions'; export default angular .module('ng-ui-router-middleware', [ - uiRouter + uiRouter, ]) .provider('ngUiStateChangeActions', stateChangeActions) .factory('ngUiRouterMiddleware', routerMiddleware) @@ -23,5 +23,5 @@ export const router = routerState; export { stateGo, stateReload, - stateTransitionTo + stateTransitionTo, }; diff --git a/src/router-listener.js b/src/router-listener.js index 199ae2e..9344f74 100644 --- a/src/router-listener.js +++ b/src/router-listener.js @@ -8,16 +8,13 @@ * @return {undefined} undefined */ export default function RouterListener($rootScope, $urlRouter, $stateParams, ngUiStateChangeActions) { - $rootScope.$on('$stateChangeStart', ngUiStateChangeActions.onStateChangeStart); - $rootScope.$on('$locationChangeSuccess', (evt) => { - evt.preventDefault(); - $urlRouter.sync(); + $rootScope.$on('$locationChangeSuccess', () => { ngUiStateChangeActions.onStateChangeSuccess(); }); - let unsubcribeStateChangeListener = $rootScope.$on('$stateChangeSuccess', () => { + const unsubcribeStateChangeListener = $rootScope.$on('$stateChangeSuccess', () => { ngUiStateChangeActions.onStateChangeSuccess(); unsubcribeStateChangeListener(); }); @@ -30,5 +27,5 @@ RouterListener.$inject = [ '$rootScope', '$urlRouter', '$stateParams', - 'ngUiStateChangeActions' + 'ngUiStateChangeActions', ]; diff --git a/src/router-middleware.js b/src/router-middleware.js index ca5a30e..a1002d8 100644 --- a/src/router-middleware.js +++ b/src/router-middleware.js @@ -7,7 +7,7 @@ import { export default function routerMiddleware($state) { return ({ getState }) => next => action => { - let { payload } = action; + const { payload } = action; switch (action.type) { case STATE_GO: @@ -29,8 +29,8 @@ export default function routerMiddleware($state) { currentState: $state.current, currentParams: $state.params, prevState: getState().router.currentState, - prevParams: getState().router.currentParams - } + prevParams: getState().router.currentParams, + }, }); default: diff --git a/src/router-state-reducer.js b/src/router-state-reducer.js index d63c54f..1761325 100644 --- a/src/router-state-reducer.js +++ b/src/router-state-reducer.js @@ -4,7 +4,7 @@ const INITIAL_STATE = { currentState: {}, currentParams: {}, prevState: {}, - prevParams: {} + prevParams: {}, }; /** diff --git a/src/state-change-actions.js b/src/state-change-actions.js index f1112d8..f29eb44 100644 --- a/src/state-change-actions.js +++ b/src/state-change-actions.js @@ -7,19 +7,16 @@ import onStateNotFound from './state-not-found'; import { bindActionCreators } from 'redux'; export default function stateChangeActions() { - - this.$get = function ($ngRedux) { - - let actionCreator = { + this.$get = ($ngRedux) => { + const actionCreator = { onStateChangeStart, onStateChangeSuccess, onStateChangeError, - onStateNotFound + onStateNotFound, }; return bindActionCreators(actionCreator, $ngRedux.dispatch); }; this.$get.$inject = ['$ngRedux']; - } diff --git a/src/state-change-error.js b/src/state-change-error.js index 3857ec2..79b2c81 100644 --- a/src/state-change-error.js +++ b/src/state-change-error.js @@ -22,7 +22,7 @@ export default function onStateChangeError(evt, toState, toParams, fromState, fr toParams, fromState, fromParams, - err - } + err, + }, }; } diff --git a/src/state-change-start.js b/src/state-change-start.js index 0779347..b64e7ca 100644 --- a/src/state-change-start.js +++ b/src/state-change-start.js @@ -20,7 +20,7 @@ export default function onStateChangeStart(evt, toState, toParams, fromState, fr toState, toParams, fromState, - fromParams - } + fromParams, + }, }; } diff --git a/src/state-change-success.js b/src/state-change-success.js index 0e4bd7d..dab53fc 100644 --- a/src/state-change-success.js +++ b/src/state-change-success.js @@ -10,6 +10,6 @@ import { STATE_CHANGE_SUCCESS } from './action-types'; */ export default function onStateChangeSuccess() { return { - type: STATE_CHANGE_SUCCESS + type: STATE_CHANGE_SUCCESS, }; } diff --git a/src/state-go.js b/src/state-go.js index 1f7bc32..dee25a0 100644 --- a/src/state-go.js +++ b/src/state-go.js @@ -17,7 +17,7 @@ export default function stateGo(to, params, options) { payload: { to, params, - options - } + options, + }, }; } diff --git a/src/state-not-found.js b/src/state-not-found.js index 50fcf84..cedc3e6 100644 --- a/src/state-not-found.js +++ b/src/state-not-found.js @@ -19,7 +19,7 @@ export default function onStateNotFound(evt, unfoundState, fromState, fromParams evt, unfoundState, fromState, - fromParams - } + fromParams, + }, }; } diff --git a/src/state-reload.js b/src/state-reload.js index 1f7fe37..ac28cb9 100644 --- a/src/state-reload.js +++ b/src/state-reload.js @@ -12,6 +12,6 @@ import { STATE_RELOAD } from './action-types'; export default function stateReload(state) { return { type: STATE_RELOAD, - payload: state + payload: state, }; } diff --git a/src/state-transition-to.js b/src/state-transition-to.js index 9004b95..925ebe9 100644 --- a/src/state-transition-to.js +++ b/src/state-transition-to.js @@ -17,7 +17,7 @@ export default function stateTransitionTo(to, toParams, options) { payload: { to, toParams, - options - } + options, + }, }; }