From 894664b41aaf8ea8336cbe660f8c6b28ebad70b2 Mon Sep 17 00:00:00 2001 From: Shandem Date: Sat, 20 Jun 2009 13:17:06 +0000 Subject: [PATCH] DO NOT DOWNLOAD. DOWNLOAD LATEST STABLE FROM RELEASE TAB Tree fixes/updates [TFS Changeset #55166] --- .../presentation/umbraco.presentation.csproj | 3 +- .../umbraco/controls/TreeControl.ascx | 23 +++-- .../controls/TreeControl.ascx.designer.cs | 65 ++++++++++++- umbraco/presentation/umbraco/umbraco.aspx | 6 +- umbraco/presentation/umbraco/umbraco.aspx.cs | 3 +- .../umbraco/umbraco.aspx.designer.cs | 18 ---- .../Application/JQuery/jquery.cookie.js | 96 +++++++++++++++++++ .../Application/UmbracoApplicationActions.js | 11 ++- .../umbraco_client/Tree/UmbracoTree.js | 56 ++++++++++- 9 files changed, 239 insertions(+), 42 deletions(-) create mode 100644 umbraco/presentation/umbraco_client/Application/JQuery/jquery.cookie.js diff --git a/umbraco/presentation/umbraco.presentation.csproj b/umbraco/presentation/umbraco.presentation.csproj index 231e15bc63..3d2f70c7f6 100644 --- a/umbraco/presentation/umbraco.presentation.csproj +++ b/umbraco/presentation/umbraco.presentation.csproj @@ -1,6 +1,6 @@  - 9.0.30729 + 9.0.21022 2.0 {651E1350-91B6-44B7-BD60-7207006D7003} {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} @@ -1538,6 +1538,7 @@ + diff --git a/umbraco/presentation/umbraco/controls/TreeControl.ascx b/umbraco/presentation/umbraco/controls/TreeControl.ascx index 6637e082d2..7f27bdc513 100644 --- a/umbraco/presentation/umbraco/controls/TreeControl.ascx +++ b/umbraco/presentation/umbraco/controls/TreeControl.ascx @@ -1,16 +1,15 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TreeControl.ascx.cs" Inherits="umbraco.presentation.umbraco.controls.TreeControl" %> - - - <%----%> - - <%----%> - - - - <%----%> - <%----%> - - + +<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency" Assembly="umbraco.presentation.ClientDependency" %> + + + + + + + + + - + @@ -26,12 +26,10 @@ - - diff --git a/umbraco/presentation/umbraco/umbraco.aspx.cs b/umbraco/presentation/umbraco/umbraco.aspx.cs index 8400e67bb7..d2b761fee4 100644 --- a/umbraco/presentation/umbraco/umbraco.aspx.cs +++ b/umbraco/presentation/umbraco/umbraco.aspx.cs @@ -12,13 +12,14 @@ using umbraco.BasePages; using System.Xml; using System.Xml.XPath; using umbraco.BusinessLogic.Actions; +using umbraco.presentation.ClientDependency; namespace umbraco.cms.presentation { /// /// Summary description for _default. /// - public partial class _umbraco : UmbracoEnsuredPage + public partial class _umbraco : UmbracoEnsuredPage { protected umbWindow UmbWindow1; protected System.Web.UI.WebControls.PlaceHolder bubbleText; diff --git a/umbraco/presentation/umbraco/umbraco.aspx.designer.cs b/umbraco/presentation/umbraco/umbraco.aspx.designer.cs index 1c5bcc5854..47905f0dd5 100644 --- a/umbraco/presentation/umbraco/umbraco.aspx.designer.cs +++ b/umbraco/presentation/umbraco/umbraco.aspx.designer.cs @@ -49,15 +49,6 @@ namespace umbraco.cms.presentation { /// protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude ClientDependencyInclude1; - /// - /// ClientDependencyInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude ClientDependencyInclude2; - /// /// ClientDependencyInclude4 control. /// @@ -85,15 +76,6 @@ namespace umbraco.cms.presentation { /// protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude ClientDependencyInclude6; - /// - /// ClientDependencyInclude8 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude ClientDependencyInclude8; - /// /// ClientDependencyInclude7 control. /// diff --git a/umbraco/presentation/umbraco_client/Application/JQuery/jquery.cookie.js b/umbraco/presentation/umbraco_client/Application/JQuery/jquery.cookie.js new file mode 100644 index 0000000000..c50b7f356a --- /dev/null +++ b/umbraco/presentation/umbraco_client/Application/JQuery/jquery.cookie.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/umbraco/presentation/umbraco_client/Application/UmbracoApplicationActions.js b/umbraco/presentation/umbraco_client/Application/UmbracoApplicationActions.js index 43a25e8d74..d36595ccf6 100644 --- a/umbraco/presentation/umbraco_client/Application/UmbracoApplicationActions.js +++ b/umbraco/presentation/umbraco_client/Application/UmbracoApplicationActions.js @@ -83,6 +83,9 @@ Umbraco.Application.Actions = function() { this._debug("shiftApp: " + whichApp + ", " + appName + ", " + ignoreDashboard); + + UmbClientMgr.mainTree().saveTreeState(this._currApp == "" ? "content" : this._currApp); + this._currApp = whichApp.toLowerCase(); if (this._currApp != 'media' && this._currApp != 'content') { @@ -95,7 +98,8 @@ Umbraco.Application.Actions = function() { if (!ignoreDashboard) { UmbClientMgr.contentFrame('dashboard.aspx?app=' + whichApp); } - + + UmbClientMgr.mainTree().rebuildTree(whichApp); jQuery("#treeWindowLabel").html(appName); @@ -292,13 +296,16 @@ Umbraco.Application.Actions = function() { if (UmbClientMgr.mainTree().getActionNode().nodeType == "content" && UmbClientMgr.mainTree().getActionNode().nodeId == '-1') return; + this._debug("actionDelete"); + if (confirm(uiKeys['defaultdialogs_confirmdelete'] + ' "' + UmbClientMgr.mainTree().getActionNode().nodeName + '"?\n\n')) { //raise nodeDeleting event jQuery(this).trigger("nodeDeleting", []); var _this = this; umbraco.presentation.webservices.legacyAjaxCalls.Delete(UmbClientMgr.mainTree().getActionNode().nodeId, "", UmbClientMgr.mainTree().getActionNode().nodeType, function() { + _this._debug("actionDelete: Raising event"); //raise nodeDeleted event - jQuery(this).trigger("nodeDeleted", []); + jQuery(_this).trigger("nodeDeleted", []); }); } }, diff --git a/umbraco/presentation/umbraco_client/Tree/UmbracoTree.js b/umbraco/presentation/umbraco_client/Tree/UmbracoTree.js index 03e5f43462..f3613c2b7a 100644 --- a/umbraco/presentation/umbraco_client/Tree/UmbracoTree.js +++ b/umbraco/presentation/umbraco_client/Tree/UmbracoTree.js @@ -80,7 +80,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); /// This will rebuild the tree structure for the application specified this._debug("rebuildTree"); - + if (this._app == null || (this._app.toLowerCase() == app.toLowerCase())) { this._debug("not rebuilding"); return; @@ -95,6 +95,22 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); this._tree.destroy(); this._container.hide(); var _this = this; + + //check if we should rebuild from a saved tree + var saveData = this._container.data("tree_" + app); + if (saveData != null) { + this._debug("rebuildTree: rebuilding from cache!"); + + //create the tree from the saved data. + this._initNode = saveData; + this._tree = $.tree_create(); + this._tree.init(this._container, this._getInitOptions()); + + this._configureNodes(this._container.find("li"), true); + this._container.show(); + return; + } + //need to get the init node for the new app var parameters = "{'app':'" + app + "','showContextMenu':'" + this._showContext + "', 'isDialog':'" + this._isDialog + "'}" $.ajax({ @@ -125,7 +141,35 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); }); }, - + + saveTreeState: function(appAlias) { + /// + /// Saves the state of the current application trees so we can restore it next time the user visits the app + /// + var saveData = this._tree.getJSON(null, [ "id", "umb:type", "class" ], [ "umb:nodedata", "href", "class", "style" ]); + + //need to update the 'state' of the data. jsTree getJSON doesn't return the state of nodes (yet)! + this._updateJSONNodeState(saveData); + + this._container.data("tree_" + appAlias, saveData); + }, + + _updateJSONNodeState: function(obj) { + /// + /// A recursive function to store the state of the node for the JSON object when using saveTreeState. + /// This is required since jsTree doesn't output the state of the tree nodes with the request to getJSON method. + /// + + var c = $("li#" + obj.attributes.id).attr("class"); + var state = c.indexOf("open") > -1 ? "open" : c.indexOf("closed") > -1 ? "closed" : null; + if (state != null) obj.state = state; + if (obj.children != null) { + for (var x in obj.children) { + this._updateJSONNodeState(obj.children[x]); + } + } + }, + syncTree: function(path, forceReload) { /// /// Syncronizes the tree with the path supplied and makes that node visible/selected. @@ -346,6 +390,8 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); onNodeDeleting: function(EV) { /// Event handler for when a tree node is about to be deleted + this._debug("onNodeDeleting") + //first, close the branch this._tree.close_branch(this._actionNode.jsNode); //show the ajax loader with deleting text @@ -357,6 +403,8 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); onNodeDeleted: function(EV) { /// Event handler for when a tree node is deleted after ajax call + this._debug("onNodeDeleted"); + //remove the ajax loader this._actionNode.jsNode.find("a").removeClass("loading"); //ensure the branch is closed @@ -678,7 +726,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); /// Url path for the tree client service /// Url path for the tree data service - this._debug("init: creating new tree with class/id: " + treeContainer.attr("class") + " / " + treeContainer.attr("id")); + this._debug("_init: creating new tree with class/id: " + treeContainer.attr("class") + " / " + treeContainer.attr("id")); this._fullMenu = jFullMenu; this._initNode = jInitNode; @@ -722,6 +770,8 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); _getInitOptions: function() { /// return the initialization objects for the tree + this._debug("_getInitOptions"); + var _this = this; var options = {