diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbappheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbappheader.directive.js index 3ddb7af0e1..ead54b3fc3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbappheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbappheader.directive.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function AppHeaderDirective(eventsService, appState, userService) { + function AppHeaderDirective(eventsService, appState, userService, focusService) { function link(scope, el, attr, ctrl) { @@ -54,7 +54,9 @@ } }); })); - + + scope.rememberFocus = focusService.rememberFocus; + scope.searchClick = function() { var showSearch = appState.getSearchState("show"); appState.setSearchState("show", !showSearch); @@ -101,4 +103,4 @@ angular.module("umbraco.directives").directive("umbAppHeader", AppHeaderDirective); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsearch.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsearch.directive.js index 7ff76d5670..30551bff09 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsearch.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsearch.directive.js @@ -13,7 +13,7 @@ } }; - function umbSearchController($timeout, backdropService, searchService) { + function umbSearchController($timeout, backdropService, searchService, focusService) { var vm = this; @@ -25,6 +25,9 @@ vm.handleKeyUp = handleKeyUp; vm.closeSearch = closeSearch; vm.focusSearch = focusSearch; + + //we need to capture the focus before this element is initialized. + vm.focusBeforeOpening = focusService.lastKnownFocus; function onInit() { vm.searchQuery = ""; @@ -70,6 +73,10 @@ * @param {object} event */ function handleKeyUp(event) { + + event.stopPropagation(); + event.preventDefault(); + // esc if(event.keyCode === 27) { closeSearch(); @@ -80,6 +87,9 @@ * Used to proxy a callback */ function closeSearch() { + if(vm.focusBeforeOpening) { + vm.focusBeforeOpening.focus(); + } if(vm.onClose) { vm.onClose(); } @@ -115,4 +125,4 @@ angular.module('umbraco.directives').component('umbSearch', umbSearch); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js index b4040d1c77..1b6fc9f4bb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js @@ -4,7 +4,7 @@ **/ angular.module("umbraco.directives") - .directive('hotkey', function($window, keyboardService, $log) { + .directive('hotkey', function($window, keyboardService, $log, focusService) { return function(scope, el, attrs) { @@ -28,7 +28,9 @@ angular.module("umbraco.directives") } keyboardService.bind(keyCombo, function() { - + + focusService.rememberFocus(); + var element = $(el); var activeElementType = document.activeElement.tagName; var clickableElements = ["A", "BUTTON"]; @@ -47,6 +49,8 @@ angular.module("umbraco.directives") } else { element.trigger("click"); } + + keyboardService.stopPropagation() } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/focus.service.js b/src/Umbraco.Web.UI.Client/src/common/services/focus.service.js new file mode 100644 index 0000000000..da381a6cc4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/focus.service.js @@ -0,0 +1,72 @@ +/** + @ngdoc service + * @name umbraco.services.focusService + * + * @description + * Added in Umbraco 8.1. Application-wide service for focus related stuff. + * + */ + +(function () { + "use strict"; + + function focusService() { + + + function focusInApp(e) { + service.currentFocus = e.target; + } + document.addEventListener('focusin', focusInApp); + + + var service = { + currentFocus: null, + + /** + * @ngdoc property + * @name umbraco.services.focusService#lastKnownFocus + * @propertyOf umbraco.services.focusService + * + * @description + * A element set to be remembered, the directive using this should store the value of this to make sure that its not changed white using that directive. + * This variable is avaiable for directives that are not able to figure out the focused element on init, and there this service will help remembering it untill the directive is initialized. + * + */ + lastKnownFocus: null, + + /** + * @ngdoc function + * @name umbraco.services.focusService#rememberFocus + * @methodOf umbraco.services.focusService + * @function + * + * @description + * Call this before a new focus is begin set, to be able to return to the focus before a given scenario. + * + */ + rememberFocus: function() { + service.lastKnownFocus = service.currentFocus; + }, + + /** + * @ngdoc function + * @name umbraco.services.focusService#setLastKnownFocus + * @methodOf umbraco.services.focusService + * @function + * + * @description + * Overwrite the element remembered as the last known element in focus. + * + */ + setLastKnownFocus: function(element) { + service.lastKnownFocus = element; + } + }; + + return service; + + } + + angular.module("umbraco.services").factory("focusService", focusService); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js index 269e269be8..59c437dc88 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js @@ -8,7 +8,9 @@ * The main application controller * */ -function MainController($scope, $location, appState, treeService, notificationsService, userService, historyService, updateChecker, assetsService, eventsService, tmhDynamicLocale, localStorageService, editorService, overlayService) { +function MainController($scope, $location, appState, treeService, notificationsService, + userService, historyService, updateChecker, assetsService, eventsService, + tmhDynamicLocale, localStorageService, editorService, overlayService, focusService) { //the null is important because we do an explicit bool check on this in the view $scope.authenticated = null; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-app-header.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-app-header.html index 07d25e7465..a14e930b8a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-app-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-app-header.html @@ -1,7 +1,7 @@