From afd91f8adbad23d2b39ca4cb7b177b5be12a9131 Mon Sep 17 00:00:00 2001 From: David Peck Date: Thu, 3 Nov 2016 16:25:45 +0000 Subject: [PATCH 01/70] Added ability to only allow templates what are allowed by the document type --- .../UmbracoSettings/IWebRoutingSection.cs | 2 + .../UmbracoSettings/WebRoutingElement.cs | 9 +- src/Umbraco.Core/Models/ContentType.cs | 22 ++ src/Umbraco.Core/Models/IContentType.cs | 14 + .../WebRoutingElementDefaultTests.cs | 6 + .../config/umbracoSettings.config | 362 +++++++++--------- .../ContentFinderByNiceUrlAndTemplate.cs | 33 +- .../Routing/ContentFinderByPageIdQuery.cs | 3 +- .../Routing/PublishedContentRequestEngine.cs | 86 +++-- src/Umbraco.Web/Templates/TemplateRenderer.cs | 30 +- .../umbraco.presentation/NotFoundHandlers.cs | 15 +- src/Umbraco.Web/umbraco.presentation/page.cs | 24 +- 12 files changed, 386 insertions(+), 220 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs index 9eb6d02aa7..aedfac7aa5 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs @@ -8,6 +8,8 @@ bool DisableAlternativeTemplates { get; } + bool DisableNotPermittedAlternativeTemplates { get; } + bool DisableFindContentByIdPath { get; } bool DisableRedirectUrlTracking { get; } diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs index 82f5d46b28..35348b0338 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs @@ -1,4 +1,5 @@ -using System.Configuration; +using System; +using System.Configuration; namespace Umbraco.Core.Configuration.UmbracoSettings { @@ -21,6 +22,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings { get { return (bool) base["disableAlternativeTemplates"]; } } + + [ConfigurationProperty("disableNotPermittedAlternativeTemplates", DefaultValue = "false")] + public bool DisableNotPermittedAlternativeTemplates + { + get { return (bool)base["disableNotPermittedAlternativeTemplates"]; } + } [ConfigurationProperty("disableFindContentByIdPath", DefaultValue = "false")] public bool DisableFindContentByIdPath { diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 88c498a147..d05fc74ac8 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -98,6 +98,28 @@ namespace Umbraco.Core.Models } } + /// + /// Determines if AllowedTemplates contains templateId + /// + /// The template id to check + /// True if AllowedTemplates contains the templateId else False + public bool IsAllowedTemplate(int templateId) + { + var allowedTemplates = AllowedContentTypes ?? new ContentTypeSort[0]; + return allowedTemplates.Any(t => t.Id.Value == templateId); + } + + /// + /// Determines if AllowedTemplates contains templateId + /// + /// The template alias to check + /// True if AllowedTemplates contains the templateAlias else False + public bool IsAllowedTemplate(string templateAlias) + { + var allowedTemplates = AllowedContentTypes ?? new ContentTypeSort[0]; + return allowedTemplates.Any(t => t.Alias.Equals(templateAlias, StringComparison.InvariantCultureIgnoreCase)); + } + /// /// Sets the default template for the ContentType /// diff --git a/src/Umbraco.Core/Models/IContentType.cs b/src/Umbraco.Core/Models/IContentType.cs index 766a8eec81..356a5acccd 100644 --- a/src/Umbraco.Core/Models/IContentType.cs +++ b/src/Umbraco.Core/Models/IContentType.cs @@ -17,6 +17,20 @@ namespace Umbraco.Core.Models /// IEnumerable AllowedTemplates { get; set; } + /// + /// Determines if AllowedTemplates contains templateId + /// + /// The template id to check + /// True if AllowedTemplates contains the templateId else False + bool IsAllowedTemplate(int templateId); + + /// + /// Determines if AllowedTemplates contains templateId + /// + /// The template alias to check + /// True if AllowedTemplates contains the templateAlias else False + bool IsAllowedTemplate(string templateAlias); + /// /// Sets the default template for the ContentType /// diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs index 1e568c608e..eb27126e57 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs @@ -23,6 +23,12 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings Assert.IsTrue(SettingsSection.WebRouting.DisableAlternativeTemplates == false); } + [Test] + public void DisableNotPermittedAlternativeTemplates() + { + Assert.IsTrue(SettingsSection.WebRouting.DisableNotPermittedAlternativeTemplates == false); + } + [Test] public void DisableFindContentByIdPath() { diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 9eb3f135e9..0d0ad45d83 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -28,162 +28,163 @@ - True - - - + - - 1 - 1079 - 1080 - - - - - your@email.here - + + 1 + 1079 + 1080 + + + + + your@email.here + - - True + +True - - False + +False - - UTF8 + +UTF8 - - false + +false - - - true + + +true - - True + +True - - True + +True - - False + +False - - False + +False - - text + +text - - - In Preview Mode - click to end - ]]> + + + In Preview Mode - click to end + ]]> + - - - 1800 + + +1800 - - - - false + + + +false - - throw - - - ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,html,htm,svg,php,htaccess +throw - - Textstring - - + +ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,html,htm,svg,php,htaccess - - - true + +Textstring - - false - - - true - - + - - - false - - true - - - - - - - - - - - - - plus - star - - - ae - oe - aa - ae - oe - ue - ss - ae - oe - - - - - - + + +true - - - - true + +false - - - Mvc - + +true + + + + + +false + +true + + - + + + + + + + + + + plus + star + + + ae + oe + aa + ae + oe + ue + ss + ae + oe + - + + + + + + + + +true + + + +Mvc + - - - - cs - vb - - + + + + cs + vb + + - - - - - p - div - ul - span - - - + + p + div + ul + span + + + - - - + + + - - + + - - - true - true - - - - - - - + +true +true + + + + + + + - - - - + + + + - - - - - 0 + + + + +0 - - + - - - - - - - - - - - - - - - UsersMembershipProvider - - + + - - - - - + + + + + - + + UsersMembershipProvider + + + + + + + + + + - diff --git a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs index 246b109dea..570f0d00c5 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs @@ -22,6 +22,8 @@ namespace Umbraco.Web.Routing /// If successful, also assigns the template. public override bool TryFindContent(PublishedContentRequest docRequest) { + const string tracePrefix = "ContentFinderByNiceUrlAndTemplate: "; + IPublishedContent node = null; string path = docRequest.Uri.GetAbsolutePathDecoded(); @@ -43,7 +45,36 @@ namespace Umbraco.Web.Routing node = FindContent(docRequest, route); if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false && node != null) - docRequest.TemplateModel = template; + { + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) + { + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(node.DocumentTypeId); + if (publishedContentContentType == null) + { + LogHelper.Warn("Content type ({1}) of published content({2}) can't be fetched ={1} alias=\"{2}\"", () => tracePrefix, () => node.Id, () => node.DocumentTypeId); + } + else + { + var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); + if (isAllowedTemplate == false) + { + //If it is not allowed then default to as if no altTemplate had been supplied + LogHelper.Warn("{0}Content type '{1}' requested altTemplate of '{2}' but this is not an allowed template", () => tracePrefix, () => node.DocumentTypeAlias, () => template.Alias); + + docRequest.PublishedContent = null; + node = null; + } + else + { + docRequest.TemplateModel = template; + } + } + } + else + { + docRequest.TemplateModel = template; + } + } } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs index 4732895311..9ff3f25ae1 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs @@ -12,7 +12,8 @@ namespace Umbraco.Web.Routing public bool TryFindContent(PublishedContentRequest docRequest) { int pageId; - if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) + + if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) { var doc = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(pageId); diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs index 03a50a4b99..3acabdcbec 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs @@ -20,6 +20,7 @@ using umbraco.cms.businesslogic.member; using Umbraco.Core.Services; using Umbraco.Web.Security; using RenderingEngine = Umbraco.Core.RenderingEngine; +using Umbraco.Core.Models; namespace Umbraco.Web.Routing { @@ -630,20 +631,11 @@ namespace Umbraco.Web.Routing var templateId = _pcr.PublishedContent.TemplateId; - if (templateId > 0) - { - ProfilingLogger.Logger.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); - var template = ApplicationContext.Current.Services.FileService.GetTemplate(templateId); - if (template == null) - throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); - _pcr.TemplateModel = template; - ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); - } - else - { - ProfilingLogger.Logger.Debug("{0}No specified template.", () => tracePrefix); - } - } + // This code was moved to GetTemplateModel to allow the same functionality on a failed altTemplate (U4-8550) + // The only change is a diffent logger prefix and null will be set to _pcr.TemplateModel if the templateId is <= 0 + // rather than no set taking place + _pcr.TemplateModel = GetTemplateModel(_pcr.PublishedContent.TemplateId); + } else { // we have an alternate template specified. lookup the template with that alias @@ -657,15 +649,33 @@ namespace Umbraco.Web.Routing ProfilingLogger.Logger.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => altTemplate); var template = ApplicationContext.Current.Services.FileService.GetTemplate(altTemplate); - if (template != null) - { - _pcr.TemplateModel = template; - ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); - } - else - { - ProfilingLogger.Logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); - } + if (template != null) + { + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates) + { + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(_pcr.PublishedContent.DocumentTypeId); + if (publishedContentContentType == null) + { + ProfilingLogger.Logger.Warn("{0}Content type ({1}) of published content({2}) can't be fetched ={1} alias=\"{2}\"", () => tracePrefix, () => _pcr.PublishedContent.Id, () => _pcr.PublishedContent.DocumentTypeId); + } + else + { + var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); + if(isAllowedTemplate == false) + { + //If it is not allowed then default to as if no altTemplate had been supplied + ProfilingLogger.Logger.Warn("{0}Content type '{1}' requested altTemplate of '{2}' but this is not an allowed template", () => tracePrefix, () => _pcr.PublishedContent.DocumentTypeAlias, () => altTemplate); + template = GetTemplateModel(_pcr.PublishedContent.TemplateId); + } + } + } + _pcr.TemplateModel = template; + ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + } + else + { + ProfilingLogger.Logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); + } } if (_pcr.HasTemplate == false) @@ -687,11 +697,31 @@ namespace Umbraco.Web.Routing } } - /// - /// Follows external redirection through umbracoRedirect document property. - /// - /// As per legacy, if the redirect does not work, we just ignore it. - private void FollowExternalRedirect() + private ITemplate GetTemplateModel(int templateId) + { + const string tracePrefix = "GetTemplateModel: "; + + if (templateId > 0) + { + ProfilingLogger.Logger.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); + var template = ApplicationContext.Current.Services.FileService.GetTemplate(templateId); + if (template == null) + throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); + ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + return template; + } + else + { + ProfilingLogger.Logger.Debug("{0}No specified template.", () => tracePrefix); + } + return null; + } + + /// + /// Follows external redirection through umbracoRedirect document property. + /// + /// As per legacy, if the redirect does not work, we just ignore it. + private void FollowExternalRedirect() { if (_pcr.HasPublishedContent == false) return; diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index d7d331d887..a409e2da2b 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -80,10 +80,32 @@ namespace Umbraco.Web.Templates //set the doc that was found by id contentRequest.PublishedContent = doc; - //set the template, either based on the AltTemplate found or the standard template of the doc - contentRequest.TemplateModel = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false - ? _umbracoContext.Application.Services.FileService.GetTemplate(doc.TemplateId) - : _umbracoContext.Application.Services.FileService.GetTemplate(AltTemplate.Value); + //set the template, either based on the AltTemplate found or the standard template of the doc + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false) + { + contentRequest.TemplateModel = _umbracoContext.Application.Services.FileService.GetTemplate(doc.TemplateId); + } + else + { + var template = _umbracoContext.Application.Services.FileService.GetTemplate(AltTemplate.Value); + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == false) + { + contentRequest.TemplateModel = template; + } + else + { + //Check if we're allowed to show the selected template + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(contentRequest.PublishedContent.DocumentTypeId); + if (publishedContentContentType != null) + { + var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); + if (isAllowedTemplate == true) + { + contentRequest.TemplateModel = template; + } + } + } + } //if there is not template then exit if (!contentRequest.HasTemplate) diff --git a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs index 27e62888d4..de8483b4d0 100644 --- a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs +++ b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs @@ -281,7 +281,20 @@ namespace umbraco { { _redirectID = int.Parse(urlNode.Attributes.GetNamedItem("id").Value); - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) + var altTemplateAllowed = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false; + + //Query: Is it worth the overhead of the DB request here? The usage of AltTemplate is checked later. + if (altTemplateAllowed && UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) + { + var nodeTypeAlias = urlNode.Attributes.GetNamedItem("nodeTypeAlias").Value; + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(nodeTypeAlias); + if (publishedContentContentType != null) + { + altTemplateAllowed = publishedContentContentType.IsAllowedTemplate(templateAlias); + } + } + + if (altTemplateAllowed) { HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] = templateAlias; HttpContext.Current.Trace.Write("umbraco.altTemplateHandler", diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index e71a290754..2172be88e5 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -152,9 +152,10 @@ namespace umbraco public page(XmlNode node) { populatePageData(node); - - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) + + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) { + var templateSet = false; // Check for alternative template if (HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] != null && HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString() != String.Empty) @@ -162,16 +163,29 @@ namespace umbraco _template = umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString()); - _elements.Add("template", _template.ToString()); + templateSet = true; } else if (helper.Request(Constants.Conventions.Url.AltTemplate) != String.Empty) { _template = umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( helper.Request(Constants.Conventions.Url.AltTemplate).ToLower()); - _elements.Add("template", _template.ToString()); + templateSet = true; } - } + + if (templateSet == true && UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) + { + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(_nodeTypeAlias); + if (publishedContentContentType != null && publishedContentContentType.IsAllowedTemplate(_template)) + { + _elements.Add("template", _template.ToString()); + } + } + else if(templateSet == true) + { + _elements.Add("template", _template.ToString()); + } + } if (_template == 0) { From 69728fb5c4ac0f7737914106de01cd684461519e Mon Sep 17 00:00:00 2001 From: David Peck Date: Tue, 8 Nov 2016 08:27:18 +0000 Subject: [PATCH 02/70] Changed Allowed Templates setting to be validate templates which checks url only --- .../UmbracoSettings/IWebRoutingSection.cs | 2 +- .../UmbracoSettings/WebRoutingElement.cs | 7 ++-- src/Umbraco.Core/Models/ContentType.cs | 6 +-- .../WebRoutingElementDefaultTests.cs | 4 +- .../config/umbracoSettings.config | 11 +++-- src/Umbraco.Web/PublishedContentExtensions.cs | 39 +++++++++++++++++ .../ContentFinderByNiceUrlAndTemplate.cs | 37 ++++------------ .../Routing/PublishedContentRequestEngine.cs | 36 +++++----------- src/Umbraco.Web/Templates/TemplateRenderer.cs | 40 ++++-------------- .../umbraco.presentation/NotFoundHandlers.cs | 15 +------ src/Umbraco.Web/umbraco.presentation/page.cs | 42 +++++++------------ 11 files changed, 98 insertions(+), 141 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs index aedfac7aa5..c59d63d42e 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IWebRoutingSection.cs @@ -8,7 +8,7 @@ bool DisableAlternativeTemplates { get; } - bool DisableNotPermittedAlternativeTemplates { get; } + bool ValidateAlternativeTemplates { get; } bool DisableFindContentByIdPath { get; } diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs index 35348b0338..ed133e5f61 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/WebRoutingElement.cs @@ -23,11 +23,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings get { return (bool) base["disableAlternativeTemplates"]; } } - [ConfigurationProperty("disableNotPermittedAlternativeTemplates", DefaultValue = "false")] - public bool DisableNotPermittedAlternativeTemplates + [ConfigurationProperty("validateAlternativeTemplates", DefaultValue = "false")] + public bool ValidateAlternativeTemplates { - get { return (bool)base["disableNotPermittedAlternativeTemplates"]; } + get { return (bool)base["validateAlternativeTemplates"]; } } + [ConfigurationProperty("disableFindContentByIdPath", DefaultValue = "false")] public bool DisableFindContentByIdPath { diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index d05fc74ac8..5849fcda04 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -105,8 +105,8 @@ namespace Umbraco.Core.Models /// True if AllowedTemplates contains the templateId else False public bool IsAllowedTemplate(int templateId) { - var allowedTemplates = AllowedContentTypes ?? new ContentTypeSort[0]; - return allowedTemplates.Any(t => t.Id.Value == templateId); + var allowedTemplates = AllowedTemplates ?? new ITemplate[0]; + return allowedTemplates.Any(t => t.Id == templateId); } /// @@ -116,7 +116,7 @@ namespace Umbraco.Core.Models /// True if AllowedTemplates contains the templateAlias else False public bool IsAllowedTemplate(string templateAlias) { - var allowedTemplates = AllowedContentTypes ?? new ContentTypeSort[0]; + var allowedTemplates = AllowedTemplates ?? new ITemplate[0]; return allowedTemplates.Any(t => t.Alias.Equals(templateAlias, StringComparison.InvariantCultureIgnoreCase)); } diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs index eb27126e57..4c77fff5bc 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/WebRoutingElementDefaultTests.cs @@ -24,9 +24,9 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings } [Test] - public void DisableNotPermittedAlternativeTemplates() + public void ValidateAlternativeTemplates() { - Assert.IsTrue(SettingsSection.WebRouting.DisableNotPermittedAlternativeTemplates == false); + Assert.IsTrue(SettingsSection.WebRouting.ValidateAlternativeTemplates == false); } [Test] diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 0d0ad45d83..522da20c9c 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -302,9 +302,12 @@ will make Umbraco render the content on the current page with the template you requested, for example: http://mysite.com/about-us/?altTemplate=Home and http://mysite.com/about-us/Home would render the "About Us" page with a template with the alias Home. Setting this setting to true stops that behavior - @disableNotPermittedAlternativeTemplates - Similar to @disableAlternativeTemplates; setting this settings prevents alternative templates which have not been - permitted for the document type. Setting will not have any effect if disableNotPermittedAlternativeTemplates is set. + @validateAlternativeTemplates + By default you can add a altTemplate querystring or append a template name to the current URL which + will make Umbraco render the content on the current page with the template you requested, for example: + http://mysite.com/about-us/?altTemplate=Home and http://mysite.com/about-us/Home would render the + "About Us" page with a template with the alias Home. Setting this setting to true will ensure that + only templates that have been permitted on the document type will be allowed @disableFindContentByIdPath By default you can call any content Id in the url and show the content with that id, for example: http://mysite.com/1092 or http://mysite.com/1092.aspx would render the content with id 1092. Setting @@ -316,7 +319,7 @@ --> diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 5caa08729a..189dda4934 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -12,6 +12,7 @@ using Umbraco.Web.Models; using Umbraco.Core; using Umbraco.Web.Routing; using ContentType = umbraco.cms.businesslogic.ContentType; +using Umbraco.Core.Configuration; namespace Umbraco.Web { @@ -114,6 +115,44 @@ namespace Umbraco.Web return template == null ? string.Empty : template.Alias; } + public static bool IsTemplateAllowed(this IPublishedContent content, int templateId) + { + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == true) + return content.TemplateId == templateId; + + if (content.TemplateId != templateId && UmbracoConfig.For.UmbracoSettings().WebRouting.ValidateAlternativeTemplates == true) + { + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(content.ContentType.Id); + if (publishedContentContentType == null) + throw new NullReferenceException("No content type returned for published content (contentType='" + content.ContentType.Id + "')"); + + return publishedContentContentType.IsAllowedTemplate(templateId); + } + + return true; + } + public static bool IsTemplateAllowed(this IPublishedContent content, string templateAlias) + { + var contentTemplateAlias = content.GetTemplateAlias(); + //I assume it is enough to compare aliases, as you can not have different templates with the same alias + var matchingAlias = contentTemplateAlias.Equals(templateAlias, StringComparison.InvariantCultureIgnoreCase); + + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == true) + return matchingAlias; + + if (matchingAlias == false && UmbracoConfig.For.UmbracoSettings().WebRouting.ValidateAlternativeTemplates == true) + { + var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(content.ContentType.Id); + if (publishedContentContentType == null) + throw new NullReferenceException("No content type returned for published content (contentType='" + content.ContentType.Id + "')"); + + //This doesn't appear to be working because new templates aren't in AllowedTemplates + return publishedContentContentType.IsAllowedTemplate(templateAlias); + } + + return true; + } + #endregion #region IsComposedOf diff --git a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs index 570f0d00c5..50696f6867 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs @@ -44,36 +44,15 @@ namespace Umbraco.Web.Routing var route = docRequest.HasDomain ? (docRequest.Domain.RootNodeId.ToString() + path) : path; node = FindContent(docRequest, route); - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false && node != null) + if (node.IsTemplateAllowed(template.Id)) { - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) - { - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(node.DocumentTypeId); - if (publishedContentContentType == null) - { - LogHelper.Warn("Content type ({1}) of published content({2}) can't be fetched ={1} alias=\"{2}\"", () => tracePrefix, () => node.Id, () => node.DocumentTypeId); - } - else - { - var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); - if (isAllowedTemplate == false) - { - //If it is not allowed then default to as if no altTemplate had been supplied - LogHelper.Warn("{0}Content type '{1}' requested altTemplate of '{2}' but this is not an allowed template", () => tracePrefix, () => node.DocumentTypeAlias, () => template.Alias); - - docRequest.PublishedContent = null; - node = null; - } - else - { - docRequest.TemplateModel = template; - } - } - } - else - { - docRequest.TemplateModel = template; - } + docRequest.TemplateModel = template; + } + else + { + LogHelper.Warn("Configuration settings prevent template \"{0}\" from showing for node \"{1}\"", () => templateAlias, () => node.Id); + docRequest.PublishedContent = null; + node = null; } } else diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs index 3acabdcbec..796ef9c1ce 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs @@ -607,9 +607,8 @@ namespace Umbraco.Web.Routing // only if the published content is the initial once, else the alternate template // does not apply // + optionnally, apply the alternate template on internal redirects - var useAltTemplate = _webRoutingSection.DisableAlternativeTemplates == false - && (_pcr.IsInitialPublishedContent - || (_webRoutingSection.InternalRedirectPreservesTemplate && _pcr.IsInternalRedirectPublishedContent)); + var useAltTemplate = _pcr.IsInitialPublishedContent + || (_webRoutingSection.InternalRedirectPreservesTemplate && _pcr.IsInternalRedirectPublishedContent); string altTemplate = useAltTemplate ? _routingContext.UmbracoContext.HttpContext.Request[Constants.Conventions.Url.AltTemplate] : null; @@ -648,33 +647,18 @@ namespace Umbraco.Web.Routing ProfilingLogger.Logger.Debug("{0}Has a template already, but also an alternate template.", () => tracePrefix); ProfilingLogger.Logger.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => altTemplate); - var template = ApplicationContext.Current.Services.FileService.GetTemplate(altTemplate); - if (template != null) + if (_pcr.PublishedContent.IsTemplateAllowed(altTemplate)) { - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates) - { - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(_pcr.PublishedContent.DocumentTypeId); - if (publishedContentContentType == null) - { - ProfilingLogger.Logger.Warn("{0}Content type ({1}) of published content({2}) can't be fetched ={1} alias=\"{2}\"", () => tracePrefix, () => _pcr.PublishedContent.Id, () => _pcr.PublishedContent.DocumentTypeId); - } - else - { - var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); - if(isAllowedTemplate == false) - { - //If it is not allowed then default to as if no altTemplate had been supplied - ProfilingLogger.Logger.Warn("{0}Content type '{1}' requested altTemplate of '{2}' but this is not an allowed template", () => tracePrefix, () => _pcr.PublishedContent.DocumentTypeAlias, () => altTemplate); - template = GetTemplateModel(_pcr.PublishedContent.TemplateId); - } - } - } - _pcr.TemplateModel = template; - ProfilingLogger.Logger.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + var template = ApplicationContext.Current.Services.FileService.GetTemplate(altTemplate); + if (template != null) + _pcr.TemplateModel = template; + else + ProfilingLogger.Logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); } else { - ProfilingLogger.Logger.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => altTemplate); + LogHelper.Warn("{0}Configuration settings prevent template \"{1}\" from showing for node \"{2}\"", () => tracePrefix, () => altTemplate, () => _pcr.PublishedContent.Id); + _pcr.TemplateModel = GetTemplateModel(_pcr.PublishedContent.TemplateId); } } diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index a409e2da2b..2eb00a9c75 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -77,38 +77,16 @@ namespace Umbraco.Web.Templates { contentRequest.Culture = _umbracoContext.PublishedContentRequest.Culture; } - - //set the doc that was found by id - contentRequest.PublishedContent = doc; - //set the template, either based on the AltTemplate found or the standard template of the doc - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false) - { - contentRequest.TemplateModel = _umbracoContext.Application.Services.FileService.GetTemplate(doc.TemplateId); - } - else - { - var template = _umbracoContext.Application.Services.FileService.GetTemplate(AltTemplate.Value); - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == false) - { - contentRequest.TemplateModel = template; - } - else - { - //Check if we're allowed to show the selected template - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(contentRequest.PublishedContent.DocumentTypeId); - if (publishedContentContentType != null) - { - var isAllowedTemplate = publishedContentContentType.IsAllowedTemplate(template.Id); - if (isAllowedTemplate == true) - { - contentRequest.TemplateModel = template; - } - } - } - } - //if there is not template then exit - if (!contentRequest.HasTemplate) + //set the doc that was found by id + contentRequest.PublishedContent = doc; + //set the template, either based on the AltTemplate found or the standard template of the doc + contentRequest.TemplateModel = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false + ? _umbracoContext.Application.Services.FileService.GetTemplate(doc.TemplateId) + : _umbracoContext.Application.Services.FileService.GetTemplate(AltTemplate.Value); + + //if there is not template then exit + if (!contentRequest.HasTemplate) { if (!AltTemplate.HasValue) { diff --git a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs index de8483b4d0..27e62888d4 100644 --- a/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs +++ b/src/Umbraco.Web/umbraco.presentation/NotFoundHandlers.cs @@ -281,20 +281,7 @@ namespace umbraco { { _redirectID = int.Parse(urlNode.Attributes.GetNamedItem("id").Value); - var altTemplateAllowed = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false; - - //Query: Is it worth the overhead of the DB request here? The usage of AltTemplate is checked later. - if (altTemplateAllowed && UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) - { - var nodeTypeAlias = urlNode.Attributes.GetNamedItem("nodeTypeAlias").Value; - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(nodeTypeAlias); - if (publishedContentContentType != null) - { - altTemplateAllowed = publishedContentContentType.IsAllowedTemplate(templateAlias); - } - } - - if (altTemplateAllowed) + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) { HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] = templateAlias; HttpContext.Current.Trace.Write("umbraco.altTemplateHandler", diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index 2172be88e5..ed4254198e 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -152,42 +152,28 @@ namespace umbraco public page(XmlNode node) { populatePageData(node); - - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) - { - var templateSet = false; - // Check for alternative template - if (HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] != null && - HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString() != String.Empty) - { - _template = - umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( - HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString()); - templateSet = true; - } - else if (helper.Request(Constants.Conventions.Url.AltTemplate) != String.Empty) - { - _template = - umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( - helper.Request(Constants.Conventions.Url.AltTemplate).ToLower()); - templateSet = true; - } - if (templateSet == true && UmbracoConfig.For.UmbracoSettings().WebRouting.DisableNotPermittedAlternativeTemplates == true) + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) + { + // Check for alternative template + if (HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] != null && + HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString() != String.Empty) { - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(_nodeTypeAlias); - if (publishedContentContentType != null && publishedContentContentType.IsAllowedTemplate(_template)) - { - _elements.Add("template", _template.ToString()); - } + _template = + umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( + HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString()); + _elements.Add("template", _template.ToString()); } - else if(templateSet == true) + else if (helper.Request(Constants.Conventions.Url.AltTemplate) != String.Empty) { + _template = + umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( + helper.Request(Constants.Conventions.Url.AltTemplate).ToLower()); _elements.Add("template", _template.ToString()); } } - if (_template == 0) + if (_template == 0) { try { From a031551fb2ba734b2a40be2e42a1720617ad2fa0 Mon Sep 17 00:00:00 2001 From: David Peck Date: Tue, 8 Nov 2016 17:59:30 +0000 Subject: [PATCH 03/70] Rationalised changes in whitespace, to reduce the differences in the PR --- .../config/umbracoSettings.config | 357 +++++++++--------- src/Umbraco.Web/PublishedContentExtensions.cs | 4 +- .../Routing/ContentFinderByPageIdQuery.cs | 3 +- .../Routing/PublishedContentRequestEngine.cs | 2 +- src/Umbraco.Web/Templates/TemplateRenderer.cs | 14 +- src/Umbraco.Web/umbraco.presentation/page.cs | 38 +- 6 files changed, 208 insertions(+), 210 deletions(-) diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 522da20c9c..3b037fa6f0 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -28,163 +28,162 @@ -True - - - + - - 1 - 1079 - 1080 - - - - - your@email.here - + + 1 + 1079 + 1080 + + + + + your@email.here + - -True + + True - -False + + False - -UTF8 + + UTF8 - -false + + false - - -true + + + true - -True + + True - -True + + True - -False + + False - -False + + False - -text + + text - - - In Preview Mode - click to end - ]]> - + + + In Preview Mode - click to end + ]]> - - -1800 + + + 1800 - - - -false + + + + false - -throw + throw + + + ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,html,htm,svg,php,htaccess - -ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,html,htm,svg,php,htaccess + + Textstring + + - -Textstring + + + true - + + false + + + true + + - - -true + + + false + + true + + - + + + + + + + + + + plus + star + + + ae + oe + aa + ae + oe + ue + ss + ae + oe + - + + + + - -false + + + + true - -true - - - - - -false - -true - - - - - - - - - - - - - plus - star - - - ae - oe - aa - ae - oe - ue - ss - ae - oe - - - - - - - - - - -true - - - -Mvc - + + + Mvc + - - - - cs - vb - - + + + + cs + vb + + - - - - - p - div - ul - span - - - + + p + div + ul + span + + + - - - + + + - - + + - - -true -true - - - - - - - + + true + true + + + + + + + - - - - + + + + - - - - -0 + + + + + 0 - - + - + + + + + + + + + - - + + + + + UsersMembershipProvider + + - - - - - + + + + + - - - - - UsersMembershipProvider - - - - - - - - - - - diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 189dda4934..c08de157b9 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -5,14 +5,14 @@ using System.Globalization; using System.Linq; using System.Web; using Examine.LuceneEngine.SearchCriteria; +using Umbraco.Core; +using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web.Models; -using Umbraco.Core; using Umbraco.Web.Routing; using ContentType = umbraco.cms.businesslogic.ContentType; -using Umbraco.Core.Configuration; namespace Umbraco.Web { diff --git a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs index 9ff3f25ae1..4732895311 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByPageIdQuery.cs @@ -12,8 +12,7 @@ namespace Umbraco.Web.Routing public bool TryFindContent(PublishedContentRequest docRequest) { int pageId; - - if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) + if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) { var doc = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(pageId); diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs index 796ef9c1ce..4f40af4b59 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Security; using umbraco; @@ -20,7 +21,6 @@ using umbraco.cms.businesslogic.member; using Umbraco.Core.Services; using Umbraco.Web.Security; using RenderingEngine = Umbraco.Core.RenderingEngine; -using Umbraco.Core.Models; namespace Umbraco.Web.Routing { diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index 2eb00a9c75..d7d331d887 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -77,16 +77,16 @@ namespace Umbraco.Web.Templates { contentRequest.Culture = _umbracoContext.PublishedContentRequest.Culture; } - - //set the doc that was found by id - contentRequest.PublishedContent = doc; - //set the template, either based on the AltTemplate found or the standard template of the doc - contentRequest.TemplateModel = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false + + //set the doc that was found by id + contentRequest.PublishedContent = doc; + //set the template, either based on the AltTemplate found or the standard template of the doc + contentRequest.TemplateModel = UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false ? _umbracoContext.Application.Services.FileService.GetTemplate(doc.TemplateId) : _umbracoContext.Application.Services.FileService.GetTemplate(AltTemplate.Value); - //if there is not template then exit - if (!contentRequest.HasTemplate) + //if there is not template then exit + if (!contentRequest.HasTemplate) { if (!AltTemplate.HasValue) { diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index ed4254198e..e71a290754 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -153,27 +153,27 @@ namespace umbraco { populatePageData(node); - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) - { + if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == false) + { // Check for alternative template - if (HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] != null && - HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString() != String.Empty) - { - _template = - umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( - HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString()); - _elements.Add("template", _template.ToString()); - } - else if (helper.Request(Constants.Conventions.Url.AltTemplate) != String.Empty) - { - _template = - umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( - helper.Request(Constants.Conventions.Url.AltTemplate).ToLower()); - _elements.Add("template", _template.ToString()); - } - } + if (HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate] != null && + HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString() != String.Empty) + { + _template = + umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( + HttpContext.Current.Items[Constants.Conventions.Url.AltTemplate].ToString()); + _elements.Add("template", _template.ToString()); + } + else if (helper.Request(Constants.Conventions.Url.AltTemplate) != String.Empty) + { + _template = + umbraco.cms.businesslogic.template.Template.GetTemplateIdFromAlias( + helper.Request(Constants.Conventions.Url.AltTemplate).ToLower()); + _elements.Add("template", _template.ToString()); + } + } - if (_template == 0) + if (_template == 0) { try { From a2611ce35f7335e6d62ec64aa67c88c29fa38f60 Mon Sep 17 00:00:00 2001 From: David Peck Date: Tue, 30 May 2017 22:39:26 +0100 Subject: [PATCH 04/70] Changed the name of IsTemplateAllowed to IsAllowedTemplate to reflect the usage elsewhere and changed the overload of IsAllowedTemplate with the alias parameter to use the template id version to be more DRY --- src/Umbraco.Web/PublishedContentExtensions.cs | 26 +++++-------------- .../ContentFinderByNiceUrlAndTemplate.cs | 2 +- .../Routing/PublishedContentRequestEngine.cs | 2 +- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index c08de157b9..b75547fca0 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -115,7 +115,7 @@ namespace Umbraco.Web return template == null ? string.Empty : template.Alias; } - public static bool IsTemplateAllowed(this IPublishedContent content, int templateId) + public static bool IsAllowedTemplate(this IPublishedContent content, int templateId) { if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == true) return content.TemplateId == templateId; @@ -131,26 +131,14 @@ namespace Umbraco.Web return true; } - public static bool IsTemplateAllowed(this IPublishedContent content, string templateAlias) + public static bool IsAllowedTemplate(this IPublishedContent content, string templateAlias) { - var contentTemplateAlias = content.GetTemplateAlias(); - //I assume it is enough to compare aliases, as you can not have different templates with the same alias - var matchingAlias = contentTemplateAlias.Equals(templateAlias, StringComparison.InvariantCultureIgnoreCase); + var template = ApplicationContext.Current.Services.FileService.GetTemplate(templateAlias); + var isAllowedTemplate = (template != null) ? + content.IsAllowedTemplate(template.Id) : + false; - if (UmbracoConfig.For.UmbracoSettings().WebRouting.DisableAlternativeTemplates == true) - return matchingAlias; - - if (matchingAlias == false && UmbracoConfig.For.UmbracoSettings().WebRouting.ValidateAlternativeTemplates == true) - { - var publishedContentContentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(content.ContentType.Id); - if (publishedContentContentType == null) - throw new NullReferenceException("No content type returned for published content (contentType='" + content.ContentType.Id + "')"); - - //This doesn't appear to be working because new templates aren't in AllowedTemplates - return publishedContentContentType.IsAllowedTemplate(templateAlias); - } - - return true; + return isAllowedTemplate; } #endregion diff --git a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs index 50696f6867..f19886c4f2 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByNiceUrlAndTemplate.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.Routing var route = docRequest.HasDomain ? (docRequest.Domain.RootNodeId.ToString() + path) : path; node = FindContent(docRequest, route); - if (node.IsTemplateAllowed(template.Id)) + if (node.IsAllowedTemplate(template.Id)) { docRequest.TemplateModel = template; } diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs index 4f40af4b59..5ab62137ee 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs @@ -647,7 +647,7 @@ namespace Umbraco.Web.Routing ProfilingLogger.Logger.Debug("{0}Has a template already, but also an alternate template.", () => tracePrefix); ProfilingLogger.Logger.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => altTemplate); - if (_pcr.PublishedContent.IsTemplateAllowed(altTemplate)) + if (_pcr.PublishedContent.IsAllowedTemplate(altTemplate)) { var template = ApplicationContext.Current.Services.FileService.GetTemplate(altTemplate); if (template != null) From ebae69d00cb29a7e3dc028d3fc09eb141542dd7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20=C3=96hman?= Date: Sun, 11 Feb 2018 16:58:46 +0100 Subject: [PATCH 05/70] U4-10962 - Disable stickyheader when nested, fix margins when disabled --- .../components/umbstickybar.directive.js | 5 +++++ .../subheader/umb-editor-sub-header.less | 22 ++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbstickybar.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbstickybar.directive.js index 91a0a41a10..e8d8315b7a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbstickybar.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbstickybar.directive.js @@ -50,6 +50,11 @@ Use this directive make an element sticky and follow the page when scrolling. function activate() { + if (bar.parents(".umb-property").length > 1) { + bar.addClass("nested"); + return; + } + if (attr.scrollableContainer) { scrollableContainer = $(attr.scrollableContainer); } else { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor/subheader/umb-editor-sub-header.less b/src/Umbraco.Web.UI.Client/src/less/components/editor/subheader/umb-editor-sub-header.less index b94055a0d2..fb71016f90 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor/subheader/umb-editor-sub-header.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor/subheader/umb-editor-sub-header.less @@ -1,12 +1,18 @@ .umb-editor-sub-header { - padding: 15px 0; - margin-bottom: 30px; - background: @white; - display: flex; - justify-content: space-between; - margin-top: -30px; - position: relative; - top: 0; + padding: 15px 0; + margin-bottom: 30px; + background: @white; + display: flex; + justify-content: space-between; + margin-top: -30px; + position: relative; + top: 0; + + &.nested { + margin-top: 0; + margin-bottom: 0; + background: @gray-10; + } } .umb-editor-sub-header.-umb-sticky-bar { From 5bfac6c5b484cd1fc8db5959feb2357d883fe616 Mon Sep 17 00:00:00 2001 From: Maciej Sadowski Date: Tue, 27 Feb 2018 09:23:35 +0100 Subject: [PATCH 06/70] fix x alignment in colorpicker in umbraco skin --- .../lib/tinymce/skins/umbraco/skin.min.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css index c17e10b917..6fa010bce0 100755 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css +++ b/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css @@ -1 +1 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{float:right;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:center;padding:2px}.mce-charmap td:hover{background:#d9d9d9}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{position:absolute;top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-colorbutton{position:relative}.mce-colorbutton .mce-preview{display:block;position:absolute;left:50%;top:50%;margin-left:-8px;margin-top:7px;background:gray;width:16px;height:2px;overflow:hidden}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border-color:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-listbox span{width:100%;display:block;overflow:hidden}.mce-menu-item{display:block;padding:6px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 20px 0 20px}.mce-menu-item .mce-caret{margin-top:6px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub{margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:normal;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-inserttime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e026"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB}.mce-i-tablerowprops:before{content:"\e604"}.mce-i-tablecellprops:before{content:"\e605"}.mce-i-table2:before{content:"\e606"}.mce-i-tablemergecells:before{content:"\e607"}.mce-i-tableinsertcolbefore:before{content:"\e608"}.mce-i-tableinsertcolafter:before{content:"\e609"}.mce-i-tableinsertrowbefore:before{content:"\e60a"}.mce-i-tableinsertrowafter:before{content:"\e60b"}.mce-i-tablesplitcells:before{content:"\e60d"}.mce-i-tabledelete:before{content:"\e60e"}.mce-i-tableleftheader:before{content:"\e62a"}.mce-i-tabletopheader:before{content:"\e62b"}.mce-i-tabledeleterow:before{content:"\e800"}.mce-i-tabledeletecol:before{content:"\e801"} \ No newline at end of file +.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{float:right;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:center;padding:2px}.mce-charmap td:hover{background:#d9d9d9}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{position:absolute;top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-colorbutton{position:relative}.mce-colorbutton .mce-preview{display:block;position:absolute;left:50%;top:50%;margin-left:-8px;margin-top:7px;background:gray;width:16px;height:2px;overflow:hidden}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border-color:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-listbox span{width:100%;display:block;overflow:hidden}.mce-menu-item{display:block;padding:6px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 20px 0 20px}.mce-menu-item .mce-caret{margin-top:6px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub{margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:normal;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-inserttime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e026"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB}.mce-i-tablerowprops:before{content:"\e604"}.mce-i-tablecellprops:before{content:"\e605"}.mce-i-table2:before{content:"\e606"}.mce-i-tablemergecells:before{content:"\e607"}.mce-i-tableinsertcolbefore:before{content:"\e608"}.mce-i-tableinsertcolafter:before{content:"\e609"}.mce-i-tableinsertrowbefore:before{content:"\e60a"}.mce-i-tableinsertrowafter:before{content:"\e60b"}.mce-i-tablesplitcells:before{content:"\e60d"}.mce-i-tabledelete:before{content:"\e60e"}.mce-i-tableleftheader:before{content:"\e62a"}.mce-i-tabletopheader:before{content:"\e62b"}.mce-i-tabledeleterow:before{content:"\e800"}.mce-i-tabledeletecol:before{content:"\e801"}.mce-colorbtn-trans div{text-align: center;vertical-align: middle;font-weight: bold;font-size: 20px;line-height: 16px;color: #707070;}.mce-grid td.mce-grid-cell div{border: 1px solid #d6d6d6;width: 15px;height: 15px;margin: 0;cursor: pointer;} \ No newline at end of file From 71d3c1112efb6d708440834bc2c49094bc2c2219 Mon Sep 17 00:00:00 2001 From: Steve Fawcett Date: Tue, 27 Feb 2018 17:48:53 +0000 Subject: [PATCH 07/70] Fix: TinyMCE overlay was showing in front of login overlay --- src/Umbraco.Web.UI.Client/src/less/pages/login.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/pages/login.less b/src/Umbraco.Web.UI.Client/src/less/pages/login.less index 5443134dd2..c33862d515 100644 --- a/src/Umbraco.Web.UI.Client/src/less/pages/login.less +++ b/src/Umbraco.Web.UI.Client/src/less/pages/login.less @@ -5,7 +5,7 @@ width: 100%; height: 100%; position: absolute; - z-index: 10000; + z-index: 65537; top: 0; left: 0; margin: 0 !important; From 13f42773d73c66a22674e4c2de15737962c6af74 Mon Sep 17 00:00:00 2001 From: Peter Duncanson Date: Tue, 6 Mar 2018 17:02:16 +0000 Subject: [PATCH 08/70] Added web.config to fonts folder to allow for caching out of the box --- src/Umbraco.Web.UI.Client/src/assets/fonts/web.config | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/assets/fonts/web.config diff --git a/src/Umbraco.Web.UI.Client/src/assets/fonts/web.config b/src/Umbraco.Web.UI.Client/src/assets/fonts/web.config new file mode 100644 index 0000000000..42051b6de2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/fonts/web.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 38e9a3d2eef332ce3fdeec2f51621969be9367d9 Mon Sep 17 00:00:00 2001 From: Nathalie Festin Date: Sun, 11 Mar 2018 20:41:51 +0100 Subject: [PATCH 09/70] Bug in exclude - Dialogoption.filter --- .../treepicker/treepicker.controller.js | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index b7512e1e8c..215b363eb6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -20,16 +20,16 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", selectedSearchResults: [] } - $scope.model.selection = []; - - //Used for toggling an empty-state message + $scope.model.selection = []; + + //Used for toggling an empty-state message //Some trees can have no items (dictionary & forms email templates) $scope.hasItems = true; - $scope.emptyStateMessage = dialogOptions.emptyStateMessage; - + $scope.emptyStateMessage = dialogOptions.emptyStateMessage; - //This is called from ng-init - //it turns out it is called from the angular html : / Have a look at views/common / overlays / contentpicker / contentpicker.html you'll see ng-init. + + //This is called from ng-init + //it turns out it is called from the angular html : / Have a look at views/common / overlays / contentpicker / contentpicker.html you'll see ng-init. //this is probably an anti pattern IMO and shouldn't be used $scope.init = function (contentType) { @@ -109,7 +109,8 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", else { if (dialogOptions.filter.startsWith("!")) { dialogOptions.filterExclude = true; - dialogOptions.filter = dialogOptions.filter.substring(1); + //dialogOptions.filter = dialogOptions.filter.substring(1); // Can't substring the value on dialogoptions.filter as it then keeps it's modified value next time the dialog opens + dialogOptions.filterTypes = dialogOptions.filter.substring(1); } //used advanced filtering @@ -157,8 +158,8 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", //gets the tree object when it loads function treeLoadedHandler(ev, args) { - //args.tree contains children (args.tree.root.children) - $scope.hasItems = args.tree.root.children.length > 0; + //args.tree contains children (args.tree.root.children) + $scope.hasItems = args.tree.root.children.length > 0; tree = args.tree; } @@ -215,7 +216,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", icon: "icon-folder", id: id, name: text - }; + }; if ($scope.multiPicker) { if (entity) { @@ -315,7 +316,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", } }); } else { - var a = dialogOptions.filter.toLowerCase().replace(/\s/g, '').split(','); + var a = dialogOptions.filterTypes.toLowerCase().replace(/\s/g, '').split(','); angular.forEach(nodes, function (value, key) { var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0; From 4512cf0145ac3519771658357eca403c2fc9034f Mon Sep 17 00:00:00 2001 From: Nathalie Festin Date: Sun, 11 Mar 2018 20:49:43 +0100 Subject: [PATCH 10/70] Filtering items 'Allow items of type' in mini list view in MNTP --- .../components/umbminilistview.directive.js | 22 ++++++++++++++++--- .../src/less/listview.less | 4 ++++ .../treepicker/treepicker.controller.js | 16 +++++++++----- .../overlays/treepicker/treepicker.html | 7 +++--- .../views/components/umb-mini-list-view.html | 4 ++-- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbminilistview.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbminilistview.directive.js index ce14aaedc5..1cf934b78c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbminilistview.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbminilistview.directive.js @@ -8,7 +8,7 @@ scope.search = ""; scope.miniListViews = []; scope.breadcrumb = []; - + var miniListViewsHistory = []; var goingForward = true; var skipAnimation = true; @@ -60,9 +60,13 @@ entityResource.getPagedChildren(miniListView.node.id, scope.entityType, miniListView.pagination) .then(function (data) { + // update children miniListView.children = data.items; _.each(miniListView.children, function(c) { + // child allowed by default + c.allowed = true; + // convert legacy icon for node if(c.icon) { c.icon = iconHelper.convertFromLegacyIcon(c.icon); @@ -74,6 +78,17 @@ c.published = c.metaData.IsPublished; } } + + // filter items if there is a filter and it's not advanced + // ** ignores advanced filter at the moment + if (scope.entityTypeFilter && !scope.entityTypeFilter.filterAdvanced) { + var a = scope.entityTypeFilter.filter.toLowerCase().replace(/\s/g, '').split(','); + var found = a.indexOf(c.metaData.ContentTypeAlias.toLowerCase()) >= 0; + + if (!scope.entityTypeFilter.filterExclude && !found || scope.entityTypeFilter.filterExclude && found) { + c.allowed = false; + } + } }); // update pagination miniListView.pagination.totalItems = data.totalItems; @@ -89,7 +104,7 @@ }; scope.selectNode = function(node) { - if(scope.onSelect) { + if (scope.onSelect && node.allowed) { scope.onSelect({'node': node}); } }; @@ -202,7 +217,8 @@ entityType: "@", startNodeId: "=", onSelect: "&", - onClose: "&" + onClose: "&", + entityTypeFilter: "=" }, link: link }; diff --git a/src/Umbraco.Web.UI.Client/src/less/listview.less b/src/Umbraco.Web.UI.Client/src/less/listview.less index d2393efb11..284de6e844 100644 --- a/src/Umbraco.Web.UI.Client/src/less/listview.less +++ b/src/Umbraco.Web.UI.Client/src/less/listview.less @@ -157,6 +157,10 @@ /* TEMP */ +.umb-minilistview { + .umb-table-row.not-allowed { opacity: 0.6; cursor: not-allowed; } +} + .umb-listview .table-striped tbody td { position: relative } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index 215b363eb6..e0b5689b72 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -83,11 +83,11 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", //if a alternative startnode is used, we need to check if it is a container if ($scope.enableSearh && dialogOptions.startNodeId && dialogOptions.startNodeId !== -1 && dialogOptions.startNodeId !== "-1") { entityResource.getById(dialogOptions.startNodeId, $scope.entityType).then(function(node) { - if (node.metaData.IsContainer) { - openMiniListView(node); - } - initTree(); - }); + if (node.metaData.IsContainer) { + openMiniListView(node); + } + initTree(); + }); } else { initTree(); @@ -120,6 +120,12 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", dialogOptions.filter = angular.fromJson(dialogOptions.filter); } } + + $scope.filter = { + filterAdvanced: dialogOptions.filterAdvanced, + filterExclude: dialogOptions.filterExclude, + filter: dialogOptions.filterTypes + }; } function initTree() { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html index ab5e61339f..a3a5fd6107 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html @@ -22,7 +22,7 @@ {{ emptyStateMessage }} - +
+ on-close="closeMiniListView()" + entity-type-filter="filter"> -
\ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-mini-list-view.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-mini-list-view.html index 9959d7b345..90a72d117e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-mini-list-view.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-mini-list-view.html @@ -1,4 +1,4 @@ -
+
@@ -61,7 +61,7 @@
+ ng-class="{'-selected':child.selected, 'not-allowed':!child.allowed}">
  From f5b017ed6794be587a9db08542b2c25bad57ee40 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Sat, 11 Nov 2017 21:01:47 +0100 Subject: [PATCH 11/70] Updates sql to include current schema in queries --- .../SqlSyntax/SqlServerSyntaxProvider.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 6cc97bdfb3..e5112cee49 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -68,19 +68,19 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// public IEnumerable> GetDefaultConstraintsPerColumn(Database db) { - var items = db.Fetch("SELECT TableName = t.Name,ColumnName = c.Name,dc.Name,dc.[Definition] FROM sys.tables t INNER JOIN sys.default_constraints dc ON t.object_id = dc.parent_object_id INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND c.column_id = dc.parent_column_id"); + var items = db.Fetch("SELECT TableName = t.Name, ColumnName = c.Name, dc.Name, dc.[Definition] FROM sys.tables t INNER JOIN sys.default_constraints dc ON t.object_id = dc.parent_object_id INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND c.column_id = dc.parent_column_id INNER JOIN sys.schemas as s on t.[schema_id] = s.[schema_id] WHERE s.name = (SELECT SCHEMA_NAME())"); return items.Select(x => new Tuple(x.TableName, x.ColumnName, x.Name, x.Definition)); } public override IEnumerable GetTablesInSchema(Database db) { - var items = db.Fetch("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"); + var items = db.Fetch("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT SCHEMA_NAME())"); return items.Select(x => x.TABLE_NAME).Cast().ToList(); } public override IEnumerable GetColumnsInSchema(Database db) { - var items = db.Fetch("SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS"); + var items = db.Fetch("SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = (SELECT SCHEMA_NAME())"); return items.Select( item => @@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax { var items = db.Fetch( - "SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE"); + "SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE WHERE TABLE_SCHEMA = (SELECT SCHEMA_NAME())"); return items.Select(item => new Tuple(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList(); } @@ -100,7 +100,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax { var items = db.Fetch( - "SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE"); + "SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE TABLE_SCHEMA = (SELECT SCHEMA_NAME())"); return items.Select(item => new Tuple(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList(); } @@ -113,7 +113,8 @@ CASE WHEN I.is_unique_constraint = 1 OR I.is_unique = 1 THEN 1 ELSE 0 END AS [U from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id] inner join sys.index_columns as IC on IC.[object_id] = I.[object_id] and IC.[index_id] = I.[index_id] inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id] -WHERE I.name NOT LIKE 'PK_%' + inner join sys.schemas as S on T.[schema_id] = S.[schema_id] +WHERE S.name = (SELECT SCHEMA_NAME()) AND I.name NOT LIKE 'PK_%' order by T.name, I.name"); return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1)).ToList(); @@ -123,7 +124,7 @@ order by T.name, I.name"); public override bool DoesTableExist(Database db, string tableName) { var result = - db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName", + db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName AND TABLE_SCHEMA = (SELECT SCHEMA_NAME())", new { TableName = tableName }); return result > 0; @@ -180,7 +181,5 @@ order by T.name, I.name"); public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } } public override string RenameColumn { get { return "sp_rename '{0}.{1}', '{2}', 'COLUMN'"; } } - - } } \ No newline at end of file From 0a2fd277a6a4f80a128582e469a67085bd82dc76 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 28 Jun 2018 19:54:42 +0100 Subject: [PATCH 12/70] U4-11166 Hide disabled users from the users list view --- src/Umbraco.Web/Editors/UsersController.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index f1670df346..64ebf1703f 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -241,6 +241,11 @@ namespace Umbraco.Web.Editors filterQuery.Where(x => x.Name.Contains(filter) || x.Username.Contains(filter)); } + if (UmbracoConfig.For.UmbracoSettings().Security.HideDisabledUsersInBackoffice) + { + filterQuery.Where(user => !user.IsApproved); + } + long pageIndex = pageNumber - 1; long total; var result = Services.UserService.GetAll(pageIndex, pageSize, out total, orderBy, orderDirection, userStates, userGroups, excludeUserGroups, filterQuery); From 3078be93b65fbf844918604f8d138ed934153b17 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 5 Jul 2018 21:07:12 +0100 Subject: [PATCH 13/70] Remove disabled users option from users list view filter --- src/Umbraco.Web/Editors/UsersController.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 64ebf1703f..ae65152944 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -219,6 +219,7 @@ namespace Umbraco.Web.Editors // so to do that here, we'll need to check if this current user is an admin and if not we should exclude all user who are // also admins + var hideDisabledUsers = UmbracoConfig.For.UmbracoSettings().Security.HideDisabledUsersInBackoffice; var excludeUserGroups = new string[0]; var isAdmin = Security.CurrentUser.IsAdmin(); if (isAdmin == false) @@ -241,7 +242,7 @@ namespace Umbraco.Web.Editors filterQuery.Where(x => x.Name.Contains(filter) || x.Username.Contains(filter)); } - if (UmbracoConfig.For.UmbracoSettings().Security.HideDisabledUsersInBackoffice) + if (hideDisabledUsers) { filterQuery.Where(user => !user.IsApproved); } @@ -249,11 +250,14 @@ namespace Umbraco.Web.Editors long pageIndex = pageNumber - 1; long total; var result = Services.UserService.GetAll(pageIndex, pageSize, out total, orderBy, orderDirection, userStates, userGroups, excludeUserGroups, filterQuery); - + var paged = new PagedUserResult(total, pageNumber, pageSize) { Items = Mapper.Map>(result), - UserStates = Services.UserService.GetUserStates() + UserStates = hideDisabledUsers + ? Services.UserService.GetUserStates().Where(state => state.Key != UserState.Disabled) + .ToDictionary(state => state.Key, state => state.Value) + : Services.UserService.GetUserStates() }; return paged; From c4a787331ff1d61e6f75b49abd48d916d9817046 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 2 Aug 2018 21:54:00 +0100 Subject: [PATCH 14/70] Reverted previous commit to show disabled users in the status filter --- src/Umbraco.Web/Editors/UsersController.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index ae65152944..0561e45263 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -254,10 +254,7 @@ namespace Umbraco.Web.Editors var paged = new PagedUserResult(total, pageNumber, pageSize) { Items = Mapper.Map>(result), - UserStates = hideDisabledUsers - ? Services.UserService.GetUserStates().Where(state => state.Key != UserState.Disabled) - .ToDictionary(state => state.Key, state => state.Value) - : Services.UserService.GetUserStates() + UserStates = Services.UserService.GetUserStates() }; return paged; From f81dc1621082f29f50967aa0e166fabca59f797f Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 2 Aug 2018 21:55:04 +0100 Subject: [PATCH 15/70] Specify which user states we want to include when getting all users --- src/Umbraco.Web/Editors/UsersController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 0561e45263..89b1f8b238 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -244,7 +244,10 @@ namespace Umbraco.Web.Editors if (hideDisabledUsers) { - filterQuery.Where(user => !user.IsApproved); + if (userStates == null || userStates.Any() == false) + { + userStates = new[] { UserState.Active, UserState.Invited, UserState.LockedOut }; + } } long pageIndex = pageNumber - 1; From 9a774c8f9e339aa1a878862d69a0a0148b12f22b Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 2 Aug 2018 22:01:45 +0100 Subject: [PATCH 16/70] Added inactive state for users who haven't logged in --- src/Umbraco.Core/Models/Membership/UserState.cs | 5 +++-- .../Persistence/Repositories/UserRepository.cs | 13 +++++++++++-- .../src/common/services/usershelper.service.js | 3 ++- src/Umbraco.Web/Editors/UsersController.cs | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Models/Membership/UserState.cs b/src/Umbraco.Core/Models/Membership/UserState.cs index 5f6ee1615a..fc277b4fa3 100644 --- a/src/Umbraco.Core/Models/Membership/UserState.cs +++ b/src/Umbraco.Core/Models/Membership/UserState.cs @@ -9,6 +9,7 @@ Active = 0, Disabled = 1, LockedOut = 2, - Invited = 3 + Invited = 3, + Inactive = 4 } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs index 5701cd1008..fb3f7b56ee 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs @@ -186,6 +186,8 @@ UNION SELECT '4CountOfLockedOut' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userNoConsole = 1 UNION SELECT '5CountOfInvited' AS colName, COUNT(id) AS num FROM umbracoUser WHERE lastLoginDate IS NULL AND userDisabled = 1 AND invitedDate IS NOT NULL +UNION +SELECT '6CountOfDisabled' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NULL ORDER BY colName"; var result = Database.Fetch(sql); @@ -196,7 +198,8 @@ ORDER BY colName"; {UserState.Active, (int)result[1].num}, {UserState.Disabled, (int)result[2].num}, {UserState.LockedOut, (int)result[3].num}, - {UserState.Invited, (int)result[4].num} + {UserState.Invited, (int)result[4].num}, + {UserState.Inactive, (int) result[5].num} }; } @@ -765,6 +768,12 @@ ORDER BY colName"; sb.Append("(userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NOT NULL)"); appended = true; } + if (userState.Contains(UserState.Inactive)) + { + if (appended) sb.Append(" OR "); + sb.Append("(userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NULL)"); + appended = true; + } if (userState.Contains(UserState.Disabled)) { if (appended) sb.Append(" OR "); @@ -915,4 +924,4 @@ ORDER BY colName"; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/common/services/usershelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/usershelper.service.js index 21fe84ff8d..6e20ce91ac 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/usershelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/usershelper.service.js @@ -8,7 +8,8 @@ { "value": 0, "name": "Active", "key": "Active", "color": "success" }, { "value": 1, "name": "Disabled", "key": "Disabled", "color": "danger" }, { "value": 2, "name": "Locked out", "key": "LockedOut", "color": "danger" }, - { "value": 3, "name": "Invited", "key": "Invited", "color": "warning" } + { "value": 3, "name": "Invited", "key": "Invited", "color": "warning" }, + { "value": 4, "name": "Inactive", "key": "Inactive", "color": "warning" } ]; angular.forEach(userStates, function (userState) { diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 89b1f8b238..6df1733509 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -246,7 +246,7 @@ namespace Umbraco.Web.Editors { if (userStates == null || userStates.Any() == false) { - userStates = new[] { UserState.Active, UserState.Invited, UserState.LockedOut }; + userStates = new[] { UserState.Active, UserState.Invited, UserState.LockedOut, UserState.Inactive }; } } From 3efbb47aedc0b16a4e20f05c7c47e67ef15bb268 Mon Sep 17 00:00:00 2001 From: Pavel Budik Date: Wed, 8 Aug 2018 10:02:48 +0200 Subject: [PATCH 17/70] U4-11527 Fix concurrency issue --- src/Umbraco.Core/ApplicationContext.cs | 20 +++++++++---------- src/Umbraco.Core/Sync/ApplicationUrlHelper.cs | 3 +-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index 82ef562bc1..b16eb18256 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -1,8 +1,8 @@ -using System; -using System.Collections.Generic; +using Semver; +using System; +using System.Collections.Concurrent; using System.Configuration; using System.Threading; -using Semver; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; @@ -13,7 +13,7 @@ using Umbraco.Core.Sync; namespace Umbraco.Core { - /// + /// /// the Umbraco Application context /// /// @@ -270,7 +270,7 @@ namespace Umbraco.Core return _umbracoApplicationUrl; } } - + /// /// Resets the url. /// @@ -280,10 +280,10 @@ namespace Umbraco.Core } // ReSharper disable once InconsistentNaming - internal string _umbracoApplicationUrl; - - internal List _umbracoApplicationDomains = new List(); - + internal string _umbracoApplicationUrl; + + internal ConcurrentDictionary _umbracoApplicationDomains = new ConcurrentDictionary(); + internal string _umbracoApplicationDeploymentId; private Lazy _configured; @@ -399,7 +399,7 @@ namespace Umbraco.Core } return version; - } + } private void AssertIsNotReady() { diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index 156cee93e2..b52bbcaf97 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -51,10 +51,9 @@ namespace Umbraco.Core.Sync if (request != null) { var applicationUrl = GetApplicationUrlFromRequest(request); - newApplicationUrl = !appContext._umbracoApplicationDomains.Contains(applicationUrl); + newApplicationUrl = appContext._umbracoApplicationDomains.TryAdd(applicationUrl, applicationUrl); if (newApplicationUrl) { - appContext._umbracoApplicationDomains.Add(applicationUrl); LogHelper.Info(typeof(ApplicationUrlHelper), string.Format("New ApplicationUrl detected: {0}", applicationUrl)); } } From 92273f263bab02b9fa1ef28341c6ad9bc3ad54b1 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 8 Aug 2018 10:23:14 +0100 Subject: [PATCH 18/70] U4-11556 V8 - Removed metablogConfig.config http://issues.umbraco.org/issue/U4-11556 For v7, I've marked the `SystemFiles.MetablogConfig` strings as deprecated. --- src/Umbraco.Core/IO/SystemFiles.cs | 1 + src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ---- .../config/metablogConfig.Release.config | 3 --- .../config/metablogConfig.config | 19 ------------------- src/umbraco.businesslogic/IO/SystemFiles.cs | 1 + 5 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 src/Umbraco.Web.UI/config/metablogConfig.Release.config delete mode 100644 src/Umbraco.Web.UI/config/metablogConfig.config diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index ccf8ea5b2c..a171b9174b 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -37,6 +37,7 @@ namespace Umbraco.Core.IO } } + [Obsolete("This file is no longer used and should not be accessed!")] public static string MetablogConfig { get diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 179b66039e..5ed3f01fde 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -561,9 +561,6 @@ scripting.config - - metablogConfig.config - ExamineSettings.config @@ -993,7 +990,6 @@ Designer - Designer diff --git a/src/Umbraco.Web.UI/config/metablogConfig.Release.config b/src/Umbraco.Web.UI/config/metablogConfig.Release.config deleted file mode 100644 index a714b2cbe9..0000000000 --- a/src/Umbraco.Web.UI/config/metablogConfig.Release.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/metablogConfig.config b/src/Umbraco.Web.UI/config/metablogConfig.config deleted file mode 100644 index a3f43d9480..0000000000 --- a/src/Umbraco.Web.UI/config/metablogConfig.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - My FAQs - 0 - 1080 - False - Articulate - - - - - - - - - - - \ No newline at end of file diff --git a/src/umbraco.businesslogic/IO/SystemFiles.cs b/src/umbraco.businesslogic/IO/SystemFiles.cs index a97dc74ba1..c480fd0424 100644 --- a/src/umbraco.businesslogic/IO/SystemFiles.cs +++ b/src/umbraco.businesslogic/IO/SystemFiles.cs @@ -29,6 +29,7 @@ namespace umbraco.IO get { return Umbraco.Core.IO.SystemFiles.TinyMceConfig; } } + [Obsolete("This file is no longer used and should not be accessed!")] public static string MetablogConfig { get { return Umbraco.Core.IO.SystemFiles.MetablogConfig; } From ba682d95dc4215fb933707610876f04db1bcbd78 Mon Sep 17 00:00:00 2001 From: Chris Houston Date: Sun, 12 Aug 2018 01:16:57 -0400 Subject: [PATCH 19/70] Small tweaks to the Getting Started tour text. --- .../config/BackOfficeTours/getting-started.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json b/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json index dbd6b8d4f5..129d3b8b4f 100644 --- a/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json +++ b/src/Umbraco.Web.UI/config/BackOfficeTours/getting-started.json @@ -140,7 +140,7 @@ { "element": "[data-element='editor-description']", "title": "Enter a description", - "content": "

A description helps to pick the right document type when creating content.

Write a description to our Home page. It could be:

The home page of the website

" + "content": "

A description helps to pick the right document type when creating content.

Write a description for our Home page. It could be:

The home page of the website

" }, { "element": "[data-element='group-add']", @@ -169,7 +169,7 @@ { "element": "[data-element~='overlay-property-settings'] [data-element='property-description']", "title": "Enter a description", - "content": "

A description will help to fill in the right content.

Enter a description for the property editor. It could be:

Write a nice introduction text so the visitors feel welcome

" + "content": "

A description will help your editor fill in the right content.

Enter a description for the property editor. It could be:

Write a nice introduction text so the visitors feel welcome

" }, { "element": "[data-element~='overlay-property-settings'] [data-element='editor-add']", @@ -247,7 +247,7 @@ "title": "Open context menu", "content": "

Open the context menu by hovering over the root of the content section.

Now click the three small dots to the right.

", "event": "click", - "eventElement": "[data-element='tree-root'] [data-element='tree-item-options']" + "eventElement": "#tree [data-element='tree-root'] [data-element='tree-item-options']" }, { "element": "[data-element='action-create-homePage']", @@ -346,7 +346,7 @@ "steps": [ { "title": "View your Umbraco site", - "content": "

Our three main components to a page are done: Document type, Template, and Content. It is now time to see the result.

In this tour you will learn how to see your published website.

", + "content": "

Our three main components for a page are done: Document type, Template, and Content. It is now time to see the result.

In this tour you will learn how to see your published website.

", "type": "intro" }, { From de73080e14ff0b8866f159b0185552eabdadf601 Mon Sep 17 00:00:00 2001 From: Jannik Anker Date: Tue, 14 Aug 2018 13:37:54 +0200 Subject: [PATCH 20/70] U4-11572 Add border to selected icon in document type icon picker dialog --- .../src/less/components/umb-iconpicker.less | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less index 6ca57e0829..473bfd6553 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less @@ -27,12 +27,16 @@ } .umb-iconpicker-item a:hover, -.umb-iconpicker-item a:focus, -.umb-iconpicker-item.-selected { +.umb-iconpicker-item a:focus { background: @gray-10; outline: none; } +.umb-iconpicker-item.-selected { + background: @gray-10; + outline: solid 1px @gray-7; +} + .umb-iconpicker-item a:active { background: @gray-10; } From f18b0aa77461beeaeb10c0e23ca58d3fded954ea Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 16 Aug 2018 13:53:42 +0200 Subject: [PATCH 21/70] U4-11579 Take startNodeId into account before picking the current node to sync to --- .../views/common/overlays/treepicker/treepicker.controller.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index d061db0f58..93f1ef6c68 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -162,7 +162,9 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", tree = args.tree; - if (node && node.path) { + var nodeHasPath = typeof node !== "undefined" && typeof node.path !== "undefined"; + var startNodeNotDefined = typeof dialogOptions.startNodeId === "undefined" || dialogOptions.startNodeId === "" || dialogOptions.startNodeId === "-1"; + if (startNodeNotDefined && nodeHasPath) { $scope.dialogTreeEventHandler.syncTree({ path: node.path, activate: false }); } From de8a24c6919b07e197d8a6c2374ab0a3fa7efdf8 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Fri, 17 Aug 2018 12:22:54 +0200 Subject: [PATCH 22/70] Add "info" style to upload button + add help text when the dropzone is hidden. --- .../src/views/common/overlays/mediaPicker/mediapicker.html | 1 + .../src/views/components/upload/umb-file-dropzone.html | 6 ++++++ src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + 5 files changed, 10 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html index c73c1d965b..dce749be55 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html @@ -28,6 +28,7 @@ label-key="general_upload" action="upload()" disabled="lockedFolder" + button-style="info" ng-if="acceptedMediatypes.length > 0">
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html index 211060c03f..c5572fad27 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html @@ -37,6 +37,12 @@
+
+ + You can drag files here to upload + +
+
From ad3d27be76714dae57e51c1070f24691b3b7ae10 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Wed, 22 Aug 2018 10:00:54 +0200 Subject: [PATCH 31/70] Reference the node object instead of the documentType object, which returns null if the user is not logged in as an admin. --- .../views/components/content/umb-content-node-info.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index 4656840eef..13cf3655b6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -178,15 +178,16 @@ + open-url="previewOpenUrl"> +
+ + + + diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 22f1fb7457..23cb209be0 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -207,7 +207,7 @@ namespace Umbraco.Web.Editors : Request.CreateNotificationValidationErrorResponse(result.Exception.Message); } - public DocumentTypeCollectionDisplay PostCreateCollection(int parentId, string collectionName, string collectionItemName, string collectionIcon, string collectionItemIcon) + public DocumentTypeCollectionDisplay PostCreateCollection(int parentId, string collectionName, bool collectionCreateTemplate, string collectionItemName, bool collectionItemCreateTemplate, string collectionIcon, string collectionItemIcon) { var storeInContainer = false; var allowUnderDocType = -1; @@ -228,6 +228,28 @@ namespace Umbraco.Web.Editors itemDocType.Name = collectionItemName; itemDocType.Alias = collectionItemName.ToSafeAlias(); itemDocType.Icon = collectionItemIcon; + + // create item doctype template + if (collectionItemCreateTemplate) + { + var template = Services.FileService.GetTemplate(itemDocType.Alias); + if (template == null) + { + var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(itemDocType.Alias, itemDocType.Name); + if (tryCreateTemplate == false) + { + Logger.Warn( + "Could not create a template for the Content Type: {0}, status: {1}", + () => itemDocType.Alias, + () => tryCreateTemplate.Result.StatusType); + } + template = tryCreateTemplate.Result.Entity; + } + + itemDocType.SetDefaultTemplate(template); + } + + // save item doctype Services.ContentTypeService.Save(itemDocType); // create collection doctype @@ -240,6 +262,28 @@ namespace Umbraco.Web.Editors { new ContentTypeSort(itemDocType.Id, 0) }; + + // create collection doctype template + if (collectionCreateTemplate) + { + var template = Services.FileService.GetTemplate(collectionDocType.Alias); + if (template == null) + { + var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(collectionDocType.Alias, collectionDocType.Name); + if (tryCreateTemplate == false) + { + Logger.Warn( + "Could not create a template for the Content Type: {0}, status: {1}", + () => collectionDocType.Alias, + () => tryCreateTemplate.Result.StatusType); + } + template = tryCreateTemplate.Result.Entity; + } + + collectionDocType.SetDefaultTemplate(template); + } + + // save collection doctype Services.ContentTypeService.Save(collectionDocType); // test if the parent id exist and then allow the collection underneath From ec1a3f0fe89263438ad4456fc986fe017aca6f0f Mon Sep 17 00:00:00 2001 From: Marcel van Helmont Date: Tue, 28 Aug 2018 22:44:53 +0200 Subject: [PATCH 56/70] make sure alias is camelCase format --- src/Umbraco.Web/Editors/ContentTypeController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 23cb209be0..4c948654c1 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -226,7 +226,7 @@ namespace Umbraco.Web.Editors // create item doctype var itemDocType = new ContentType(parentId); itemDocType.Name = collectionItemName; - itemDocType.Alias = collectionItemName.ToSafeAlias(); + itemDocType.Alias = collectionItemName.ToSafeAlias(true); itemDocType.Icon = collectionItemIcon; // create item doctype template @@ -255,7 +255,7 @@ namespace Umbraco.Web.Editors // create collection doctype var collectionDocType = new ContentType(parentId); collectionDocType.Name = collectionName; - collectionDocType.Alias = collectionName.ToSafeAlias(); + collectionDocType.Alias = collectionName.ToSafeAlias(true); collectionDocType.Icon = collectionIcon; collectionDocType.IsContainer = true; collectionDocType.AllowedContentTypes = new List() From 26a8d680d4a499579b87a3c848f9d4c53c642510 Mon Sep 17 00:00:00 2001 From: "Ali.Taheri" Date: Wed, 29 Aug 2018 14:28:33 +0100 Subject: [PATCH 57/70] u4-8310 - Fixed rename content type with the same alias but with different casing. --- src/Umbraco.Web/Editors/ContentTypeControllerBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 20dc316c49..73b9043f12 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -227,7 +227,7 @@ namespace Umbraco.Web.Editors // works since that is based on aliases. var allAliases = Services.ContentTypeService.GetAllContentTypeAliases(); var exists = allAliases.InvariantContains(contentTypeSave.Alias); - if ((exists) && (ctId == 0 || ct.Alias != contentTypeSave.Alias)) + if (exists && (ctId == 0 || ct.Alias.InvariantEquals(contentTypeSave.Alias) == false)) { ModelState.AddModelError("Alias", "A content type, media type or member type with this alias already exists"); } From 541e546f7b02583a5c9ba1cab4a6cf76e65a3d39 Mon Sep 17 00:00:00 2001 From: "Ali.Taheri" Date: Wed, 29 Aug 2018 14:35:20 +0100 Subject: [PATCH 58/70] u4-8310 - Added error message to the xml file. --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + src/Umbraco.Web/Editors/ContentTypeControllerBase.cs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 80c18a597d..f7a5ac5ef4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -480,6 +480,7 @@ The active list view data type Create custom list view Remove custom list view + A content type, media type or member type with this alias already exists Renamed diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index b018a562fc..655c619095 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -480,6 +480,7 @@ The active list view data type Create custom list view Remove custom list view + A content type, media type or member type with this alias already exists Renamed diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 73b9043f12..1d728c63a5 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -229,7 +229,7 @@ namespace Umbraco.Web.Editors var exists = allAliases.InvariantContains(contentTypeSave.Alias); if (exists && (ctId == 0 || ct.Alias.InvariantEquals(contentTypeSave.Alias) == false)) { - ModelState.AddModelError("Alias", "A content type, media type or member type with this alias already exists"); + ModelState.AddModelError("Alias", Services.TextService.Localize("editcontenttype/aliasAlreadyExists")); } //now let the external validators execute From 74ca3151971d5e90b92917869ca954450e46cc71 Mon Sep 17 00:00:00 2001 From: Marcel van Helmont Date: Wed, 29 Aug 2018 15:38:12 +0200 Subject: [PATCH 59/70] added val-email to corrrectly validate emails supporting new TLD --- src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html index e6900a8a30..b4e330c13e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html @@ -181,7 +181,7 @@
- +
From f35964821581fa4f1afaa77423a844937ac0cf86 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 26 Jun 2018 10:52:42 +1000 Subject: [PATCH 60/70] fixes U4-11463 MembershipHelper is not working with basic auth on the initial request --- src/Umbraco.Web/Security/MembershipHelper.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs index eeb9bad52b..598d7dbab9 100644 --- a/src/Umbraco.Web/Security/MembershipHelper.cs +++ b/src/Umbraco.Web/Security/MembershipHelper.cs @@ -647,10 +647,15 @@ namespace Umbraco.Web.Security var provider = _membershipProvider; string username; + if (provider.IsUmbracoMembershipProvider()) { var member = GetCurrentPersistedMember(); + // If a member could not be resolved from the provider, we are clearly not authorized and can break right here + if (member == null) + return false; username = member.Username; + // If types defined, check member is of one of those types var allowTypesList = allowTypes as IList ?? allowTypes.ToList(); if (allowTypesList.Any(allowType => allowType != string.Empty)) @@ -669,6 +674,9 @@ namespace Umbraco.Web.Security else { var member = provider.GetCurrentUser(); + // If a member could not be resolved from the provider, we are clearly not authorized and can break right here + if (member == null) + return false; username = member.UserName; } From fb6079d4e2af45b151d466441ee6f63ff677d185 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 30 Aug 2018 09:55:03 +0200 Subject: [PATCH 61/70] Add issue templates and updated PR template --- docs/ISSUE_TEMPLATE/1_Bug.md | 66 ++++++++++++++++++++ docs/ISSUE_TEMPLATE/2_Feature_request.md | 31 +++++++++ docs/ISSUE_TEMPLATE/3_Support_question.md | 9 +++ docs/ISSUE_TEMPLATE/4_Documentation_issue.md | 9 +++ docs/ISSUE_TEMPLATE/5_Security_issue.md | 31 +++++++++ docs/PULL_REQUEST_TEMPLATE.md | 6 +- 6 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 docs/ISSUE_TEMPLATE/1_Bug.md create mode 100644 docs/ISSUE_TEMPLATE/2_Feature_request.md create mode 100644 docs/ISSUE_TEMPLATE/3_Support_question.md create mode 100644 docs/ISSUE_TEMPLATE/4_Documentation_issue.md create mode 100644 docs/ISSUE_TEMPLATE/5_Security_issue.md diff --git a/docs/ISSUE_TEMPLATE/1_Bug.md b/docs/ISSUE_TEMPLATE/1_Bug.md new file mode 100644 index 0000000000..21b79789ba --- /dev/null +++ b/docs/ISSUE_TEMPLATE/1_Bug.md @@ -0,0 +1,66 @@ +--- +name: 🐛 Bug Report +about: File a bug report, if you've discovered a problem in Umbraco. +--- + +A brief description of the issue goes here. + + + + + +Reproduction +------------ + +If you're filing a bug, please describe how to reproduce it. Include as much +relevant information as possible, such as: + +### Bug summary + + + +### Specifics + + + +### Steps to reproduce + + + +### Expected result + + + +### Actual result + + diff --git a/docs/ISSUE_TEMPLATE/2_Feature_request.md b/docs/ISSUE_TEMPLATE/2_Feature_request.md new file mode 100644 index 0000000000..16ec2568dd --- /dev/null +++ b/docs/ISSUE_TEMPLATE/2_Feature_request.md @@ -0,0 +1,31 @@ +--- +name: 📮 Feature Request +about: Open a feature request, if you want to propose a new feature. +--- + +A brief description of your feature request goes here. + + + + +How can you help? +------------------------------- + + diff --git a/docs/ISSUE_TEMPLATE/3_Support_question.md b/docs/ISSUE_TEMPLATE/3_Support_question.md new file mode 100644 index 0000000000..829df982f9 --- /dev/null +++ b/docs/ISSUE_TEMPLATE/3_Support_question.md @@ -0,0 +1,9 @@ +--- +name: ⁉️ Support Question +about: Having trouble with Umbraco? -> https://our.umbraco.com +--- + +This issue tracker is NOT meant for support questions. If you have a question, +please join us on the forum at https://our.umbraco.com. + +Thanks! diff --git a/docs/ISSUE_TEMPLATE/4_Documentation_issue.md b/docs/ISSUE_TEMPLATE/4_Documentation_issue.md new file mode 100644 index 0000000000..8893647aa8 --- /dev/null +++ b/docs/ISSUE_TEMPLATE/4_Documentation_issue.md @@ -0,0 +1,9 @@ +--- +name: 📖 Documentation Issue +about: See https://github.com/umbraco/UmbracoDocs/issues for documentation issues +--- + +The Umbraco documentation has its own dedicated repository. Please open your +documentation-related issue at https://github.com/umbraco/UmbracoDocs/issues + +Thanks! diff --git a/docs/ISSUE_TEMPLATE/5_Security_issue.md b/docs/ISSUE_TEMPLATE/5_Security_issue.md new file mode 100644 index 0000000000..84c5f5989c --- /dev/null +++ b/docs/ISSUE_TEMPLATE/5_Security_issue.md @@ -0,0 +1,31 @@ +--- +name: 🔐 Security Issue +about: Discovered a Security Issue in Umbraco? +--- + +⚠️ PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, SEE BELOW. + +If you have found a security issue in Umbraco, please send the details to +security@umbraco.com and don't disclose it publicly until we can provide a fix for +it. If you wish, we'll credit you for finding verified issues, when we release +the patched version. + +❗ Please read more about how to report security issues on https://umbraco.com/security + +A note on "Self XSS" +-------------------- + +Umbraco is a CMS, that allows users to edit content on a website. As such, +all _authenticated users_ can: + + - Edit content, and (depending on the field types) insert HTML and CSS in that + content, with a variety of allowed attributes. + - Depending on the user level: Edit template files, and insert C#, HTML, CSS and + javascript in so on. + - Upload files to the site, which will become publicly available. + +We see these functionalities as _features_, and not as security issues. Please +report the mentioned items only if they can be performed by non-authorized +users, or other exploitable vulnerabilities. + +Thanks! diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md index db1e5c88bd..6275d161dc 100644 --- a/docs/PULL_REQUEST_TEMPLATE.md +++ b/docs/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,11 @@ ### Prerequisites -- [ ] I have written a descriptive pull-request title -- [ ] I have linked this PR to an issue on the tracker at http://issues.umbraco.org +- [ ] I have [created an issue](https://github.com/umbraco/Umbraco-CMS/issues) for the proposed changes in this PR, the link is: +- [ ] I have added steps to test this contribution in the description below ### Description - + From 90a47cd042a2742a7a3f4f1a4505753aeee741f6 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 30 Aug 2018 09:58:29 +0200 Subject: [PATCH 62/70] Move from docs to github folder --- {docs => .github}/BUILD.md | 0 {docs => .github}/CODE_OF_CONDUCT.md | 0 {docs => .github}/CONTRIBUTING.md | 0 {docs => .github}/CONTRIBUTING_DETAILED.md | 0 {docs => .github}/CONTRIBUTION_GUIDELINES.md | 0 {docs => .github}/ISSUE_TEMPLATE/1_Bug.md | 0 .../ISSUE_TEMPLATE/2_Feature_request.md | 0 .../ISSUE_TEMPLATE/3_Support_question.md | 0 .../ISSUE_TEMPLATE/4_Documentation_issue.md | 0 .../ISSUE_TEMPLATE/5_Security_issue.md | 0 {docs => .github}/PULL_REQUEST_TEMPLATE.md | 0 {docs => .github}/README.md | 0 {docs => .github}/REVIEW_PROCESS.md | 0 {docs => .github}/img/clonefork.png | Bin {docs => .github}/img/createpullrequest.png | Bin {docs => .github}/img/defaultbranch.png | Bin {docs => .github}/img/forkrepository.png | Bin {docs => .github}/img/gulpbuild.png | Bin {docs => .github}/img/vimeo.png | Bin 19 files changed, 0 insertions(+), 0 deletions(-) rename {docs => .github}/BUILD.md (100%) rename {docs => .github}/CODE_OF_CONDUCT.md (100%) rename {docs => .github}/CONTRIBUTING.md (100%) rename {docs => .github}/CONTRIBUTING_DETAILED.md (100%) rename {docs => .github}/CONTRIBUTION_GUIDELINES.md (100%) rename {docs => .github}/ISSUE_TEMPLATE/1_Bug.md (100%) rename {docs => .github}/ISSUE_TEMPLATE/2_Feature_request.md (100%) rename {docs => .github}/ISSUE_TEMPLATE/3_Support_question.md (100%) rename {docs => .github}/ISSUE_TEMPLATE/4_Documentation_issue.md (100%) rename {docs => .github}/ISSUE_TEMPLATE/5_Security_issue.md (100%) rename {docs => .github}/PULL_REQUEST_TEMPLATE.md (100%) rename {docs => .github}/README.md (100%) rename {docs => .github}/REVIEW_PROCESS.md (100%) rename {docs => .github}/img/clonefork.png (100%) rename {docs => .github}/img/createpullrequest.png (100%) rename {docs => .github}/img/defaultbranch.png (100%) rename {docs => .github}/img/forkrepository.png (100%) rename {docs => .github}/img/gulpbuild.png (100%) rename {docs => .github}/img/vimeo.png (100%) diff --git a/docs/BUILD.md b/.github/BUILD.md similarity index 100% rename from docs/BUILD.md rename to .github/BUILD.md diff --git a/docs/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from docs/CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/docs/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from docs/CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/docs/CONTRIBUTING_DETAILED.md b/.github/CONTRIBUTING_DETAILED.md similarity index 100% rename from docs/CONTRIBUTING_DETAILED.md rename to .github/CONTRIBUTING_DETAILED.md diff --git a/docs/CONTRIBUTION_GUIDELINES.md b/.github/CONTRIBUTION_GUIDELINES.md similarity index 100% rename from docs/CONTRIBUTION_GUIDELINES.md rename to .github/CONTRIBUTION_GUIDELINES.md diff --git a/docs/ISSUE_TEMPLATE/1_Bug.md b/.github/ISSUE_TEMPLATE/1_Bug.md similarity index 100% rename from docs/ISSUE_TEMPLATE/1_Bug.md rename to .github/ISSUE_TEMPLATE/1_Bug.md diff --git a/docs/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md similarity index 100% rename from docs/ISSUE_TEMPLATE/2_Feature_request.md rename to .github/ISSUE_TEMPLATE/2_Feature_request.md diff --git a/docs/ISSUE_TEMPLATE/3_Support_question.md b/.github/ISSUE_TEMPLATE/3_Support_question.md similarity index 100% rename from docs/ISSUE_TEMPLATE/3_Support_question.md rename to .github/ISSUE_TEMPLATE/3_Support_question.md diff --git a/docs/ISSUE_TEMPLATE/4_Documentation_issue.md b/.github/ISSUE_TEMPLATE/4_Documentation_issue.md similarity index 100% rename from docs/ISSUE_TEMPLATE/4_Documentation_issue.md rename to .github/ISSUE_TEMPLATE/4_Documentation_issue.md diff --git a/docs/ISSUE_TEMPLATE/5_Security_issue.md b/.github/ISSUE_TEMPLATE/5_Security_issue.md similarity index 100% rename from docs/ISSUE_TEMPLATE/5_Security_issue.md rename to .github/ISSUE_TEMPLATE/5_Security_issue.md diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from docs/PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/docs/README.md b/.github/README.md similarity index 100% rename from docs/README.md rename to .github/README.md diff --git a/docs/REVIEW_PROCESS.md b/.github/REVIEW_PROCESS.md similarity index 100% rename from docs/REVIEW_PROCESS.md rename to .github/REVIEW_PROCESS.md diff --git a/docs/img/clonefork.png b/.github/img/clonefork.png similarity index 100% rename from docs/img/clonefork.png rename to .github/img/clonefork.png diff --git a/docs/img/createpullrequest.png b/.github/img/createpullrequest.png similarity index 100% rename from docs/img/createpullrequest.png rename to .github/img/createpullrequest.png diff --git a/docs/img/defaultbranch.png b/.github/img/defaultbranch.png similarity index 100% rename from docs/img/defaultbranch.png rename to .github/img/defaultbranch.png diff --git a/docs/img/forkrepository.png b/.github/img/forkrepository.png similarity index 100% rename from docs/img/forkrepository.png rename to .github/img/forkrepository.png diff --git a/docs/img/gulpbuild.png b/.github/img/gulpbuild.png similarity index 100% rename from docs/img/gulpbuild.png rename to .github/img/gulpbuild.png diff --git a/docs/img/vimeo.png b/.github/img/vimeo.png similarity index 100% rename from docs/img/vimeo.png rename to .github/img/vimeo.png From 58dab23d043db6effad538380b281baa8b73b662 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 30 Aug 2018 10:00:29 +0200 Subject: [PATCH 63/70] Fix links --- .github/ISSUE_TEMPLATE/1_Bug.md | 2 +- .github/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1_Bug.md b/.github/ISSUE_TEMPLATE/1_Bug.md index 21b79789ba..a1e33e3854 100644 --- a/.github/ISSUE_TEMPLATE/1_Bug.md +++ b/.github/ISSUE_TEMPLATE/1_Bug.md @@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue template below. The more details you can give us, the easier it will be for us to determine the cause of a problem. -See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/docs/CONTRIBUTING.md +See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md --> diff --git a/.github/README.md b/.github/README.md index 7e22e4710f..74f9762040 100644 --- a/.github/README.md +++ b/.github/README.md @@ -44,6 +44,6 @@ Umbraco is contribution focused and community driven. If you want to contribute ## Found a bug? -Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/docs/CONTRIBUTING.md). +Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md). To view existing issues, please visit [http://issues.umbraco.org](http://issues.umbraco.org). From cc680f2cfbcbebe890ea5677f511aec8b69a976a Mon Sep 17 00:00:00 2001 From: AJ_Dhaliwal Date: Thu, 30 Aug 2018 18:01:25 +0800 Subject: [PATCH 64/70] Fix comment regarding the length of the salt bytes array --- src/Umbraco.Core/Security/MembershipProviderBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Security/MembershipProviderBase.cs b/src/Umbraco.Core/Security/MembershipProviderBase.cs index ea7296fed2..b6a0588f98 100644 --- a/src/Umbraco.Core/Security/MembershipProviderBase.cs +++ b/src/Umbraco.Core/Security/MembershipProviderBase.cs @@ -720,7 +720,7 @@ namespace Umbraco.Core.Security } else { - //if the salt bytes is too long for the required key length for the algorithm, extend it + //if the salt bytes is too short for the required key length for the algorithm, extend it var numArray2 = new byte[keyedHashAlgorithm.Key.Length]; var dstOffset = 0; while (dstOffset < numArray2.Length) @@ -963,4 +963,4 @@ namespace Umbraco.Core.Security } } -} \ No newline at end of file +} From c29357b845b99ecc7b550b6fa8a137b3c6d83d6d Mon Sep 17 00:00:00 2001 From: Marcel van Helmont Date: Thu, 30 Aug 2018 21:06:29 +0200 Subject: [PATCH 65/70] inside ensureWithinStartNode also check if node is trashed otherwise go to startnode. --- .../common/overlays/mediaPicker/mediapicker.controller.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js index 345b9dec5b..1b4c533123 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js @@ -250,7 +250,8 @@ angular.module("umbraco") // make sure that last opened node is on the same path as start node var nodePath = node.path.split(","); - if (nodePath.indexOf($scope.startNodeId.toString()) !== -1) { + // also make sure the node is not trashed + if (nodePath.indexOf($scope.startNodeId.toString()) !== -1 && node.trashed === false) { $scope.gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder" }); return true; } else { From 9ea9c5d6b7634f325cd06c7248b82d243c9430dc Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 31 Aug 2018 20:20:37 +0200 Subject: [PATCH 66/70] Don't repeat the code to check for and create a template --- .../Editors/ContentTypeController.cs | 66 +++++++------------ 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 4c948654c1..ac58b764f0 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -232,20 +232,7 @@ namespace Umbraco.Web.Editors // create item doctype template if (collectionItemCreateTemplate) { - var template = Services.FileService.GetTemplate(itemDocType.Alias); - if (template == null) - { - var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(itemDocType.Alias, itemDocType.Name); - if (tryCreateTemplate == false) - { - Logger.Warn( - "Could not create a template for the Content Type: {0}, status: {1}", - () => itemDocType.Alias, - () => tryCreateTemplate.Result.StatusType); - } - template = tryCreateTemplate.Result.Entity; - } - + var template = CreateTemplateForContentType(itemDocType.Alias, itemDocType.Name); itemDocType.SetDefaultTemplate(template); } @@ -266,20 +253,7 @@ namespace Umbraco.Web.Editors // create collection doctype template if (collectionCreateTemplate) { - var template = Services.FileService.GetTemplate(collectionDocType.Alias); - if (template == null) - { - var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(collectionDocType.Alias, collectionDocType.Name); - if (tryCreateTemplate == false) - { - Logger.Warn( - "Could not create a template for the Content Type: {0}, status: {1}", - () => collectionDocType.Alias, - () => tryCreateTemplate.Result.StatusType); - } - template = tryCreateTemplate.Result.Entity; - } - + var template = CreateTemplateForContentType(collectionDocType.Alias, collectionDocType.Name); collectionDocType.SetDefaultTemplate(template); } @@ -296,8 +270,6 @@ namespace Umbraco.Web.Editors allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count())); parentCt.AllowedContentTypes = allowedCts; Services.ContentTypeService.Save(parentCt); - } else - { } } @@ -320,19 +292,7 @@ namespace Umbraco.Web.Editors //create a default template if it doesnt exist -but only if default template is == to the content type if (ctSave.DefaultTemplate.IsNullOrWhiteSpace() == false && ctSave.DefaultTemplate == ctSave.Alias) { - var template = Services.FileService.GetTemplate(ctSave.Alias); - if (template == null) - { - var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(ctSave.Alias, ctSave.Name); - if (tryCreateTemplate == false) - { - Logger.Warn( - "Could not create a template for the Content Type: {0}, status: {1}", - () => ctSave.Alias, - () => tryCreateTemplate.Result.StatusType); - } - template = tryCreateTemplate.Result.Entity; - } + var template = CreateTemplateForContentType(ctSave.Alias, ctSave.Name); // If the alias has been manually updated before the first save, // make sure to also update the first allowed template, as the @@ -362,6 +322,26 @@ namespace Umbraco.Web.Editors return display; } + private ITemplate CreateTemplateForContentType(string contentTypeAlias, string contentTypeName) + { + var template = Services.FileService.GetTemplate(contentTypeAlias); + if (template == null) + { + var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(contentTypeAlias, contentTypeName); + if (tryCreateTemplate == false) + { + Logger.Warn( + "Could not create a template for the Content Type: {0}, status: {1}", + () => contentTypeAlias, + () => tryCreateTemplate.Result.StatusType); + } + + template = tryCreateTemplate.Result.Entity; + } + + return template; + } + /// /// Returns an empty content type for use as a scaffold when creating a new type /// From 2dd5010d2cec94983c4fbe0b52a0161da0d99185 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Sun, 2 Sep 2018 09:57:45 +0200 Subject: [PATCH 67/70] Seems there is no need to hide the .small class, fixes #2896 --- .../src/less/components/umb-iconpicker.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less index aa1dd8c9e7..95ee176060 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less @@ -61,8 +61,8 @@ } // Hide Circle when not active - i.small{ - display: none; + i.small { + display: none; } // Circle behind the checkmark From b2b9b53af1cd63ac8ce45d4c63e8fcdbbd599211 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Sun, 2 Sep 2018 10:03:51 +0200 Subject: [PATCH 68/70] Whoops, fixes previous commit for #2896 --- .../src/less/components/umb-iconpicker.less | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less index 95ee176060..6b03d80214 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less @@ -60,11 +60,6 @@ border-radius: 3px; } - // Hide Circle when not active - i.small { - display: none; - } - // Circle behind the checkmark i.small.active{ font-size: 14px; From ac9c6305e77402b0d03f28e2b7e4fa2b856b3556 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 3 Sep 2018 12:12:27 +0200 Subject: [PATCH 69/70] Update CONTRIBUTING_DETAILED.md --- .github/CONTRIBUTING_DETAILED.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING_DETAILED.md b/.github/CONTRIBUTING_DETAILED.md index bffac4801b..020346dc5e 100644 --- a/.github/CONTRIBUTING_DETAILED.md +++ b/.github/CONTRIBUTING_DETAILED.md @@ -129,7 +129,7 @@ We like to use [Gitflow as much as possible](https://jeffkreeftmeijer.com/git-fl The easiest way to get started is to run `build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `gulp dev` in `src\Umbraco.Web.UI.Client`. See [this page](BUILD.md) for more details. -Alternatively, you can open `src\umbraco.sln` in Visual Studio 2017 ([the community edition is free](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15) for you to use to contribute to Open Source projects). In Visual Studio, find the Task Runner Explorer (in the View menu under Other Windows) and run the build task under the gulpfile. +Alternatively, you can open `src\umbraco.sln` in Visual Studio 2017 (version 15.3 or higher, [the community edition is free](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15) for you to use to contribute to Open Source projects). In Visual Studio, find the Task Runner Explorer (in the View menu under Other Windows) and run the build task under the gulpfile. ![Gulp build in Visual Studio](img/gulpbuild.png) @@ -156,4 +156,4 @@ git rebase upstream/dev-v7 In this command we're syncing with the `dev-v7` branch, but you can of course choose another one if needed. -(More info on how this works: [http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated](http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated)) \ No newline at end of file +(More info on how this works: [http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated](http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated)) From 6ff2f1eabb1a4b7dfdda9464ed581bb1d37b7b9a Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Mon, 3 Sep 2018 18:06:15 +0200 Subject: [PATCH 70/70] The name field is not automatically in focus when creating a new data type folder --- src/Umbraco.Web.UI.Client/src/views/datatypes/create.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/create.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/create.html index 4875e4b1ea..b50e1bba98 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/create.html @@ -29,7 +29,7 @@ val-form-manager> - +