diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 1ebcf1b90d..54818e4477 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -841,6 +841,10 @@ To manage your website, simply open the Umbraco back office and start adding con Partial view saved without any errors! Partial view not saved An error occurred saving the file. + Script view saved + Script view saved without any errors! + Script view not saved + An error occurred saving the file. Uses CSS syntax ex: h1, .redHeader, .blueTex diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index f8a362d4f1..3548526c83 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -842,6 +842,10 @@ To manage your website, simply open the Umbraco back office and start adding con Partial view saved without any errors! Partial view not saved An error occurred saving the file. + Script view saved + Script view saved without any errors! + Script view not saved + An error occurred saving the file. Uses CSS syntax ex: h1, .redHeader, .blueTex diff --git a/src/Umbraco.Web.UI/umbraco/settings/scripts/editScript.aspx b/src/Umbraco.Web.UI/umbraco/settings/scripts/editScript.aspx index e68922bd98..be0d68d3ba 100644 --- a/src/Umbraco.Web.UI/umbraco/settings/scripts/editScript.aspx +++ b/src/Umbraco.Web.UI/umbraco/settings/scripts/editScript.aspx @@ -1,6 +1,7 @@ <%@ Page Language="C#" MasterPageFile="../../masterpages/umbracoPage.Master" AutoEventWireup="true" CodeBehind="editScript.aspx.cs" Inherits="umbraco.cms.presentation.settings.scripts.editScript" ValidateRequest="False" %> +<%@ Import Namespace="Umbraco.Core" %> <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> <%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> @@ -21,13 +22,10 @@ nameTxtBox: $('#<%= NameTxt.ClientID %>'), originalFileName: '<%= NameTxt.Text %>', saveButton: $("#<%= ((Control)SaveButton).ClientID %>"), + restServiceLocation: "<%= Url.GetSaveFileServicePath() %>", editorSourceElement: $('#<%= editorSource.ClientID %>'), - text: { - fileErrorHeader: '<%= HttpUtility.JavaScriptStringEncode(umbraco.ui.Text("speechBubbles", "fileErrorHeader")) %>', - fileSavedHeader: '<%= HttpUtility.JavaScriptStringEncode(umbraco.ui.Text("speechBubbles", "fileSavedHeader")) %>', - fileSavedText: '', - fileErrorText: '<%= HttpUtility.JavaScriptStringEncode(umbraco.ui.Text("speechBubbles", "fileErrorText")) %>', - } + treeSyncPath: "<%= ScriptTreeSyncPath %>", + lttPathElement: $('#<%= lttPath.ClientID %>') }); editor.init(); diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js index 7c66dc9a1d..a286eed582 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js +++ b/src/Umbraco.Web.UI/umbraco_client/Editors/EditScript.js @@ -30,63 +30,69 @@ doSubmit: function () { var self = this; - var fileName = this._opts.nameTxtBox.val(); - var codeVal = this._opts.editorSourceElement.val(); + var filename = this._opts.nameTxtBox.val(); + var codeval = this._opts.editorSourceElement.val(); //if CodeMirror is not defined, then the code editor is disabled. if (typeof (CodeMirror) != "undefined") { - codeVal = UmbEditor.GetCode(); + codeval = UmbEditor.GetCode(); } - umbraco.presentation.webservices.codeEditorSave.SaveScript( - fileName, self._opts.originalFileName, codeVal, - function (t) { self.submitSucces(t); }, - function (t) { self.submitFailure(t); }); + this.save( + filename, + self._opts.originalFileName, + codeval); }, - submitSucces: function(t) { + save: function (filename, oldName, contents) { + var self = this; - if (t != 'true') { - top.UmbSpeechBubble.ShowMessage('error', unescape(this._opts.text.fileErrorHeader), unescape(this._opts.text.fileErrorText)); + $.post(self._opts.restServiceLocation + "SaveScript", + JSON.stringify({ + filename: filename, + oldName: oldName, + contents: contents + }), + function (e) { + if (e.success) { + self.submitSuccess(e); + } else { + self.submitFailure(e.message, e.header); + } + }); + }, + + submitSuccess: function(args) { + var msg = args.message; + var header = args.header; + var path = this._opts.treeSyncPath; + var pathChanged = false; + if (args.path) { + if (path != args.path) { + pathChanged = true; + } + path = args.path; + } + if (args.contents) { + UmbEditor.SetCode(args.contents); } - var newFilePath = this._opts.nameTxtBox.val(); - - //if the filename changes, we need to redirect since the file name is used in the url - if (this._opts.originalFileName != newFilePath) { - var newLocation = window.location.pathname + "?" + "&file=" + newFilePath; - - UmbClientMgr.contentFrame(newLocation); - - //we need to do this after we navigate otherwise the navigation will wait unti lthe message timeout is done! - top.UmbSpeechBubble.ShowMessage('save', unescape(this._opts.text.fileSavedHeader), unescape(this._opts.text.fileSavedText)); + top.UmbSpeechBubble.ShowMessage("save", header, msg); + UmbClientMgr.mainTree().setActiveTreeType("scripts"); + if (pathChanged) { + UmbClientMgr.mainTree().moveNode(this._opts.originalFileName, path); + this._opts.treeSyncPath = args.path; + this._opts.lttPathElement.prop("href", args.url).html(args.url); } else { - - top.UmbSpeechBubble.ShowMessage('save', unescape(this._opts.text.fileSavedHeader), unescape(this._opts.text.fileSavedText)); - UmbClientMgr.mainTree().setActiveTreeType('scripts'); - - //we need to create a list of ids for each folder/file. Each folder/file's id is it's full path so we need to build each one. - var paths = []; - var parts = this._opts.originalFileName.split('/'); - for (var i = 0;i < parts.length;i++) { - if (paths.length > 0) { - paths.push(paths[i - 1] + "/" + parts[i]); - } - else { - paths.push(parts[i]); - } - } - - //we need to pass in the newId parameter so it knows which node to resync after retreival from the server - UmbClientMgr.mainTree().syncTree("-1,init," + paths.join(','), true, null, newFilePath); - //set the original file path to the new one - this._opts.originalFileName = newFilePath; + UmbClientMgr.mainTree().syncTree(path, true); } - + + this._opts.lttPathElement.prop("href", args.url).html(args.url); + this._opts.originalFileName = args.name; }, - submitFailure: function(t) { - top.UmbSpeechBubble.ShowMessage('error', unescape(this._opts.text.fileErrorHeader), unescape(this._opts.text.fileErrorText)); + submitFailure: function(err, header) { + top.UmbSpeechBubble.ShowMessage('error', header, err); } }); })(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web/WebServices/SaveFileController.cs b/src/Umbraco.Web/WebServices/SaveFileController.cs index 651b372988..3abfd31f52 100644 --- a/src/Umbraco.Web/WebServices/SaveFileController.cs +++ b/src/Umbraco.Web/WebServices/SaveFileController.cs @@ -12,8 +12,9 @@ using Umbraco.Web.Mvc; using umbraco; using umbraco.cms.businesslogic.macro; using System.Collections.Generic; +using umbraco.cms.helpers; using Umbraco.Core; - +using Umbraco.Core.Configuration; using Template = umbraco.cms.businesslogic.template.Template; namespace Umbraco.Web.WebServices @@ -216,6 +217,42 @@ namespace Umbraco.Web.WebServices } } + [HttpPost] + public JsonResult SaveScript(string filename, string oldName, string contents) + { + filename = filename.TrimStart(System.IO.Path.DirectorySeparatorChar); + + var svce = (FileService) Services.FileService; + var script = svce.GetScriptByName(oldName); + if (script == null) + script = new Script(filename); + else + script.Path = filename; + script.Content = contents; + + try + { + if (svce.ValidateScript(script) == false) + return Failed(ui.Text("speechBubbles", "scriptErrorText"), ui.Text("speechBubbles", "scriptErrorHeader"), + new FileSecurityException("File '" + filename + "' is not a valid script file.")); + + svce.SaveScript(script); + } + catch (Exception e) + { + return Failed(ui.Text("speechBubbles", "scriptErrorText"), ui.Text("speechBubbles", "scriptErrorHeader"), e); + } + + return Success(ui.Text("speechBubbles", "scriptSavedText"), ui.Text("speechBubbles", "scriptSavedHeader"), + new + { + path = DeepLink.GetTreePathFromFilePath(script.Path), + name = script.Path, + url = script.VirtualPath, + contents = script.Content + }); + } + /// /// Returns a successful message /// diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs index ee54297f06..dc26d20bb6 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs @@ -41,58 +41,42 @@ namespace umbraco.cms.presentation.settings.scripts protected MenuButton SaveButton; - private string file; + private string filename; + + protected string ScriptTreeSyncPath { get; private set; } + protected int ScriptId { get; private set; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); - NameTxt.Text = file; + NameTxt.Text = filename; - string path = ""; - if (file.StartsWith("~/")) - path = IOHelper.ResolveUrl(file); - else - path = IOHelper.ResolveUrl(SystemDirectories.Scripts + "/" + file); + // get the script, ensure it exists (not null) and validate (because + // the file service ensures that it loads scripts from the proper location + // but does not seem to validate extensions?) - in case of an error, + // throw - that's what we did anyways. + // also scrapping the code that added .cshtml and .vbhtml extensions, and + // ~/Views directory - we're not using editScript.aspx for views anymore. - lttPath.Text = "" + path + ""; + var svce = ApplicationContext.Current.Services.FileService; + var script = svce.GetScriptByName(filename); + if (script == null) // not found + throw new FileNotFoundException("Could not find file '" + filename + "'."); - var exts = UmbracoConfig.For.UmbracoSettings().Content.ScriptFileTypes.ToList(); - if (UmbracoConfig.For.UmbracoSettings().Templates.DefaultRenderingEngine == RenderingEngine.Mvc) - { - exts.Add("cshtml"); - exts.Add("vbhtml"); - } - - var dirs = SystemDirectories.Scripts; - if (UmbracoConfig.For.UmbracoSettings().Templates.DefaultRenderingEngine == RenderingEngine.Mvc) - dirs += "," + SystemDirectories.MvcViews; - - // validate file - IOHelper.ValidateEditPath(IOHelper.MapPath(path), dirs.Split(',')); - - // validate extension - IOHelper.ValidateFileExtension(IOHelper.MapPath(path), exts); - - - StreamReader SR; - string S; - SR = File.OpenText(IOHelper.MapPath(path)); - S = SR.ReadToEnd(); - SR.Close(); - - editorSource.Text = S; + lttPath.Text = "" + script.VirtualPath + ""; + editorSource.Text = script.Content; + ScriptTreeSyncPath = DeepLink.GetTreePathFromFilePath(filename); Panel1.Text = ui.Text("editscript", base.getUser()); pp_name.Text = ui.Text("name", base.getUser()); pp_path.Text = ui.Text("path", base.getUser()); - if (!IsPostBack) + if (IsPostBack == false) { - string sPath = DeepLink.GetTreePathFromFilePath(file); ClientTools .SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree().Tree.Alias) - .SyncTree(sPath, false); + .SyncTree(ScriptTreeSyncPath, false); } } @@ -100,12 +84,12 @@ namespace umbraco.cms.presentation.settings.scripts { base.OnInit(e); - file = Request.QueryString["file"].TrimStart('/'); + filename = Request.QueryString["file"].TrimStart('/'); //need to change the editor type if it is XML - if (file.EndsWith("xml")) + if (filename.EndsWith("xml")) editorSource.CodeBase = uicontrols.CodeArea.EditorType.XML; - else if (file.EndsWith("master")) + else if (filename.EndsWith("master")) editorSource.CodeBase = uicontrols.CodeArea.EditorType.HTML; @@ -153,7 +137,6 @@ namespace umbraco.cms.presentation.settings.scripts } } - protected override void OnPreRender(EventArgs e) { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs index 65fbf2537b..23d30181a9 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/codeEditorSave.asmx.cs @@ -355,6 +355,7 @@ namespace umbraco.presentation.webservices // return "false"; //} + [Obsolete("This method has been superceded by the REST service /Umbraco/RestServices/SaveFile/SaveScript which is powered by the SaveFileController.")] [WebMethod] public string SaveScript(string filename, string oldName, string contents) {