diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js
new file mode 100644
index 0000000000..7fdd2c4c25
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js
@@ -0,0 +1,254 @@
+
+//TODO: WE NEED TO CONVERT ALL OF THESE METHODS TO PROXY TO OUR APPLICATION SINCE MANY CUSTOM APPS USE THIS!
+
+Umbraco.Sys.registerNamespace("Umbraco.Application");
+
+(function($) {
+ Umbraco.Application.ClientManager = function() {
+
+ /**
+ * @ngdoc function
+ * @name getRootScope
+ * @methodOf UmbClientMgr
+ * @function
+ *
+ * @description
+ * Returns the root angular scope
+ */
+ function getRootScope() {
+ return angular.element(document.getElementById("umbracoMainPageBody")).scope();
+ }
+
+ /**
+ * @ngdoc function
+ * @name getRootInjector
+ * @methodOf UmbClientMgr
+ * @function
+ *
+ * @description
+ * Returns the root angular injector
+ */
+ function getRootInjector() {
+ return angular.element(document.getElementById("umbracoMainPageBody")).injector();
+ }
+
+
+ return {
+ _isDirty: false,
+ _isDebug: false,
+ _mainTree: null,
+ _appActions: null,
+ _historyMgr: null,
+ _rootPath: "/umbraco", //this is the default
+ _modal: new Array(), //track all modal window objects (they get stacked)
+
+ historyManager: function() {
+ if (!this._historyMgr) {
+ this._historyMgr = new Umbraco.Controls.HistoryManager();
+ }
+ return this._historyMgr;
+ },
+
+ setUmbracoPath: function(strPath) {
+ ///
+ /// sets the Umbraco root path folder
+ ///
+ this._debug("setUmbracoPath: " + strPath);
+ this._rootPath = strPath;
+ },
+
+ mainWindow: function() {
+ ///
+ /// Returns a reference to the main frame of the application
+ ///
+ return top;
+ },
+ mainTree: function() {
+ ///
+ /// Returns a reference to the main UmbracoTree API object.
+ /// Sometimes an Umbraco page will need to be opened without being contained in the iFrame from the main window
+ /// so this method is will construct a false tree to be returned if this is the case as to avoid errors.
+ ///
+ ///
+
+ if (this._mainTree == null) {
+ if (this.mainWindow().jQuery == null
+ || this.mainWindow().jQuery(".umbTree").length == 0
+ || this.mainWindow().jQuery(".umbTree").UmbracoTreeAPI() == null) {
+ //creates a false tree with all the public tree params set to a false method.
+ var tmpTree = {};
+ var treeProps = ["init", "setRecycleBinNodeId", "clearTreeCache", "toggleEditMode", "refreshTree", "rebuildTree", "saveTreeState", "syncTree", "childNodeCreated", "moveNode", "copyNode", "findNode", "selectNode", "reloadActionNode", "getActionNode", "setActiveTreeType", "getNodeDef"];
+ for (var p in treeProps) {
+ tmpTree[treeProps[p]] = function() { return false; };
+ }
+ this._mainTree = tmpTree;
+ }
+ else {
+ this._mainTree = this.mainWindow().jQuery(".umbTree").UmbracoTreeAPI();
+ }
+ }
+ return this._mainTree;
+ },
+ appActions: function() {
+ ///
+ /// Returns a reference to the application actions object
+ ///
+
+ //if the main window has no actions, we'll create some
+ if (this._appActions == null) {
+ if (typeof this.mainWindow().appActions == 'undefined') {
+ this._appActions = new Umbraco.Application.Actions();
+ }
+ else this._appActions = this.mainWindow().appActions;
+ }
+ return this._appActions;
+ },
+ uiKeys: function() {
+ ///
+ /// Returns a reference to the main windows uiKeys object for globalization
+ ///
+
+ //TODO: If there is no main window, we need to go retrieve the appActions from the server!
+ return this.mainWindow().uiKeys;
+ },
+ // windowMgr: function()
+ // return null;
+ // },
+ contentFrameAndSection: function(app, rightFrameUrl) {
+ //this.appActions().shiftApp(app, this.uiKeys()['sections_' + app]);
+ var self = this;
+ self.mainWindow().UmbClientMgr.historyManager().addHistory(app, true);
+ window.setTimeout(function() {
+ self.mainWindow().UmbClientMgr.contentFrame(rightFrameUrl);
+ }, 200);
+ },
+
+ /**
+ * @ngdoc function
+ * @name contentFrame
+ * @methodOf UmbClientMgr
+ * @function
+ *
+ * @description
+ * This will tell our angular app to create and load in an iframe at the specified location
+ * @param strLocation {String} The URL to load the iframe in
+ */
+ contentFrame: function (strLocation) {
+
+ if (!strLocation || strLocation == "") {
+ //SD: NOTE: We used to return the content iframe object but now I'm not sure we should do that ?!
+ return null;
+ }
+
+ this._debug("contentFrame: " + strLocation);
+
+ //get our angular navigation service
+ var injector = getRootInjector();
+ var navService = injector.get("navigationService");
+
+ //if the path doesn't start with "/" or with the root path then
+ //prepend the root path
+ if (!strLocation.startsWith("/")) {
+ strLocation = this._rootPath + "/" + strLocation;
+ }
+ else if (strLocation.length >= this._rootPath.length
+ && strLocation.substr(0, this._rootPath.length) != this._rootPath) {
+ strLocation = this._rootPath + "/" + strLocation;
+ }
+
+ navService.loadLegacyIFrame(strLocation);
+
+ //if (strLocation == null || strLocation == "") {
+ // if (typeof this.mainWindow().right != "undefined") {
+ // return this.mainWindow().right;
+ // }
+ // else {
+ // return this.mainWindow(); //return the current window if the content frame doesn't exist in the current context
+ // }
+ //}
+ //else {
+ // //if the path doesn't start with "/" or with the root path then
+ // //prepend the root path
+ // if (strLocation.substr(0, 1) != "/") {
+ // strLocation = this._rootPath + "/" + strLocation;
+ // }
+ // else if (strLocation.length >= this._rootPath.length
+ // && strLocation.substr(0, this._rootPath.length) != this._rootPath) {
+ // strLocation = this._rootPath + "/" + strLocation;
+ // }
+
+ // this._debug("contentFrame: parsed location: " + strLocation);
+ // var self = this;
+ // window.setTimeout(function() {
+ // if (typeof self.mainWindow().right != "undefined") {
+ // self.mainWindow().right.location.href = strLocation;
+ // }
+ // else {
+ // self.mainWindow().location.href = strLocation; //set the current windows location if the right frame doesn't exist int he current context
+ // }
+ // }, 200);
+ //}
+ },
+ openModalWindow: function(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback) {
+ //need to create the modal on the top window if the top window has a client manager, if not, create it on the current window
+
+ //if this is the top window, or if the top window doesn't have a client manager, create the modal in this manager
+ if (window == this.mainWindow() || !this.mainWindow().UmbClientMgr) {
+ var m = new Umbraco.Controls.ModalWindow();
+ this._modal.push(m);
+ m.open(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback);
+ }
+ else {
+ //if the main window has a client manager, then call the main window's open modal method whilst keeping the context of it's manager.
+ if (this.mainWindow().UmbClientMgr) {
+ this.mainWindow().UmbClientMgr.openModalWindow.apply(this.mainWindow().UmbClientMgr,
+ [url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback]);
+ }
+ else {
+ return; //exit recurse.
+ }
+ }
+ },
+ closeModalWindow: function(rVal) {
+ ///
+ /// will close the latest open modal window.
+ /// if an rVal is passed in, then this will be sent to the onCloseCallback method if it was specified.
+ ///
+ if (this._modal != null && this._modal.length > 0) {
+ this._modal.pop().close(rVal);
+ }
+ else {
+ //this will recursively try to close a modal window until the parent window has a modal object or the window is the top and has the modal object
+ var mgr = null;
+ if (window.parent == null || window.parent == window) {
+ //we are at the root window, check if we can close the modal window from here
+ if (window.UmbClientMgr != null && window.UmbClientMgr._modal != null && window.UmbClientMgr._modal.length > 0) {
+ mgr = window.UmbClientMgr;
+ }
+ else {
+ return; //exit recursion.
+ }
+ }
+ else if (typeof window.parent.UmbClientMgr != "undefined") {
+ mgr = window.parent.UmbClientMgr;
+ }
+ mgr.closeModalWindow.call(mgr, rVal);
+ }
+ },
+ _debug: function(strMsg) {
+ if (this._isDebug) {
+ Sys.Debug.trace("UmbClientMgr: " + strMsg);
+ }
+ },
+ get_isDirty: function() {
+ return this._isDirty;
+ },
+ set_isDirty: function(value) {
+ this._isDirty = value;
+ }
+ };
+ };
+})(jQuery);
+
+//define alias for use throughout application
+var UmbClientMgr = new Umbraco.Application.ClientManager();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js
index e32304cd9b..282eb05ff7 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js
@@ -1,5 +1,5 @@
angular.module("umbraco.directives")
-.directive('umbTreeItem', function($compile, $http, $templateCache, $interpolate, $log, treeService) {
+.directive('umbTreeItem', function($compile, $http, $templateCache, $interpolate, $log, $location, treeService) {
return {
restrict: 'E',
replace: true,
@@ -14,7 +14,7 @@ angular.module("umbraco.directives")
'' +
'' +
'' +
- '{{node.name}}' +
+ '{{node.name}}' +
'' +
''+
'',
@@ -25,8 +25,46 @@ angular.module("umbraco.directives")
scope.$emit("treeOptionsClick", {element: e, node: n, event: ev});
};
+ /**
+ * @ngdoc function
+ * @name select
+ * @methodOf umbraco.directives.umbTreeItem
+ * @function
+ *
+ * @description
+ * Handles the click event of a tree node
+
+ * @param n {object} The tree node object associated with the click
+ */
scope.select = function(e,n,ev){
- scope.$emit("treeNodeSelect", {element: e, node: n, event: ev});
+
+ //here we need to check for some legacy tree code
+ if (n.jsClickCallback && n.jsClickCallback != "") {
+ //this is a legacy tree node!
+ var js;
+ if (n.jsClickCallback.startsWith("javascript:")) {
+ js = n.jsClickCallback.substr("javascript:".length);
+ }
+ else {
+ js = n.jsClickCallback;
+ }
+ try {
+ var func = eval(js);
+ //this is normally not necessary since the eval above should execute the method and will return nothing.
+ if (func != null && (typeof func === "function")) {
+ func.call();
+ }
+ }
+ catch(e) {
+ $log.error("Error evaluating js callback from legacy tree node: " + e);
+ }
+ }
+ else {
+ //not legacy, lets just set the route value
+ $location.path(n.view);
+ }
+
+ scope.$emit("treeNodeSelect", { element: e, node: n, event: ev });
};
scope.load = function (node) {
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 08fd919ccd..66bdfd76db 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
@@ -1,55 +1,55 @@
angular.module('umbraco.services')
-.factory('navigationService', function ($rootScope, $routeParams, $log, dialogService, treeService) {
+.factory('navigationService', function ($rootScope, $routeParams, $log, $location, dialogService, treeService) {
- var _currentSection = $routeParams.section;
- var _currentId = $routeParams.id;
- var _currentNode;
- var _ui = {};
+ var currentSection = $routeParams.section;
+ var currentId = $routeParams.id;
+ var currentNode;
+ var ui = {};
- function _setMode(mode){
+ function setMode(mode){
switch(mode)
{
case 'tree':
- _ui.showNavigation = true;
- _ui.showContextMenu = false;
- _ui.showContextMenuDialog = false;
- _ui.stickyNavigation = false;
+ ui.showNavigation = true;
+ ui.showContextMenu = false;
+ ui.showContextMenuDialog = false;
+ ui.stickyNavigation = false;
$("#search-form input").focus();
break;
case 'menu':
- _ui.showNavigation = true;
- _ui.showContextMenu = true;
- _ui.showContextMenuDialog = false;
- _ui.stickyNavigation = true;
+ ui.showNavigation = true;
+ ui.showContextMenu = true;
+ ui.showContextMenuDialog = false;
+ ui.stickyNavigation = true;
break;
case 'dialog':
- _ui.stickyNavigation = true;
- _ui.showNavigation = true;
- _ui.showContextMenu = false;
- _ui.showContextMenuDialog = true;
+ ui.stickyNavigation = true;
+ ui.showNavigation = true;
+ ui.showContextMenu = false;
+ ui.showContextMenuDialog = true;
break;
case 'search':
- _ui.stickyNavigation = false;
- _ui.showNavigation = true;
- _ui.showContextMenu = false;
- _ui.showSearchResults = true;
- _ui.showContextMenuDialog = false;
+ ui.stickyNavigation = false;
+ ui.showNavigation = true;
+ ui.showContextMenu = false;
+ ui.showSearchResults = true;
+ ui.showContextMenuDialog = false;
break;
default:
- _ui.showNavigation = false;
- _ui.showContextMenu = false;
- _ui.showContextMenuDialog = false;
- _ui.showSearchResults = false;
- _ui.stickyNavigation = false;
+ ui.showNavigation = false;
+ ui.showContextMenu = false;
+ ui.showContextMenuDialog = false;
+ ui.showSearchResults = false;
+ ui.stickyNavigation = false;
break;
}
}
return {
- currentNode: _currentNode,
+ currentNode: currentNode,
mode: "default",
- ui: _ui,
+ ui: ui,
sections: function(){
return [
@@ -61,9 +61,23 @@ angular.module('umbraco.services')
];
},
+ /**
+ * @ngdoc function
+ * @name loadLegacyIFrame
+ * @methodOf navigationService
+ * @function
+ *
+ * @description
+ * Shows the legacy iframe and loads in the content based on the source url
+ * @param source {String} The URL to load into the iframe
+ */
+ loadLegacyIFrame: function (source) {
+ $location.path("/framed/" + encodeURIComponent(source));
+ },
+
changeSection: function(sectionAlias){
if(this.ui.stickyNavigation){
- _setMode("default-opensection");
+ setMode("default-opensection");
this.ui.currentSection = selectedSection;
this.showTree(selectedSection);
}
@@ -73,7 +87,7 @@ angular.module('umbraco.services')
if(!this.ui.stickyNavigation && sectionAlias !== this.ui.currentTree){
$log.log("show tree" + sectionAlias);
this.ui.currentTree = sectionAlias;
- _setMode("tree");
+ setMode("tree");
}
},
@@ -81,7 +95,7 @@ angular.module('umbraco.services')
if(!this.ui.stickyNavigation){
$log.log("hide tree");
this.ui.currentTree = "";
- _setMode("default-hidesectiontree");
+ setMode("default-hidesectiontree");
}
},
@@ -101,9 +115,10 @@ angular.module('umbraco.services')
action: act,
section: this.ui.currentTree
});
- }else{
- _setMode("menu");
- _ui.actions = treeService.getActions({node: args.node, section: this.ui.currentTree});
+ }
+ else {
+ setMode("menu");
+ ui.actions = treeService.getActions({node: args.node, section: this.ui.currentTree});
this.ui.currentNode = args.node;
@@ -112,17 +127,17 @@ angular.module('umbraco.services')
},
hideMenu: function () {
- _selectedId = $routeParams.id;
+ var selectedId = $routeParams.id;
this.ui.currentNode = undefined;
this.ui.actions = [];
- _setMode("tree");
+ setMode("tree");
},
showDialog: function (args) {
- _setMode("dialog");
+ setMode("dialog");
- var _scope = args.scope || $rootScope.$new();
- _scope.currentNode = args.node;
+ var scope = args.scope || $rootScope.$new();
+ scope.currentNode = args.node;
//this.currentNode = item;
this.ui.dialogTitle = args.action.name;
@@ -131,7 +146,7 @@ angular.module('umbraco.services')
var d = dialogService.append(
{
container: $("#dialog div.umb-panel-body"),
- scope: _scope,
+ scope: scope,
template: templateUrl
});
},
@@ -142,11 +157,11 @@ angular.module('umbraco.services')
},
showSearch: function() {
- _setMode("search");
+ setMode("search");
},
hideSearch: function() {
- _setMode("default-hidesearch");
+ setMode("default-hidesearch");
},
hideNavigation: function(){
@@ -154,7 +169,7 @@ angular.module('umbraco.services')
this.ui.actions = [];
this.ui.currentNode = undefined;
- _setMode("default");
+ setMode("default");
}
};
diff --git a/src/Umbraco.Web.UI.Client/src/less/tree.less b/src/Umbraco.Web.UI.Client/src/less/tree.less
index b502499ec8..65099406ac 100644
--- a/src/Umbraco.Web.UI.Client/src/less/tree.less
+++ b/src/Umbraco.Web.UI.Client/src/less/tree.less
@@ -43,6 +43,7 @@
.umb-tree a {
vertical-align: middle;
display: inline-block;
+ cursor:pointer;
}
.umb-tree a:hover {
diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js
index 92ff159370..8b6d809ba4 100644
--- a/src/Umbraco.Web.UI.Client/src/routes.js
+++ b/src/Umbraco.Web.UI.Client/src/routes.js
@@ -3,6 +3,15 @@ app.config(function ($routeProvider) {
.when('/:section', {
templateUrl: "views/common/dashboard.html"
})
+ .when('/framed/:url', {
+ //This occurs when we need to launch some content in an iframe
+ templateUrl: function (rp) {
+ if (!rp.url)
+ throw "A framed resource must have a url route parameter";
+
+ return 'views/common/legacy.html';
+ }
+ })
.when('/:section/:method', {
templateUrl: function(rp) {
if (!rp.method)
@@ -12,13 +21,13 @@ app.config(function ($routeProvider) {
}
})
.when('/:section/:method/:id', {
- templateUrl: function(rp) {
- if (!rp.method)
+ templateUrl: function (rp) {
+ if (!rp.method)
return "views/common/dashboard.html";
-
+
return 'views/' + rp.section + '/' + rp.method + '.html';
}
- })
+ })
.otherwise({ redirectTo: '/content' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/legacy.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/legacy.controller.js
index de1ef5afef..a5da3970b6 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/legacy.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/legacy.controller.js
@@ -1,4 +1,19 @@
-angular.module("umbraco").controller("Umbraco.Common.LegacyController",
- function($scope, $routeParams){
- $scope.legacyPath = decodeURI($routeParams.p);
- });
\ No newline at end of file
+/**
+ * @ngdoc controller
+ * @name LegacyController
+ * @function
+ *
+ * @description
+ * A controller to control the legacy iframe injection
+ *
+ * @param myParam {object} Enter param description here
+*/
+function LegacyController($scope, $routeParams, $element) {
+ //set the legacy path
+ $scope.legacyPath = decodeURIComponent($routeParams.url);
+
+ //$scope.$on('$routeChangeSuccess', function () {
+ // var asdf = $element;
+ //});
+}
+angular.module("umbraco").controller('LegacyController', LegacyController);
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/legacy.html b/src/Umbraco.Web.UI.Client/src/views/common/legacy.html
index 8e61774783..10ac1a378b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/legacy.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/legacy.html
@@ -1 +1,3 @@
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/config/ClientDependency.config b/src/Umbraco.Web.UI/config/ClientDependency.config
index 6c1ff881cf..87bd6c9da4 100644
--- a/src/Umbraco.Web.UI/config/ClientDependency.config
+++ b/src/Umbraco.Web.UI/config/ClientDependency.config
@@ -10,7 +10,7 @@ NOTES:
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
* A new version will invalidate both client and server cache and create new persisted files
-->
-
+