diff --git a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js index 89c1ea6975..263397787d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js @@ -2,13 +2,13 @@ * @ngdoc service * @name umbraco.services.dialogService * - * @requires $rootScope + * @requires $rootScope * @requires $compile * @requires $http * @requires $log * @requires $q * @requires $templateCache - * + * * @description * Application-wide service for handling modals, overlays and dialogs * By default it injects the passed template url into a div to body of the document @@ -22,10 +22,10 @@ *
  *    var dialog = dialogService.open({template: 'path/to/page.html', show: true, callback: done});
  *    functon done(data){
- *      //The dialog has been submitted 
+ *      //The dialog has been submitted
  *      //data contains whatever the dialog has selected / attached
- *    }     
- * 
+ * } + * */ angular.module('umbraco.services') @@ -38,12 +38,12 @@ angular.module('umbraco.services') for (var i = 0; i < dialogs.length; i++) { var dialog = dialogs[i]; - //very special flag which means that global events cannot close this dialog - currently only used on the login + //very special flag which means that global events cannot close this dialog - currently only used on the login // dialog since it's special and cannot be closed without logging in. if (!dialog.manualClose) { dialog.close(args); } - + } } @@ -56,28 +56,18 @@ angular.module('umbraco.services') //this is not entirely enough since the damn webforms scriploader still complains if (dialog.iframe) { dialog.element.find("iframe").attr("src", "about:blank"); - $timeout(function () { - //we need to do more than just remove the element, this will not destroy the - // scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont - // take care of this ourselves we have memory leaks. - dialog.element.remove(); - //SD: No idea why this is required but was there before - pretty sure it's not required - $("#" + dialog.element.attr("id")).remove(); - dialog.scope.$destroy(); - }, 1000); - } else { - //we need to do more than just remove the element, this will not destroy the - // scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont - // take care of this ourselves we have memory leaks. - dialog.element.remove(); - //SD: No idea why this is required but was there before - pretty sure it's not required - $("#" + dialog.element.attr("id")).remove(); - dialog.scope.$destroy(); } - } - //remove 'this' dialog from the dialogs array - dialogs = _.reject(dialogs, function (i) { return i === dialog; }); + dialog.scope.$destroy(); + + //we need to do more than just remove the element, this will not destroy the + // scope in angular 1.1x, in angular 1.2x this is taken care of but if we dont + // take care of this ourselves we have memory leaks. + dialog.element.remove(); + + //remove 'this' dialog from the dialogs array + dialogs = _.reject(dialogs, function (i) { return i === dialog; }); + } } /** Internal method that handles opening all dialogs */ @@ -93,17 +83,17 @@ angular.module('umbraco.services') template: "views/common/notfound.html", callback: undefined, closeCallback: undefined, - element: undefined, + element: undefined, // It will set this value as a property on the dialog controller's scope as dialogData, - // used to pass in custom data to the dialog controller's $scope. Though this is near identical to - // the dialogOptions property that is also set the the dialog controller's $scope object. + // used to pass in custom data to the dialog controller's $scope. Though this is near identical to + // the dialogOptions property that is also set the the dialog controller's $scope object. // So there's basically 2 ways of doing the same thing which we're now stuck with and in fact // dialogData has another specially attached property called .selection which gets used. dialogData: undefined }; var dialog = angular.extend(defaults, options); - + //NOTE: People should NOT pass in a scope object that is legacy functoinality and causes problems. We will ALWAYS // destroy the scope when the dialog is closed regardless if it is in use elsewhere which is why it shouldn't be done. var scope = options.scope || $rootScope.$new(); @@ -156,7 +146,7 @@ angular.module('umbraco.services') dialog.element.css("width", dialog.width); - //Autoshow + //Autoshow if (dialog.show) { dialog.element.modal('show'); } @@ -167,7 +157,7 @@ angular.module('umbraco.services') else { //We need to load the template with an httpget and once it's loaded we'll compile and assign the result to the container - // object. However since the result could be a promise or just data we need to use a $q.when. We still need to return the + // object. However since the result could be a promise or just data we need to use a $q.when. We still need to return the // $modal object so we'll actually return the modal object synchronously without waiting for the promise. Otherwise this openDialog // method will always need to return a promise which gets nasty because of promises in promises plus the result just needs a reference // to the $modal object which will not change (only it's contents will change). @@ -177,7 +167,7 @@ angular.module('umbraco.services') // Build modal object dialog.element.html(template); - //append to body or other container element + //append to body or other container element dialog.container.append(dialog.element); // Compile modal content @@ -224,8 +214,8 @@ angular.module('umbraco.services') scope.close = function (data) { dialog.close(data); }; - - //NOTE: This can ONLY ever be used to show the dialog if dialog.show is false (autoshow). + + //NOTE: This can ONLY ever be used to show the dialog if dialog.show is false (autoshow). // You CANNOT call show() after you call hide(). hide = close, they are the same thing and once // a dialog is closed it's resources are disposed of. scope.show = function () { @@ -237,7 +227,7 @@ angular.module('umbraco.services') //just show normally dialog.element.modal('show'); } - + }; scope.select = function (item) { @@ -266,11 +256,11 @@ angular.module('umbraco.services') dialog.scope = scope; - //Autoshow + //Autoshow if (dialog.show) { scope.show(); } - + }); //Return the modal object outside of the promise! @@ -368,7 +358,7 @@ angular.module('umbraco.services') * @param {Function} options.callback callback function * @returns {Object} modal object */ - contentPicker: function (options) { + contentPicker: function (options) { options.treeAlias = "content"; options.section = "content"; @@ -424,7 +414,7 @@ angular.module('umbraco.services') * @returns {Object} modal object */ memberPicker: function (options) { - + options.treeAlias = "member"; options.section = "member"; @@ -511,7 +501,7 @@ angular.module('umbraco.services') * @name umbraco.services.dialogService#embedDialog * @methodOf umbraco.services.dialogService * @description - * Opens a dialog to an embed dialog + * Opens a dialog to an embed dialog */ embedDialog: function (options) { options.template = 'views/common/dialogs/rteembed.html'; @@ -546,4 +536,4 @@ angular.module('umbraco.services') return openDialog(options); } }; -}); \ No newline at end of file +}); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index f404419340..11c62f1aec 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -2,14 +2,14 @@ * @ngdoc service * @name umbraco.services.navigationService * - * @requires $rootScope + * @requires $rootScope * @requires $routeParams * @requires $log * @requires $location * @requires dialogService * @requires treeService * @requires sectionResource - * + * * @description * Service to handle the main application navigation. Responsible for invoking the tree * Section navigation and search, and maintain their state for the entire application lifetime @@ -17,10 +17,10 @@ */ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeout, $injector, dialogService, umbModelMapper, treeService, notificationsService, historyService, appState, angularHelper) { - + //used to track the current dialog object var currentDialog = null; - + //the main tree event handler, which gets assigned via the setupTreeEvents method var mainTreeEventHandler = null; //tracks the user profile dialog @@ -35,8 +35,8 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo appState.setMenuState("showMenuDialog", false); appState.setGlobalState("stickyNavigation", false); appState.setGlobalState("showTray", false); - - //$("#search-form input").focus(); + + //$("#search-form input").focus(); break; case 'menu': appState.setGlobalState("navMode", "menu"); @@ -87,7 +87,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo /** initializes the navigation service */ init: function() { - //keep track of the current section - initially this will always be undefined so + //keep track of the current section - initially this will always be undefined so // no point in setting it now until it changes. $rootScope.$watch(function () { return $routeParams.section; @@ -95,7 +95,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo appState.setSectionState("currentSection", newVal); }); - + }, /** @@ -107,7 +107,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * Shows the legacy iframe and loads in the content based on the source url * @param {String} source The URL to load into the iframe */ - loadLegacyIFrame: function (source) { + loadLegacyIFrame: function (source) { $location.path("/" + appState.getSectionState("currentSection") + "/framed/" + encodeURIComponent(source)); }, @@ -149,7 +149,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo showTree: function (sectionAlias, syncArgs) { if (sectionAlias !== appState.getSectionState("currentSection")) { appState.setSectionState("currentSection", sectionAlias); - + if (syncArgs) { this.syncTree(syncArgs); } @@ -165,7 +165,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo appState.setGlobalState("showTray", false); }, - /** + /** Called to assign the main tree event handler - this is called by the navigation controller. TODO: Potentially another dev could call this which would kind of mung the whole app so potentially there's a better way. */ @@ -179,7 +179,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo //when a tree node is synced this event will fire, this allows us to set the currentNode mainTreeEventHandler.bind("treeSynced", function (ev, args) { - + if (args.activate === undefined || args.activate === true) { //set the current selected node appState.setTreeState("selectedNode", args.node); @@ -196,7 +196,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo //Set the current action node (this is not the same as the current selected node!) appState.setMenuState("currentNode", args.node); - + if (args.event && args.event.altKey) { args.skipDefault = true; } @@ -220,7 +220,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo ev.preventDefault(); if (n.metaData && n.metaData["jsClickCallback"] && angular.isString(n.metaData["jsClickCallback"]) && n.metaData["jsClickCallback"] !== "") { - //this is a legacy tree node! + //this is a legacy tree node! var jsPrefix = "javascript:"; var js; if (n.metaData["jsClickCallback"].startsWith(jsPrefix)) { @@ -243,7 +243,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo else if (n.routePath) { //add action to the history service historyService.add({ name: n.name, link: n.routePath, icon: n.icon }); - + //put this node into the tree state appState.setTreeState("selectedNode", args.node); //when a node is clicked we also need to set the active menu node to this node @@ -269,7 +269,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * The path format is: ["itemId","itemId"], and so on * so to sync to a specific document type node do: *
-         * navigationService.syncTree({tree: 'content', path: ["-1","123d"], forceReload: true});  
+         * navigationService.syncTree({tree: 'content', path: ["-1","123d"], forceReload: true});
          * 
* @param {Object} args arguments passed to the function * @param {String} args.tree the tree alias to sync to @@ -287,7 +287,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo if (!args.tree) { throw "args.tree cannot be null"; } - + if (mainTreeEventHandler) { //returns a promise return mainTreeEventHandler.syncTree(args); @@ -297,8 +297,8 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo return angularHelper.rejectedPromise(); }, - /** - Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to + /** + Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to have to set an active tree and then sync, the new API does this in one method by using syncTree */ _syncPath: function(path, forceReload) { @@ -322,8 +322,8 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo } }, - /** - Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to + /** + Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to have to set an active tree and then sync, the new API does this in one method by using syncTreePath */ _setActiveTreeType: function (treeAlias, loadChildren) { @@ -331,7 +331,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo mainTreeEventHandler._setActiveTreeType(treeAlias, loadChildren); } }, - + /** * @ngdoc method * @name umbraco.services.navigationService#hideTree @@ -356,7 +356,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * @methodOf umbraco.services.navigationService * * @description - * Hides the tree by hiding the containing dom element. + * Hides the tree by hiding the containing dom element. * This always returns a promise! * * @param {Event} event the click event triggering the method, passed from the DOM element @@ -382,7 +382,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo //NOTE: This is assigning the current action node - this is not the same as the currently selected node! appState.setMenuState("currentNode", args.node); - + //ensure the current dialog is cleared before creating another! if (currentDialog) { dialogService.close(currentDialog); @@ -400,13 +400,13 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo } } - //there is no default or we couldn't find one so just continue showing the menu + //there is no default or we couldn't find one so just continue showing the menu setMode("menu"); appState.setMenuState("currentNode", args.node); appState.setMenuState("menuActions", data.menuItems); - appState.setMenuState("dialogTitle", args.node.name); + appState.setMenuState("dialogTitle", args.node.name); //we're not opening a dialog, return null. deferred.resolve(null); @@ -437,7 +437,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo throw "action cannot be null"; } if (!node) { - throw "node cannot be null"; + throw "node cannot be null"; } if (!section) { throw "section cannot be null"; @@ -456,9 +456,9 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo var menuAction = action.metaData["jsAction"].split('.'); if (menuAction.length !== 2) { - //if it is not two parts long then this most likely means that it's a legacy action + //if it is not two parts long then this most likely means that it's a legacy action var js = action.metaData["jsAction"].replace("javascript:", ""); - //there's not really a different way to acheive this except for eval + //there's not really a different way to acheive this except for eval eval(js); } else { @@ -551,7 +551,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo modalClass: "umb-modal-left", show: true }); - + return service.helpDialog; }, @@ -564,13 +564,13 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * Opens a dialog, for a given action on a given tree node * uses the dialogService to inject the selected action dialog * into #dialog div.umb-panel-body - * the path to the dialog view is determined by: + * the path to the dialog view is determined by: * "views/" + current tree + "/" + action alias + ".html" * The dialog controller will get passed a scope object that is created here with the properties: * scope.currentNode = the selected tree node * scope.currentAction = the selected menu item * so that the dialog controllers can use these properties - * + * * @param {Object} args arguments passed to the function * @param {Scope} args.scope current scope passed to the dialog * @param {Object} args.action the clicked action containing `name` and `alias` @@ -590,6 +590,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo //ensure the current dialog is cleared before creating another! if (currentDialog) { dialogService.close(currentDialog); + currentDialog = null; } setMode("dialog"); @@ -649,14 +650,14 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo } //TODO: some action's want to launch a new window like live editing, we support this in the menu item's metadata with - // a key called: "actionUrlMethod" which can be set to either: Dialog, BlankWindow. Normally this is always set to Dialog - // if a URL is specified in the "actionUrl" metadata. For now I'm not going to implement launching in a blank window, + // a key called: "actionUrlMethod" which can be set to either: Dialog, BlankWindow. Normally this is always set to Dialog + // if a URL is specified in the "actionUrl" metadata. For now I'm not going to implement launching in a blank window, // though would be v-easy, just not sure we want to ever support that? var dialog = dialogService.open( { container: $("#dialog div.umb-modalcolumn-body"), - //The ONLY reason we're passing in scope to the dialogService (which is legacy functionality) is + //The ONLY reason we're passing in scope to the dialogService (which is legacy functionality) is // for backwards compatibility since many dialogs require $scope.currentNode or $scope.currentAction // to exist scope: dialogScope, @@ -685,9 +686,9 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * hides the currently open dialog */ hideDialog: function (showMenu) { - + setMode("default"); - + if(showMenu){ this.showMenu(undefined, { skipDefault: true, node: appState.getMenuState("currentNode") }); }