From 4f2848094e1864d23acb572193793faad201e8d0 Mon Sep 17 00:00:00 2001 From: Nate Abele Date: Tue, 18 Aug 2015 23:05:05 -0400 Subject: [PATCH] feat(uiState): add ui-state directive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refactor StateRefDirective for better modularity - Drop key restrictions on ui-sref-opts - Improves performance over prior implementation with no extra $eval()’s Fixes #395, #900, #1932 --- src/stateDirectives.js | 184 ++++++++++++++++++++++-------------- test/stateDirectivesSpec.js | 92 ++++++++++++------ test/stateSpec.js | 2 +- 3 files changed, 179 insertions(+), 99 deletions(-) diff --git a/src/stateDirectives.js b/src/stateDirectives.js index 8835ee91a..ec7faf499 100644 --- a/src/stateDirectives.js +++ b/src/stateDirectives.js @@ -14,6 +14,43 @@ function stateContext(el) { } } +function getTypeInfo(el) { + // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute. + var isSvg = Object.prototype.toString.call(el.prop('href')) === '[object SVGAnimatedString]'; + var isForm = el[0].nodeName === "FORM"; + + return { + attr: isForm ? "action" : (isSvg ? 'xlink:href' : 'href'), + isAnchor: el.prop("tagName").toUpperCase() === "A", + clickable: !isForm + }; +} + +function clickHook(el, $state, $timeout, type, current) { + return function(e) { + var button = e.which || e.button, target = current(); + + if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) { + // HACK: This is to allow ng-clicks to be processed before the transition is initiated: + var transition = $timeout(function() { + $state.go(target.state, target.params, target.options); + }); + e.preventDefault(); + + // if the state has no URL, ignore one preventDefault from the directive. + var ignorePreventDefaultCount = type.isAnchor && !target.href ? 1: 0; + + e.preventDefault = function() { + if (ignorePreventDefaultCount-- <= 0) $timeout.cancel(transition); + }; + } + }; +} + +function defaultOpts(el, $state) { + return { relative: stateContext(el) || $state.$current, inherit: true }; +} + /** * @ngdoc directive * @name ui.router.state.directive:ui-sref @@ -24,17 +61,17 @@ function stateContext(el) { * @restrict A * * @description - * A directive that binds a link (`` tag) to a state. If the state has an associated - * URL, the directive will automatically generate & update the `href` attribute via - * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking - * the link will trigger a state transition with optional parameters. + * A directive that binds a link (`` tag) to a state. If the state has an associated + * URL, the directive will automatically generate & update the `href` attribute via + * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking + * the link will trigger a state transition with optional parameters. * - * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be + * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be * handled natively by the browser. * - * You can also use relative state paths within ui-sref, just like the relative + * You can also use relative state paths within ui-sref, just like the relative * paths passed to `$state.go()`. You just need to be aware that the path is relative - * to the state that the link lives in, in other words the state that loaded the + * to the state that the link lives in, in other words the state that loaded the * template containing the link. * * You can specify options to pass to {@link ui.router.state.$state#go $state.go()} @@ -42,22 +79,22 @@ function stateContext(el) { * and `reload`. * * @example - * Here's an example of how you'd use ui-sref and how it would compile. If you have the + * Here's an example of how you'd use ui-sref and how it would compile. If you have the * following template: *
  * Home | About | Next page
- * 
+ *
  * 
  * 
- * + * * Then the compiled html would be (assuming Html5Mode is off and current state is contacts): *
  * Home | About | Next page
- * 
+ *
  *