From 54dfd6d44a057815f47dac3e908f5df613f4d00d Mon Sep 17 00:00:00 2001 From: PerPloug Date: Mon, 6 Sep 2010 13:48:30 +0000 Subject: [PATCH] Merging, installer / skinning branch with 4.1 branch [TFS Changeset #76863] --- foreign dlls/HtmlAgilityPack.dll | Bin 0 -> 135168 bytes umbraco.sln | 5 +- umbraco/businesslogic/IO/SystemFiles.cs | 9 + umbraco/businesslogic/UmbracoSettings.cs | 23 + umbraco/businesslogic/Utils/TypeFinder.cs | 3 + .../Repositories/RepositoryWebservice.cs | 401 ++++++++++- umbraco/cms/businesslogic/events/EventArgs.cs | 2 + .../businesslogic/installer/IInstallerStep.cs | 12 + .../installer/InstallStepCollection.cs | 52 ++ .../businesslogic/installer/InstallerStep.cs | 24 + .../cms/businesslogic/skinning/Dependency.cs | 129 ++++ .../businesslogic/skinning/DependencyType.cs | 26 + .../businesslogic/skinning/ProviderBase.cs | 13 + umbraco/cms/businesslogic/skinning/Skin.cs | 284 ++++++++ .../cms/businesslogic/skinning/Skinning.cs | 426 ++++++++++++ umbraco/cms/businesslogic/skinning/Task.cs | 89 +++ .../cms/businesslogic/skinning/TaskType.cs | 68 ++ .../skinning/controls/ColorPicker.cs | 42 ++ .../skinning/dependencies/Color.cs | 62 ++ .../skinning/dependencies/Image.cs | 64 ++ .../skinning/dependencies/Text.cs | 60 ++ .../businesslogic/skinning/tasks/ModifyCss.cs | 57 ++ .../skinning/tasks/ModifyTemplate.cs | 95 +++ umbraco/cms/businesslogic/web/Access.cs | 620 +++++++++--------- umbraco/cms/umbraco.cms.csproj | 23 + .../interfaces/skinning/IDependencyType.cs | 16 + umbraco/interfaces/skinning/ITaskType.cs | 36 + umbraco/interfaces/umbraco.interfaces.csproj | 3 + umbraco/presentation/config/Dashboard.config | 40 +- umbraco/presentation/config/Skinning.config | 4 + .../presentation/config/metablogConfig.config | 15 + umbraco/presentation/config/scripting.config | 1 + .../config/umbracoSettings.config | 1 + .../presentation/config/xsltExtensions.config | 2 +- umbraco/presentation/default.aspx.cs | 168 +++-- umbraco/presentation/install/default.aspx | 56 +- umbraco/presentation/install/default.aspx.cs | 153 +++-- .../install/default.aspx.designer.cs | 22 +- umbraco/presentation/install/installer.js | 1 + .../install/steps/Definitions/Database.cs | 58 ++ .../install/steps/Definitions/DefaultUser.cs | 47 ++ .../steps/Definitions/FilePermissions.cs | 31 + .../install/steps/Definitions/Skinning.cs | 31 + .../install/steps/Definitions/TheEnd.cs | 31 + .../install/steps/Definitions/Welcome.cs | 39 ++ .../steps/Skinning/loadStarterKitDesigns.ascx | 31 + .../Skinning/loadStarterKitDesigns.ascx.cs | 94 +++ .../loadStarterKitDesigns.ascx.designer.cs | 33 + .../steps/Skinning/loadStarterKits.ascx | 27 + .../steps/Skinning/loadStarterKits.ascx.cs | 93 +++ .../Skinning/loadStarterKits.ascx.designer.cs | 33 + .../steps/{detect.ascx => database.ascx} | 2 +- .../{detect.ascx.cs => database.ascx.cs} | 0 ....designer.cs => database.ascx.designer.cs} | 0 .../{detect.ascx.resx => database.ascx.resx} | 0 .../presentation/install/steps/license.ascx | 18 +- .../presentation/install/steps/skinning.ascx | 24 + .../install/steps/skinning.ascx.cs | 47 ++ .../install/steps/skinning.ascx.designer.cs | 51 ++ umbraco/presentation/install/style.css | 207 +----- .../install/utills/FilePermissions.cs | 154 +++++ umbraco/presentation/page.cs | 13 +- umbraco/presentation/template.cs | 45 +- .../presentation/umbraco.presentation.csproj | 105 ++- .../Controls/LiveEditingToolbar.cs | 12 + .../Modules/SkinModule/SkinCustomizer.ascx | 31 + .../Modules/SkinModule/SkinCustomizer.ascx.cs | 177 +++++ .../SkinCustomizer.ascx.designer.cs | 96 +++ .../Modules/SkinModule/SkinModule.cs | 56 ++ .../Modules/SkinModule/SkinModule.js | 1 + .../LiveEditing/Modules/SkinModule/skin.png | Bin 0 -> 3764 bytes .../umbraco/Trees/loadTemplates.cs | 140 +++- .../presentation/umbraco/config/create/UI.xml | 37 +- .../presentation/umbraco/dashboard.aspx.cs | 5 +- .../umbraco/dashboard/Settings/Applyskin.ascx | 9 + .../dashboard/Settings/Applyskin.ascx.cs | 41 ++ .../Settings/Applyskin.ascx.designer.cs | 42 ++ .../presentation/umbraco/editContent.aspx.cs | 102 +-- .../umbraco/editContent.aspx.designer.cs | 3 +- .../settings/scripts/editScript.aspx.cs | 60 +- .../webservices/codeEditorSave.asmx.cs | 27 +- .../colorpicker/css/colorpicker.css | 162 +++++ .../colorpicker/images/blank.gif | Bin 0 -> 49 bytes .../images/colorpicker_background.png | Bin 0 -> 1897 bytes .../colorpicker/images/colorpicker_hex.png | Bin 0 -> 532 bytes .../colorpicker/images/colorpicker_hsb_b.png | Bin 0 -> 970 bytes .../colorpicker/images/colorpicker_hsb_h.png | Bin 0 -> 1012 bytes .../colorpicker/images/colorpicker_hsb_s.png | Bin 0 -> 1171 bytes .../colorpicker/images/colorpicker_indic.gif | Bin 0 -> 86 bytes .../images/colorpicker_overlay.png | Bin 0 -> 10355 bytes .../colorpicker/images/colorpicker_rgb_b.png | Bin 0 -> 970 bytes .../colorpicker/images/colorpicker_rgb_g.png | Bin 0 -> 1069 bytes .../colorpicker/images/colorpicker_rgb_r.png | Bin 0 -> 1066 bytes .../colorpicker/images/colorpicker_select.gif | Bin 0 -> 78 bytes .../colorpicker/images/colorpicker_submit.png | Bin 0 -> 984 bytes .../colorpicker/images/custom_background.png | Bin 0 -> 1916 bytes .../colorpicker/images/custom_hex.png | Bin 0 -> 562 bytes .../colorpicker/images/custom_hsb_b.png | Bin 0 -> 1097 bytes .../colorpicker/images/custom_hsb_h.png | Bin 0 -> 970 bytes .../colorpicker/images/custom_hsb_s.png | Bin 0 -> 1168 bytes .../colorpicker/images/custom_indic.gif | Bin 0 -> 86 bytes .../colorpicker/images/custom_rgb_b.png | Bin 0 -> 1008 bytes .../colorpicker/images/custom_rgb_g.png | Bin 0 -> 1069 bytes .../colorpicker/images/custom_rgb_r.png | Bin 0 -> 1018 bytes .../colorpicker/images/custom_submit.png | Bin 0 -> 997 bytes .../colorpicker/images/select.png | Bin 0 -> 506 bytes .../colorpicker/images/select2.png | Bin 0 -> 518 bytes .../colorpicker/images/slider.png | Bin 0 -> 315 bytes .../colorpicker/js/colorpicker.js | 484 ++++++++++++++ 109 files changed, 5026 insertions(+), 780 deletions(-) create mode 100644 foreign dlls/HtmlAgilityPack.dll create mode 100644 umbraco/cms/businesslogic/installer/IInstallerStep.cs create mode 100644 umbraco/cms/businesslogic/installer/InstallStepCollection.cs create mode 100644 umbraco/cms/businesslogic/installer/InstallerStep.cs create mode 100644 umbraco/cms/businesslogic/skinning/Dependency.cs create mode 100644 umbraco/cms/businesslogic/skinning/DependencyType.cs create mode 100644 umbraco/cms/businesslogic/skinning/ProviderBase.cs create mode 100644 umbraco/cms/businesslogic/skinning/Skin.cs create mode 100644 umbraco/cms/businesslogic/skinning/Skinning.cs create mode 100644 umbraco/cms/businesslogic/skinning/Task.cs create mode 100644 umbraco/cms/businesslogic/skinning/TaskType.cs create mode 100644 umbraco/cms/businesslogic/skinning/controls/ColorPicker.cs create mode 100644 umbraco/cms/businesslogic/skinning/dependencies/Color.cs create mode 100644 umbraco/cms/businesslogic/skinning/dependencies/Image.cs create mode 100644 umbraco/cms/businesslogic/skinning/dependencies/Text.cs create mode 100644 umbraco/cms/businesslogic/skinning/tasks/ModifyCss.cs create mode 100644 umbraco/cms/businesslogic/skinning/tasks/ModifyTemplate.cs create mode 100644 umbraco/interfaces/skinning/IDependencyType.cs create mode 100644 umbraco/interfaces/skinning/ITaskType.cs create mode 100644 umbraco/presentation/config/Skinning.config create mode 100644 umbraco/presentation/install/installer.js create mode 100644 umbraco/presentation/install/steps/Definitions/Database.cs create mode 100644 umbraco/presentation/install/steps/Definitions/DefaultUser.cs create mode 100644 umbraco/presentation/install/steps/Definitions/FilePermissions.cs create mode 100644 umbraco/presentation/install/steps/Definitions/Skinning.cs create mode 100644 umbraco/presentation/install/steps/Definitions/TheEnd.cs create mode 100644 umbraco/presentation/install/steps/Definitions/Welcome.cs create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.cs create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.designer.cs create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.cs create mode 100644 umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.designer.cs rename umbraco/presentation/install/steps/{detect.ascx => database.ascx} (96%) rename umbraco/presentation/install/steps/{detect.ascx.cs => database.ascx.cs} (100%) rename umbraco/presentation/install/steps/{detect.ascx.designer.cs => database.ascx.designer.cs} (100%) rename umbraco/presentation/install/steps/{detect.ascx.resx => database.ascx.resx} (100%) create mode 100644 umbraco/presentation/install/steps/skinning.ascx create mode 100644 umbraco/presentation/install/steps/skinning.ascx.cs create mode 100644 umbraco/presentation/install/steps/skinning.ascx.designer.cs create mode 100644 umbraco/presentation/install/utills/FilePermissions.cs create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.cs create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.designer.cs create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.cs create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.js create mode 100644 umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/skin.png create mode 100644 umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx create mode 100644 umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.cs create mode 100644 umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.designer.cs create mode 100644 umbraco/presentation/umbraco_client/colorpicker/css/colorpicker.css create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/blank.gif create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_background.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hex.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hsb_b.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hsb_h.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hsb_s.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_indic.gif create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_overlay.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_b.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_g.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_r.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_select.gif create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_submit.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_background.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_hex.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_b.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_h.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_s.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_indic.gif create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_rgb_b.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_rgb_g.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_rgb_r.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/custom_submit.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/select.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/select2.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/images/slider.png create mode 100644 umbraco/presentation/umbraco_client/colorpicker/js/colorpicker.js diff --git a/foreign dlls/HtmlAgilityPack.dll b/foreign dlls/HtmlAgilityPack.dll new file mode 100644 index 0000000000000000000000000000000000000000..b0692c1d9ec87451375a0047f5193dc0eac51b18 GIT binary patch literal 135168 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 CCmeeK literal 0 HcmV?d00001 diff --git a/umbraco.sln b/umbraco.sln index 8ab9934e7f..d4c25628fe 100644 --- a/umbraco.sln +++ b/umbraco.sln @@ -10,7 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SHOCKING.testrunconfig = SHOCKING.testrunconfig umbraco weekly.build = umbraco weekly.build umbraco.build = umbraco.build - umbraco3.vsmdi = umbraco3.vsmdi + umbraco2.vsmdi = umbraco2.vsmdi UMBRACOELISE.testrunconfig = UMBRACOELISE.testrunconfig UMBRACOHUMMER.testrunconfig = UMBRACOHUMMER.testrunconfig EndProjectSection @@ -64,6 +64,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DLLs", "DLLs", "{F06D18F6-C foreign dlls\ClientDependency.Core.dll = foreign dlls\ClientDependency.Core.dll foreign dlls\CookComputing.XmlRpcV2.dll = foreign dlls\CookComputing.XmlRpcV2.dll foreign dlls\Examine.dll = foreign dlls\Examine.dll + foreign dlls\HtmlAgilityPack.dll = foreign dlls\HtmlAgilityPack.dll foreign dlls\ICSharpCode.SharpZipLib.dll = foreign dlls\ICSharpCode.SharpZipLib.dll foreign dlls\IronMath.dll = foreign dlls\IronMath.dll IronPython License.Rtf = IronPython License.Rtf @@ -153,7 +154,7 @@ Global SccLocalPath13 = umbraco.Test EndGlobalSection GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = umbraco3.vsmdi + CategoryFile = umbraco2.vsmdi EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/umbraco/businesslogic/IO/SystemFiles.cs b/umbraco/businesslogic/IO/SystemFiles.cs index 285cb9d99d..aa747f2459 100644 --- a/umbraco/businesslogic/IO/SystemFiles.cs +++ b/umbraco/businesslogic/IO/SystemFiles.cs @@ -67,6 +67,15 @@ namespace umbraco.IO } } + + public static string SkinningXml + { + get + { + return SystemDirectories.Data + "/skinning.config"; + } + } + public static string NotFoundhandlersConfig { get diff --git a/umbraco/businesslogic/UmbracoSettings.cs b/umbraco/businesslogic/UmbracoSettings.cs index 89c641f177..4df3d5f30c 100644 --- a/umbraco/businesslogic/UmbracoSettings.cs +++ b/umbraco/businesslogic/UmbracoSettings.cs @@ -251,6 +251,29 @@ namespace umbraco } } + + /// + /// Gets a value indicating whether umbraco will attempt to load any skins to override default template files + /// + /// true if umbraco will override templates with skins if present and configured false. + public static bool EnableTemplateFolders + { + get + { + try + { + bool result; + if (bool.TryParse(GetKey("/settings/templates/enableTemplateFolders"), out result)) + return result; + return false; + } + catch + { + return false; + } + } + } + /// /// Gets a value indicating whether umbraco will clone XML cache on publish. /// diff --git a/umbraco/businesslogic/Utils/TypeFinder.cs b/umbraco/businesslogic/Utils/TypeFinder.cs index c78fd2eae8..3c0eb63f70 100644 --- a/umbraco/businesslogic/Utils/TypeFinder.cs +++ b/umbraco/businesslogic/Utils/TypeFinder.cs @@ -52,6 +52,9 @@ namespace umbraco.BusinessLogic.Utils string binFolder = Path.Combine(IO.IOHelper.MapPath("/", false), "bin"); string[] strTypes = TypeResolver.GetAssignablesFromType(binFolder, "*.dll"); + + + List types = new List(); foreach (string type in strTypes) diff --git a/umbraco/cms/businesslogic/Packager/Repositories/RepositoryWebservice.cs b/umbraco/cms/businesslogic/Packager/Repositories/RepositoryWebservice.cs index 108c3db9c9..6c49a3bce9 100644 --- a/umbraco/cms/businesslogic/Packager/Repositories/RepositoryWebservice.cs +++ b/umbraco/cms/businesslogic/Packager/Repositories/RepositoryWebservice.cs @@ -19,6 +19,7 @@ namespace umbraco.cms.businesslogic.packager.repositories { private System.Threading.SendOrPostCallback CategoriesOperationCompleted; + private System.Threading.SendOrPostCallback NitrosOperationCompleted; private System.Threading.SendOrPostCallback NitrosByVersionOperationCompleted; @@ -27,6 +28,8 @@ namespace umbraco.cms.businesslogic.packager.repositories private System.Threading.SendOrPostCallback NitrosCategorizedByVersionOperationCompleted; + private System.Threading.SendOrPostCallback StarterKitsOperationCompleted; + private System.Threading.SendOrPostCallback authenticateOperationCompleted; private System.Threading.SendOrPostCallback fetchPackageByVersionOperationCompleted; @@ -39,10 +42,14 @@ namespace umbraco.cms.businesslogic.packager.repositories private System.Threading.SendOrPostCallback PackageByGuidOperationCompleted; + private System.Threading.SendOrPostCallback SkinByGuidOperationCompleted; + + private System.Threading.SendOrPostCallback SkinsOperationCompleted; + /// public RepositoryWebservice(string url) { - this.Url = url; // "http://packages.umbraco.org/umbraco/webservices/api/repository.asmx"; + this.Url = url; //"http://packages.umbraco.org/umbraco/webservices/api/repository.asmx"; } /// @@ -60,6 +67,9 @@ namespace umbraco.cms.businesslogic.packager.repositories /// public event NitrosCategorizedByVersionCompletedEventHandler NitrosCategorizedByVersionCompleted; + /// + public event StarterKitsCompletedEventHandler StarterKitsCompleted; + /// public event authenticateCompletedEventHandler authenticateCompleted; @@ -78,6 +88,12 @@ namespace umbraco.cms.businesslogic.packager.repositories /// public event PackageByGuidCompletedEventHandler PackageByGuidCompleted; + /// + public event SkinByGuidCompletedEventHandler SkinByGuidCompleted; + + /// + public event SkinsCompletedEventHandler SkinsCompleted; + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://packages.umbraco.org/webservices/Categories", RequestNamespace = "http://packages.umbraco.org/webservices/", ResponseNamespace = "http://packages.umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public Category[] Categories(string repositoryGuid) @@ -317,6 +333,52 @@ namespace umbraco.cms.businesslogic.packager.repositories } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://packages.umbraco.org/webservices/StarterKits", RequestNamespace = "http://packages.umbraco.org/webservices/", ResponseNamespace = "http://packages.umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public Package[] StarterKits() + { + object[] results = this.Invoke("StarterKits", new object[0]); + return ((Package[])(results[0])); + } + + /// + public System.IAsyncResult BeginStarterKits(System.AsyncCallback callback, object asyncState) + { + return this.BeginInvoke("StarterKits", new object[0], callback, asyncState); + } + + /// + public Package[] EndStarterKits(System.IAsyncResult asyncResult) + { + object[] results = this.EndInvoke(asyncResult); + return ((Package[])(results[0])); + } + + /// + public void StarterKitsAsync() + { + this.StarterKitsAsync(null); + } + + /// + public void StarterKitsAsync(object userState) + { + if ((this.StarterKitsOperationCompleted == null)) + { + this.StarterKitsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnStarterKitsOperationCompleted); + } + this.InvokeAsync("StarterKits", new object[0], this.StarterKitsOperationCompleted, userState); + } + + private void OnStarterKitsOperationCompleted(object arg) + { + if ((this.StarterKitsCompleted != null)) + { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.StarterKitsCompleted(this, new StarterKitsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://packages.umbraco.org/webservices/authenticate", RequestNamespace = "http://packages.umbraco.org/webservices/", ResponseNamespace = "http://packages.umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string authenticate(string email, string md5Password) @@ -650,6 +712,104 @@ namespace umbraco.cms.businesslogic.packager.repositories } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://packages.umbraco.org/webservices/SkinByGuid", RequestNamespace = "http://packages.umbraco.org/webservices/", ResponseNamespace = "http://packages.umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public Skin SkinByGuid(string skinGuid) + { + object[] results = this.Invoke("SkinByGuid", new object[] { + skinGuid}); + return ((Skin)(results[0])); + } + + /// + public System.IAsyncResult BeginSkinByGuid(string skinGuid, System.AsyncCallback callback, object asyncState) + { + return this.BeginInvoke("SkinByGuid", new object[] { + skinGuid}, callback, asyncState); + } + + /// + public Skin EndSkinByGuid(System.IAsyncResult asyncResult) + { + object[] results = this.EndInvoke(asyncResult); + return ((Skin)(results[0])); + } + + /// + public void SkinByGuidAsync(string skinGuid) + { + this.SkinByGuidAsync(skinGuid, null); + } + + /// + public void SkinByGuidAsync(string skinGuid, object userState) + { + if ((this.SkinByGuidOperationCompleted == null)) + { + this.SkinByGuidOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSkinByGuidOperationCompleted); + } + this.InvokeAsync("SkinByGuid", new object[] { + skinGuid}, this.SkinByGuidOperationCompleted, userState); + } + + private void OnSkinByGuidOperationCompleted(object arg) + { + if ((this.SkinByGuidCompleted != null)) + { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SkinByGuidCompleted(this, new SkinByGuidCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://packages.umbraco.org/webservices/Skins", RequestNamespace = "http://packages.umbraco.org/webservices/", ResponseNamespace = "http://packages.umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public Skin[] Skins(string starterKitGuid) + { + object[] results = this.Invoke("Skins", new object[] { + starterKitGuid}); + return ((Skin[])(results[0])); + } + + /// + public System.IAsyncResult BeginSkins(string starterKitGuid, System.AsyncCallback callback, object asyncState) + { + return this.BeginInvoke("Skins", new object[] { + starterKitGuid}, callback, asyncState); + } + + /// + public Skin[] EndSkins(System.IAsyncResult asyncResult) + { + object[] results = this.EndInvoke(asyncResult); + return ((Skin[])(results[0])); + } + + /// + public void SkinsAsync(string starterKitGuid) + { + this.SkinsAsync(starterKitGuid, null); + } + + /// + public void SkinsAsync(string starterKitGuid, object userState) + { + if ((this.SkinsOperationCompleted == null)) + { + this.SkinsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSkinsOperationCompleted); + } + this.InvokeAsync("Skins", new object[] { + starterKitGuid}, this.SkinsOperationCompleted, userState); + } + + private void OnSkinsOperationCompleted(object arg) + { + if ((this.SkinsCompleted != null)) + { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SkinsCompleted(this, new SkinsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { @@ -962,6 +1122,151 @@ namespace umbraco.cms.businesslogic.packager.repositories } } + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://packages.umbraco.org/webservices/")] + public partial class Skin + { + + private System.Guid repoGuidField; + + private string textField; + + private string thumbnailField; + + private string previewField; + + private string descriptionField; + + private string authorField; + + private string authorUrlField; + + private string licenseField; + + private string licenseUrlField; + + /// + public System.Guid RepoGuid + { + get + { + return this.repoGuidField; + } + set + { + this.repoGuidField = value; + } + } + + /// + public string Text + { + get + { + return this.textField; + } + set + { + this.textField = value; + } + } + + /// + public string Thumbnail + { + get + { + return this.thumbnailField; + } + set + { + this.thumbnailField = value; + } + } + + /// + public string Preview + { + get + { + return this.previewField; + } + set + { + this.previewField = value; + } + } + + /// + public string Description + { + get + { + return this.descriptionField; + } + set + { + this.descriptionField = value; + } + } + + /// + public string Author + { + get + { + return this.authorField; + } + set + { + this.authorField = value; + } + } + + /// + public string AuthorUrl + { + get + { + return this.authorUrlField; + } + set + { + this.authorUrlField = value; + } + } + + /// + public string License + { + get + { + return this.licenseField; + } + set + { + this.licenseField = value; + } + } + + /// + public string LicenseUrl + { + get + { + return this.licenseUrlField; + } + set + { + this.licenseUrlField = value; + } + } + } + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] [System.SerializableAttribute()] @@ -978,6 +1283,9 @@ namespace umbraco.cms.businesslogic.packager.repositories /// Version41, + /// + Version41Legacy, + /// Version50, } @@ -1152,6 +1460,36 @@ namespace umbraco.cms.businesslogic.packager.repositories } } + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + public delegate void StarterKitsCompletedEventHandler(object sender, StarterKitsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class StarterKitsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs + { + + private object[] results; + + internal StarterKitsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) + { + this.results = results; + } + + /// + public Package[] Result + { + get + { + this.RaiseExceptionIfNecessary(); + return ((Package[])(this.results[0])); + } + } + } + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] public delegate void authenticateCompletedEventHandler(object sender, authenticateCompletedEventArgs e); @@ -1331,4 +1669,65 @@ namespace umbraco.cms.businesslogic.packager.repositories } } } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + public delegate void SkinByGuidCompletedEventHandler(object sender, SkinByGuidCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class SkinByGuidCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs + { + + private object[] results; + + internal SkinByGuidCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) + { + this.results = results; + } + + /// + public Skin Result + { + get + { + this.RaiseExceptionIfNecessary(); + return ((Skin)(this.results[0])); + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + public delegate void SkinsCompletedEventHandler(object sender, SkinsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class SkinsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs + { + + private object[] results; + + internal SkinsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) + { + this.results = results; + } + + /// + public Skin[] Result + { + get + { + this.RaiseExceptionIfNecessary(); + return ((Skin[])(this.results[0])); + } + } + } + } diff --git a/umbraco/cms/businesslogic/events/EventArgs.cs b/umbraco/cms/businesslogic/events/EventArgs.cs index 44988842c7..b3175c8664 100644 --- a/umbraco/cms/businesslogic/events/EventArgs.cs +++ b/umbraco/cms/businesslogic/events/EventArgs.cs @@ -47,4 +47,6 @@ namespace umbraco.cms.businesslogic { public umbraco.cms.businesslogic.web.DocumentType DocumentType { get; internal set; } public int ParentId { get; internal set; } } + + } diff --git a/umbraco/cms/businesslogic/installer/IInstallerStep.cs b/umbraco/cms/businesslogic/installer/IInstallerStep.cs new file mode 100644 index 0000000000..e8c163a464 --- /dev/null +++ b/umbraco/cms/businesslogic/installer/IInstallerStep.cs @@ -0,0 +1,12 @@ +using System; +namespace umbraco.cms.businesslogic.installer +{ + interface IInstallerStep + { + string Alias { get;} + bool Completed(); + string Name { get;} + string NextStep(); + string UserControl {get;} + } +} diff --git a/umbraco/cms/businesslogic/installer/InstallStepCollection.cs b/umbraco/cms/businesslogic/installer/InstallStepCollection.cs new file mode 100644 index 0000000000..8f823157c5 --- /dev/null +++ b/umbraco/cms/businesslogic/installer/InstallStepCollection.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections.Specialized; + +namespace umbraco.cms.businesslogic.installer +{ + public class InstallerStepCollection : List> + { + public void Add(InstallerStep step){ + step.Index = this.Count; + KeyValuePair kv = new KeyValuePair(step.Alias, step); + this.Add(kv); + } + + public InstallerStep Get(int index) + { + return this[index].Value; + } + + public InstallerStep Get(string key) + { + return this.First(item => item.Key == key).Value; + } + + public bool StepExists(string key) + { + return this.Exists(item => item.Key == key); + } + + public InstallerStep GotoNextStep(string key) + { + InstallerStep s = this.Get(key); + for (int i = s.Index+1; i < this.Count; i++) + { + InstallerStep next = this[i].Value; + if (!next.Completed()) + return next; + } + + return null; + } + + + public InstallerStep FirstAvailableStep() + { + return this.First(item => item.Value.Completed() == false ).Value; + } + } +} + diff --git a/umbraco/cms/businesslogic/installer/InstallerStep.cs b/umbraco/cms/businesslogic/installer/InstallerStep.cs new file mode 100644 index 0000000000..f3a7f55cd9 --- /dev/null +++ b/umbraco/cms/businesslogic/installer/InstallerStep.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace umbraco.cms.businesslogic.installer +{ + public abstract class InstallerStep : umbraco.cms.businesslogic.installer.IInstallerStep + { + public abstract string Alias { get; } + public abstract string Name { get; } + public abstract string UserControl { get;} + public virtual int Index { get; set; } + + public virtual bool MoveToNextStepAutomaticly { get; set; } + public virtual bool HideNextButtonUntillCompleted { get; set; } + + public abstract bool Completed(); + + public virtual string NextStep(){ + return "meh"; + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/Dependency.cs b/umbraco/cms/businesslogic/skinning/Dependency.cs new file mode 100644 index 0000000000..247185706c --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/Dependency.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Web; +using System.Reflection; + +namespace umbraco.cms.businesslogic.skinning +{ + public class Dependency + { + public Dependency() + { + Tasks = new List(); + Properties = new Dictionary(); + } + + public static Dependency CreateFromXmlNode(XmlNode node) + { + Dependency d = new Dependency(); + + + + if (node.SelectSingleNode("Properties") != null) + { + foreach (XmlNode prop in node.SelectSingleNode("Properties").ChildNodes) + { + if(prop.Name != "Output" && prop.Name != "#comment") + d.Properties.Add(prop.Name, prop.InnerText); + } + } + + + if(node.Attributes["label"] != null) + d.Label = node.Attributes["label"].Value; + + if (node.Attributes["type"] != null) + { + + if (node.Attributes["assembly"] != null) + { + //custom dependency type + + string assemblyFile = + HttpContext.Current.Server.MapPath( + String.Format("{0}/../bin/{1}.dll", + GlobalSettings.Path, + node.Attributes["assembly"].Value)); + + Assembly customAssembly = Assembly.LoadFrom(assemblyFile); + + d.DependencyType = (DependencyType)Activator.CreateInstance( + customAssembly.GetType(node.Attributes["type"].Value),d); + + foreach (var prop in d.Properties) + { + d.DependencyType.GetType().InvokeMember(prop.Key, System.Reflection.BindingFlags.SetProperty, null, d.DependencyType, new object[] { prop.Value }); + } + //d.DependencyType.Properties = d.Properties; + + } + else + { + //internal dependency type + + string assemblyFile = + HttpContext.Current.Server.MapPath( + String.Format("{0}/../bin/{1}.dll", + GlobalSettings.Path, + "cms")); + + Assembly defaultAssembly = Assembly.LoadFrom(assemblyFile); + + d.DependencyType = (DependencyType)Activator.CreateInstance( + defaultAssembly.GetType( + string.Format( + "umbraco.cms.businesslogic.skinning.dependencies.{0}", + node.Attributes["type"].Value))); + + + foreach (var prop in d.Properties) + { + d.DependencyType.GetType().InvokeMember(prop.Key, System.Reflection.BindingFlags.SetProperty, null, d.DependencyType, new object[] { prop.Value }); + } + + //d.DependencyType.Properties = d.Properties; + } + + XmlNode outputNode = node.SelectSingleNode("Properties/Output"); + + if (outputNode != null) + { + d.DependencyType.Values.Add(outputNode.InnerText); + } + } + + + + + foreach (XmlNode taskNode in node.SelectNodes("Tasks/Task")) + { + try + { + d.Tasks.Add(Task.CreateFromXmlNode(taskNode)); + } + catch (Exception ex) + { + umbraco.BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, 0, + "Failed to load task type " + (taskNode.Attributes["type"] != null ? taskNode.Attributes["type"].Value : string.Empty) + ex.Message); + } + } + + + return d; + } + + + public DependencyType DependencyType { get; set; } + + public string Label { get; set; } + + public Dictionary Properties {get; set;} + + public List Tasks { get; set; } + + + } +} diff --git a/umbraco/cms/businesslogic/skinning/DependencyType.cs b/umbraco/cms/businesslogic/skinning/DependencyType.cs new file mode 100644 index 0000000000..ac754d3b9c --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/DependencyType.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI.WebControls; +using umbraco.interfaces.skinning; + +namespace umbraco.cms.businesslogic.skinning +{ + public abstract class DependencyType : ProviderBase, IDependencyType + { + public virtual WebControl Editor { get; set; } + public virtual List Values { get; set; } + + public virtual string ClientSideGetValueScript() + { + return string.Format( + "jQuery('#{0}').val()" + ,Editor.ClientID); + } + public virtual string ClientSidePreviewEventType() + { + return "change"; + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/ProviderBase.cs b/umbraco/cms/businesslogic/skinning/ProviderBase.cs new file mode 100644 index 0000000000..9b6eed8279 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/ProviderBase.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace umbraco.cms.businesslogic.skinning +{ + public abstract class ProviderBase + { + public string Name { get; set; } + public string Description { get; set; } + } +} diff --git a/umbraco/cms/businesslogic/skinning/Skin.cs b/umbraco/cms/businesslogic/skinning/Skin.cs new file mode 100644 index 0000000000..815f9c1704 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/Skin.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.IO; +using System.Xml.XPath; + +namespace umbraco.cms.businesslogic.skinning +{ + public class Skin + { + public Skin() + { + AllowedDocumentTypeAliases = new List(); + Dependencies = new List(); + } + + public static Skin CreateFromFile(string filename) + { + XmlDocument manifest = new XmlDocument(); + + FileInfo f = new FileInfo(filename); + + if (f.Exists) + { + manifest.Load(filename); + + Skin s = Skin.CreateFromXmlNode(manifest.SelectSingleNode("//Skin")); + s.FullFileName = filename; + s.Alias = f.Directory.Name; + + return s; + } + else + return null; + + + } + + public static Skin CreateFromXmlNode(XmlNode node) + { + Skin s = new Skin(); + + + if(node.SelectSingleNode("/Skin/Name") != null) + s.Name = node.SelectSingleNode("/Skin/Name").InnerText; + + if(node.SelectSingleNode("/Skin/Author") != null) + s.Author = node.SelectSingleNode("/Skin/Author").InnerText; + + if(node.SelectSingleNode("/Skin/Version") != null) + s.Version = node.SelectSingleNode("/Skin/Version").InnerText; + + if(node.SelectSingleNode("/Skin/Description") != null) + s.Description = node.SelectSingleNode("/Skin/Description").InnerText; + + if (node.SelectSingleNode("/Skin/AllowedDocumentTypes") != null) + { + s.AllowedDocumentTypeAliases.AddRange( + node.SelectSingleNode("/Skin/AllowedDocumentTypes").InnerText.Split(',')); + } + + if (node.SelectSingleNode("/Skin/AllowedRootTemplate") != null) + s.AllowedRootTemplate = node.SelectSingleNode("/Skin/AllowedRootTemplate").InnerText; + + + foreach (XmlNode depNode in node.SelectNodes("/Skin//Dependency")) + { + try + { + s.Dependencies.Add(Dependency.CreateFromXmlNode(depNode)); + } + catch (Exception ex) + { + umbraco.BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, 0, + "Failed to load dependency type " + (depNode.Attributes["type"] != null ? depNode.Attributes["type"].Value : string.Empty) + ex.Message); + } + } + + + return s; + } + + public static Skin CreateFromAlias(string alias) + { + string manifest = Path.Combine(IO.IOHelper.MapPath( IO.SystemDirectories.Masterpages + "/" + alias), "skin.xml"); + return CreateFromFile(manifest); + } + + public bool OverridesTemplates() + { + return (System.IO.Directory.GetFiles(IO.IOHelper.MapPath(SkinFolder), "*.master").Count() > 0); + } + + public bool HasBackupFiles() + { + return System.IO.Directory.Exists( IO.IOHelper.MapPath(SkinBackupFolder) ); + } + + + public void SaveOutput() + { + + XmlDocument manifest = new XmlDocument(); + manifest.Load(FullFileName); + + int i = 1; + foreach (Dependency d in Dependencies) + { + if (d.DependencyType.Values.Count > 0) + { + XmlNode pNode = manifest.SelectSingleNode( + string.Format("/Skin/Dependencies/Dependency[{0}]/Properties", i.ToString())); + + + XmlNode outputNode = pNode.SelectSingleNode("./Output"); + + if (outputNode == null) + { + outputNode = manifest.CreateElement("Output"); + outputNode.InnerText = d.DependencyType.Values[0].ToString(); + pNode.AppendChild(outputNode); + } + else + { + outputNode.InnerText = d.DependencyType.Values[0].ToString(); + } + + + } + + i++; + } + + manifest.Save(FullFileName); + } + + public string FullFileName { get; set; } + + public string Name { get; set; } + + public string Author { get; set; } + public string Version { get; set; } + public string Description { get; set; } + + public string Alias { get; set; } + + public List AllowedDocumentTypeAliases { get; set; } + public string AllowedRootTemplate { get; set; } + + + public List Dependencies { get; set; } + + public void RollbackDependencies() + { + XmlDocument manifest = new XmlDocument(); + manifest.Load(FullFileName); + XmlNode hNode = manifest.SelectSingleNode("/Skin/History"); + + if (!(hNode == null || hNode.SelectNodes("Task").Count == 0)) + { + XPathNavigator navigator = manifest.CreateNavigator(); + XPathExpression expression = navigator.Compile("/Skin/History/Task"); + + expression.AddSort("@executed", XmlSortOrder.Descending, XmlCaseOrder.UpperFirst, + string.Empty, XmlDataType.Text); + + XPathNodeIterator iterator = navigator.Select(expression); + + foreach (XPathNavigator item in iterator) + { + Task t = Task.CreateFromXmlNode(((System.Xml.IHasXmlNode)item).GetNode()); + t.TaskType.RollBack(((System.Xml.IHasXmlNode)item).GetNode().SelectSingleNode("OriginalValue").InnerText); + } + + hNode.RemoveAll(); + manifest.Save(FullFileName); + } + } + + public void DeployTemplateFiles() + { + DeployTemplateFiles(IO.SystemDirectories.Masterpages); + } + + + public void DeployTemplateFiles(string folder) + { + string[] masterFiles = System.IO.Directory.GetFiles(IO.IOHelper.MapPath(SkinFolder), "*.master"); + + if (masterFiles.Count() > 0) + { + if (!System.IO.Directory.Exists(IO.IOHelper.MapPath(SkinBackupFolder))) + System.IO.Directory.CreateDirectory(IO.IOHelper.MapPath(SkinBackupFolder)); + + foreach (string master in masterFiles) + { + FileInfo fi = new FileInfo(master); + string original = Path.Combine(IO.IOHelper.MapPath(IO.SystemDirectories.Masterpages), fi.Name); + string backup = Path.Combine(IO.IOHelper.MapPath(SkinBackupFolder), fi.Name); + + if (System.IO.File.Exists(original)) + System.IO.File.Copy(original, backup, true); + + System.IO.File.Copy(master, original, true); + } + } + } + + + public void RollbackTemplateFiles(){ + RollbackTemplateFiles(IO.SystemDirectories.Masterpages); + } + + public void RollbackTemplateFiles(string folder) + { + string[] masterFiles = System.IO.Directory.GetFiles(IO.IOHelper.MapPath(SkinFolder), "*.master"); + + //1. take the skin files back into skin folder to store the changes made + if (masterFiles.Count() > 0) + { + foreach (string master in masterFiles) + { + FileInfo fi = new FileInfo(master); + string inUse = Path.Combine(IO.IOHelper.MapPath(IO.SystemDirectories.Masterpages), fi.Name); + + + if (System.IO.File.Exists(inUse)) + System.IO.File.Copy(inUse, master, true); + } + } + + + //2. copy the /backup files back to the masterpages to restore the templates to the way they were before the skin was applied + string[] backedUpmasterFiles = System.IO.Directory.GetFiles(IO.IOHelper.MapPath(SkinBackupFolder), "*.master"); + foreach (string backup in backedUpmasterFiles) + { + FileInfo fi = new FileInfo(backup); + string inUse = Path.Combine(IO.IOHelper.MapPath(IO.SystemDirectories.Masterpages), fi.Name); + + System.IO.File.Copy(backup, inUse, true); + System.IO.File.Delete(backup); + } + + //3. put on some clothes + } + + public void AddTaskHistoryNode(XmlNode taskNode) + { + XmlDocument manifest = new XmlDocument(); + manifest.Load(FullFileName); + + XmlNode hNode = manifest.SelectSingleNode("/Skin/History"); + + if (hNode == null) + { + hNode = manifest.CreateElement("History"); + manifest.SelectSingleNode("/Skin").AppendChild(hNode); + } + + hNode.AppendChild(manifest.ImportNode(taskNode, true)); + + manifest.Save(FullFileName); + } + + public string SkinFolder + { + get + { + return IO.SystemDirectories.Masterpages + "/" + Alias; + } + } + + public string SkinBackupFolder + { + get + { + return SkinFolder + "/backup"; + } + } + + } +} diff --git a/umbraco/cms/businesslogic/skinning/Skinning.cs b/umbraco/cms/businesslogic/skinning/Skinning.cs new file mode 100644 index 0000000000..1810fe0137 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/Skinning.cs @@ -0,0 +1,426 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using umbraco.IO; +using System.IO; +using System.Collections; +using System.Web; +using System.Web.Caching; +using umbraco.cms.businesslogic.web; +using umbraco.BusinessLogic; +using umbraco.cms.businesslogic.template; + +namespace umbraco.cms.businesslogic.skinning +{ + public class Skinning + { + static private Hashtable _checkedPages = new Hashtable(); + static private XmlDocument _skinningXmlContent; + static private string _skinningXmlSource = IOHelper.MapPath(SystemFiles.SkinningXml, false); + + private const string CACHEKEY = "SkinnableTemplates"; + + private static void clearCheckPages() + { + _checkedPages.Clear(); + } + + + public static void RollbackSkin(int template) + { + string currentSkin = GetCurrentSkinAlias(template); + Skin skin = Skin.CreateFromAlias(currentSkin); + + if (skin.OverridesTemplates()) + skin.RollbackTemplateFiles(); + else + skin.RollbackDependencies(); + + RemoveSkin(template); + save(); + } + + public static void ActivateAsCurrentSkin(Skin skin) + { + Template t = Template.GetByAlias(skin.AllowedRootTemplate); + ActivateAsCurrentSkin(t.Id, skin.Alias); + } + + public static void ActivateAsCurrentSkin(int template, string skinAlias) + { + //lookup template in skinning.config + string currentSkin = GetCurrentSkinAlias(template); + + //if different from current, and the template is skinned + if(currentSkin != skinAlias){ + + //this will restore the files to the standard runway, as they looked before the skin was applied + if (currentSkin != string.Empty) + { + RollbackSkin(template); + } + + Skin newSkin = Skin.CreateFromAlias(skinAlias); + + if (newSkin.OverridesTemplates()) + newSkin.DeployTemplateFiles(); + + SetSkin(template, skinAlias); + save(); + } + } + + + + private static void save() + { + System.IO.FileStream f = System.IO.File.Open(_skinningXmlSource, FileMode.Create); + SkinXml.Save(f); + f.Close(); + } + + public static string GetCurrentSkinAlias(int templateID) + { + XmlElement x = (XmlElement)getTemplate(templateID); + if(x != null && x.HasAttribute("alias") && !string.IsNullOrEmpty(x.Attributes["alias"].Value)) + return x.Attributes["alias"].Value; + + return string.Empty; + } + + private static void SetSkin(int templateID, string skinAlias) + { + XmlElement x = (XmlElement)getTemplate(templateID); + if (x == null) + { + x = (XmlElement)_skinningXmlContent.CreateNode(XmlNodeType.Element, "skin", ""); + SkinXml.DocumentElement.AppendChild(x); + } + + x.SetAttribute("template", templateID.ToString()); + x.SetAttribute("alias", skinAlias); + save(); + + clearCheckPages(); + } + + private static void RemoveSkin(int templateID) + { + XmlElement x = (XmlElement)getTemplate(templateID); + if (x != null) + { + x.ParentNode.RemoveChild(x); + save(); + clearCheckPages(); + } + } + + + private static XmlNode getTemplate(int templateId) + { + XmlNode x = SkinXml.SelectSingleNode("/skinning/skin [@template=" + templateId.ToString() + "]"); + return x; + } + + public static List GetAllSkins() + { + List skins = new List(); + + foreach (string dir in Directory.GetDirectories(IO.IOHelper.MapPath(SystemDirectories.Masterpages))) + { + if (File.Exists(Path.Combine(dir, "skin.xml"))) + { + Skin s = Skin.CreateFromFile((Path.Combine(dir, "skin.xml"))); + s.Alias = new DirectoryInfo(dir).Name; + skins.Add(s); + } + } + return skins; + } + + + private static XmlDocument SkinXml + { + get + { + if (_skinningXmlContent == null) + { + if (_skinningXmlSource == null) + { + //if we pop it here it'll make for better stack traces ;) + _skinningXmlSource = IOHelper.MapPath(SystemFiles.SkinningXml, false); + } + + _skinningXmlContent = new XmlDocument(); + + if (!System.IO.File.Exists(_skinningXmlSource)) + { + System.IO.FileStream f = System.IO.File.Open(_skinningXmlSource, FileMode.Create); + System.IO.StreamWriter sw = new StreamWriter(f); + sw.WriteLine(""); + sw.Close(); + f.Close(); + } + _skinningXmlContent.Load(_skinningXmlSource); + } + return _skinningXmlContent; + } + } + + public static Dictionary> SkinnableTemplates() + { + Dictionary> dts = (Dictionary>)HttpRuntime.Cache[CACHEKEY]; + if (dts == null) + dts = registerSkinnableTemplates(); + + return dts; + } + + //this is an pretty expensive operation, so we will cache the result... + private static Dictionary> registerSkinnableTemplates() + { + HttpRuntime.Cache.Remove(CACHEKEY); + Dictionary> _allowedTemplates = new Dictionary>(); + + foreach (string dir in Directory.GetDirectories(IO.IOHelper.MapPath(SystemDirectories.Masterpages))) + { + if (File.Exists(Path.Combine(dir, "skin.xml"))) + { + XmlDocument manifest = new XmlDocument(); + manifest.Load(Path.Combine(dir, "skin.xml")); + + string name = umbraco.xmlHelper.GetNodeValue(manifest.SelectSingleNode("/Skin/Name")); + string[] types = umbraco.xmlHelper.GetNodeValue(manifest.SelectSingleNode("/Skin/AllowedRootTemplate")).Split(','); + string alias = new DirectoryInfo(dir).Name; + + //foreach allowed type, test if it is already there... + foreach (string t in types) + { + if (!_allowedTemplates.ContainsKey(t)) + _allowedTemplates.Add(t, new Dictionary()); + + if (!_allowedTemplates[t].ContainsKey(alias)) + _allowedTemplates[t].Add(alias, name); + } + } + } + HttpRuntime.Cache.Insert(CACHEKEY, _allowedTemplates, new CacheDependency(IO.IOHelper.MapPath(SystemDirectories.Masterpages))); + + return _allowedTemplates; + } + + //Helpers for detecting what skins work with what document types + public static bool IsSkinnable(string templateAlias) + { + return SkinnableTemplates().ContainsKey(templateAlias); + } + + public static bool IsSkinnable(Template template) + { + return IsSkinnable(template.Alias); + } + + public static Dictionary AllowedSkins(Template template) + { + return AllowedSkins(template.Alias); + } + + public static Dictionary AllowedSkins(string templateAlias) + { + if (IsSkinnable(templateAlias)) + { + return SkinnableTemplates()[templateAlias]; + } + else + return new Dictionary(); + } + + public static Guid? StarterKitGuid(int template) + { + XmlDocument installed = new XmlDocument(); + installed.Load(IO.IOHelper.MapPath(SystemDirectories.Packages) + "/installed/installedPackages.config"); + + XmlNode starterKit = installed.SelectSingleNode( + string.Format("//templates [contains (., '{0}') ]//ancestor::package",template)); + + if (starterKit != null) + return new Guid(starterKit.Attributes["repositoryGuid"].Value); + else + return null; + } + + public static bool HasAvailableSkins(int template) + { + bool r = false; + + Guid? g = StarterKitGuid(template); + + if (g != null) + { + try + { + r = cms.businesslogic.packager.repositories.Repository. + getByGuid("65194810-1f85-11dd-bd0b-0800200c9a66").Webservice.Skins(g.ToString()).Length > 0; + } + catch { } + } + return r; + } + #region old code + + + + /* + + public static string FindAppliedSkin(int DocumentId, string Path) + { + string skinAlias = string.Empty; + + if (!_checkedPages.ContainsKey(DocumentId)) + { + foreach (string id in Path.Split(',')) + { + XmlNode n = getPage(int.Parse(id)); + if (n != null && n.Attributes["skin"] != null && !string.IsNullOrEmpty(n.Attributes["skin"].Value)) + { + skinAlias = n.Attributes["skin"].Value; + break; + } + } + + // Add thread safe updating to the hashtable + System.Web.HttpContext.Current.Application.Lock(); + if (!_checkedPages.ContainsKey(DocumentId)) + _checkedPages.Add(DocumentId, skinAlias); + + System.Web.HttpContext.Current.Application.UnLock(); + } + else + skinAlias = (string)_checkedPages[DocumentId]; + + return skinAlias; + } + * + * + public static Skin AppliedSkin(int DocumentId, string Path) + { + string active = FindAppliedSkin(DocumentId, Path); + if (!string.IsNullOrEmpty(active)) + { + + return Skin.CreateFromFile(IO.IOHelper.MapPath(SystemDirectories.Masterpages) + "/" + active + "/skin.xml"); + } + + return null; + } + + + public static Dictionary> SkinnableDocumentTypes() + { + Dictionary> dts = (Dictionary>)HttpRuntime.Cache[CACHEKEY]; + if (dts == null) + dts = registerAllowedDocumentTypes(); + + return dts; + } + + //this is an pretty expensive operation, so we will cache the result... + private static Dictionary> registerAllowedDocumentTypes() + { + HttpRuntime.Cache.Remove(CACHEKEY); + Dictionary> _allowedDocumentTypes = new Dictionary>(); + + foreach (string dir in Directory.GetDirectories(IO.IOHelper.MapPath(SystemDirectories.Masterpages))) + { + if( File.Exists( Path.Combine( dir , "skin.xml" ) )) { + XmlDocument manifest = new XmlDocument(); + manifest.Load(Path.Combine(dir, "skin.xml")); + + string name = umbraco.xmlHelper.GetNodeValue( manifest.SelectSingleNode("/Skin/Name")); + string[] types = umbraco.xmlHelper.GetNodeValue( manifest.SelectSingleNode("/Skin/AllowedDocumentTypes")).Split(','); + string alias = new DirectoryInfo(dir).Name; + + //foreach allowed type, test if it is already there... + foreach(string t in types){ + if (!_allowedDocumentTypes.ContainsKey(t)) + _allowedDocumentTypes.Add(t, new Dictionary()); + + if (!_allowedDocumentTypes[t].ContainsKey(alias)) + _allowedDocumentTypes[t].Add(alias, name); + } + } + } + HttpRuntime.Cache.Insert(CACHEKEY, _allowedDocumentTypes, new CacheDependency( IO.IOHelper.MapPath(SystemDirectories.Masterpages) )); + + return _allowedDocumentTypes; + } + + public static void SetSkin(int DocumentId, string skinAlias) + { + + XmlElement x = (XmlElement)getPage(DocumentId); + if (x == null) + { + x = (XmlElement)_skinningXmlContent.CreateNode(XmlNodeType.Element, "page", ""); + SkinXml.DocumentElement.AppendChild(x); + } + + x.SetAttribute("id", DocumentId.ToString()); + x.SetAttribute("skin", skinAlias); + save(); + + clearCheckPages(); + } + + public static void RemoveSkin(int DocumentId) + { + XmlElement x = (XmlElement)getPage(DocumentId); + if (x != null) + { + x.ParentNode.RemoveChild(x); + save(); + clearCheckPages(); + } + } + + private static XmlNode getPage(int documentId) + { + XmlNode x = SkinXml.SelectSingleNode("/skinning/page [@id=" + documentId.ToString() + "]"); + return x; + } + + //Helpers for detecting what skins work with what document types + public static bool IsSkinnable(string documentTypeAlias) + { + return SkinnableDocumentTypes().ContainsKey(documentTypeAlias); + } + + public static bool IsSkinnable(DocumentType documentType) + { + return IsSkinnable(documentType.Alias); + } + + + public static Dictionary AllowedSkins(DocumentType documentType) + { + return AllowedSkins(documentType.Alias); + } + + public static Dictionary AllowedSkins(string documentTypeAlias) + { + if (IsSkinnable(documentTypeAlias)) + { + return SkinnableDocumentTypes()[documentTypeAlias]; + } + else + return new Dictionary(); + } + * + * + */ + #endregion + + } +} diff --git a/umbraco/cms/businesslogic/skinning/Task.cs b/umbraco/cms/businesslogic/skinning/Task.cs new file mode 100644 index 0000000000..ae223eef37 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/Task.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; +using System.Web; +using System.Reflection; + +namespace umbraco.cms.businesslogic.skinning +{ + public class Task + { + public Task() + { + Properties = new Dictionary(); + } + + public static Task CreateFromXmlNode(XmlNode node) + { + Task t = new Task(); + + if (node.Attributes["type"] != null) + { + + if (node.Attributes["assembly"] != null) + { + //custom task type + + string assemblyFile = + HttpContext.Current.Server.MapPath( + String.Format("{0}/../bin/{1}.dll", + GlobalSettings.Path, + node.Attributes["assembly"].Value)); + + Assembly customAssembly = Assembly.LoadFrom(assemblyFile); + + t.TaskType = (TaskType)Activator.CreateInstance( + customAssembly.GetType(node.Attributes["type"].Value)); + + + + } + else + { + //internal dependency type + + string assemblyFile = + HttpContext.Current.Server.MapPath( + String.Format("{0}/../bin/{1}.dll", + GlobalSettings.Path, + "cms")); + + Assembly defaultAssembly = Assembly.LoadFrom(assemblyFile); + + t.TaskType = (TaskType)Activator.CreateInstance( + defaultAssembly.GetType( + string.Format( + "umbraco.cms.businesslogic.skinning.tasks.{0}", + node.Attributes["type"].Value))); + } + } + + foreach (XmlNode prop in node.ChildNodes) + { + if (prop.Name != "OriginalValue" && prop.Name != "NewValue") + { + if (prop.Name == "Value") + t.Value = prop.InnerText; + else + t.Properties.Add(prop.Name, prop.InnerText); + + t.TaskType.GetType().InvokeMember( + prop.Name, + System.Reflection.BindingFlags.SetProperty, + null, + t.TaskType, + new object[] { prop.InnerText }); + } + } + return t; + } + + public TaskType TaskType { get; set; } + + public Dictionary Properties { get; set; } + + public string Value { get; set; } + } +} diff --git a/umbraco/cms/businesslogic/skinning/TaskType.cs b/umbraco/cms/businesslogic/skinning/TaskType.cs new file mode 100644 index 0000000000..4c0092667e --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/TaskType.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.interfaces.skinning; +using System.Xml; +using System.Reflection; + +namespace umbraco.cms.businesslogic.skinning +{ + public abstract class TaskType : ProviderBase, ITaskType + { + public abstract TaskExecutionDetails Execute(string Value); + + public virtual TaskExecutionStatus RollBack(string OriginalValue) + { + return Execute(OriginalValue).TaskExecutionStatus; + } + + public abstract string PreviewClientScript(string ControlClientId, string ClientSidePreviewEventType, string ClientSideGetValueScript); + + public String Value { get; set; } + + public virtual XmlNode ToXml(string OriginalValue, string NewValue) + { + XmlDocument d = new XmlDocument(); + + XmlNode n = d.CreateElement("Task"); + + XmlAttribute type = d.CreateAttribute("type"); + type.Value = this.GetType().Name; + n.Attributes.Append(type); + + if (!this.GetType().FullName.Contains("umbraco.cms.businesslogic.skinning")) + { + XmlAttribute assembly = d.CreateAttribute("assembly"); + assembly.Value = this.GetType().Assembly.FullName; + n.Attributes.Append(assembly); + } + + XmlAttribute executed = d.CreateAttribute("executed"); + executed.Value = DateTime.Now.ToString("s"); + n.Attributes.Append(executed); + + foreach(PropertyInfo p in this.GetType().GetProperties()) + { + if(p.Name != "Name" && p.Name != "Description") + { + XmlNode pNode = d.CreateElement(p.Name); + pNode.InnerText = p.GetValue(this,null) != null ? p.GetValue(this,null).ToString() : string.Empty; + + n.AppendChild(pNode); + } + } + + + XmlNode origValNode = d.CreateElement("OriginalValue"); + origValNode.InnerText = OriginalValue; + n.AppendChild(origValNode); + + XmlNode newValNode = d.CreateElement("NewValue"); + newValNode.InnerText = NewValue; + n.AppendChild(newValNode); + + return n; + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/controls/ColorPicker.cs b/umbraco/cms/businesslogic/skinning/controls/ColorPicker.cs new file mode 100644 index 0000000000..70e346bc3b --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/controls/ColorPicker.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI.WebControls; +using ClientDependency.Core; +using System.Web.UI; + +namespace umbraco.cms.businesslogic.skinning.controls +{ + //[ClientDependency(ClientDependencyType.Javascript, "colorpicker/js/colorpicker.js", "UmbracoClient")] + [ClientDependency(ClientDependencyType.Css, "colorpicker/css/colorpicker.css", "UmbracoClient")] + public class ColorPicker: TextBox + { + + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "colorpicker.js", + this.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco_client + "/colorpicker/js/colorpicker.js")); + + + ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "cp" + this.ClientID, + string.Format(@"$(document).ready(function() {{ + $('#{0}').ColorPicker({{ + onSubmit: function(hsb, hex, rgb, el) {{ + $(el).val('#' + hex); + $(el).ColorPickerHide(); + jQuery(el).trigger('change'); + }}, + onBeforeShow: function () {{ + $(this).ColorPickerSetColor(this.value); + }} + }}) + .bind('keyup', function(){{ + $(this).ColorPickerSetColor(this.value); + }});}});", this.ClientID), true); + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/dependencies/Color.cs b/umbraco/cms/businesslogic/skinning/dependencies/Color.cs new file mode 100644 index 0000000000..1185615f17 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/dependencies/Color.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.cms.businesslogic.skinning; +using umbraco.cms.businesslogic.skinning.controls; +using System.Web.UI.WebControls; + +namespace umbraco.cms.businesslogic.skinning.dependencies +{ + public class Color : DependencyType + { + public ColorPicker cp; + public List _value; + + public Color() + { + this.Name = "Color"; + this.Description = "Will render a color picker"; + + + cp = new ColorPicker(); + _value = new List(); + } + + public override WebControl Editor + { + get + { + cp.TextMode = System.Web.UI.WebControls.TextBoxMode.SingleLine; + cp.CssClass = "color"; + + if (_value.Count > 0) + cp.Text = _value[0].ToString(); + + return cp; + } + set + { + base.Editor = value; + } + } + + public override List Values + { + get + { + if (cp.Text != "") + { + _value.Clear(); + _value.Add(cp.Text); + } + return _value; + } + set + { + _value = value; + } + } + + } +} diff --git a/umbraco/cms/businesslogic/skinning/dependencies/Image.cs b/umbraco/cms/businesslogic/skinning/dependencies/Image.cs new file mode 100644 index 0000000000..a92c98fceb --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/dependencies/Image.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI.WebControls; + +namespace umbraco.cms.businesslogic.skinning.dependencies +{ + public class Image: DependencyType + { + + public string Height { get; set; } + public string Width { get; set; } + //currently just returning a textbox, need to replace this with a custom image control + + public System.Web.UI.WebControls.TextBox tb; + public List _value; + + public Image() + { + this.Name = "Text"; + this.Description = "Will render a text input"; + + + tb = new TextBox(); + _value = new List(); + } + + public override WebControl Editor + { + get + { + tb.TextMode = System.Web.UI.WebControls.TextBoxMode.SingleLine; + tb.CssClass = "text"; + + if (_value.Count > 0) + tb.Text = _value[0].ToString(); + + return tb; + } + set + { + base.Editor = value; + } + } + + public override List Values + { + get + { + if (tb.Text != "") + { + _value.Clear(); + _value.Add(tb.Text); + } + return _value; + } + set + { + _value = value; + } + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/dependencies/Text.cs b/umbraco/cms/businesslogic/skinning/dependencies/Text.cs new file mode 100644 index 0000000000..d0cb9dbf61 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/dependencies/Text.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI.WebControls; + +namespace umbraco.cms.businesslogic.skinning.dependencies +{ + public class Text : DependencyType + { + public System.Web.UI.WebControls.TextBox tb; + public List _value; + + public Text() + { + this.Name = "Text"; + this.Description = "Will render a text input"; + + + tb = new TextBox(); + _value = new List(); + } + + public override WebControl Editor + { + get + { + tb.TextMode = System.Web.UI.WebControls.TextBoxMode.SingleLine; + tb.CssClass = "text"; + + if (_value.Count > 0) + tb.Text = _value[0].ToString(); + + return tb; + } + set + { + base.Editor = value; + } + } + + public override List Values + { + get + { + if (tb.Text != "") + { + _value.Clear(); + _value.Add(tb.Text); + } + return _value; + } + set + { + _value = value; + } + } + + } +} diff --git a/umbraco/cms/businesslogic/skinning/tasks/ModifyCss.cs b/umbraco/cms/businesslogic/skinning/tasks/ModifyCss.cs new file mode 100644 index 0000000000..bc71f24978 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/tasks/ModifyCss.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.interfaces.skinning; +using System.IO; +using umbraco.IO; +using System.Web; + +namespace umbraco.cms.businesslogic.skinning.tasks +{ + public class ModifyCss : TaskType + { + public string TargetFile { get; set; } + public string TargetRule { get; set; } + public string TargetParameter { get; set; } + + public ModifyCss() + { + this.Name = "Modify Css"; + this.Description = "Will modify the stylesheet"; + } + + public override TaskExecutionDetails Execute(string Value) + { + TaskExecutionDetails d = new TaskExecutionDetails(); + + //currently just appending it to the end of the css file + StreamWriter sw = File.AppendText(IO.IOHelper.MapPath(SystemDirectories.Masterpages) + "/" + TargetFile); + sw.WriteLine(string.Format("{0}{{ {1}:{2};}}", TargetRule, TargetParameter, Value)); + sw.Close(); + + d.TaskExecutionStatus = TaskExecutionStatus.Completed; + d.OriginalValue = ""; + d.NewValue = Value; + + return d; + } + + + public override string PreviewClientScript(string ControlClientId,string ClientSidePreviewEventType, string ClientSideGetValueScript) + { + + return string.Format( + @"jQuery('#{0}').bind('{5}', function() {{ + var val = '{3}'; + jQuery('{1}').css('{2}', val.replace('${{Output}}',{4})); + }});", + ControlClientId, + TargetRule, + TargetParameter, + Value, + ClientSideGetValueScript, + ClientSidePreviewEventType); + } + } +} diff --git a/umbraco/cms/businesslogic/skinning/tasks/ModifyTemplate.cs b/umbraco/cms/businesslogic/skinning/tasks/ModifyTemplate.cs new file mode 100644 index 0000000000..fc84dcdbb5 --- /dev/null +++ b/umbraco/cms/businesslogic/skinning/tasks/ModifyTemplate.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.interfaces.skinning; +using System.Text.RegularExpressions; +using System.IO; +using System.Web; +using umbraco.IO; +using umbraco.cms.businesslogic.packager.standardPackageActions; +using System.Xml; +using HtmlAgilityPack; + +namespace umbraco.cms.businesslogic.skinning.tasks +{ + public class ModifyTemplate : TaskType + { + public string TargetFile { get; set; } + public string TargetID { get; set; } + public string TargetAttribute { get; set; } + + public ModifyTemplate() + { + this.Name = " Modify template"; + this.Description = "Will modify a template"; + } + + public override TaskExecutionDetails Execute(string Value) + { + TaskExecutionDetails d = new TaskExecutionDetails(); + + //open template + + HtmlDocument doc = new HtmlDocument(); + doc.Load(IO.IOHelper.MapPath(SystemDirectories.Masterpages) + "/" +TargetFile); + + foreach(HtmlNode target in doc.DocumentNode.SelectNodes(string.Format("//*[@id = '{0}']",TargetID))) + { + if (string.IsNullOrEmpty(TargetAttribute)) + { + d.OriginalValue = target.InnerHtml; + target.InnerHtml = Value; + } + else + { + if (target.Attributes[TargetAttribute] == null) + { + target.Attributes.Add(TargetAttribute, Value); + } + else + { + d.OriginalValue = target.Attributes[TargetAttribute].Value; + target.Attributes[TargetAttribute].Value = Value; + } + } + } + + doc.Save(IO.IOHelper.MapPath(SystemDirectories.Masterpages) + "/" + TargetFile); + + d.TaskExecutionStatus = TaskExecutionStatus.Completed; + d.NewValue = Value; + //save + + return d; + } + + + public override string PreviewClientScript(string ControlClientId,string ClientSidePreviewEventType, string ClientSideGetValueScript) + { + if (string.IsNullOrEmpty(TargetAttribute)) + { + return string.Format( + @"jQuery('#{0}').bind('{3}', function() {{ + jQuery('#{1}').html({2}); + }});", + ControlClientId, + TargetID, + ClientSideGetValueScript, + ClientSidePreviewEventType); + } + else + { + return string.Format( + @"jQuery('#{0}').bind('{4}', function() {{ + jQuery('#{1}').attr('{2}',{3}); + }});", + ControlClientId, + TargetID, + TargetAttribute, + ClientSideGetValueScript, + ClientSidePreviewEventType); + } + } + } +} diff --git a/umbraco/cms/businesslogic/web/Access.cs b/umbraco/cms/businesslogic/web/Access.cs index 022f58e9d5..d84d11bfd8 100644 --- a/umbraco/cms/businesslogic/web/Access.cs +++ b/umbraco/cms/businesslogic/web/Access.cs @@ -37,11 +37,11 @@ namespace umbraco.cms.businesslogic.web get { if (_accessXmlContent == null) { - if (_accessXmlSource == null) - { - //if we pop it here it'll make for better stack traces ;) - _accessXmlSource = IOHelper.MapPath(SystemFiles.AccessXml, false); - } + if (_accessXmlSource == null) + { + //if we pop it here it'll make for better stack traces ;) + _accessXmlSource = IOHelper.MapPath(SystemFiles.AccessXml, false); + } _accessXmlContent = new XmlDocument(); @@ -59,30 +59,30 @@ namespace umbraco.cms.businesslogic.web } } - public static void AddMembershipRoleToDocument(int documentId, string role) { - //event - AddMemberShipRoleToDocumentEventArgs e = new AddMemberShipRoleToDocumentEventArgs(); - new Access().FireBeforeAddMemberShipRoleToDocument(new Document(documentId), role, e); + public static void AddMembershipRoleToDocument(int documentId, string role) { + //event + AddMemberShipRoleToDocumentEventArgs e = new AddMemberShipRoleToDocumentEventArgs(); + new Access().FireBeforeAddMemberShipRoleToDocument(new Document(documentId), role, e); - if (!e.Cancel) { - XmlElement x = (XmlElement)getPage(documentId); + if (!e.Cancel) { + XmlElement x = (XmlElement)getPage(documentId); - if (x == null) - throw new Exception("Document is not protected!"); - else { - if (x.SelectSingleNode("group [@id = '" + role + "']") == null) { - XmlElement groupXml = (XmlElement)AccessXml.CreateNode(XmlNodeType.Element, "group", ""); - groupXml.SetAttribute("id", role); - x.AppendChild(groupXml); - save(); - } - } + if (x == null) + throw new Exception("Document is not protected!"); + else { + if (x.SelectSingleNode("group [@id = '" + role + "']") == null) { + XmlElement groupXml = (XmlElement)AccessXml.CreateNode(XmlNodeType.Element, "group", ""); + groupXml.SetAttribute("id", role); + x.AppendChild(groupXml); + save(); + } + } - new Access().FireAfterAddMemberShipRoleToDocument(new Document(documentId), role, e); - } - } + new Access().FireAfterAddMemberShipRoleToDocument(new Document(documentId), role, e); + } + } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] public static void AddMemberGroupToDocument(int DocumentId, int MemberGroupId) { XmlElement x = (XmlElement) getPage(DocumentId); @@ -101,7 +101,7 @@ namespace umbraco.cms.businesslogic.web } } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] public static void AddMemberToDocument(int DocumentId, int MemberId) { XmlElement x = (XmlElement) getPage(DocumentId); @@ -117,31 +117,31 @@ namespace umbraco.cms.businesslogic.web save(); } } - - public static void AddMembershipUserToDocument(int documentId, string membershipUserName) { - //event - AddMembershipUserToDocumentEventArgs e = new AddMembershipUserToDocumentEventArgs(); - new Access().FireBeforeAddMembershipUserToDocument(new Document(documentId), membershipUserName, e); + + public static void AddMembershipUserToDocument(int documentId, string membershipUserName) { + //event + AddMembershipUserToDocumentEventArgs e = new AddMembershipUserToDocumentEventArgs(); + new Access().FireBeforeAddMembershipUserToDocument(new Document(documentId), membershipUserName, e); - if (!e.Cancel) { - XmlElement x = (XmlElement)getPage(documentId); + if (!e.Cancel) { + XmlElement x = (XmlElement)getPage(documentId); - if (x == null) - throw new Exception("Document is not protected!"); - else { - if (x.Attributes.GetNamedItem("memberId") != null) - x.Attributes.GetNamedItem("memberId").Value = membershipUserName; - else - x.SetAttribute("memberId", membershipUserName); - save(); - } + if (x == null) + throw new Exception("Document is not protected!"); + else { + if (x.Attributes.GetNamedItem("memberId") != null) + x.Attributes.GetNamedItem("memberId").Value = membershipUserName; + else + x.SetAttribute("memberId", membershipUserName); + save(); + } - new Access().FireAfterAddMembershipUserToDocument(new Document(documentId), membershipUserName, e); - } - - } + new Access().FireAfterAddMembershipUserToDocument(new Document(documentId), membershipUserName, e); + } + + } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] public static void RemoveMemberGroupFromDocument(int DocumentId, int MemberGroupId) { XmlElement x = (XmlElement) getPage(DocumentId); @@ -159,111 +159,111 @@ namespace umbraco.cms.businesslogic.web } } - public static void RemoveMembershipRoleFromDocument(int documentId, string role) { + public static void RemoveMembershipRoleFromDocument(int documentId, string role) { - RemoveMemberShipRoleFromDocumentEventArgs e = new RemoveMemberShipRoleFromDocumentEventArgs(); - new Access().FireBeforeRemoveMemberShipRoleFromDocument(new Document(documentId), role, e); + RemoveMemberShipRoleFromDocumentEventArgs e = new RemoveMemberShipRoleFromDocumentEventArgs(); + new Access().FireBeforeRemoveMemberShipRoleFromDocument(new Document(documentId), role, e); - if (!e.Cancel) { - XmlElement x = (XmlElement)getPage(documentId); + if (!e.Cancel) { + XmlElement x = (XmlElement)getPage(documentId); - if (x == null) - throw new Exception("Document is not protected!"); - else { - XmlNode xGroup = x.SelectSingleNode("group [@id = '" + role + "']"); - if (xGroup != null) { - x.RemoveChild(xGroup); - save(); - } - } + if (x == null) + throw new Exception("Document is not protected!"); + else { + XmlNode xGroup = x.SelectSingleNode("group [@id = '" + role + "']"); + if (xGroup != null) { + x.RemoveChild(xGroup); + save(); + } + } - new Access().FireAfterRemoveMemberShipRoleFromDocument(new Document(documentId), role, e); - } - } + new Access().FireAfterRemoveMemberShipRoleFromDocument(new Document(documentId), role, e); + } + } - public static bool RenameMemberShipRole(string oldRolename, string newRolename) - { - bool hasChange = false; - if (oldRolename != newRolename) - { - foreach (XmlNode x in AccessXml.SelectNodes("//group [@id = '" + oldRolename + "']")) - { - x.Attributes["id"].Value = newRolename; - hasChange = true; - } - if (hasChange) - save(); - } - - return hasChange; - - } - - public static void ProtectPage(bool Simple, int DocumentId, int LoginDocumentId, int ErrorDocumentId) + public static bool RenameMemberShipRole(string oldRolename, string newRolename) { - AddProtectionEventArgs e = new AddProtectionEventArgs(); - new Access().FireBeforeAddProtection(new Document(DocumentId), e); + bool hasChange = false; + if (oldRolename != newRolename) + { + foreach (XmlNode x in AccessXml.SelectNodes("//group [@id = '" + oldRolename + "']")) + { + x.Attributes["id"].Value = newRolename; + hasChange = true; + } + if (hasChange) + save(); + } - if (!e.Cancel) { + return hasChange; + + } + + public static void ProtectPage(bool Simple, int DocumentId, int LoginDocumentId, int ErrorDocumentId) + { + AddProtectionEventArgs e = new AddProtectionEventArgs(); + new Access().FireBeforeAddProtection(new Document(DocumentId), e); - XmlElement x = (XmlElement)getPage(DocumentId); - if (x == null) { - x = (XmlElement)_accessXmlContent.CreateNode(XmlNodeType.Element, "page", ""); - AccessXml.DocumentElement.AppendChild(x); - } - // if using simple mode, make sure that all existing groups are removed - else if (Simple) { - x.RemoveAll(); - } - x.SetAttribute("id", DocumentId.ToString()); - x.SetAttribute("loginPage", LoginDocumentId.ToString()); - x.SetAttribute("noRightsPage", ErrorDocumentId.ToString()); - x.SetAttribute("simple", Simple.ToString()); - save(); + if (!e.Cancel) { - clearCheckPages(); + XmlElement x = (XmlElement)getPage(DocumentId); + if (x == null) { + x = (XmlElement)_accessXmlContent.CreateNode(XmlNodeType.Element, "page", ""); + AccessXml.DocumentElement.AppendChild(x); + } + // if using simple mode, make sure that all existing groups are removed + else if (Simple) { + x.RemoveAll(); + } + x.SetAttribute("id", DocumentId.ToString()); + x.SetAttribute("loginPage", LoginDocumentId.ToString()); + x.SetAttribute("noRightsPage", ErrorDocumentId.ToString()); + x.SetAttribute("simple", Simple.ToString()); + save(); - new Access().FireAfterAddProtection(new Document(DocumentId), e); - } + clearCheckPages(); + + new Access().FireAfterAddProtection(new Document(DocumentId), e); + } } public static void RemoveProtection(int DocumentId) { - XmlElement x = (XmlElement) getPage(DocumentId); + XmlElement x = (XmlElement) getPage(DocumentId); if (x != null) { - //event - RemoveProtectionEventArgs e = new RemoveProtectionEventArgs(); - new Access().FireBeforeRemoveProtection(new Document(DocumentId), e); + //event + RemoveProtectionEventArgs e = new RemoveProtectionEventArgs(); + new Access().FireBeforeRemoveProtection(new Document(DocumentId), e); - if (!e.Cancel) { + if (!e.Cancel) { - x.ParentNode.RemoveChild(x); - save(); - clearCheckPages(); + x.ParentNode.RemoveChild(x); + save(); + clearCheckPages(); - new Access().FireAfterRemoveProtection(new Document(DocumentId), e); - } + new Access().FireAfterRemoveProtection(new Document(DocumentId), e); + } } } private static void save() { - SaveEventArgs e = new SaveEventArgs(); + SaveEventArgs e = new SaveEventArgs(); - new Access().FireBeforeSave(e); + new Access().FireBeforeSave(e); - if (!e.Cancel) { - System.IO.FileStream f = System.IO.File.Open(_accessXmlSource, FileMode.Create); - AccessXml.Save(f); - f.Close(); + if (!e.Cancel) { + System.IO.FileStream f = System.IO.File.Open(_accessXmlSource, FileMode.Create); + AccessXml.Save(f); + f.Close(); - new Access().FireAfterSave(e); - } + new Access().FireAfterSave(e); + } } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] public static bool IsProtectedByGroup(int DocumentId, int GroupId) { bool isProtected = false; @@ -284,39 +284,39 @@ namespace umbraco.cms.businesslogic.web return isProtected; } - public static bool IsProtectedByMembershipRole(int documentId, string role) { - bool isProtected = false; + public static bool IsProtectedByMembershipRole(int documentId, string role) { + bool isProtected = false; - CMSNode d = new CMSNode(documentId); + CMSNode d = new CMSNode(documentId); - if (!IsProtected(documentId, d.Path)) - isProtected = false; - else { - XmlNode currentNode = getPage(getProtectedPage(d.Path)); - if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { - isProtected = true; - } - } + if (!IsProtected(documentId, d.Path)) + isProtected = false; + else { + XmlNode currentNode = getPage(getProtectedPage(d.Path)); + if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { + isProtected = true; + } + } - return isProtected; - } + return isProtected; + } - public static string[] GetAccessingMembershipRoles(int documentId, string path) { - ArrayList roles = new ArrayList(); + public static string[] GetAccessingMembershipRoles(int documentId, string path) { + ArrayList roles = new ArrayList(); - if (!IsProtected(documentId, path)) - return null; - else { - XmlNode currentNode = getPage(getProtectedPage(path)); - foreach (XmlNode n in currentNode.SelectNodes("./group")) { - roles.Add(n.Attributes.GetNamedItem("id").Value); - } - return (string[])roles.ToArray(typeof(string)); - } + if (!IsProtected(documentId, path)) + return null; + else { + XmlNode currentNode = getPage(getProtectedPage(path)); + foreach (XmlNode n in currentNode.SelectNodes("./group")) { + roles.Add(n.Attributes.GetNamedItem("id").Value); + } + return (string[])roles.ToArray(typeof(string)); + } - } + } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] public static cms.businesslogic.member.MemberGroup[] GetAccessingGroups(int DocumentId) { cms.businesslogic.web.Document d = new Document(DocumentId); @@ -325,7 +325,7 @@ namespace umbraco.cms.businesslogic.web return null; else { - XmlNode currentNode = getPage(getProtectedPage(d.Path)); + XmlNode currentNode = getPage(getProtectedPage(d.Path)); cms.businesslogic.member.MemberGroup[] mg = new umbraco.cms.businesslogic.member.MemberGroup[currentNode.SelectNodes("./group").Count]; int count = 0; foreach (XmlNode n in currentNode.SelectNodes("./group")) @@ -338,47 +338,47 @@ namespace umbraco.cms.businesslogic.web } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] - public static cms.businesslogic.member.Member GetAccessingMember(int DocumentId) { - cms.businesslogic.web.Document d = new Document(DocumentId); + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + public static cms.businesslogic.member.Member GetAccessingMember(int DocumentId) { + cms.businesslogic.web.Document d = new Document(DocumentId); - if (!IsProtected(DocumentId, d.Path)) - return null; - else if (GetProtectionType(DocumentId) != ProtectionType.Simple) - throw new Exception("Document isn't protected using Simple mechanism. Use GetAccessingMemberGroups instead"); - else { - XmlNode currentNode = getPage(getProtectedPage(d.Path)); - if (currentNode.Attributes.GetNamedItem("memberId") != null) - return new cms.businesslogic.member.Member(int.Parse( - currentNode.Attributes.GetNamedItem("memberId").Value)); - else - throw new Exception("Document doesn't contain a memberId. This might be caused if document is protected using umbraco RC1 or older."); + if (!IsProtected(DocumentId, d.Path)) + return null; + else if (GetProtectionType(DocumentId) != ProtectionType.Simple) + throw new Exception("Document isn't protected using Simple mechanism. Use GetAccessingMemberGroups instead"); + else { + XmlNode currentNode = getPage(getProtectedPage(d.Path)); + if (currentNode.Attributes.GetNamedItem("memberId") != null) + return new cms.businesslogic.member.Member(int.Parse( + currentNode.Attributes.GetNamedItem("memberId").Value)); + else + throw new Exception("Document doesn't contain a memberId. This might be caused if document is protected using umbraco RC1 or older."); - } + } - } - - public static MembershipUser GetAccessingMembershipUser(int documentId) { - CMSNode d = new CMSNode(documentId); + } + + public static MembershipUser GetAccessingMembershipUser(int documentId) { + CMSNode d = new CMSNode(documentId); - if (!IsProtected(documentId, d.Path)) - return null; - else if (GetProtectionType(documentId) != ProtectionType.Simple) - throw new Exception("Document isn't protected using Simple mechanism. Use GetAccessingMemberGroups instead"); - else { - XmlNode currentNode = getPage(getProtectedPage(d.Path)); - if (currentNode.Attributes.GetNamedItem("memberId") != null) - return Membership.GetUser(currentNode.Attributes.GetNamedItem("memberId").Value); - else - throw new Exception("Document doesn't contain a memberId. This might be caused if document is protected using umbraco RC1 or older."); + if (!IsProtected(documentId, d.Path)) + return null; + else if (GetProtectionType(documentId) != ProtectionType.Simple) + throw new Exception("Document isn't protected using Simple mechanism. Use GetAccessingMemberGroups instead"); + else { + XmlNode currentNode = getPage(getProtectedPage(d.Path)); + if (currentNode.Attributes.GetNamedItem("memberId") != null) + return Membership.GetUser(currentNode.Attributes.GetNamedItem("memberId").Value); + else + throw new Exception("Document doesn't contain a memberId. This might be caused if document is protected using umbraco RC1 or older."); - } + } - } + } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] - public static bool HasAccess(int DocumentId, cms.businesslogic.member.Member Member) + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + public static bool HasAccess(int DocumentId, cms.businesslogic.member.Member Member) { bool hasAccess = false; @@ -407,30 +407,30 @@ namespace umbraco.cms.businesslogic.web return hasAccess; } - public static bool HasAccces(int documentId, object memberId) { - bool hasAccess = false; - cms.businesslogic.CMSNode node = new CMSNode(documentId); + public static bool HasAccces(int documentId, object memberId) { + bool hasAccess = false; + cms.businesslogic.CMSNode node = new CMSNode(documentId); - if (!IsProtected(documentId, node.Path)) - return true; - else { - MembershipUser member = Membership.GetUser(memberId); - XmlNode currentNode = getPage(getProtectedPage(node.Path)); + if (!IsProtected(documentId, node.Path)) + return true; + else { + MembershipUser member = Membership.GetUser(memberId); + XmlNode currentNode = getPage(getProtectedPage(node.Path)); - if (member != null) { - foreach(string role in Roles.GetRolesForUser()) { - if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { - hasAccess = true; - break; - } - } - } - } - return hasAccess; - } + if (member != null) { + foreach(string role in Roles.GetRolesForUser()) { + if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { + hasAccess = true; + break; + } + } + } + } + return hasAccess; + } - [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] - private static bool HasAccess(int DocumentId, string Path, cms.businesslogic.member.Member Member) + [Obsolete("This method is no longer supported. Use the ASP.NET MemberShip methods instead", true)] + private static bool HasAccess(int DocumentId, string Path, cms.businesslogic.member.Member Member) { bool hasAccess = false; @@ -457,28 +457,28 @@ namespace umbraco.cms.businesslogic.web return hasAccess; } - public static bool HasAccess(int documentId, string path, MembershipUser member) { - bool hasAccess = false; + public static bool HasAccess(int documentId, string path, MembershipUser member) { + bool hasAccess = false; - if (!IsProtected(documentId, path)) - hasAccess = true; - else { - XmlNode currentNode = getPage(getProtectedPage(path)); - if (member != null) { - string[] roles = Roles.GetRolesForUser(member.UserName); - foreach(string role in roles) { - if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { - hasAccess = true; - break; - } - } - } - } + if (!IsProtected(documentId, path)) + hasAccess = true; + else { + XmlNode currentNode = getPage(getProtectedPage(path)); + if (member != null) { + string[] roles = Roles.GetRolesForUser(member.UserName); + foreach(string role in roles) { + if (currentNode.SelectSingleNode("./group [@id='" + role + "']") != null) { + hasAccess = true; + break; + } + } + } + } - return hasAccess; - } + return hasAccess; + } - public static ProtectionType GetProtectionType(int DocumentId) + public static ProtectionType GetProtectionType(int DocumentId) { XmlNode x = getPage(DocumentId); try @@ -510,13 +510,13 @@ namespace umbraco.cms.businesslogic.web } } - // Add thread safe updating to the hashtable - System.Web.HttpContext.Current.Application.Lock(); - if (!_checkedPages.ContainsKey(DocumentId)) - _checkedPages.Add(DocumentId, isProtected); - System.Web.HttpContext.Current.Application.UnLock(); - } - else + // Add thread safe updating to the hashtable + System.Web.HttpContext.Current.Application.Lock(); + if (!_checkedPages.ContainsKey(DocumentId)) + _checkedPages.Add(DocumentId, isProtected); + System.Web.HttpContext.Current.Application.UnLock(); + } + else isProtected = (bool) _checkedPages[DocumentId]; return isProtected; @@ -540,7 +540,7 @@ namespace umbraco.cms.businesslogic.web if (getPage(int.Parse(id)) != null) protectedPage = int.Parse(id); - return protectedPage; + return protectedPage; } private static XmlNode getPage(int documentId) @@ -550,104 +550,104 @@ namespace umbraco.cms.businesslogic.web } - //Event delegates - public delegate void SaveEventHandler(Access sender, SaveEventArgs e); + //Event delegates + public delegate void SaveEventHandler(Access sender, SaveEventArgs e); - public delegate void AddProtectionEventHandler(Document sender, AddProtectionEventArgs e); - public delegate void RemoveProtectionEventHandler(Document sender, RemoveProtectionEventArgs e); + public delegate void AddProtectionEventHandler(Document sender, AddProtectionEventArgs e); + public delegate void RemoveProtectionEventHandler(Document sender, RemoveProtectionEventArgs e); - public delegate void AddMemberShipRoleToDocumentEventHandler(Document sender, string role, AddMemberShipRoleToDocumentEventArgs e); - public delegate void RemoveMemberShipRoleFromDocumentEventHandler(Document sender, string role, RemoveMemberShipRoleFromDocumentEventArgs e); + public delegate void AddMemberShipRoleToDocumentEventHandler(Document sender, string role, AddMemberShipRoleToDocumentEventArgs e); + public delegate void RemoveMemberShipRoleFromDocumentEventHandler(Document sender, string role, RemoveMemberShipRoleFromDocumentEventArgs e); - public delegate void RemoveMemberShipUserFromDocumentEventHandler(Document sender, string MembershipUserName, RemoveMemberShipUserFromDocumentEventArgs e); - public delegate void AddMembershipUserToDocumentEventHandler(Document sender, string MembershipUserName, AddMembershipUserToDocumentEventArgs e); + public delegate void RemoveMemberShipUserFromDocumentEventHandler(Document sender, string MembershipUserName, RemoveMemberShipUserFromDocumentEventArgs e); + public delegate void AddMembershipUserToDocumentEventHandler(Document sender, string MembershipUserName, AddMembershipUserToDocumentEventArgs e); - //Events + //Events - public static event SaveEventHandler BeforeSave; - protected virtual void FireBeforeSave(SaveEventArgs e) { - if (BeforeSave != null) - BeforeSave(this, e); - } + public static event SaveEventHandler BeforeSave; + protected virtual void FireBeforeSave(SaveEventArgs e) { + if (BeforeSave != null) + BeforeSave(this, e); + } - public static event SaveEventHandler AfterSave; - protected virtual void FireAfterSave(SaveEventArgs e) { - if (AfterSave != null) - AfterSave(this, e); - } + public static event SaveEventHandler AfterSave; + protected virtual void FireAfterSave(SaveEventArgs e) { + if (AfterSave != null) + AfterSave(this, e); + } - public static event AddProtectionEventHandler BeforeAddProtection; - protected virtual void FireBeforeAddProtection(Document doc, AddProtectionEventArgs e) { - if (BeforeAddProtection != null) - BeforeAddProtection(doc, e); - } + public static event AddProtectionEventHandler BeforeAddProtection; + protected virtual void FireBeforeAddProtection(Document doc, AddProtectionEventArgs e) { + if (BeforeAddProtection != null) + BeforeAddProtection(doc, e); + } - public static event AddProtectionEventHandler AfterAddProtection; - protected virtual void FireAfterAddProtection(Document doc, AddProtectionEventArgs e) { - if (AfterAddProtection != null) - AfterAddProtection(doc, e); - } + public static event AddProtectionEventHandler AfterAddProtection; + protected virtual void FireAfterAddProtection(Document doc, AddProtectionEventArgs e) { + if (AfterAddProtection != null) + AfterAddProtection(doc, e); + } - public static event RemoveProtectionEventHandler BeforeRemoveProtection; - protected virtual void FireBeforeRemoveProtection(Document doc, RemoveProtectionEventArgs e) { - if (BeforeRemoveProtection != null) - BeforeRemoveProtection(doc, e); - } + public static event RemoveProtectionEventHandler BeforeRemoveProtection; + protected virtual void FireBeforeRemoveProtection(Document doc, RemoveProtectionEventArgs e) { + if (BeforeRemoveProtection != null) + BeforeRemoveProtection(doc, e); + } - public static event RemoveProtectionEventHandler AfterRemoveProtection; - protected virtual void FireAfterRemoveProtection(Document doc, RemoveProtectionEventArgs e) { - if (AfterRemoveProtection != null) - AfterRemoveProtection(doc, e); - } + public static event RemoveProtectionEventHandler AfterRemoveProtection; + protected virtual void FireAfterRemoveProtection(Document doc, RemoveProtectionEventArgs e) { + if (AfterRemoveProtection != null) + AfterRemoveProtection(doc, e); + } - public static event AddMemberShipRoleToDocumentEventHandler BeforeAddMemberShipRoleToDocument; - protected virtual void FireBeforeAddMemberShipRoleToDocument(Document doc, string role, AddMemberShipRoleToDocumentEventArgs e) { - if (BeforeAddMemberShipRoleToDocument != null) - BeforeAddMemberShipRoleToDocument(doc, role, e); - } + public static event AddMemberShipRoleToDocumentEventHandler BeforeAddMemberShipRoleToDocument; + protected virtual void FireBeforeAddMemberShipRoleToDocument(Document doc, string role, AddMemberShipRoleToDocumentEventArgs e) { + if (BeforeAddMemberShipRoleToDocument != null) + BeforeAddMemberShipRoleToDocument(doc, role, e); + } - public static event AddMemberShipRoleToDocumentEventHandler AfterAddMemberShipRoleToDocument; - protected virtual void FireAfterAddMemberShipRoleToDocument(Document doc, string role, AddMemberShipRoleToDocumentEventArgs e) { - if (AfterAddMemberShipRoleToDocument != null) - AfterAddMemberShipRoleToDocument(doc, role, e); - } + public static event AddMemberShipRoleToDocumentEventHandler AfterAddMemberShipRoleToDocument; + protected virtual void FireAfterAddMemberShipRoleToDocument(Document doc, string role, AddMemberShipRoleToDocumentEventArgs e) { + if (AfterAddMemberShipRoleToDocument != null) + AfterAddMemberShipRoleToDocument(doc, role, e); + } - public static event RemoveMemberShipRoleFromDocumentEventHandler BeforeRemoveMemberShipRoleToDocument; - protected virtual void FireBeforeRemoveMemberShipRoleFromDocument(Document doc, string role, RemoveMemberShipRoleFromDocumentEventArgs e) { - if (BeforeRemoveMemberShipRoleToDocument != null) - BeforeRemoveMemberShipRoleToDocument(doc, role, e); - } + public static event RemoveMemberShipRoleFromDocumentEventHandler BeforeRemoveMemberShipRoleToDocument; + protected virtual void FireBeforeRemoveMemberShipRoleFromDocument(Document doc, string role, RemoveMemberShipRoleFromDocumentEventArgs e) { + if (BeforeRemoveMemberShipRoleToDocument != null) + BeforeRemoveMemberShipRoleToDocument(doc, role, e); + } - public static event RemoveMemberShipRoleFromDocumentEventHandler AfterRemoveMemberShipRoleToDocument; - protected virtual void FireAfterRemoveMemberShipRoleFromDocument(Document doc, string role, RemoveMemberShipRoleFromDocumentEventArgs e) { - if (AfterRemoveMemberShipRoleToDocument != null) - AfterRemoveMemberShipRoleToDocument(doc, role, e); - } + public static event RemoveMemberShipRoleFromDocumentEventHandler AfterRemoveMemberShipRoleToDocument; + protected virtual void FireAfterRemoveMemberShipRoleFromDocument(Document doc, string role, RemoveMemberShipRoleFromDocumentEventArgs e) { + if (AfterRemoveMemberShipRoleToDocument != null) + AfterRemoveMemberShipRoleToDocument(doc, role, e); + } - public static event RemoveMemberShipUserFromDocumentEventHandler BeforeRemoveMembershipUserFromDocument; - protected virtual void FireBeforeRemoveMembershipUserFromDocument(Document doc, string username, RemoveMemberShipUserFromDocumentEventArgs e) { - if (BeforeRemoveMembershipUserFromDocument != null) - BeforeRemoveMembershipUserFromDocument(doc, username, e); - } + public static event RemoveMemberShipUserFromDocumentEventHandler BeforeRemoveMembershipUserFromDocument; + protected virtual void FireBeforeRemoveMembershipUserFromDocument(Document doc, string username, RemoveMemberShipUserFromDocumentEventArgs e) { + if (BeforeRemoveMembershipUserFromDocument != null) + BeforeRemoveMembershipUserFromDocument(doc, username, e); + } - public static event RemoveMemberShipUserFromDocumentEventHandler AfterRemoveMembershipUserFromDocument; - protected virtual void FireAfterRemoveMembershipUserFromDocument(Document doc, string username, RemoveMemberShipUserFromDocumentEventArgs e) { - if (AfterRemoveMembershipUserFromDocument != null) - AfterRemoveMembershipUserFromDocument(doc, username, e); - } + public static event RemoveMemberShipUserFromDocumentEventHandler AfterRemoveMembershipUserFromDocument; + protected virtual void FireAfterRemoveMembershipUserFromDocument(Document doc, string username, RemoveMemberShipUserFromDocumentEventArgs e) { + if (AfterRemoveMembershipUserFromDocument != null) + AfterRemoveMembershipUserFromDocument(doc, username, e); + } - public static event AddMembershipUserToDocumentEventHandler BeforeAddMembershipUserToDocument; - protected virtual void FireBeforeAddMembershipUserToDocument(Document doc, string username, AddMembershipUserToDocumentEventArgs e) { - if (BeforeAddMembershipUserToDocument != null) - BeforeAddMembershipUserToDocument(doc, username, e); - } + public static event AddMembershipUserToDocumentEventHandler BeforeAddMembershipUserToDocument; + protected virtual void FireBeforeAddMembershipUserToDocument(Document doc, string username, AddMembershipUserToDocumentEventArgs e) { + if (BeforeAddMembershipUserToDocument != null) + BeforeAddMembershipUserToDocument(doc, username, e); + } - public static event AddMembershipUserToDocumentEventHandler AfterAddMembershipUserToDocument; - protected virtual void FireAfterAddMembershipUserToDocument(Document doc, string username, AddMembershipUserToDocumentEventArgs e) { - if (AfterAddMembershipUserToDocument != null) - AfterAddMembershipUserToDocument(doc, username, e); - } - } + public static event AddMembershipUserToDocumentEventHandler AfterAddMembershipUserToDocument; + protected virtual void FireAfterAddMembershipUserToDocument(Document doc, string username, AddMembershipUserToDocumentEventArgs e) { + if (AfterAddMembershipUserToDocument != null) + AfterAddMembershipUserToDocument(doc, username, e); + } + } public enum ProtectionType { diff --git a/umbraco/cms/umbraco.cms.csproj b/umbraco/cms/umbraco.cms.csproj index 7871710bfd..6c1390bcaa 100644 --- a/umbraco/cms/umbraco.cms.csproj +++ b/umbraco/cms/umbraco.cms.csproj @@ -101,6 +101,9 @@ False ..\..\foreign dlls\ClientDependency.Core.dll + + ..\..\foreign dlls\HtmlAgilityPack.dll + False ..\..\foreign dlls\ICSharpCode.SharpZipLib.dll @@ -195,6 +198,13 @@ + + + Code + + + Code + True @@ -202,9 +212,22 @@ PackageFiles.resx + + + + + + + + + + + + + Code diff --git a/umbraco/interfaces/skinning/IDependencyType.cs b/umbraco/interfaces/skinning/IDependencyType.cs new file mode 100644 index 0000000000..5f65126ee0 --- /dev/null +++ b/umbraco/interfaces/skinning/IDependencyType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI.WebControls; + +namespace umbraco.interfaces.skinning +{ + public interface IDependencyType + { + String Name { get; set; } + + List Values { get; set; } + WebControl Editor { get; set; } + } +} diff --git a/umbraco/interfaces/skinning/ITaskType.cs b/umbraco/interfaces/skinning/ITaskType.cs new file mode 100644 index 0000000000..327e2dc173 --- /dev/null +++ b/umbraco/interfaces/skinning/ITaskType.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +namespace umbraco.interfaces.skinning +{ + public interface ITaskType + { + String Name { get; set; } + String Value { get; set; } + + TaskExecutionDetails Execute(string Value); + + TaskExecutionStatus RollBack(string OriginalValue); + + string PreviewClientScript(string ControlClientId, string ClientSidePreviewEventType, string ClientSideGetValueScript); + + XmlNode ToXml(string OriginalValue, string NewValue); + } + + public struct TaskExecutionDetails + { + public TaskExecutionStatus TaskExecutionStatus; + public string OriginalValue; + public string NewValue; + } + + public enum TaskExecutionStatus + { + Failed, + Cancelled, + Completed + } +} diff --git a/umbraco/interfaces/umbraco.interfaces.csproj b/umbraco/interfaces/umbraco.interfaces.csproj index 4502c73dee..1c2cb51727 100644 --- a/umbraco/interfaces/umbraco.interfaces.csproj +++ b/umbraco/interfaces/umbraco.interfaces.csproj @@ -160,6 +160,8 @@ Code + + @@ -178,6 +180,7 @@ true + diff --git a/umbraco/presentation/config/Dashboard.config b/umbraco/presentation/config/Dashboard.config index f1b0bce91a..6a9d5db194 100644 --- a/umbraco/presentation/config/Dashboard.config +++ b/umbraco/presentation/config/Dashboard.config @@ -1,6 +1,18 @@  -
+ +
+ + settings + + + /umbraco/dashboard/settings/Applyskin.ascx + +
+ + + +
translator @@ -52,13 +64,21 @@ /usercontrols/dashboards/EmailAFriendForm_logs.ascx
-
- - default - member - - - /umbraco/members/membersearch.ascx - -
+
+ + default + member + + + /umbraco/members/membersearch.ascx + +
+
+ + contour + + + /umbraco/plugins/umbracocontour/formsdashboard.ascx + +
\ No newline at end of file diff --git a/umbraco/presentation/config/Skinning.config b/umbraco/presentation/config/Skinning.config new file mode 100644 index 0000000000..51a396269c --- /dev/null +++ b/umbraco/presentation/config/Skinning.config @@ -0,0 +1,4 @@ + + + + diff --git a/umbraco/presentation/config/metablogConfig.config b/umbraco/presentation/config/metablogConfig.config index a714b2cbe9..06fafc8306 100644 --- a/umbraco/presentation/config/metablogConfig.config +++ b/umbraco/presentation/config/metablogConfig.config @@ -1,3 +1,18 @@  + + My FAQs + 0 + 1080 + False + FAQItem + + + + answer + + + + + \ No newline at end of file diff --git a/umbraco/presentation/config/scripting.config b/umbraco/presentation/config/scripting.config index 6de82e06ee..931857f168 100644 --- a/umbraco/presentation/config/scripting.config +++ b/umbraco/presentation/config/scripting.config @@ -5,6 +5,7 @@ + \ No newline at end of file diff --git a/umbraco/presentation/config/umbracoSettings.config b/umbraco/presentation/config/umbracoSettings.config index 112086075a..eca97c1f67 100644 --- a/umbraco/presentation/config/umbracoSettings.config +++ b/umbraco/presentation/config/umbracoSettings.config @@ -88,6 +88,7 @@ true + true diff --git a/umbraco/presentation/config/xsltExtensions.config b/umbraco/presentation/config/xsltExtensions.config index 159eb96896..ca4dd26e58 100644 --- a/umbraco/presentation/config/xsltExtensions.config +++ b/umbraco/presentation/config/xsltExtensions.config @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/umbraco/presentation/default.aspx.cs b/umbraco/presentation/default.aspx.cs index b156ac9ba3..f530c07bce 100644 --- a/umbraco/presentation/default.aspx.cs +++ b/umbraco/presentation/default.aspx.cs @@ -6,6 +6,7 @@ using System.Xml; using System.Text.RegularExpressions; using umbraco.presentation; using umbraco.cms.businesslogic.web; +using umbraco.cms.businesslogic; namespace umbraco { @@ -141,6 +142,8 @@ namespace umbraco if (UmbracoSettings.UseAspNetMasterPages) { + HttpContext.Current.Trace.Write("umbracoPage", "Looking up skin information"); + if (m_umbPage != null) this.MasterPageFile = template.GetMasterPageName(m_umbPage.Template); @@ -165,9 +168,6 @@ namespace umbraco } else Page.Trace.IsEnabled = false; - - - } @@ -187,71 +187,85 @@ namespace umbraco private void initUmbracoPage() { - if (!UmbracoSettings.EnableSplashWhileLoading || !content.Instance.isInitializing) + + RequestInitEventArgs e = new RequestInitEventArgs(); + e.Page = m_umbPage; + e.PageId = m_umbPage.PageID; + e.Context = System.Web.HttpContext.Current; + + FireBeforeRequestInit(e); + if (!e.Cancel) { - if (m_umbPage != null) + + if (!UmbracoSettings.EnableSplashWhileLoading || !content.Instance.isInitializing) { - // Add page elements to global items - try - { - System.Web.HttpContext.Current.Items.Add("pageElements", m_umbPage.Elements); + if (m_umbPage != null) + { + // Add page elements to global items + try + { + + System.Web.HttpContext.Current.Items.Add("pageElements", m_umbPage.Elements); + + } + catch (ArgumentException aex) + { + + System.Web.HttpContext.Current.Items.Remove("pageElements"); + System.Web.HttpContext.Current.Items.Add("pageElements", m_umbPage.Elements); + } + + string tempCulture = m_umbPage.GetCulture(); + if (tempCulture != "") + { + System.Web.HttpContext.Current.Trace.Write("default.aspx", "Culture changed to " + tempCulture); + System.Threading.Thread.CurrentThread.CurrentCulture = + System.Globalization.CultureInfo.CreateSpecificCulture(tempCulture); + System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture; + } + + if (!UmbracoSettings.UseAspNetMasterPages) + { + layoutControls.umbracoPageHolder pageHolder = new umbraco.layoutControls.umbracoPageHolder(); + pageHolder.ID = "umbPageHolder"; + Page.Controls.Add(pageHolder); + m_umbPage.RenderPage(m_umbPage.Template); + layoutControls.umbracoPageHolder umbPageHolder = + (layoutControls.umbracoPageHolder)Page.FindControl("umbPageHolder"); + umbPageHolder.Populate(m_umbPage); + } } - catch (ArgumentException aex) + else { + // If there's no published content, show friendly error + if (umbraco.content.Instance.XmlContent.SelectSingleNode("/root/*") == null) + Response.Redirect(IO.SystemDirectories.Config + "/splashes/noNodes.aspx"); + else + { - System.Web.HttpContext.Current.Items.Remove("pageElements"); - System.Web.HttpContext.Current.Items.Add("pageElements", m_umbPage.Elements); + Response.StatusCode = 404; + Response.Write("

Page not found

"); + if (m_umbRequest != null) + HttpContext.Current.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(Request.Url.ToString()) + "'

umbraco tried this to match it using this xpath query'" + m_umbRequest.PageXPathQuery + "')"); + else + HttpContext.Current.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(Request.Url.ToString()) + "'

"); + Response.Write("

"); + Response.Write("

This page can be replaced with a custom 404 page by adding the id of the umbraco document to show as 404 page in the /config/umbracoSettings.config file. Just add the id to the '/settings/content/errors/error404' element.

"); + Response.Write("

For more information, visit information about custom 404 on the umbraco website.

"); + Response.Write("

This page is intentionally left ugly ;-)

"); + Response.Write(""); + } } - - string tempCulture = m_umbPage.GetCulture(); - if (tempCulture != "") - { - System.Web.HttpContext.Current.Trace.Write("default.aspx", "Culture changed to " + tempCulture); - System.Threading.Thread.CurrentThread.CurrentCulture = - System.Globalization.CultureInfo.CreateSpecificCulture(tempCulture); - System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture; - } - - if (!UmbracoSettings.UseAspNetMasterPages) - { - layoutControls.umbracoPageHolder pageHolder = new umbraco.layoutControls.umbracoPageHolder(); - pageHolder.ID = "umbPageHolder"; - Page.Controls.Add(pageHolder); - m_umbPage.RenderPage(m_umbPage.Template); - layoutControls.umbracoPageHolder umbPageHolder = - (layoutControls.umbracoPageHolder)Page.FindControl("umbPageHolder"); - umbPageHolder.Populate(m_umbPage); - } - } else { - // If there's no published content, show friendly error - if (umbraco.content.Instance.XmlContent.SelectSingleNode("/root/*") == null) - Response.Redirect(IO.SystemDirectories.Config + "/splashes/noNodes.aspx"); - else - { - - Response.StatusCode = 404; - Response.Write("

Page not found

"); - if (m_umbRequest != null) - HttpContext.Current.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(Request.Url.ToString()) + "'

umbraco tried this to match it using this xpath query'" + m_umbRequest.PageXPathQuery + "')"); - else - HttpContext.Current.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(Request.Url.ToString()) + "'

"); - Response.Write("

"); - Response.Write("

This page can be replaced with a custom 404 page by adding the id of the umbraco document to show as 404 page in the /config/umbracoSettings.config file. Just add the id to the '/settings/content/errors/error404' element.

"); - Response.Write("

For more information, visit information about custom 404 on the umbraco website.

"); - Response.Write("

This page is intentionally left ugly ;-)

"); - Response.Write(""); - } + Response.Redirect(IO.SystemDirectories.Config + "/splashes/booting.aspx?orgUrl=" + Request.Url); } - } - else - { - Response.Redirect(IO.SystemDirectories.Config + "/splashes/booting.aspx?orgUrl=" + Request.Url); + + FireAfterRequestInit(e); } } @@ -264,5 +278,49 @@ namespace umbraco } #endregion + + + + /// + /// The preinit event handler + /// + public delegate void RequestInitEventHandler(object sender, RequestInitEventArgs e); + /// + /// occurs before the umbraco page is initialized for rendering. + /// + public static event RequestInitEventHandler BeforeRequestInit; + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected internal new virtual void FireBeforeRequestInit(RequestInitEventArgs e) + { + if (BeforeRequestInit != null) + BeforeRequestInit(this, e); + } + + /// + /// Occurs when [after save]. + /// + public static event RequestInitEventHandler AfterRequestInit; + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void FireAfterRequestInit(RequestInitEventArgs e) + { + if (AfterRequestInit != null) + AfterRequestInit(this, e); + + } } + + //Request Init Events Arguments + public class RequestInitEventArgs : System.ComponentModel.CancelEventArgs + { + public page Page { get; internal set; } + public HttpContext Context { get; internal set; } + public string Url { get; internal set; } + public int PageId { get; internal set; } + } } diff --git a/umbraco/presentation/install/default.aspx b/umbraco/presentation/install/default.aspx index 03d4e17bd2..610d4c9c80 100644 --- a/umbraco/presentation/install/default.aspx +++ b/umbraco/presentation/install/default.aspx @@ -1,6 +1,7 @@ <%@ Page Language="c#" CodeBehind="default.aspx.cs" AutoEventWireup="True" Inherits="umbraco.presentation.install._default" EnableViewState="False" %> <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> <%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> + <%@ Register Src="~/install/Title.ascx" TagPrefix="umb1" TagName="PageTitle" %> @@ -11,29 +12,17 @@ - + + + + - - @@ -41,7 +30,7 @@ function nextStep(button, elementId) { showProgress(button, elementId); - setTimeout('document.location.href = \'default.aspx?installStep=' + document.getElementById("step").value + '\'', 100); + //setTimeout('document.location.href = \'default.aspx?installStep=' + document.getElementById("step").value + '\'', 100); } function showProgress(button, elementId) { @@ -73,20 +62,29 @@
- -
- -
-
-
-
-
+ + +
+ + +

+ +
+ +
+ +
+
+
+
- - -
- + +
+ +
+ +
diff --git a/umbraco/presentation/install/default.aspx.cs b/umbraco/presentation/install/default.aspx.cs index 9b54c50936..886139c051 100644 --- a/umbraco/presentation/install/default.aspx.cs +++ b/umbraco/presentation/install/default.aspx.cs @@ -10,13 +10,14 @@ using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Collections.Specialized; using umbraco.IO; +using umbraco.cms.businesslogic.installer; namespace umbraco.presentation.install { /// /// Summary description for _default. /// - public partial class _default : BasePages.BasePage + public partial class _default : BasePages.BasePage { private string _installStep = ""; @@ -25,63 +26,83 @@ namespace umbraco.presentation.install { ClientLoader.DataBind(); - //If user wishes to subscribe to security updates - if (!string.IsNullOrEmpty(Request["email"]) && !string.IsNullOrEmpty(Request["name"])) - SubscribeToNewsLetter(Request["name"], Request["email"]); + //If user wishes to subscribe to security updates + if (!string.IsNullOrEmpty(Request["email"]) && !string.IsNullOrEmpty(Request["name"])) + SubscribeToNewsLetter(Request["name"], Request["email"]); - // use buffer, so content isn't sent until it's ready (minimizing the blank screen experience) - Response.Buffer = true; - step.Value = _installStep; - //ScriptManager sm = Page.FindControl("umbracoScriptManager") as ScriptManager; - //webservices.ajaxHelpers.EnsureLegacyCalls(Page); - prepareNextButton(); - } + // use buffer, so content isn't sent until it's ready (minimizing the blank screen experience) + Response.Buffer = true; + + //ScriptManager sm = Page.FindControl("umbracoScriptManager") as ScriptManager; + //webservices.ajaxHelpers.EnsureLegacyCalls(Page); + //prepareNextButton(); + } - private void SubscribeToNewsLetter(string name, string email) { - try { - System.Net.WebClient client = new System.Net.WebClient(); - NameValueCollection values = new NameValueCollection(); - values.Add("name", name); - values.Add("email", email); + private void SubscribeToNewsLetter(string name, string email) { + try { + System.Net.WebClient client = new System.Net.WebClient(); + NameValueCollection values = new NameValueCollection(); + values.Add("name", name); + values.Add("email", email); - client.UploadValues("http://umbraco.org/base/Ecom/SubmitEmail/installer.aspx", values); + client.UploadValues("http://umbraco.org/base/Ecom/SubmitEmail/installer.aspx", values); - } catch { /* fail in silence */ } - } + } catch { /* fail in silence */ } + } - private void loadContent() + private void loadContent(InstallerStep currentStep) { - //Response.Redirect("./default.aspx?installStep=" + step.Value, true); + PlaceHolderStep.Controls.Clear(); + PlaceHolderStep.Controls.Add(new System.Web.UI.UserControl().LoadControl(IOHelper.ResolveUrl( currentStep.UserControl ) )); + step.Value = currentStep.Alias; + next.CommandArgument = currentStep.Alias; + lt_header.Text = currentStep.Name; + } + + protected void onNextCommand(object sender, CommandEventArgs e) + { + string currentStep = (string)e.CommandArgument; + InstallerStep _s = InstallerSteps().GotoNextStep(currentStep); + Response.Redirect("?installStep=" + _s.Alias); } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { - InitializeComponent(); - base.OnInit(e); - _installStep = helper.Request("installStep"); - - //if this is not an upgrade we will log in with the default user. - if (!String.IsNullOrEmpty(GlobalSettings.ConfigurationStatus.Trim())) { - try { - ensureContext(); - } catch { - Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl)); - } + InitializeComponent(); + base.OnInit(e); - //set the first step to upgrade. - if (string.IsNullOrEmpty(_installStep)) - _installStep = "upgrade"; + //we might override the beginning step here + _installStep = helper.Request("installStep"); + + InstallerStep currentStep; + //if this is not an upgrade we will log in with the default user. + + if (!String.IsNullOrEmpty(GlobalSettings.ConfigurationStatus.Trim())) { + try { + ensureContext(); + } catch { + Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl)); + } - } + //set the first step to upgrade. + if (string.IsNullOrEmpty(_installStep)) + _installStep = "upgrade"; - // empty / security check: only controls inside steps folder allowed - if (_installStep == "" || _installStep.Contains("/")) - _installStep = "welcome"; + } - PlaceHolderStep.Controls.Add(new System.Web.UI.UserControl().LoadControl( IOHelper.ResolveUrl( SystemDirectories.Install ) + "/steps/" + _installStep + ".ascx")); + if (!string.IsNullOrEmpty(_installStep) && InstallerSteps().StepExists(_installStep)) + currentStep = InstallerSteps().Get(_installStep); + else + currentStep = InstallerSteps().FirstAvailableStep(); + + //if the step we are loading is complete, we will continue to the next one if it's set to auto redirect + if (currentStep.Completed() && currentStep.MoveToNextStepAutomaticly) + currentStep = InstallerSteps().FirstAvailableStep(); + + loadContent(currentStep); } /// @@ -94,34 +115,46 @@ namespace umbraco.presentation.install } #endregion + + private static InstallerStepCollection InstallerSteps() + { + InstallerStepCollection ics = new InstallerStepCollection(); + ics.Add(new install.steps.Definitions.License()); + ics.Add(new install.steps.Definitions.FilePermissions()); + ics.Add(new install.steps.Definitions.Database()); + //ics.Add(new install.steps.Definitions.DefaultUser()); + ics.Add(new install.steps.Definitions.TheEnd()); + return ics; + } +/* protected void prepareNextButton() { switch (step.Value) { - case "welcome": case "upgrade": - step.Value = "license"; - loadContent(); - break; - case "license": - step.Value = "detect"; - loadContent(); - break; - case "detect": - // upgrade! - if (!String.IsNullOrEmpty(GlobalSettings.ConfigurationStatus.Trim())) - step.Value = "renaming"; - else - step.Value = "validatePermissions"; + case "welcome": case "upgrade": + step.Value = "license"; + loadContent(); + break; + case "license": + step.Value = "detect"; + loadContent(); + break; + case "detect": + // upgrade! + if (!String.IsNullOrEmpty(GlobalSettings.ConfigurationStatus.Trim())) + step.Value = "renaming"; + else + step.Value = "validatePermissions"; loadContent(); break; case "upgradeIndex": step.Value = "validatePermissions"; loadContent(); break; - case "renaming" : - step.Value = "validatePermissions"; - loadContent(); - break; + case "renaming" : + step.Value = "validatePermissions"; + loadContent(); + break; case "validatePermissions": step.Value = "defaultUser"; loadContent(); @@ -136,6 +169,6 @@ namespace umbraco.presentation.install default: break; } - } + }*/ } } diff --git a/umbraco/presentation/install/default.aspx.designer.cs b/umbraco/presentation/install/default.aspx.designer.cs index f1c22e19e1..51c736112d 100644 --- a/umbraco/presentation/install/default.aspx.designer.cs +++ b/umbraco/presentation/install/default.aspx.designer.cs @@ -21,15 +21,6 @@ namespace umbraco.presentation.install { /// protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - /// /// CssInclude2 control. /// @@ -75,6 +66,15 @@ namespace umbraco.presentation.install { /// protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; + /// + /// JsInclude5 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.JsInclude JsInclude5; + /// /// Form1 control. /// @@ -94,13 +94,13 @@ namespace umbraco.presentation.install { protected global::System.Web.UI.ScriptManager umbracoScriptManager; /// - /// Panel1 control. + /// lt_header control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::umbraco.uicontrols.UmbracoPanel Panel1; + protected global::System.Web.UI.WebControls.Literal lt_header; /// /// PlaceHolderStep control. diff --git a/umbraco/presentation/install/installer.js b/umbraco/presentation/install/installer.js new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/umbraco/presentation/install/installer.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/Database.cs b/umbraco/presentation/install/steps/Definitions/Database.cs new file mode 100644 index 0000000000..ed01754daa --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/Database.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; +using umbraco.IO; +using umbraco.DataLayer.Utility.Installer; +using umbraco.DataLayer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class Database : InstallerStep + { + public override string Alias + { + get { return "database"; } + } + + public override string Name + { + get { return "Database configuration"; } + } + + public override string UserControl + { + get { return SystemDirectories.Install + "/steps/database.ascx"; } + } + + public override bool HideNextButtonUntillCompleted + { + get + { + return false; + } + } + + public override bool MoveToNextStepAutomaticly + { + get + { + return true; + } + } + + //here we determine if the installer should skip this step... + public override bool Completed() + { + bool retval = false; + IInstallerUtility m_Installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); + retval = m_Installer.IsLatestVersion; + m_Installer = null; + + return retval; + } + + + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/DefaultUser.cs b/umbraco/presentation/install/steps/Definitions/DefaultUser.cs new file mode 100644 index 0000000000..6b66ff28dd --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/DefaultUser.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class DefaultUser : InstallerStep + { + public override string Alias + { + get { return "defaultUser"; } + } + + public override string Name + { + get { return "Default user"; } + } + + public override bool HideNextButtonUntillCompleted + { + get + { + return false; + } + } + + public override string UserControl + { + get { return IO.SystemDirectories.Install + "/steps/defaultuser.ascx"; } + } + + public override bool Completed() + { + BusinessLogic.User u = BusinessLogic.User.GetUser(0); + if (u.NoConsole || u.Disabled) + return true; + + if (u.GetPassword() != "default") + return true; + + + return false; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/FilePermissions.cs b/umbraco/presentation/install/steps/Definitions/FilePermissions.cs new file mode 100644 index 0000000000..3afb1d61e0 --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/FilePermissions.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class FilePermissions : InstallerStep + { + public override string Alias + { + get { return "filepermissions"; } + } + + public override string Name + { + get { return "Confirm permissions"; } + } + + public override string UserControl + { + get { return IO.SystemDirectories.Install + "/steps/validatepermissions.ascx"; } + } + + public override bool Completed() + { + return utills.FilePermissions.RunFilePermissionTestSuite(); + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/Skinning.cs b/umbraco/presentation/install/steps/Definitions/Skinning.cs new file mode 100644 index 0000000000..61c8e02e7a --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/Skinning.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class Skinning : InstallerStep + { + public override string Alias + { + get { return "skinning"; } + } + + public override string Name + { + get { return "Configure your site"; } + } + + public override string UserControl + { + get { return IO.SystemDirectories.Install + "/steps/skinning.ascx"; } + } + + public override bool Completed() + { + return false; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/TheEnd.cs b/umbraco/presentation/install/steps/Definitions/TheEnd.cs new file mode 100644 index 0000000000..112fe5ae92 --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/TheEnd.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class TheEnd : InstallerStep + { + public override string Alias + { + get { return "theend"; } + } + + public override string Name + { + get { return "thats all folks"; } + } + + public override string UserControl + { + get { return IO.SystemDirectories.Install + "/steps/theend.ascx"; } + } + + public override bool Completed() + { + return false; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Definitions/Welcome.cs b/umbraco/presentation/install/steps/Definitions/Welcome.cs new file mode 100644 index 0000000000..2da583be38 --- /dev/null +++ b/umbraco/presentation/install/steps/Definitions/Welcome.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + public class License : InstallerStep + { + public override string Alias + { + get { return "license"; } + } + + public override string Name + { + get { return "License"; } + } + + public override bool HideNextButtonUntillCompleted + { + get + { + return false; + } + } + + public override string UserControl + { + get { return IO.SystemDirectories.Install + "/steps/license.ascx"; } + } + + public override bool Completed() + { + return false; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx new file mode 100644 index 0000000000..6e721d8182 --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx @@ -0,0 +1,31 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="loadStarterKitDesigns.ascx.cs" Inherits="umbraco.presentation.install.steps.Skinning.loadStarterKitDesigns" %> +<%@ Import Namespace="umbraco.cms.businesslogic.packager.repositories" %> + + + + + + + +
    + + +
  • + + + <%# ((Skin)Container.DataItem).Text %> + + +
    + + + +
  • +
    + +
+ +
+ + +
\ No newline at end of file diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.cs b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.cs new file mode 100644 index 0000000000..087f6868a6 --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.BusinessLogic; + +namespace umbraco.presentation.install.steps.Skinning +{ + public partial class loadStarterKitDesigns : System.Web.UI.UserControl + { + public Guid StarterKitGuid { get; set; } + + private cms.businesslogic.packager.repositories.Repository repo; + private string repoGuid = "65194810-1f85-11dd-bd0b-0800200c9a66"; + + public loadStarterKitDesigns() + { + repo = cms.businesslogic.packager.repositories.Repository.getByGuid(repoGuid); + } + + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + + + if (repo.HasConnection()) + { + try + { + rep_starterKitDesigns.DataSource = repo.Webservice.Skins(StarterKitGuid.ToString()); + rep_starterKitDesigns.DataBind(); + } + catch (Exception ex) + { + Log.Add(LogTypes.Debug, -1, ex.ToString()); + + ShowConnectionError(); + } + } + else + { + ShowConnectionError(); + } + } + + private void ShowConnectionError() + { + + uicontrols.Feedback fb = new global::umbraco.uicontrols.Feedback(); + fb.type = global::umbraco.uicontrols.Feedback.feedbacktype.error; + fb.Text = "No connection to repository. Starter Kits Designs could not be fetched from the repository as there was no connection to: '" + repo.RepositoryUrl + "'"; + + pl_loadStarterKitDesigns.Controls.Clear(); + pl_loadStarterKitDesigns.Controls.Add(fb); + } + + protected void SelectStarterKitDesign(object sender, EventArgs e) + { + Guid kitGuid = new Guid(((LinkButton)sender).CommandArgument); + + cms.businesslogic.packager.Installer installer = new cms.businesslogic.packager.Installer(); + + if (repo.HasConnection()) + { + cms.businesslogic.packager.Installer p = new cms.businesslogic.packager.Installer(); + + string tempFile = p.Import(repo.fetch(kitGuid.ToString())); + p.LoadConfig(tempFile); + int pID = p.CreateManifest(tempFile, kitGuid.ToString(), repoGuid); + + p.InstallBusinessLogic(pID, tempFile); + p.InstallCleanUp(pID, tempFile); + + library.RefreshContent(); + + //((skinning)Parent.Parent.Parent).showStarterKitDesigns(kitGuid); + + } + else + { + ShowConnectionError(); + } + + + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.designer.cs b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.designer.cs new file mode 100644 index 0000000000..beedbc9b59 --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKitDesigns.ascx.designer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace umbraco.presentation.install.steps.Skinning { + + + public partial class loadStarterKitDesigns { + + /// + /// pl_loadStarterKitDesigns control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel pl_loadStarterKitDesigns; + + /// + /// rep_starterKitDesigns control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater rep_starterKitDesigns; + } +} diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx new file mode 100644 index 0000000000..3a53cacb1c --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx @@ -0,0 +1,27 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="loadStarterKits.ascx.cs" Inherits="umbraco.presentation.install.steps.Skinning.loadStarterKits" %> +<%@ Import Namespace="umbraco.cms.businesslogic.packager.repositories" %> + + + + + + +
    + + +
  • + + + <%# ((Package)Container.DataItem).Text %> + + +
  • +
    + +
+ +
+ + + +
\ No newline at end of file diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.cs b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.cs new file mode 100644 index 0000000000..e8ee36c952 --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.BusinessLogic; +using umbraco.IO; +using System.IO; + +namespace umbraco.presentation.install.steps.Skinning +{ + public partial class loadStarterKits : System.Web.UI.UserControl + { + private cms.businesslogic.packager.repositories.Repository repo; + private string repoGuid = "65194810-1f85-11dd-bd0b-0800200c9a66"; + + public loadStarterKits() + { + repo = cms.businesslogic.packager.repositories.Repository.getByGuid(repoGuid); + } + + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + + if (repo.HasConnection()) + { + try + { + rep_starterKits.DataSource = repo.Webservice.StarterKits(); + rep_starterKits.DataBind(); + + } + catch (Exception ex) + { + Log.Add(LogTypes.Debug, -1, ex.ToString()); + ShowConnectionError(); + + } + } + else + { + ShowConnectionError(); + } + } + + private void ShowConnectionError() + { + + uicontrols.Feedback fb = new global::umbraco.uicontrols.Feedback(); + fb.type = global::umbraco.uicontrols.Feedback.feedbacktype.error; + fb.Text = "No connection to repository. Starter Kits could not be fetched from the repository as there was no connection to: '" + repo.RepositoryUrl + "'"; + + pl_loadStarterKits.Controls.Clear(); + pl_loadStarterKits.Controls.Add(fb); + } + protected void SelectStarterKit(object sender, EventArgs e) + { + Guid kitGuid = new Guid(((LinkButton)sender).CommandArgument); + + cms.businesslogic.packager.Installer installer = new cms.businesslogic.packager.Installer(); + + if (repo.HasConnection()) + { + cms.businesslogic.packager.Installer p = new cms.businesslogic.packager.Installer(); + + string tempFile = p.Import(repo.fetch(kitGuid.ToString())); + p.LoadConfig(tempFile); + int pID = p.CreateManifest(tempFile, kitGuid.ToString(), repoGuid); + + p.InstallBusinessLogic(pID, tempFile); + p.InstallCleanUp(pID, tempFile); + + library.RefreshContent(); + + ((skinning)Parent.Parent.Parent).showStarterKitDesigns(kitGuid); + + } + else + { + ShowConnectionError(); + } + + + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.designer.cs b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.designer.cs new file mode 100644 index 0000000000..80774b2c8a --- /dev/null +++ b/umbraco/presentation/install/steps/Skinning/loadStarterKits.ascx.designer.cs @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace umbraco.presentation.install.steps.Skinning { + + + public partial class loadStarterKits { + + /// + /// pl_loadStarterKits control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel pl_loadStarterKits; + + /// + /// rep_starterKits control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater rep_starterKits; + } +} diff --git a/umbraco/presentation/install/steps/detect.ascx b/umbraco/presentation/install/steps/database.ascx similarity index 96% rename from umbraco/presentation/install/steps/detect.ascx rename to umbraco/presentation/install/steps/database.ascx index f27ee231f9..f1a731f335 100644 --- a/umbraco/presentation/install/steps/detect.ascx +++ b/umbraco/presentation/install/steps/database.ascx @@ -1,4 +1,4 @@ -<%@ Control Language="c#" AutoEventWireup="True" Codebehind="detect.ascx.cs" Inherits="umbraco.presentation.install.steps.detect" +<%@ Control Language="c#" AutoEventWireup="True" Codebehind="database.ascx.cs" Inherits="umbraco.presentation.install.steps.detect" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>

Step 2/5: Database configuration

diff --git a/umbraco/presentation/install/steps/detect.ascx.cs b/umbraco/presentation/install/steps/database.ascx.cs similarity index 100% rename from umbraco/presentation/install/steps/detect.ascx.cs rename to umbraco/presentation/install/steps/database.ascx.cs diff --git a/umbraco/presentation/install/steps/detect.ascx.designer.cs b/umbraco/presentation/install/steps/database.ascx.designer.cs similarity index 100% rename from umbraco/presentation/install/steps/detect.ascx.designer.cs rename to umbraco/presentation/install/steps/database.ascx.designer.cs diff --git a/umbraco/presentation/install/steps/detect.ascx.resx b/umbraco/presentation/install/steps/database.ascx.resx similarity index 100% rename from umbraco/presentation/install/steps/detect.ascx.resx rename to umbraco/presentation/install/steps/database.ascx.resx diff --git a/umbraco/presentation/install/steps/license.ascx b/umbraco/presentation/install/steps/license.ascx index 8619baf092..0577b880f9 100644 --- a/umbraco/presentation/install/steps/license.ascx +++ b/umbraco/presentation/install/steps/license.ascx @@ -1,11 +1,14 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="license.ascx.cs" Inherits="umbraco.presentation.install.steps.license" %> -

- Step 1/5 Accept license

+

+ Accept the license for umbraco CMS

+ +

By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below.

-
-
+
+ +

The License (MIT):

@@ -30,9 +33,6 @@ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-

  -

-

- (That's all. That didn't hurt, did it?)

-
+ +

That's all. That didn't hurt, did it?)

diff --git a/umbraco/presentation/install/steps/skinning.ascx b/umbraco/presentation/install/steps/skinning.ascx new file mode 100644 index 0000000000..57a55d4b2e --- /dev/null +++ b/umbraco/presentation/install/steps/skinning.ascx @@ -0,0 +1,24 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="skinning.ascx.cs" Inherits="umbraco.presentation.install.steps.skinning" %> + + + + + + +
+ +
+ +
+ + + + + +
+ +
+ +
+ + \ No newline at end of file diff --git a/umbraco/presentation/install/steps/skinning.ascx.cs b/umbraco/presentation/install/steps/skinning.ascx.cs new file mode 100644 index 0000000000..b566638fcc --- /dev/null +++ b/umbraco/presentation/install/steps/skinning.ascx.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.IO; + +namespace umbraco.presentation.install.steps +{ + public partial class skinning : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + + if (string.IsNullOrEmpty(Request.QueryString["starterKit"])) + showStarterKits(); + else + showStarterKitDesigns(new Guid(Request.QueryString["starterKit"])); + + } + private void showStarterKits() + { + ph_starterKits.Controls.Add(new UserControl().LoadControl(SystemDirectories.Install + "/steps/Skinning/loadStarterKits.ascx")); + + pl_starterKit.Visible = true; + pl_starterKitDesign.Visible = false; + } + + public void showStarterKitDesigns(Guid starterKitGuid) + { + Skinning.loadStarterKitDesigns ctrl = (Skinning.loadStarterKitDesigns)new UserControl().LoadControl(SystemDirectories.Install + "/steps/Skinning/loadStarterKitDesigns.ascx"); + ctrl.StarterKitGuid = starterKitGuid; + + ph_starterKitDesigns.Controls.Add(ctrl); + + pl_starterKit.Visible = false; + pl_starterKitDesign.Visible = true; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/install/steps/skinning.ascx.designer.cs b/umbraco/presentation/install/steps/skinning.ascx.designer.cs new file mode 100644 index 0000000000..1cbded5e34 --- /dev/null +++ b/umbraco/presentation/install/steps/skinning.ascx.designer.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace umbraco.presentation.install.steps { + + + public partial class skinning { + + /// + /// pl_starterKit control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel pl_starterKit; + + /// + /// ph_starterKits control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder ph_starterKits; + + /// + /// pl_starterKitDesign control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel pl_starterKitDesign; + + /// + /// ph_starterKitDesigns control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder ph_starterKitDesigns; + } +} diff --git a/umbraco/presentation/install/style.css b/umbraco/presentation/install/style.css index b85036e439..ae26476ac3 100644 --- a/umbraco/presentation/install/style.css +++ b/umbraco/presentation/install/style.css @@ -1,201 +1,26 @@ body, input, select { - font-size: 11px; - font-family: "Trebuchet MS" , Verdana, Arial, "Lucida Grande"; + font-size: 12px; + font-family: Calibri, "Trebuchet MS" , Verdana, Arial, "Lucida Grande"; } + body { width: 100%; text-align: center; padding-top: 25px; margin: 0px; + background: no-repeat #fff url(images/logo_type.png) center 20px; } - #Panel1_content - { - margin-left: 1px; - background: url(images/background.png) no-repeat bottom center; - width: 100%; - overflow: hidden; - } - #Panel1_content p - { - font-size: 11px; - line-height: 15px; - } - #buttons - { - position: absolute; - bottom: 5px; - width: 248px; - margin-left: 400px; - } - #buttons #next - { - float: right; - } - #buttons #back - { - float: left; - } - #loadingBar - { - visibility: hidden; - margin-left: -180px; - } - #loadingBar img - { - width: 220px; - } - #contentScroll - { - overflow: auto; - width: 100%; - height: 465px; - padding-right: 7px; - } - h1 - { - font-size: 2em; - margin-top: 5px; - margin-bottom: 5px; - } - h2 - { - font-size: 1.4em; - margin-top: 5px; - margin-bottom: 5px; - } - .error, .notice, .success - { - padding: .8em; - padding-top: 0em; - padding-bottom: 0em; - margin-bottom: .5em; - border: 2px solid #ddd; - } - .error - { - background: #FBE3E4; - color: #8a1f11; - border-color: #FBC2C4; - } - .notice - { - background: #FFF6BF; - color: #514721; - border-color: #FFD324; - } - .success - { - background: #E6EFC2; - color: #264409; - border-color: #C6D880; - } - .error a - { - color: #8a1f11; - } - .notice a - { - color: #514721; - } - .success a - { - color: #264409; - } - .errormessage - { - color: #8a1f11; - } - #videos - { - padding: 0px; - width: 400px; - text-align: center; - margin: auto; - font-size: 11px; - } - #videos td - { - text-align: center; - } - #videos a - { - color: #666; - text-decoration: none; - } - #videos img - { - padding: 1px; - border: none; - display: block; - margin: auto; - } - #videos.single - { - margin: 0px; - width: 150px; - } - - #nitros - { - margin: 0; - } - - #nitros h2 - { - font-size: 1.2em; - } - #nitros h3 - { - font-size: 1em; - margin-bottom: 0px; - margin-top: 0px; - } - - #nitros .umbNitroList input - { - float: left; - } - #nitros .umbNitroList div.nitro - { - float: left; - padding: 3px 0px 5px 10px; - clear: right; - } - ol.form - { - list-style: none; - margin: 0; - padding: 5px; - } - ol.form li - { - padding: 3px 0 5px 0; - } - ol.form label - { - width: 130px; - float: left; - clear: both; - } - ol.form .textfield - { - width: 200px; - } - - #list1a a.accordianOpener{cursor: pointer; font-size: 14px; font-weight: bold; display: block; padding: 5px; text-decoration: none;} - #list1a a.accordianOpener small{display: block;} - #list1a div.accordianContainer{border-bottom: 1px solid #D9D7D7; height: auto; overflow: auto; display: block; clear: both;} - #list1a .nitroCB{display: block; padding: 2px; margin: 0px 0px 5px 20px; clear: both;} - #list1a .nitroCB small{clear: both; display: block;} - #list1a input{float: left; margin: 0px 10px 20px 0px;} - #list1a div.nitro{float: left; padding: 0px 10px 0px 0px; width: 90%;} - #list1a div.nitro h3{padding: 0px; margin: 0px; line-height: 14px;} - - #newsLetterForm{padding:10px; margin: 0px 0px 0px 10px;} - #newsLetterForm input.text{border: 1px #ccc solid; background: #fff; padding: 3px; margin:0px 0px 7px 0px; width: 200px; clear: right;} - #newsLetterForm label{padding: 5px; width: 70px; display: block; float: left; clear: left;} - #newsLetterForm p{padding-left: 80px;} #newsLetterForm a{color: Blue; text-decoration: underline;} - #newsLetterResponse{padding:10px; margin: 0px 0px 0px 10px; color: #264409;} - input.errorField{background: #FBE3E4 !Important; color: #8A1F11 !Important; border-color: #FBC2C4 !Important} \ No newline at end of file + + h1,h2,h3,h4,h5{font-weight: normal; } + + h1{font-size: 2.5em; border-bottom: 1px solid #eaeaea; padding-bottom: 7px; margin-bottom: 7px;} + + + #main{text-align: left; width: 900px; margin: auto; margin-top: 120px;} + + #buttons{text-align: center; position: relative; border-top: 1px solid #eaeaea; margin-top: 40px;} + #buttons img{margin: auto; margin-top: 15px;} + #buttons .next{position: absolute; top: 10px; right: 10px;} + \ No newline at end of file diff --git a/umbraco/presentation/install/utills/FilePermissions.cs b/umbraco/presentation/install/utills/FilePermissions.cs new file mode 100644 index 0000000000..327f5ed30b --- /dev/null +++ b/umbraco/presentation/install/utills/FilePermissions.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.IO; +using System.IO; + +namespace umbraco.presentation.install.utills +{ + + + public class FilePermissions + { + public static string[] permissionDirs = { SystemDirectories.Css, SystemDirectories.Config, SystemDirectories.Data, SystemDirectories.Media, SystemDirectories.Masterpages, SystemDirectories.Xslt, SystemDirectories.Usercontrols, SystemDirectories.Preview }; + public static string[] permissionFiles = { }; + public static string[] packagesPermissionsDirs = { SystemDirectories.Bin, SystemDirectories.Umbraco, SystemDirectories.Usercontrols, SystemDirectories.Packages }; + + public static bool RunFilePermissionTestSuite() + { + Dictionary newReport = new Dictionary(); + + if (!TestDirectories(permissionDirs, ref newReport)) + return false; + + if (!TestDirectories(packagesPermissionsDirs, ref newReport)) + return false; + + if (!TestFiles(permissionFiles, ref newReport)) + return false; + + if (!TestContentXml(ref newReport)) + return false; + + if (!TestFolderCreation(SystemDirectories.Media, ref newReport)) + return false; + + return true; + } + + public static bool TestDirectories(string[] directories, ref Dictionary errorReport) + { + bool succes = true; + foreach (string dir in permissionDirs) + { + bool result = SaveAndDeleteFile(IOHelper.MapPath(dir + "/configWizardPermissionTest.txt")); + + if (!result) + { + succes = false; + + if (errorReport != null) + errorReport.Add(dir, "Missing permissions, cannot create new files"); + } + } + + return succes; + } + + public static bool TestFiles(string[] files, ref Dictionary errorReport) + { + bool succes = true; + foreach (string file in permissionFiles) + { + bool result = OpenFileForWrite(IOHelper.MapPath(file)); + if (!result) + { + if (errorReport != null) + errorReport.Add(file, "Missing write permissions"); + + succes = false; + } + } + + return succes; + } + + public static bool TestFolderCreation(string folder, ref Dictionary errorReport) + { + try + { + string tempDir = IOHelper.MapPath(folder + "/testCreatedByConfigWizard"); + Directory.CreateDirectory(tempDir); + Directory.Delete(tempDir); + return true; + } + catch + { + if (errorReport != null) + errorReport.Add(folder, "Could not create sub-directory"); + return false; + } + } + + public static bool TestContentXml(ref Dictionary errorReport) + { + // Test umbraco.xml file + try + { + content.Instance.PersistXmlToFile(); + return true; + } + catch + { + if(errorReport != null) + errorReport.Add(SystemFiles.ContentCacheXml, "Could not persist content cache"); + return false; + } + } + + private static string successOrFailure(bool result) + { + if (result) + return "Success"; + else + return "Failure"; + } + + private static bool SaveAndDeleteFile(string file) + { + try + { + //first check if the directory of the file exists, and if not try to create that first. + FileInfo fi = new FileInfo(file); + if (!fi.Directory.Exists) + { + fi.Directory.Create(); + } + + File.WriteAllText(file, + "This file has been created by the umbraco configuration wizard. It is safe to delete it!"); + File.Delete(file); + return true; + } + catch + { + return false; + } + + } + + private static bool OpenFileForWrite(string file) + { + try + { + File.AppendText(file).Close(); + } + catch + { + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/page.cs b/umbraco/presentation/page.cs index 547de6d6ba..03049d4efa 100644 --- a/umbraco/presentation/page.cs +++ b/umbraco/presentation/page.cs @@ -31,6 +31,8 @@ namespace umbraco private int pageID; private Guid pageVersion; private int template; + + private Hashtable elements = new Hashtable(); private StringBuilder pageContent = new StringBuilder(); private Control pageContentControl = new Control(); @@ -70,11 +72,14 @@ namespace umbraco string sValue = p.Value!=null ? p.Value.ToString() : String.Empty; elements.Add(p.PropertyType.Alias, sValue); } + template = d.Template; + + HttpContext.Current.Trace.Write("umbracoPage", "Pagedata loaded for " + pageName + " (ID: " + pageID.ToString() + ", Version: " + pageVersion.ToString() + ")"); - // RenderPage(template); + //RenderPage(template); } private void populatePageData(int pageID, string pageName, int nodeType, string nodeTypeAlias, string writerName, string creatorName, @@ -191,6 +196,7 @@ namespace umbraco { } + HttpContext.Current.Trace.Write("umbracoPage", "testing altTemplate"); // Check for alternative template if (HttpContext.Current.Items["altTemplate"] != null && HttpContext.Current.Items["altTemplate"].ToString() != "") @@ -218,7 +224,8 @@ namespace umbraco HttpContext.Current.Trace.Warn("umbracoPage", "No template defined"); } } - + + // Load all page elements string xpath = UmbracoSettings.UseLegacyXmlSchema ? "./data" : "./* [not(@id)]"; foreach (XmlNode dataNode in xmlNode.SelectNodes(xpath)) @@ -381,4 +388,4 @@ namespace umbraco #endregion } -} \ No newline at end of file +} diff --git a/umbraco/presentation/template.cs b/umbraco/presentation/template.cs index 9819dc8e31..fae1845b98 100644 --- a/umbraco/presentation/template.cs +++ b/umbraco/presentation/template.cs @@ -63,6 +63,39 @@ namespace umbraco { } } + //Support for template folders, if a alternative skin folder is requested + //we will try to look for template files in another folder + public string AlternateMasterPageFile(string templateFolder) + { + string file = TemplateAlias.Replace(" ", "") + ".master"; + string path = SystemDirectories.Masterpages + "/" + templateFolder + "/" + file; + + //if it doesn't exists then we return the normal file + if (!System.IO.File.Exists(IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)))){ + + string originalPath = IOHelper.MapPath(VirtualPathUtility.ToAbsolute(MasterPageFile)); + string copyPath = IOHelper.MapPath(VirtualPathUtility.ToAbsolute(path)); + + FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.ReadWrite); + StreamReader f = new StreamReader(fs); + String newfile = f.ReadToEnd(); + f.Close(); + fs.Close(); + + newfile = newfile.Replace("MasterPageFile=\"~/masterpages/", "MasterPageFile=\""); + + fs = new FileStream(copyPath, FileMode.Create, FileAccess.Write); + + StreamWriter replacement = new StreamWriter(fs); + replacement.Write(newfile); + replacement.Close(); + } + + return path; + + } + + public string TemplateAlias { get { return _templateAlias; } } @@ -383,13 +416,21 @@ namespace umbraco { #region constructors - public static string GetMasterPageName(int templateID) { + public static string GetMasterPageName(int templateID) + { + return GetMasterPageName(templateID, null); + } + + public static string GetMasterPageName(int templateID, string templateFolder) { template t = (template)templateCache["template" + templateID]; if (t == null) t = new template(templateID); if (t != null) - return t.MasterPageFile; + if (!string.IsNullOrEmpty(templateFolder)) + return t.AlternateMasterPageFile(templateFolder); + else + return t.MasterPageFile; else throw new ArgumentException(String.Format("Template with id '{0}' not found", templateID)); } diff --git a/umbraco/presentation/umbraco.presentation.csproj b/umbraco/presentation/umbraco.presentation.csproj index 6e84244843..4312cf9d9b 100644 --- a/umbraco/presentation/umbraco.presentation.csproj +++ b/umbraco/presentation/umbraco.presentation.csproj @@ -186,6 +186,41 @@ Properties\SolutionInfo.cs + + database.ascx + ASPXCodeBehind + + + database.ascx + + + + + + + + + skinning.ascx + ASPXCodeBehind + + + skinning.ascx + + + loadStarterKitDesigns.ascx + ASPXCodeBehind + + + loadStarterKitDesigns.ascx + + + loadStarterKits.ascx + ASPXCodeBehind + + + loadStarterKits.ascx + + Code @@ -242,13 +277,6 @@ defaultUser.ascx - - detect.ascx - ASPXCodeBehind - - - detect.ascx - license.ascx ASPXCodeBehind @@ -519,6 +547,13 @@ + + Applyskin.ascx + ASPXCodeBehind + + + Applyskin.ascx + Preview.aspx ASPXCodeBehind @@ -550,6 +585,14 @@ Code + + SkinCustomizer.ascx + ASPXCodeBehind + + + SkinCustomizer.ascx + + MemberSearch.ascx ASPXCodeBehind @@ -1511,13 +1554,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1980,9 +2060,6 @@ UserControl - - UserControl - UserControl @@ -2028,6 +2105,7 @@ + SettingsSingleFileGenerator Settings1.Designer.cs @@ -2770,14 +2848,13 @@ Reference.map + + database.ascx.cs + defaultUser.ascx.cs Designer - - detect.ascx.cs - Designer - theend.ascx.cs Designer diff --git a/umbraco/presentation/umbraco/LiveEditing/Controls/LiveEditingToolbar.cs b/umbraco/presentation/umbraco/LiveEditing/Controls/LiveEditingToolbar.cs index 9c501e4c56..b083076543 100644 --- a/umbraco/presentation/umbraco/LiveEditing/Controls/LiveEditingToolbar.cs +++ b/umbraco/presentation/umbraco/LiveEditing/Controls/LiveEditingToolbar.cs @@ -14,6 +14,8 @@ using umbraco.BusinessLogic.Actions; using umbraco.presentation.umbraco.controls; using ClientDependency.Core; using umbraco.IO; +using umbraco.presentation.umbraco.LiveEditing.Modules.SkinModule; +using umbraco.cms.businesslogic.skinning; namespace umbraco.presentation.LiveEditing.Controls { /// @@ -76,6 +78,16 @@ namespace umbraco.presentation.LiveEditing.Controls m_Manager.LiveEditingContext.Menu.Add(new UnpublishModule(m_Manager)); m_Manager.LiveEditingContext.Menu.Add(new DeleteModule(m_Manager)); //m_Manager.LiveEditingContext.Menu.Add(new MacroModule(m_Manager)); + + + //only add if there is a skin + nodeFactory.Node n = nodeFactory.Node.GetCurrent(); + + if(!string.IsNullOrEmpty(Skinning.GetCurrentSkinAlias(n.template)) || Skinning.HasAvailableSkins(n.template)) + { + m_Manager.LiveEditingContext.Menu.Add(new Separator()); + m_Manager.LiveEditingContext.Menu.Add(new SkinModule(m_Manager)); + } } /// diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx new file mode 100644 index 0000000000..70ed9ff41d --- /dev/null +++ b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx @@ -0,0 +1,31 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SkinCustomizer.ascx.cs" Inherits="umbraco.presentation.umbraco.LiveEditing.Modules.SkinModule.SkinCustomizer" %> + + +
> + +
+ +
+ +

... or change skin

+ + + + +
+ +
> + +
+ +
+ +

... or customize current skin

+ + + +
+ + + + diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.cs b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.cs new file mode 100644 index 0000000000..041b019fc2 --- /dev/null +++ b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.cms.businesslogic.skinning; +using System.Xml; +using System.Text; +using umbraco.interfaces.skinning; +using umbraco.IO; + +namespace umbraco.presentation.umbraco.LiveEditing.Modules.SkinModule +{ + + public partial class SkinCustomizer : System.Web.UI.UserControl + { + private Skin ActiveSkin { get; set; } + + private List sDependencies = new List(); + + protected void Page_Load(object sender, EventArgs e) + { + + + nodeFactory.Node n = nodeFactory.Node.GetCurrent(); + + ActiveSkin = Skin.CreateFromAlias(Skinning.GetCurrentSkinAlias(n.template)); + + //load dependencies + if (ActiveSkin != null) + LoadDependencies(); + else + { + //show skin selection + pCustomizeSkin.Visible = false; + ltCustomizeSkinStyle.Text = ltChangeSkinStyle.Text; + ltChangeSkinStyle.Text = string.Empty; + } + + LoadSkins(); + } + + protected void LoadSkins() + { + Guid? g = Skinning.StarterKitGuid(nodeFactory.Node.GetCurrent().template); + + + if (g == null || !Skinning.HasAvailableSkins(nodeFactory.Node.GetCurrent().template)) + { + pChangeSkin.Visible = false; + } + else + { + install.steps.Skinning.loadStarterKitDesigns ctrl = + (install.steps.Skinning.loadStarterKitDesigns)new UserControl().LoadControl(SystemDirectories.Install + "/steps/Skinning/loadStarterKitDesigns.ascx"); + ctrl.StarterKitGuid = (Guid)g; + + ph_skins.Controls.Add(ctrl); + } + + + } + + + protected void LoadDependencies() + { + ph_dependencies.Controls.Clear(); + + StringBuilder s = new StringBuilder(); + + s.Append(@" + var hasSetTasksClientScriptsRun = false; + function setTasksClientScripts(){ + if(hasSetTasksClientScriptsRun == false){"); + + + foreach (Dependency d in ActiveSkin.Dependencies) + { + if (d.DependencyType != null) + { + sDependencies.Add(d); + + ph_dependencies.Controls.Add(new LiteralControl("

")); + + Label lbl = new Label(); + + lbl.Text = d.Label; + + Control ctrl = d.DependencyType.Editor; + + lbl.AssociatedControlID = ctrl.ID; + + ph_dependencies.Controls.Add(lbl); + + ph_dependencies.Controls.Add(new LiteralControl("
")); + + ph_dependencies.Controls.Add(ctrl); + + ph_dependencies.Controls.Add(new LiteralControl("

")); + + + + foreach (Task t in d.Tasks) + { + + s.Append(t.TaskType.PreviewClientScript( + ctrl.ClientID, + d.DependencyType.ClientSidePreviewEventType(), + d.DependencyType.ClientSideGetValueScript())); + + //ScriptManager.RegisterClientScriptBlock( + // this, + // this.GetType(), + // d.Label + "_" + t.TaskType.Name, + // t.TaskType.PreviewClientScript(ctrl.ClientID,d.Properties), + // true); + + } + + + } + + + } + + s.Append("hasSetTasksClientScriptsRun = true; }}"); + + ScriptManager.RegisterClientScriptBlock( + this, + this.GetType(), + "TasksClientScripts", + s.ToString(), + true); + + } + + protected void btnOk_Click(object sender, EventArgs e) + { + ActiveSkin.SaveOutput(); + + foreach (Dependency d in sDependencies) + { + if (d.DependencyType.Values.Count > 0) + { + string output = d.DependencyType.Values[0].ToString(); + + foreach (Task t in d.Tasks) + { + TaskExecutionDetails details = t.TaskType.Execute(ParsePlaceHolders(t.Value, output)); + + if (details.TaskExecutionStatus == TaskExecutionStatus.Completed) + { + ActiveSkin.AddTaskHistoryNode( + t.TaskType.ToXml(details.OriginalValue,details.NewValue)); + } + } + } + } + + + } + + private string ParsePlaceHolders(string value,string output) + { + //parse ${Output} + value = value.Replace("${Output}", output); + + return value; + } + + protected void bt_ChangeSkin_Click(object sender, EventArgs e) + { + + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.designer.cs b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.designer.cs new file mode 100644 index 0000000000..eb9bed0f2c --- /dev/null +++ b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinCustomizer.ascx.designer.cs @@ -0,0 +1,96 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace umbraco.presentation.umbraco.LiveEditing.Modules.SkinModule { + + + public partial class SkinCustomizer { + + /// + /// ltCustomizeSkinStyle control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal ltCustomizeSkinStyle; + + /// + /// ph_dependencies control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder ph_dependencies; + + /// + /// pChangeSkin control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlGenericControl pChangeSkin; + + /// + /// btnOk control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnOk; + + /// + /// btnCancel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnCancel; + + /// + /// ltChangeSkinStyle control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal ltChangeSkinStyle; + + /// + /// ph_skins control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder ph_skins; + + /// + /// pCustomizeSkin control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlGenericControl pCustomizeSkin; + + /// + /// btnCancelSkin control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnCancelSkin; + } +} diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.cs b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.cs new file mode 100644 index 0000000000..4495351610 --- /dev/null +++ b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using umbraco.presentation.LiveEditing.Modules; +using ClientDependency.Core; +using System.Web.UI.WebControls; +using umbraco.presentation.LiveEditing.Controls; +using umbraco.IO; +using System.Web.UI; + +namespace umbraco.presentation.umbraco.LiveEditing.Modules.SkinModule +{ + [ClientDependency(200, ClientDependencyType.Javascript, "modal/modal.js", "UmbracoClient")] + [ClientDependency(200, ClientDependencyType.Css, "modal/style.css", "UmbracoClient")] + public class SkinModule : BaseModule + { + protected ImageButton m_SkinButton = new ImageButton(); + protected Panel m_SkinModal; + + + public SkinModule(LiveEditingManager manager) + : base(manager) + { } + + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + EnsureChildControls(); + + + } + + protected override void CreateChildControls() + { + base.CreateChildControls(); + + m_SkinModal = new Panel(); + m_SkinModal.ID = "LeSkinModal"; + m_SkinModal.Attributes.Add("style", "display: none"); + + m_SkinModal.Controls.Add(new UserControl().LoadControl(String.Format("{0}/LiveEditing/Modules/SKinModule/SkinCustomizer.ascx", SystemDirectories.Umbraco))); + + Controls.Add(m_SkinModal); + + m_SkinButton.ID = "LeSkinButton"; + m_SkinButton.CssClass = "button"; + m_SkinButton.ToolTip = ui.GetText("skin"); + m_SkinButton.ImageUrl = String.Format("{0}/LiveEditing/Modules/SKinModule/skin.png", SystemDirectories.Umbraco); + m_SkinButton.OnClientClick = "setTasksClientScripts();jQuery('#" + m_SkinModal.ClientID + @"').ModalWindowShow('" + ui.GetText("skin") + "',true,500,400,50,0, ['.modalbuton'], null);return false;"; + + Controls.Add(m_SkinButton); + + } + } +} \ No newline at end of file diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.js b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.js new file mode 100644 index 0000000000..ab545be481 --- /dev/null +++ b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/SkinModule.js @@ -0,0 +1 @@ +/********************* Live Editing SkinModule functions *********************/ diff --git a/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/skin.png b/umbraco/presentation/umbraco/LiveEditing/Modules/SkinModule/skin.png new file mode 100644 index 0000000000000000000000000000000000000000..ea3f06e5a688563c9425dcaebdcd355873bedbb2 GIT binary patch literal 3764 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 euj$0#e+B^I{LK$t{mZ`q0000 actions) { actions.Clear(); actions.AddRange(new IAction[] { ActionNew.Instance, ActionDelete.Instance, diff --git a/umbraco/presentation/umbraco/config/create/UI.xml b/umbraco/presentation/umbraco/config/create/UI.xml index 7fe689cb11..dd94bf49d3 100644 --- a/umbraco/presentation/umbraco/config/create/UI.xml +++ b/umbraco/presentation/umbraco/config/create/UI.xml @@ -1,4 +1,4 @@ - +
Nodetype
@@ -53,10 +53,10 @@
Page
/create/content.ascx - + -
+
Page
/create/content.ascx @@ -270,7 +270,6 @@
-
Scripting file
/create/DLRScripting.ascx @@ -278,7 +277,6 @@
-
Macro
/create/DLRScripting.ascx @@ -286,7 +284,6 @@
-
Script file
/create/script.ascx @@ -309,7 +306,6 @@
-
Package
/create/simple.ascx @@ -346,5 +342,28 @@
- -
+ +
Forms
+ /plugins/umbracocontour/createform.ascx + + + + +
+ +
Datasources
+ /create/simple.ascx + + + + +
+ +
Prevalue source
+ /create/simple.ascx + + + + +
+ \ No newline at end of file diff --git a/umbraco/presentation/umbraco/dashboard.aspx.cs b/umbraco/presentation/umbraco/dashboard.aspx.cs index c6582bc92a..c6f2a1d284 100644 --- a/umbraco/presentation/umbraco/dashboard.aspx.cs +++ b/umbraco/presentation/umbraco/dashboard.aspx.cs @@ -80,11 +80,14 @@ namespace umbraco.cms.presentation { string control = getFirstText(uc).Trim(' ', '\r', '\n'); string path = IOHelper.FindFile(control); + try { + Control c = LoadControl(path); + //resolving files from dashboard config which probably does not map to a virtual fi - tab.Controls.Add(LoadControl(path)); + tab.Controls.Add(c); } catch (Exception ee) { diff --git a/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx new file mode 100644 index 0000000000..6f336980ce --- /dev/null +++ b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx @@ -0,0 +1,9 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Applyskin.ascx.cs" Inherits="umbraco.presentation.umbraco.dashboard.Settings.Applyskin" %> + + + + + + + + \ No newline at end of file diff --git a/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.cs b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.cs new file mode 100644 index 0000000000..458293c2a1 --- /dev/null +++ b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.cms.businesslogic.skinning; +using umbraco.cms.businesslogic.template; + +namespace umbraco.presentation.umbraco.dashboard.Settings +{ + public partial class Applyskin : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + skinpicker.Items.Add("Choose..."); + foreach (Skin s in Skinning.GetAllSkins()) + { + skinpicker.Items.Add( new ListItem(s.Name, s.Alias)); + } + } + + protected void apply(object sender, EventArgs e) + { + if (skinpicker.SelectedIndex > 0) + { + Skin s = Skin.CreateFromAlias(skinpicker.SelectedValue); + Skinning.ActivateAsCurrentSkin(s); + } + } + + protected void rollback(object sender, EventArgs e) + { + Template t = Template.GetByAlias("RunwayHomepage"); + Skinning.RollbackSkin(t.Id); + } + + + } +} \ No newline at end of file diff --git a/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.designer.cs b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.designer.cs new file mode 100644 index 0000000000..c9d7cd1b76 --- /dev/null +++ b/umbraco/presentation/umbraco/dashboard/Settings/Applyskin.ascx.designer.cs @@ -0,0 +1,42 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace umbraco.presentation.umbraco.dashboard.Settings { + + + public partial class Applyskin { + + /// + /// skinpicker control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList skinpicker; + + /// + /// bt_apply control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button bt_apply; + + /// + /// bt_rollback control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button bt_rollback; + } +} diff --git a/umbraco/presentation/umbraco/editContent.aspx.cs b/umbraco/presentation/umbraco/editContent.aspx.cs index 8b4fc1ff7a..79daa051a3 100644 --- a/umbraco/presentation/umbraco/editContent.aspx.cs +++ b/umbraco/presentation/umbraco/editContent.aspx.cs @@ -18,6 +18,8 @@ using umbraco.BusinessLogic; using umbraco.presentation.preview; using umbraco.cms.businesslogic.web; using umbraco.presentation; +using umbraco.cms.businesslogic.skinning; +using System.Collections.Generic; namespace umbraco.cms.presentation { @@ -27,7 +29,7 @@ namespace umbraco.cms.presentation protected System.Web.UI.WebControls.TextBox documentName; private cms.businesslogic.web.Document _document; private bool _documentHasPublishedVersion = false; - protected System.Web.UI.WebControls.Literal jsIds; + protected System.Web.UI.WebControls.Literal jsIds; private LiteralControl dp = new LiteralControl(); private DateTimePicker dpRelease = new DateTimePicker(); private DateTimePicker dpExpire = new DateTimePicker(); @@ -35,7 +37,7 @@ namespace umbraco.cms.presentation controls.ContentControl cControl; DropDownList ddlDefaultTemplate = new DropDownList(); - + uicontrols.Pane publishProps = new uicontrols.Pane(); uicontrols.Pane linkProps = new uicontrols.Pane(); @@ -130,8 +132,12 @@ namespace umbraco.cms.presentation PlaceHolder template = new PlaceHolder(); cms.businesslogic.web.DocumentType DocumentType = new cms.businesslogic.web.DocumentType(_document.ContentType.Id); cControl.PropertiesPane.addProperty(ui.Text("documentType"), new LiteralControl(DocumentType.Text)); - cControl.PropertiesPane.addProperty(ui.Text("template"), template); + + + + //template picker + cControl.PropertiesPane.addProperty(ui.Text("template"), template); int defaultTemplate; if (_document.Template != 0) defaultTemplate = _document.Template; @@ -186,14 +192,13 @@ namespace umbraco.cms.presentation cControl.SaveToPublish += new System.EventHandler(SendToPublish); // Add panes to property page... - cControl.tpProp.Controls.AddAt(1,publishProps); - cControl.tpProp.Controls.AddAt(2,linkProps); + cControl.tpProp.Controls.AddAt(1, publishProps); + cControl.tpProp.Controls.AddAt(2, linkProps); // add preview to properties pane too addPreviewButton(cControl.tpProp.Menu, _document.Id); - } protected void Page_Load(object sender, System.EventArgs e) @@ -205,17 +210,18 @@ namespace umbraco.cms.presentation return; // clear preview cookie - if (!String.IsNullOrEmpty(StateHelper.GetCookieValue(PreviewContent.PREVIEW_COOKIE_KEY))) { + if (!String.IsNullOrEmpty(StateHelper.GetCookieValue(PreviewContent.PREVIEW_COOKIE_KEY))) + { PreviewContent.ClearPreviewCookie(); } if (!IsPostBack) { - + BusinessLogic.Log.Add(BusinessLogic.LogTypes.Open, base.getUser(), _document.Id, ""); - ClientTools.SyncTree(_document.Path, false); + ClientTools.SyncTree(_document.Path, false); } - + jsIds.Text = "var umbPageId = " + _document.Id.ToString() + ";\nvar umbVersionId = '" + _document.Version.ToString() + "';\n"; @@ -232,51 +238,56 @@ namespace umbraco.cms.presentation tp.ErrorHeader = ui.Text("errorHandling", "errorButDataWasSaved"); tp.CloseCaption = ui.Text("close"); } - } else if (Page.IsPostBack) { + } + else if (Page.IsPostBack) + { // hide validation summaries foreach (uicontrols.TabPage tp in cControl.GetPanels()) { tp.ErrorControl.Visible = false; } } - //Audit trail... - BusinessLogic.Log.Add(BusinessLogic.LogTypes.Save, base.getUser(), _document.Id, ""); + //Audit trail... + BusinessLogic.Log.Add(BusinessLogic.LogTypes.Save, base.getUser(), _document.Id, ""); - // Update name - if (_document.Text != cControl.NameTxt.Text) - { - //_refreshTree = true; - _document.Text = cControl.NameTxt.Text; - //newName.Text = _document.Text; - } + // Update name + if (_document.Text != cControl.NameTxt.Text) + { + //_refreshTree = true; + _document.Text = cControl.NameTxt.Text; + //newName.Text = _document.Text; + } - - if (dpRelease.DateTime > new DateTime(1753, 1, 1) && dpRelease.DateTime < new DateTime(9999, 12, 31)) - _document.ReleaseDate = dpRelease.DateTime; - else - _document.ReleaseDate = new DateTime(1, 1, 1, 0, 0, 0); - if (dpExpire.DateTime > new DateTime(1753, 1, 1) && dpExpire.DateTime < new DateTime(9999, 12, 31)) - _document.ExpireDate = dpExpire.DateTime; - else - _document.ExpireDate = new DateTime(1, 1, 1, 0, 0, 0); - // Update default template - if (ddlDefaultTemplate.SelectedIndex > 0) - { - _document.Template = int.Parse(ddlDefaultTemplate.SelectedValue); - } + if (dpRelease.DateTime > new DateTime(1753, 1, 1) && dpRelease.DateTime < new DateTime(9999, 12, 31)) + _document.ReleaseDate = dpRelease.DateTime; + else + _document.ReleaseDate = new DateTime(1, 1, 1, 0, 0, 0); + if (dpExpire.DateTime > new DateTime(1753, 1, 1) && dpExpire.DateTime < new DateTime(9999, 12, 31)) + _document.ExpireDate = dpExpire.DateTime; + else + _document.ExpireDate = new DateTime(1, 1, 1, 0, 0, 0); - // Run Handler - BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance); - _document.Save(); + // Update default template + if (ddlDefaultTemplate.SelectedIndex > 0) + { + _document.Template = int.Parse(ddlDefaultTemplate.SelectedValue); + } - // Update the update date - dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); + - if (!cControl.DoesPublish) - ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSavedHeader", null), ui.Text("speechBubbles", "editContentSavedText", null)); - ClientTools.SyncTree(_document.Path, true); + // Run Handler + BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance); + _document.Save(); + + // Update the update date + dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); + + if (!cControl.DoesPublish) + ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSavedHeader", null), ui.Text("speechBubbles", "editContentSavedText", null)); + + ClientTools.SyncTree(_document.Path, true); } protected void SendToPublish(object sender, System.EventArgs e) @@ -298,12 +309,13 @@ namespace umbraco.cms.presentation if (_document.PublishWithResult(base.getUser())) { + ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editContentPublishedHeader", null), ui.Text("speechBubbles", "editContentPublishedText", null)); library.UpdateDocumentCache(_document.Id); BusinessLogic.Log.Add(BusinessLogic.LogTypes.Publish, base.getUser(), _document.Id, ""); littPublishStatus.Text = ui.Text("content", "lastPublished", base.getUser()) + ": " + _document.VersionDate.ToString() + "
"; - + if (base.getUser().GetPermissions(_document.Path).IndexOf("U") > -1) UnPublish.Visible = true; @@ -317,7 +329,7 @@ namespace umbraco.cms.presentation } else ClientTools.ShowSpeechBubble(speechBubbleIcon.error, ui.Text("error"), ui.Text("speechBubbles", "editContentPublishedFailedByParent")); - + // page cache disabled... // cms.businesslogic.cache.Cache.ClearCacheObjectTypes("umbraco.page"); @@ -336,7 +348,7 @@ namespace umbraco.cms.presentation //newPublishStatus.Text = "0"; - } + } private void updateLinks() { diff --git a/umbraco/presentation/umbraco/editContent.aspx.designer.cs b/umbraco/presentation/umbraco/editContent.aspx.designer.cs index 7f1e794705..cfb5246ba7 100644 --- a/umbraco/presentation/umbraco/editContent.aspx.designer.cs +++ b/umbraco/presentation/umbraco/editContent.aspx.designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.4927 // // Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// the code is regenerated. // //------------------------------------------------------------------------------ diff --git a/umbraco/presentation/umbraco/settings/scripts/editScript.aspx.cs b/umbraco/presentation/umbraco/settings/scripts/editScript.aspx.cs index 1f4231d04e..87b1306fac 100644 --- a/umbraco/presentation/umbraco/settings/scripts/editScript.aspx.cs +++ b/umbraco/presentation/umbraco/settings/scripts/editScript.aspx.cs @@ -27,21 +27,26 @@ namespace umbraco.cms.presentation.settings.scripts protected umbraco.uicontrols.PropertyPanel pp_name; protected umbraco.uicontrols.PropertyPanel pp_path; + private string file; + protected void Page_Load(object sender, System.EventArgs e) { - String file = Request.QueryString["file"].TrimStart('/'); + NameTxt.Text = file; - //need to change the editor type if it is XML - if (file.EndsWith("xml")) - editorSource.CodeBase = umbraco.uicontrols.CodeArea.EditorType.XML; + - string path = IOHelper.ResolveUrl(SystemDirectories.Scripts + "/" + file); - + string path = ""; + if (file.StartsWith("~/")) + path = IOHelper.ResolveUrl(file); + else + path = IOHelper.ResolveUrl(SystemDirectories.Scripts + "/" + file); + + lttPath.Text = "" + path + ""; //security check... only allow script files - if (path.StartsWith(IOHelper.ResolveUrl(SystemDirectories.Scripts) + "/")) + if (path.StartsWith(IOHelper.ResolveUrl(SystemDirectories.Scripts) + "/") || path.StartsWith(IOHelper.ResolveUrl(SystemDirectories.Masterpages) + "/")) { StreamReader SR; string S; @@ -69,11 +74,50 @@ namespace umbraco.cms.presentation.settings.scripts #region Web Form Designer generated code override protected void OnInit(EventArgs e) { + + file = Request.QueryString["file"].TrimStart('/'); + + //need to change the editor type if it is XML + if (file.EndsWith("xml")) + editorSource.CodeBase = umbraco.uicontrols.CodeArea.EditorType.XML; + else if (file.EndsWith("master")) + editorSource.CodeBase = umbraco.uicontrols.CodeArea.EditorType.HTML; + uicontrols.MenuIconI save = Panel1.Menu.NewIcon(); save.ImageURL = SystemDirectories.Umbraco + "/images/editor/save.gif"; save.OnClickCommand = "doSubmit()"; save.AltText = "Save File"; - + + if (editorSource.CodeBase == uicontrols.CodeArea.EditorType.HTML) + { + // Editing buttons + Panel1.Menu.InsertSplitter(); + uicontrols.MenuIconI umbField = Panel1.Menu.NewIcon(); + umbField.ImageURL = UmbracoPath + "/images/editor/insField.gif"; + umbField.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDATA", ui.Text("template", "insertPageField"), 640, 550); + umbField.AltText = ui.Text("template", "insertPageField"); + + // TODO: Update icon + uicontrols.MenuIconI umbDictionary = Panel1.Menu.NewIcon(); + umbDictionary.ImageURL = GlobalSettings.Path + "/images/editor/dictionaryItem.gif"; + umbDictionary.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/umbracoField.aspx?objectId=" + editorSource.ClientID + "&tagName=UMBRACOGETDICTIONARY", ui.Text("template", "insertDictionaryItem"), 640, 550); + umbDictionary.AltText = "Insert umbraco dictionary item"; + + uicontrols.MenuIconI umbMacro = Panel1.Menu.NewIcon(); + umbMacro.ImageURL = UmbracoPath + "/images/editor/insMacro.gif"; + umbMacro.AltText = ui.Text("template", "insertMacro"); + umbMacro.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/dialogs/editMacro.aspx?objectId=" + editorSource.ClientID, ui.Text("template", "insertMacro"), 470, 530); + + // Help + Panel1.Menu.InsertSplitter(); + + uicontrols.MenuIconI helpIcon = Panel1.Menu.NewIcon(); + helpIcon.OnClickCommand = umbraco.BasePages.ClientTools.Scripts.OpenModalWindow(umbraco.IO.IOHelper.ResolveUrl(umbraco.IO.SystemDirectories.Umbraco) + "/settings/modals/showumbracotags.aspx?alias=" , ui.Text("template", "quickGuide"), 600, 580); + helpIcon.ImageURL = UmbracoPath + "/images/editor/help.png"; + helpIcon.AltText = ui.Text("template", "quickGuide"); + + } + this.Load += new System.EventHandler(Page_Load); InitializeComponent(); diff --git a/umbraco/presentation/umbraco/webservices/codeEditorSave.asmx.cs b/umbraco/presentation/umbraco/webservices/codeEditorSave.asmx.cs index fb9549079d..488890a069 100644 --- a/umbraco/presentation/umbraco/webservices/codeEditorSave.asmx.cs +++ b/umbraco/presentation/umbraco/webservices/codeEditorSave.asmx.cs @@ -300,22 +300,33 @@ namespace umbraco.presentation.webservices string val = contents; string returnValue = "false"; try - { - string savePath = IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename); + { + string saveOldPath = ""; + if (oldName.StartsWith("~/")) + saveOldPath = IOHelper.MapPath(oldName); + else + saveOldPath = IOHelper.MapPath(SystemDirectories.Scripts + "/" + oldName); + + string savePath = ""; + if (filename.StartsWith("~/")) + savePath = IOHelper.MapPath(filename); + else + savePath = IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename); + //Directory check.. only allow files in script dir and below to be edited - if (savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Scripts + "/"))) + if (savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Scripts + "/")) || savePath.StartsWith(IOHelper.MapPath(SystemDirectories.Masterpages + "/"))) { StreamWriter SW; - SW = File.CreateText(IOHelper.MapPath(SystemDirectories.Scripts + "/" + filename)); + SW = File.CreateText(savePath); SW.Write(val); SW.Close(); //deletes the old file - if (filename != oldName) { - string p = IOHelper.MapPath(SystemDirectories.Scripts + "/" + oldName); - if (System.IO.File.Exists(p)) - System.IO.File.Delete(p); + if (savePath != saveOldPath) + { + if (System.IO.File.Exists(saveOldPath)) + System.IO.File.Delete(saveOldPath); } returnValue = "true"; diff --git a/umbraco/presentation/umbraco_client/colorpicker/css/colorpicker.css b/umbraco/presentation/umbraco_client/colorpicker/css/colorpicker.css new file mode 100644 index 0000000000..180c6262c4 --- /dev/null +++ b/umbraco/presentation/umbraco_client/colorpicker/css/colorpicker.css @@ -0,0 +1,162 @@ +.colorpicker { + width: 356px; + height: 176px; + overflow: hidden; + position: absolute; + background: url(../images/colorpicker_background.png); + font-family: Arial, Helvetica, sans-serif; + display: none; + z-index:10020; +} +.colorpicker_color { + width: 150px; + height: 150px; + left: 14px; + top: 13px; + position: absolute; + background: #f00; + overflow: hidden; + cursor: crosshair; +} +.colorpicker_color div { + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; + background: url(../images/colorpicker_overlay.png); +} +.colorpicker_color div div { + position: absolute; + top: 0; + left: 0; + width: 11px; + height: 11px; + overflow: hidden; + background: url(../images/colorpicker_select.gif); + margin: -5px 0 0 -5px; +} +.colorpicker_hue { + position: absolute; + top: 13px; + left: 171px; + width: 35px; + height: 150px; + cursor: n-resize; +} +.colorpicker_hue div { + position: absolute; + width: 35px; + height: 9px; + overflow: hidden; + background: url(../images/colorpicker_indic.gif) left top; + margin: -4px 0 0 0; + left: 0px; +} +.colorpicker_new_color { + position: absolute; + width: 60px; + height: 30px; + left: 213px; + top: 13px; + background: #f00; +} +.colorpicker_current_color { + position: absolute; + width: 60px; + height: 30px; + left: 283px; + top: 13px; + background: #f00; +} +.colorpicker input { + background-color: transparent; + border: 1px solid transparent; + position: absolute; + font-size: 10px; + font-family: Arial, Helvetica, sans-serif; + color: #898989; + top: 4px; + right: 11px; + text-align: right; + margin: 0; + padding: 0; + height: 11px; +} +.colorpicker_hex { + position: absolute; + width: 72px; + height: 22px; + background: url(../images/colorpicker_hex.png) top; + left: 212px; + top: 142px; +} +.colorpicker_hex input { + right: 6px; +} +.colorpicker_field { + height: 22px; + width: 62px; + background-position: top; + position: absolute; +} +.colorpicker_field span { + position: absolute; + width: 12px; + height: 22px; + overflow: hidden; + top: 0; + right: 0; + cursor: n-resize; +} +.colorpicker_rgb_r { + background-image: url(../images/colorpicker_rgb_r.png); + top: 52px; + left: 212px; +} +.colorpicker_rgb_g { + background-image: url(../images/colorpicker_rgb_g.png); + top: 82px; + left: 212px; +} +.colorpicker_rgb_b { + background-image: url(../images/colorpicker_rgb_b.png); + top: 112px; + left: 212px; +} +.colorpicker_hsb_h { + background-image: url(../images/colorpicker_hsb_h.png); + top: 52px; + left: 282px; +} +.colorpicker_hsb_s { + background-image: url(../images/colorpicker_hsb_s.png); + top: 82px; + left: 282px; +} +.colorpicker_hsb_b { + background-image: url(../images/colorpicker_hsb_b.png); + top: 112px; + left: 282px; +} +.colorpicker_submit { + position: absolute; + width: 22px; + height: 22px; + background: url(../images/colorpicker_submit.png) top; + left: 322px; + top: 142px; + overflow: hidden; +} +.colorpicker_focus { + background-position: center; +} +.colorpicker_hex.colorpicker_focus { + background-position: bottom; +} +.colorpicker_submit.colorpicker_focus { + background-position: bottom; +} +.colorpicker_slider { + background-position: bottom; +} diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/blank.gif b/umbraco/presentation/umbraco_client/colorpicker/images/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b945d2553848b8b6f41fe5e24599c0687b8472 GIT binary patch literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_background.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_background.png new file mode 100644 index 0000000000000000000000000000000000000000..8401572f1939a1a24c1963513573b0194ad36ee0 GIT binary patch literal 1897 zcmY*a3pATo9RCoHhLk=v9+hya?P*IB^(tbYgf7-$bhEY|(I?UtUPi9vs#R ziy#P&{yr@fLG&2ly2iu^RFBrRRp1Ms>i=nK7%MiF8HO#xOG2 z_n6)YVr)vMq5IN*f2sWccT3)gRvu2oXh6my%^v}*O;ra5-< zrfBywZT3aSz8bWP1#@=ep&&&2r%2Xx zddEiY1@l}|b6YxdaO6Q`RJq3)wtKZi&2z5yNzot36|pnd_gApH!?MH9gq?hIkpDQ? zoi#k4#OM3Qvsl*nW+NM0+h-~TfAN~J`Np!FYfHA<4F{vc3Gd`y^@%F1#Ljo6xgBMf z>q*?e(2(gjbtEPC06P3(T2t>_N`opfT&(A|#nr9ubq;Roe8EGc50&a+@Ca&D8N&V5 zfWzVZ*wTW^c5k?}vCRiBX+63NTRRx9IULPb=kLtbG7G2PR9LSNtF=j!&s8JxkH+I- zofPjPqCAy{x*V^kY%4z8I+~=}5Ut2+RB9hQnF-=Yy8f)_*S6oz?C#RkmvpMq7QP(o zbZ!bUKi!a-F8i&JTjM>>TAUAmd?)cz-HnW2PWdWk#$QRa^0SMsE*Ei8-<`C&zPP^R zdHWR`(Q|r$)T?{(gtteqpleg1llyjZ0ZVLw8leHw(a;G~vcN1Y>6s-e44f7NN&vzO zSzky!K z<_U2aPpuI;9PaSb&;Ej+#b@gJvw)$&8ZCQ!O0HDG-5Ryk0-~ziB-tPWKJK=>?ocx|gRt#KYNSCK| zmrMW=4om~tMIU%ONCY$t9RcY(kaUNR#1=v%^?pW-QzJnZCkAr|iCQDD687K8FZ`q_ zi57h%KMX!lwtAe@@x)l}04zNB(A4Qum^BC!^1cdZ=xa=ei3OvQ+5@W08>NszykE}f zv?z;H%6*$BjvuB;iP6rpc{~#`#C$juv62eaJ-(#wzbS@&`|x8xR0#<2lFZ9l84oq~ z)RtYb1_uH_On@$HmKKWl$={|vFVC?D2S?ere)+Ii3ZCYJc1u{wg0CgRowk%p6z-vm z25al~YDe{K&MKf#`#$i4g$_`C3_gpv%r}IrbhdU7n7ws`iL~u?7mnTC+5f*Z3oqn> z!F~y5)zR3`!AmrFCO)o-qINJDjGjk AumAu6 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hex.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hex.png new file mode 100644 index 0000000000000000000000000000000000000000..4e532d7c65393fe56d7463e1da3faa591f03de84 GIT binary patch literal 532 zcmV+v0_**WP)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA2nn^@KRCwC#n6YcZKorKmBnM{5VnN~}9ReD%Nhj%)e@2UckI?wn+*F*3;85I( zxENdy>|*I~AlHjh(Li4w_e~$k1>TSMlH7e>k|a?SftQq0B8sB@e$Nc7)9DBRzVCyb z1b`q2c!CKbZg`U5o2itl0Sv%)yQM?b>-9{KyTHhep8?|QckHZYvzcW~5d<@9^YvHp ztN^T5E7MqasmZKO0Qfo_tQD_Cp^cRCbkSPY3PWmOrwUtP=mYq!XfhrH$n!kUb8V{2 z2zJb@O#p!BU0T}j_bo$O28aMq#VY1=a}K4HFOx|FxU3(vcdlc4{G^oH07wS|@(ugl zu}h2#{EpG-rzyuU{=%QDL_0lRX0#t`gyJhJT=_461{Fr^gFFz2D& z?#3}Quw7Y-ZXCZam(0MPhC`Q9H4*H#%p;?>f&5sn>j`t-77IF5&!dq`sa#4$MD?Up z1Z7s}QYx2H{U_Ho#}=1TQ65E?QgHyga(l)Q>~phW+cE0rF`i(%vV0^K=++YE{0sm& WpVhv@?^YTB0000h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4P)S5VRCwC#nn6n&K^TU=-E6Jmny{kAgHdYMnDn-IF?jG$4BqP9gMtMis0Dw8 zAV{dW=nt@ez?%dVDIU_2gRqI_5Em~-k8ZNXWV1btZa3MO4c19#+Wqh_Zf2N=;hoLQ zLzrMN$n!kVR;sFUJkQ_V-BE`=I5@}w0L!vKVQ~Q9@px!O=Q!>KBXRE#RaJ4J1Hkq5 zH74#rAmB*#N9cI-&+9?5X8Zj7{P_5|^XQH{u=yKC6vb33b$ff;+uIw9#SFtZ zJw0vcV;BZjbSqURlaVB;VRjAxerlS1&~!NI`5fVIQh?ryB; zCRH|X*Y~znJyFxHP3oeqGU3e&1O9;`*C3*9*=)dr#lP& zn<{s4fg0h-$-2z|0F15BXa1p~(a}*s5CEWXbyYJAdmo&O{#YpD48vSpURq~=HZW^z zYn4ic=lPM5k&}~?zi?i#P(>mU00>*Q=~G~A=!rx^QIxK(E{0+5@9$+<_W68FXS3cg z9in$e&*$@{Qpx;xe0;nc^Q+Ji{h4jrtW!Iut3V(?BD!Pgx=!e-({Wy>6NMqMNDj~M~n z)!GO=qQA@t;I7t2;1S(50Ji7R-H^E z;Fxt5y+yKp{*YWFP<>kUy}douSY2JE!wBfrD*F4hvVtJ@ z_xH_*L>mEXHkOx{0bprq$rczQjer>#REvv?4Nu550(w0tO-7)tlOusf;N935Ms)0f sary=%7ro}V>f{=MmOlY4Yuc{?08g~^-7;vm)Bpeg07*qoM6N<$g2&OnRsaA1 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hsb_h.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_hsb_h.png new file mode 100644 index 0000000000000000000000000000000000000000..3977ed9f21e3186eefd37b198a7cc3f8de6c69cb GIT binary patch literal 1012 zcmVh+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4dPzh1Z?xtc9W|d^8%pySrl!Jsywq01yZSfWhDafa5q;(RrSK!_25Mnz_o6R-Q8VL6wU6+%F4pRf-Q$MI@dS4=mAHh)9FT|@$~eByOWcX z!Cq-b_?cFRh?(5s;V}d2mk4K?&4-6bIBX^iheAZrO{%IS z0YIfv$z`+F(Rl#Sb=`U9^73-C*$nbL0E`QQVHk#CxMmUxbFA4+=9etvc4lVg#bpWz zInPX|)2gcCza|_G>$(mIxn`0I%UGFA#{CZCigR#qP_0(EKmY)WdwYgq^vWbf{@jo* zE^s3|JL^F2F_(#niAW>@0HNVwp65~TOfr++9V?g3RwW5{t@J$$rn?^>GJgkDFu7a~ z0J4_L6actnGO6o2dKt1Tm&@fyBr-HKgb=#EzCJrUYqeSQ+^ z@p#6tJ$H`nQONIahe-%W5W9r2sHGI!dV# zn9t`wEiLs)_< zqd%&uZ8MDk?wUrxmh*4WOQjM3lu9KVI=x0fd;SdeWoPH>w{N(;v%SrL5$IU%>swn} z&Ykoc0rTVI;o%`}Y;JDa?=Z*_rV$WDQ4~e15wPVDEf~Cg-q^s9M@L8IPO6Q7wKmq* z*8yN{ZOu_IR2l)>*Xq^PRofnVjezF$`JY}R@TxaQ3XQ;rsVRc!#0$pj@kcMZ?m6r9 i8Ue%TbFitZe+B@uIz19ZnQ%P-0000P)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA58A(JzRCwC#nn6h0U=+t+YIIeCZ8N0REt9otS9j@(Ajt5v?W7gKqX!Ee2!alT z*{jEbDCoQ>c=RY9Hf%t4)YgLZFxlE#lxYuB4{FKmYLj+{XqP4>>D<09+4?7kkiL)i zCw=+8yx$khX0s6l0a_EoFgQUFr>Ccyv)*xTdJ9d`TAin3TNEXx9h36D@HluRbgX0xZi|M`m->2&(y;zATt zUtgb2rxE!!7z{#JcW)%jt^)w9^msr~9*-v;i!CfHcs!of)m5L*$Fi&_47G}h;x`gy z*8u=lD!{P5zCN4HW;7V?-@EsXVF2Ld*VWaPbRbERt*xy_qcI!~ z@9yrBBxyFAg#ir>4MLasI!M{&seDmP)0v*(}F#R;yKycq%MgFbV-Kmy2at z6btolO5PRDr@!4Z$8p@>z3aEPu8Q|{ty*UoMyqW#X);+#XFW~m>+vyeF`IXyQO#NJ zbh~RrKwCuMN$DHKAJ?Z?3}IWn844lt{j9sYMg;ybB7j=*MBv)`?T7$s$rFKV>l!5j zc-gjXW@g6ebar)h4ST%+u)Mq+iA1Vh>;hK~hoekI)rdfi2>c2WDBo(VtgHlsL7oWA z&(HHjpvo(k$QAFtqAp4OL_n^=BM3sifqK^6t;x3f;LDd95%>>@z}MsBc8bzsTdm2i z6abo=n^j5#I^FK)FJH<8eAw7fFA-2=n(8G26ji+};bGxL%+uSO z+~1duRQyKZk=2THHElK;WdhRY=jtT_oYMBcdWk?qZ;mP?0uS5U5n4xHFiI<+dadUb l@49-4fb1urmzm6u0RTq3k6f>52*3aU002ovPDHLkV1hB)7U=*0 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_indic.gif b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_indic.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9fa95e2825eadd2d779ad270a71eddb94f94748 GIT binary patch literal 86 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 RdwKu>002ovPDHLkV1myV#+d*B literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_b.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_b.png new file mode 100644 index 0000000000000000000000000000000000000000..dfac595d017e279ff670df2c816e02d922660d9f GIT binary patch literal 970 zcmV;*12z1KP)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4P)S5VRCwC#nn6n&K^TU=-E6Jmny{kAgHdYMnDn-IF?jG$4BqP9gMtMis0Dw8 zAV{dW=nt@ez?%dVDIU_2gRqI_5Em~-k8ZNXWV1btZa3MO4c19#+Wqh_Zf2N=;hoLQ zLzrMN$n!kVR;sFUJkQ_V-BE`=I5@}w0L!vKVQ~Q9@px!O=Q!>KBXRE#RaJ4J1Hkq5 zH74#rAmB*#N9cI-&+9?5X8Zj7{P_5|^XQH{u=yKC6vb33b$ff;+uIw9#SFtZ zJw0vcV;BZjbSqURlaVB;VRjAxerlS1&~!NI`5fVIQh?ryB; zCRH|X*Y~znJyFxHP3oeqGU3e&1O9;`*C3*9*=)dr#lP& zn<{s4fg0h-$-2z|0F15BXa1p~(a}*s5CEWXbyYJAdmo&O{#YpD48vSpURq~=HZW^z zYn4ic=lPM5k&}~?zi?i#P(>mU00>*Q=~G~A=!rx^QIxK(E{0+5@9$+<_W68FXS3cg z9in$e&*$@{Qpx;xe0;nc^Q+Ji{h4jrtW!Iut3V(?BD!Pgx=!e-({Wy>6NMqMNDj~M~n z)!GO=qQA@t;I7t2;1S(50Ji7R-H^E z;Fxt5y+yKp{*YWFP<>kUy}douSY2JE!wBfrD*F4hvVtJ@ z_xH_*L>mEXHkOx{0bprq$rczQjer>#REvv?4Nu550(w0tO-7)tlOusf;N935Ms)0f sary=%7ro}V>f{=MmOlY4Yuc{?08g~^-7;vm)Bpeg07*qoM6N<$g2&OnRsaA1 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_g.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_g.png new file mode 100644 index 0000000000000000000000000000000000000000..72b32760a5c40b7ab834d176ac588750a06f13f2 GIT binary patch literal 1069 zcmV+|1k(G7P)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4vq?ljRCwC#na@w+KorMcp|EVXQK$+YM6*gzHqnN7BF59kyLV$Gkwjyn8-M%_ zE{RbNUKIZauO4)ds|T|oT-ef(s1a0_$f>a^t?r@HEtF8AJM1*eOAln2$@}v7PN(lv zVqjo^rfD!+2!cS;G+ihZOeejotBV8xi^T#a3=#mWR;yX1lO*|ym8f@!APA_W1Hk3w zB_iEkuh&r3o1~-lLnG2_dVP3!cw}V6=kpbd#Y`r1aB$FM>4rPdqTFGsf@RrABvLAs z_V)IUj*iC1$ET;KtLC7VuFaK9CiU4#0Js;$s%4Xtll%Mo+uPgi?d>#8=kxjb`T6VX zYnRih&Uxo>AeFAF`pIzskVqr~Lqpo^765pv442ErFwDvEaR>5>mzrVKEiOMUN%>sbW=d;^vxor09`ug(nG5}<=S@G^porYX_`AU~VE3z!TGDK12 zc|IHtTS-zB#k2Esx7%GV#GgQ4^p{X9P7p+z=e5~u7zO}#c6JsQ7vu3b&+`;T_4M>` z9GA&t7={6YXue?rfdBvuX|^c<5G>0+K0fLf%ChWqI(vJ2Z8lpnnM|cp%5P9_w|2W7 z>1kS1l^S-tomBpdnunPn2&bo~4-XFj(BI$hKzujU8^&M)%d(Orp*X1D81+?=O8VFB zIa!wfZPi~d9gF96vq~2P!K`gH<8pO-Jf@R=lh2dg9?y?N!gSI{gTWRNFc%T{RQW{l z*CWMo2;1uKCntz>kA*@lBG4iNxDWx@ z)`lq&7!3wLPfXOA@a^yrUm{@0H1Q<@4N1q72$V`Cvl4;&Z#A$c0u5CiPaZTH69Gx%^@W86{U8at z_Fg3dSGk-*1b!6?u~UR@?manP6sovBm$~8BD1qf>UcbEU>Hn@ zfYuw~a2Nn)W@dDT!IB76y{(>_nyMPXmk7v4umABS0u4PmVn_r&_Vpo@j@&Rtryjo2 npA4&xFA;ctuJh%cDE=M*G)vtq^hrv*00000NkvXXu0mjffA{0B literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_r.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_rgb_r.png new file mode 100644 index 0000000000000000000000000000000000000000..4855fe03f8ea8d88b4f8ae625c7958eea65208ac GIT binary patch literal 1066 zcmV+_1l9YAP)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4ut`KgRCwC#nL$e%K@`W|#$^*@2)1ijA*P`i*Vs!8o}|Yj_z@}|6buN87D4dl zS;)b(p0whp5G)M=FI7^gQ8aB#6dSZ+h!%w1Y;?1+hmFg+nRFn+=R+9LJG1n=PBo8cw>y;UEFPWHNyPjRb(ErY56GCrR=VBT=6aj^j{C z2Y}PlQ$)I5E>~4mPm+!{9%_-UkM*gkDWxt5LNprP-`}sZ^r|P&B!6Kv=J9woH#gVT z*4Ee8bGcj~5O6x38Xwfs)pPCb?dfMH0U$33`jPQ?{QUg<*V)k*x3{;YrDbbti|2U@V!3Kl zRCTj#GL@3+Y**KVSOqeE%ahy@p z>gUg%wKI(2q+et*WIMxri^U8lz0dD&5CLNmfmf=FKMMPvNFYqBzie+K(*3%>zd-~V zL;x2efZ8e(fs*tF5oi#B1`)uT2$WAXLZQ&n(GgA41VQBU`NhRWQ51QeZ*Fd`W2iq+ zC9AKVB^iPU{58STq)rq?Q52=WX&5rCK1rt=MBqOp0vDN#+vPH1T5ZUz6aegYJElaS z&+mUTFi^oE5)R`_1gbJke2G9!((xn$q9_`b2vmO6z?uluwCZ>gfvT~NFA}u zJ+zYaydY?bOazXPk7GMK??WM;=NX3ieRZYrsgLwvFbDv_U{E6+Um_sgKZCuSp8l}3 zB-f`^k&G`9D5zq6Vq!wyh%XUP9v_#Nm*vX%__#5MfK({RB``K7i(FY*Q5vx(0tHD@ z%IN4Q0E~=`C@okM0nKam@bIvv1z#c{ReS!&mk88!bHtDcymY$}N=F_r<$jdLkY231 k>i80YySoaVIYIa{0Hu_2rW%yutN;K207*qoM6N<$f_Z=6i~s-t literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_select.gif b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_select.gif new file mode 100644 index 0000000000000000000000000000000000000000..599f7f13a6854d198f501588948ffcf97bf9f365 GIT binary patch literal 78 zcmZ?wbhEHbij|08)1sO8@`> literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_submit.png b/umbraco/presentation/umbraco_client/colorpicker/images/colorpicker_submit.png new file mode 100644 index 0000000000000000000000000000000000000000..7f4c0825f53cc4faba8fc9e043502276765da1f5 GIT binary patch literal 984 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 P00000NkvXXu0mjfA`AaT literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_h.png b/umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_h.png new file mode 100644 index 0000000000000000000000000000000000000000..a217e9218e6a512b507a35e8a6141f0e56193439 GIT binary patch literal 970 zcmV;*12z1KP)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA4P)S5VRCwC#m|aK|K^(yUyEA+4?d5?fXd;=M7I&7CAQ1#X&_j>CL_YN-gn@+F zgHSIeAw>3IK|;|7L=oge5IzJ#A^0E&>G?(8=|!HGo*#L7AKu<>4|8pMd)HkZt+#{w zXC7weW^aBB|Jj-SF*9F$o1tx>E$qcMycycAC@-ZBJ@9=M1Art+Kw)425XHpaLf3nT z*o$qs(c_|+-@n%!JfIWz{MV(NRK`u1oK!3sq$xeUk30*0rTO&r;Lz}xX3Q?2XDLZ^ zNtQLm=b0`ovGcrzGy{tZJ8^M;iCsNLZ*=us&BvV@!eqi&`J(hE1%Vf=JRxLR*23X^ zHtTjcstkxmW4fX%R1Gc%0Gw!YjZb;hvts~YStk9-f%l(m0w0fy0I;#P!Y~ZOFd0Yc z6v|xg8E^fO8d9H}oln`OnfJJ7mbVJzw2DT;EXx*f%c_Y}(B({td#$~-(d7^m2>@v8 zyhBz%)<4CSQ06-3bdbu#v?m=s^TUgQAW80>SVT-DWO+Bqe^ZT5c^X^}GWW!^H|6DM z{2&`t&HcxOX}{XxtgBuQu9KfyE}VDPRTnB@)bzR0U55`X2iGIf82PEXs$7=k;M$J@ zqW{A-4Q++h&2S`|@upE=bVXp?Ee;`O5dSyi! z_6LF|n~ze5J~HYyjR0NfpC{*ZC2Op&)zJu?In|^S_t5Z|X#`9oU=$;ucVssLNp#Z) zm`1=f0;Ul#jllmj0z<=NR2qTWnkv%>>_H8 zN}^l&B27_@0BI^lKr=??RZm8DS1SN?ceNr_7}^MstN?&p_nzJCxJ2r=d!JKa1US_; z?df}&-f3JTfPWoH*RQmY%H4;rv~L($))vJGczsJ=-;&x0XvXM>ju9#M``?gN>ukHI zbY@GK!e7T#7lFRVZvo)JlL2+7ag6|%dL;F~c&F(xt`Sh)F!UJ#{5Lm80~&$3`EU8J sdf~SzMzo^mJOqtv1hQW_1cCoK0IhW09jn*o82|tP07*qoM6N<$g4YtalK=n! literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_s.png b/umbraco/presentation/umbraco_client/colorpicker/images/custom_hsb_s.png new file mode 100644 index 0000000000000000000000000000000000000000..7826b415077be23ed1b1bf05b2da62d4aa5b1c67 GIT binary patch literal 1168 zcmV;B1aJF^P)h+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA57D+@wRCwC#nQcf@Q5eUc-Fr6Onu3&AF^rild$UyX1q~x8l(L`*3O@uvFO(o; z_5wxr@*$1tgY{vMl7$6QeMqAy6e1xqkX2R|TUIxmtGu(iIrnyNAC8Ud=Dmt?_1xOS z`EYjbGoJs>o;~L|ziI4tJI8S#VLo05L|S~@48(C$eTIg-ib~hV#^6c%;`soO zlezfi8;3YL0sx8%PiTw9QdL!zm6bIwEpOSPl&u?AQj2Q*-QCgA(fXtl0Cw!$vnn?|%wceFNYM&oFvQ9@3=R%a03eJUpBbjP zxp`q)T3K1y!+W<%Hg9jJw`vg*Mw-&Q9tyNHEd`IT=#UEpqjD~4E z^RfC@Z$F3^H8z_~ryHfSWm(qgbTa*XVcv?&bj$btfnHa?*um@dDVpmsF>?L3*Xu+0 zyNG<2kdR<9neuc7gy{DU#-ng495vU+K24>ZIF9oRKKZ>NR5}3gyyPRArjJ2 zf+9GneqF87jYgx)wVGJz@o_T{>vs3KTv8sMfSye0b7#*&eJ)p4MuzH$z|-elQ6iu& zBJkq1T~TGrm!v941lAN}Dx|xuy)#M#qC|icBA~R%6M*&npp9OT#pigC=nPp5g7fdQCeDBTwIKaKxO%EOa#U(w2IzM!^(@?E$JU80&VS` zsw4ubW>b_1{D(wfc2d$OhEe0SngVs&z)y})BJlKi*ZoJ2WgLpv7LrQ@Xd0=N2vB3; zSaOMgR;yDh5zy*l)Jg<&+6m=42}FRVDYX&-MAM;h_SjzWOGMK|6M@hlJ|_?D1b{O~ zcb%xIR|gRYCCsVwSC1dqf#;_$G^l_GXhlEMv$c(piwF||u`vwu!e-l0Qj(pWefUUx zZQbpLdh413tIzMB(#G&_!c^|xjwk0X-;976L=pjnXgn@jo3O}(`?iG^i6#O_)CkmG zxeWl9>h6da$t42Xkw=pC+TE}fa*4p0M-sV20F9?}B#;Q$d%jF+*QfVdjmwBCrAMCe isv!dMU5CLC`)2?-k0%YdqHBTx0000b%7 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/images/custom_rgb_b.png b/umbraco/presentation/umbraco_client/colorpicker/images/custom_rgb_b.png new file mode 100644 index 0000000000000000000000000000000000000000..80764e5d6dd8aac3c5ef87d83b45d29780af1fe9 GIT binary patch literal 1008 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 T=Ar9_QX-DN@01`G*?mYE;P(j>ieaLJ zp1@KmP7DbnxHd5epSMZF>_Ios1X7kEzM%)`8u}mxVv)EwgAVwi+aL%gVHgVE_pQ>@ zbuG%W6jfCb)Fr3i6gRMr(1H#Un@BbTwH6Q2xnfI1$74|x z`a$b3REt~>BR!+Rjm(B~!)%yB$32-1&(IZ{4HWmQa;H~;maQBTMsJ;5 wu=L25Ib=s<$1=nh_wOs&FkN?ph+v*8l*BQUCyPMF0TmW&i*=2LJ#e`2#0~ zRsaA2j7da6RCwC#n88ZJKomvKOQ$N-q%EcB2MDDFapS&Ut2tcoJKO0Z5XR@gxT5=E@BPRC5JM(-{EmRs+wi z*>P|@#ScQvT9QAwUwvX=#Ku^(QHKpv2~+}=KqXKKR03@~kh1h#z3lU2-9S7%K9wHY zZlHd@zd1k|%qmdMx=&^ql(G#p7!3Z$L#9{gzl=qFW|hX6M^<+t`|yc1Y?-gyyEotInm#MOm!f^^y*-dYoVJ8o0wy4TmX zR?7dfn;bc9{iI8VpES5yofZaYh;TjCpK_UhilywQPp{V&o!)zNr-EuAP#7%xRC{Am z6GR!1|0e8}W%vqnuQi`zyC%VuOt~~QLec?j5=hH8t&PuqF6Zm0mDYFhgqkAab@NoR n(3#>M@3IhYo&TccjBE_r(UXjnZhw#mdW^x-)z4*}Q$iB}AxU+4 literal 0 HcmV?d00001 diff --git a/umbraco/presentation/umbraco_client/colorpicker/js/colorpicker.js b/umbraco/presentation/umbraco_client/colorpicker/js/colorpicker.js new file mode 100644 index 0000000000..10a2b2244b --- /dev/null +++ b/umbraco/presentation/umbraco_client/colorpicker/js/colorpicker.js @@ -0,0 +1,484 @@ +/** + * + * Color picker + * Author: Stefan Petre www.eyecon.ro + * + * Dual licensed under the MIT and GPL licenses + * + */ +(function ($) { + var ColorPicker = function () { + var + ids = {}, + inAction, + charMin = 65, + visible, + tpl = '
', + defaults = { + eventName: 'click', + onShow: function () {}, + onBeforeShow: function(){}, + onHide: function () {}, + onChange: function () {}, + onSubmit: function () {}, + color: 'ff0000', + livePreview: true, + flat: false + }, + fillRGBFields = function (hsb, cal) { + var rgb = HSBToRGB(hsb); + $(cal).data('colorpicker').fields + .eq(1).val(rgb.r).end() + .eq(2).val(rgb.g).end() + .eq(3).val(rgb.b).end(); + }, + fillHSBFields = function (hsb, cal) { + $(cal).data('colorpicker').fields + .eq(4).val(hsb.h).end() + .eq(5).val(hsb.s).end() + .eq(6).val(hsb.b).end(); + }, + fillHexFields = function (hsb, cal) { + $(cal).data('colorpicker').fields + .eq(0).val(HSBToHex(hsb)).end(); + }, + setSelector = function (hsb, cal) { + $(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100})); + $(cal).data('colorpicker').selectorIndic.css({ + left: parseInt(150 * hsb.s/100, 10), + top: parseInt(150 * (100-hsb.b)/100, 10) + }); + }, + setHue = function (hsb, cal) { + $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10)); + }, + setCurrentColor = function (hsb, cal) { + $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb)); + }, + setNewColor = function (hsb, cal) { + $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb)); + }, + keyDown = function (ev) { + var pressedKey = ev.charCode || ev.keyCode || -1; + if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) { + return false; + } + var cal = $(this).parent().parent(); + if (cal.data('colorpicker').livePreview === true) { + change.apply(this); + } + }, + change = function (ev) { + var cal = $(this).parent().parent(), col; + if (this.parentNode.className.indexOf('_hex') > 0) { + cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value)); + } else if (this.parentNode.className.indexOf('_hsb') > 0) { + cal.data('colorpicker').color = col = fixHSB({ + h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10), + s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10), + b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10) + }); + } else { + cal.data('colorpicker').color = col = RGBToHSB(fixRGB({ + r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10), + g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10), + b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10) + })); + } + if (ev) { + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]); + }, + blur = function (ev) { + var cal = $(this).parent().parent(); + cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus'); + }, + focus = function () { + charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65; + $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus'); + $(this).parent().addClass('colorpicker_focus'); + }, + downIncrement = function (ev) { + var field = $(this).parent().find('input').focus(); + var current = { + el: $(this).parent().addClass('colorpicker_slider'), + max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), + y: ev.pageY, + field: field, + val: parseInt(field.val(), 10), + preview: $(this).parent().parent().data('colorpicker').livePreview + }; + $(document).bind('mouseup', current, upIncrement); + $(document).bind('mousemove', current, moveIncrement); + }, + moveIncrement = function (ev) { + ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10)))); + if (ev.data.preview) { + change.apply(ev.data.field.get(0), [true]); + } + return false; + }, + upIncrement = function (ev) { + change.apply(ev.data.field.get(0), [true]); + ev.data.el.removeClass('colorpicker_slider').find('input').focus(); + $(document).unbind('mouseup', upIncrement); + $(document).unbind('mousemove', moveIncrement); + return false; + }, + downHue = function (ev) { + var current = { + cal: $(this).parent(), + y: $(this).offset().top + }; + current.preview = current.cal.data('colorpicker').livePreview; + $(document).bind('mouseup', current, upHue); + $(document).bind('mousemove', current, moveHue); + }, + moveHue = function (ev) { + change.apply( + ev.data.cal.data('colorpicker') + .fields + .eq(4) + .val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upHue = function (ev) { + fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + $(document).unbind('mouseup', upHue); + $(document).unbind('mousemove', moveHue); + return false; + }, + downSelector = function (ev) { + var current = { + cal: $(this).parent(), + pos: $(this).offset() + }; + current.preview = current.cal.data('colorpicker').livePreview; + $(document).bind('mouseup', current, upSelector); + $(document).bind('mousemove', current, moveSelector); + }, + moveSelector = function (ev) { + change.apply( + ev.data.cal.data('colorpicker') + .fields + .eq(6) + .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10)) + .end() + .eq(5) + .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upSelector = function (ev) { + fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + $(document).unbind('mouseup', upSelector); + $(document).unbind('mousemove', moveSelector); + return false; + }, + enterSubmit = function (ev) { + $(this).addClass('colorpicker_focus'); + }, + leaveSubmit = function (ev) { + $(this).removeClass('colorpicker_focus'); + }, + clickSubmit = function (ev) { + var cal = $(this).parent(); + var col = cal.data('colorpicker').color; + cal.data('colorpicker').origColor = col; + setCurrentColor(col, cal.get(0)); + cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el); + }, + show = function (ev) { + var cal = $('#' + $(this).data('colorpickerId')); + cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]); + var pos = $(this).offset(); + var viewPort = getViewport(); + var top = pos.top + this.offsetHeight; + var left = pos.left; + if (top + 176 > viewPort.t + viewPort.h) { + top -= this.offsetHeight + 176; + } + if (left + 356 > viewPort.l + viewPort.w) { + left -= 356; + } + cal.css({left: left + 'px', top: top + 'px'}); + if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) { + cal.show(); + } + $(document).bind('mousedown', {cal: cal}, hide); + return false; + }, + hide = function (ev) { + if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) { + if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) { + ev.data.cal.hide(); + } + $(document).unbind('mousedown', hide); + } + }, + isChildOf = function(parentEl, el, container) { + if (parentEl == el) { + return true; + } + if (parentEl.contains) { + return parentEl.contains(el); + } + if ( parentEl.compareDocumentPosition ) { + return !!(parentEl.compareDocumentPosition(el) & 16); + } + var prEl = el.parentNode; + while(prEl && prEl != container) { + if (prEl == parentEl) + return true; + prEl = prEl.parentNode; + } + return false; + }, + getViewport = function () { + var m = document.compatMode == 'CSS1Compat'; + return { + l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), + t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop), + w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth), + h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight) + }; + }, + fixHSB = function (hsb) { + return { + h: Math.min(360, Math.max(0, hsb.h)), + s: Math.min(100, Math.max(0, hsb.s)), + b: Math.min(100, Math.max(0, hsb.b)) + }; + }, + fixRGB = function (rgb) { + return { + r: Math.min(255, Math.max(0, rgb.r)), + g: Math.min(255, Math.max(0, rgb.g)), + b: Math.min(255, Math.max(0, rgb.b)) + }; + }, + fixHex = function (hex) { + var len = 6 - hex.length; + if (len > 0) { + var o = []; + for (var i=0; i -1) ? hex.substring(1) : hex), 16); + return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; + }, + HexToHSB = function (hex) { + return RGBToHSB(HexToRGB(hex)); + }, + RGBToHSB = function (rgb) { + var hsb = { + h: 0, + s: 0, + b: 0 + }; + var min = Math.min(rgb.r, rgb.g, rgb.b); + var max = Math.max(rgb.r, rgb.g, rgb.b); + var delta = max - min; + hsb.b = max; + if (max != 0) { + + } + hsb.s = max != 0 ? 255 * delta / max : 0; + if (hsb.s != 0) { + if (rgb.r == max) { + hsb.h = (rgb.g - rgb.b) / delta; + } else if (rgb.g == max) { + hsb.h = 2 + (rgb.b - rgb.r) / delta; + } else { + hsb.h = 4 + (rgb.r - rgb.g) / delta; + } + } else { + hsb.h = -1; + } + hsb.h *= 60; + if (hsb.h < 0) { + hsb.h += 360; + } + hsb.s *= 100/255; + hsb.b *= 100/255; + return hsb; + }, + HSBToRGB = function (hsb) { + var rgb = {}; + var h = Math.round(hsb.h); + var s = Math.round(hsb.s*255/100); + var v = Math.round(hsb.b*255/100); + if(s == 0) { + rgb.r = rgb.g = rgb.b = v; + } else { + var t1 = v; + var t2 = (255-s)*v/255; + var t3 = (t1-t2)*(h%60)/60; + if(h==360) h = 0; + if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} + else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} + else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} + else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} + else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} + else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} + else {rgb.r=0; rgb.g=0; rgb.b=0} + } + return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; + }, + RGBToHex = function (rgb) { + var hex = [ + rgb.r.toString(16), + rgb.g.toString(16), + rgb.b.toString(16) + ]; + $.each(hex, function (nr, val) { + if (val.length == 1) { + hex[nr] = '0' + val; + } + }); + return hex.join(''); + }, + HSBToHex = function (hsb) { + return RGBToHex(HSBToRGB(hsb)); + }, + restoreOriginal = function () { + var cal = $(this).parent(); + var col = cal.data('colorpicker').origColor; + cal.data('colorpicker').color = col; + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + }; + return { + init: function (opt) { + opt = $.extend({}, defaults, opt||{}); + if (typeof opt.color == 'string') { + opt.color = HexToHSB(opt.color); + } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { + opt.color = RGBToHSB(opt.color); + } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { + opt.color = fixHSB(opt.color); + } else { + return this; + } + return this.each(function () { + if (!$(this).data('colorpickerId')) { + var options = $.extend({}, opt); + options.origColor = opt.color; + var id = 'collorpicker_' + parseInt(Math.random() * 1000); + $(this).data('colorpickerId', id); + var cal = $(tpl).attr('id', id); + if (options.flat) { + cal.appendTo(this).show(); + } else { + cal.appendTo(document.body); + } + options.fields = cal + .find('input') + .bind('keyup', keyDown) + .bind('change', change) + .bind('blur', blur) + .bind('focus', focus); + cal + .find('span').bind('mousedown', downIncrement).end() + .find('>div.colorpicker_current_color').bind('click', restoreOriginal); + options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector); + options.selectorIndic = options.selector.find('div div'); + options.el = this; + options.hue = cal.find('div.colorpicker_hue div'); + cal.find('div.colorpicker_hue').bind('mousedown', downHue); + options.newColor = cal.find('div.colorpicker_new_color'); + options.currentColor = cal.find('div.colorpicker_current_color'); + cal.data('colorpicker', options); + cal.find('div.colorpicker_submit') + .bind('mouseenter', enterSubmit) + .bind('mouseleave', leaveSubmit) + .bind('click', clickSubmit); + fillRGBFields(options.color, cal.get(0)); + fillHSBFields(options.color, cal.get(0)); + fillHexFields(options.color, cal.get(0)); + setHue(options.color, cal.get(0)); + setSelector(options.color, cal.get(0)); + setCurrentColor(options.color, cal.get(0)); + setNewColor(options.color, cal.get(0)); + if (options.flat) { + cal.css({ + position: 'relative', + display: 'block' + }); + } else { + $(this).bind(options.eventName, show); + } + } + }); + }, + showPicker: function() { + return this.each( function () { + if ($(this).data('colorpickerId')) { + show.apply(this); + } + }); + }, + hidePicker: function() { + return this.each( function () { + if ($(this).data('colorpickerId')) { + $('#' + $(this).data('colorpickerId')).hide(); + } + }); + }, + setColor: function(col) { + if (typeof col == 'string') { + col = HexToHSB(col); + } else if (col.r != undefined && col.g != undefined && col.b != undefined) { + col = RGBToHSB(col); + } else if (col.h != undefined && col.s != undefined && col.b != undefined) { + col = fixHSB(col); + } else { + return this; + } + return this.each(function(){ + if ($(this).data('colorpickerId')) { + var cal = $('#' + $(this).data('colorpickerId')); + cal.data('colorpicker').color = col; + cal.data('colorpicker').origColor = col; + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + setHue(col, cal.get(0)); + setSelector(col, cal.get(0)); + setCurrentColor(col, cal.get(0)); + setNewColor(col, cal.get(0)); + } + }); + } + }; + }(); + $.fn.extend({ + ColorPicker: ColorPicker.init, + ColorPickerHide: ColorPicker.hidePicker, + ColorPickerShow: ColorPicker.showPicker, + ColorPickerSetColor: ColorPicker.setColor + }); +})(jQuery) \ No newline at end of file