From fb4de621c003afc557faa4f2d3ef3f6eaf2de88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mads=20J=C3=B8rgensen?= Date: Wed, 16 Apr 2014 20:10:53 +0200 Subject: [PATCH 01/39] Prevalue editor added to textbox --- .../PropertyEditors/TextboxPropertyEditor.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs index 69bc1452cf..01cd2585f3 100644 --- a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs @@ -12,6 +12,19 @@ namespace Umbraco.Web.PropertyEditors { [PropertyEditor(Constants.PropertyEditors.TextboxAlias, "Textbox", "textbox", IsParameterEditor = true)] public class TextboxPropertyEditor : PropertyEditor - { + { + + + protected override PreValueEditor CreatePreValueEditor() + { + return new TextboxPreValueEditor(); + } + + internal class TextboxPreValueEditor : PreValueEditor + { + [PreValueField("Maximum allowed characters", "number")] + public bool IsRequired { get; set; } + } + } } From 756d554b47956973a55a39d8c247fe25c9ea9b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mads=20J=C3=B8rgensen?= Date: Wed, 16 Apr 2014 20:55:45 +0200 Subject: [PATCH 02/39] charlimit on textbox added --- .../textbox/textbox.controller.js | 26 +++++++++++++++++++ .../propertyeditors/textbox/textbox.html | 7 ++--- .../PropertyEditors/TextboxPropertyEditor.cs | 4 +-- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js new file mode 100644 index 0000000000..77052a70f5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js @@ -0,0 +1,26 @@ +function textboxController($rootScope, $scope, $log) { + $scope.model.maxlength = false; + if($scope.model.config.MaxChars) { + $scope.model.maxlength = true; + if($scope.model.value == undefined) { + $scope.model.count = ($scope.model.config.MaxChars * 1); + } else { + $scope.model.count = ($scope.model.config.MaxChars * 1) - $scope.model.value.length; + } + } + + $scope.model.change = function() { + if($scope.model.config.MaxChars) { + if($scope.model.value == undefined) { + $scope.model.count = ($scope.model.config.MaxChars * 1); + } else { + $scope.model.count = ($scope.model.config.MaxChars * 1) - $scope.model.value.length; + } + if($scope.model.count < 0) { + $scope.model.value = $scope.model.value.substring(0, ($scope.model.config.MaxChars * 1)); + $scope.model.count = 0; + } + } + } +} +angular.module('umbraco').controller("Umbraco.PropertyEditors.textboxController", textboxController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html index 7df7e9fded..1e23b36718 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html @@ -1,9 +1,10 @@ -
+
- + ng-required="model.validation.mandatory" + ng-keyup="model.change()" /> Required +
{{model.count}} characters left
diff --git a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs index 01cd2585f3..85b4155f57 100644 --- a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs @@ -22,8 +22,8 @@ namespace Umbraco.Web.PropertyEditors internal class TextboxPreValueEditor : PreValueEditor { - [PreValueField("Maximum allowed characters", "number")] - public bool IsRequired { get; set; } + [PreValueField("maxChars", "Maximum allowed characters", "number", Description = "If empty - no character limit")] + public bool MaxChars { get; set; } } } From 53928c02f8b987acbe6556db66eff7ab177e0254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mads=20J=C3=B8rgensen?= Date: Wed, 16 Apr 2014 22:20:55 +0200 Subject: [PATCH 03/39] Textarea made work --- .../textarea/textarea.controller.js | 26 +++++++++++++++++++ .../propertyeditors/textarea/textarea.html | 10 +++++-- .../textbox/textbox.controller.js | 14 +++++----- .../propertyeditors/textbox/textbox.html | 5 +++- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 3 +++ src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 3 +++ .../umbraco/config/lang/en_us.xml | 3 +++ .../PropertyEditors/TextAreaPropertyEditor.cs | 10 +++++++ 8 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.controller.js diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.controller.js new file mode 100644 index 0000000000..2d4e114dcf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.controller.js @@ -0,0 +1,26 @@ +function textAreaController($rootScope, $scope, $log) { + $scope.model.maxlength = false; + if($scope.model.config.maxChars) { + $scope.model.maxlength = true; + if($scope.model.value == undefined) { + $scope.model.count = ($scope.model.config.maxChars * 1); + } else { + $scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length; + } + } + + $scope.model.change = function() { + if($scope.model.config.maxChars) { + if($scope.model.value == undefined) { + $scope.model.count = ($scope.model.config.maxChars * 1); + } else { + $scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length; + } + if($scope.model.count < 0) { + $scope.model.value = $scope.model.value.substring(0, ($scope.model.config.maxChars * 1)); + $scope.model.count = 0; + } + } + } +} +angular.module('umbraco').controller("Umbraco.PropertyEditors.textAreaController", textAreaController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.html index 8601155bda..92735db301 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.html @@ -1,2 +1,8 @@ - - \ No newline at end of file +
+ + +
+ {{model.count}} + characters left +
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js index 77052a70f5..03f7510112 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.controller.js @@ -1,23 +1,23 @@ function textboxController($rootScope, $scope, $log) { $scope.model.maxlength = false; - if($scope.model.config.MaxChars) { + if($scope.model.config.maxChars) { $scope.model.maxlength = true; if($scope.model.value == undefined) { - $scope.model.count = ($scope.model.config.MaxChars * 1); + $scope.model.count = ($scope.model.config.maxChars * 1); } else { - $scope.model.count = ($scope.model.config.MaxChars * 1) - $scope.model.value.length; + $scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length; } } $scope.model.change = function() { - if($scope.model.config.MaxChars) { + if($scope.model.config.maxChars) { if($scope.model.value == undefined) { - $scope.model.count = ($scope.model.config.MaxChars * 1); + $scope.model.count = ($scope.model.config.maxChars * 1); } else { - $scope.model.count = ($scope.model.config.MaxChars * 1) - $scope.model.value.length; + $scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length; } if($scope.model.count < 0) { - $scope.model.value = $scope.model.value.substring(0, ($scope.model.config.MaxChars * 1)); + $scope.model.value = $scope.model.value.substring(0, ($scope.model.config.maxChars * 1)); $scope.model.count = 0; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html index 1e23b36718..699c677621 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html @@ -6,5 +6,8 @@ ng-keyup="model.change()" /> Required -
{{model.count}} characters left
+
+ {{model.count}} + characters left +
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index c4b85332fa..6244e8f7e1 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -801,4 +801,7 @@ Mange hilsner fra umbraco robotten Din historik Session udløber + + Karakterer tilbage + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 5d57f57f42..a00131baba 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -985,4 +985,7 @@ To manage your website, simply open the umbraco back office and start adding con Your recent history Session expires in + + characters left + \ No newline at end of file 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 54e4918126..758ae1efaf 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -998,4 +998,7 @@ To manage your website, simply open the umbraco back office and start adding con Your recent history Session expires in + + characters left + diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs index e92a78dea8..9d5052c7e2 100644 --- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs @@ -6,5 +6,15 @@ namespace Umbraco.Web.PropertyEditors [PropertyEditor(Constants.PropertyEditors.TextboxMultipleAlias, "Textarea", "textarea", IsParameterEditor = true)] public class TextAreaPropertyEditor : PropertyEditor { + protected override PreValueEditor CreatePreValueEditor() + { + return new TextAreaPreValueEditor(); + } + + internal class TextAreaPreValueEditor : PreValueEditor + { + [PreValueField("maxChars", "Maximum allowed characters", "number", Description = "If empty - no character limit")] + public bool MaxChars { get; set; } + } } } \ No newline at end of file From 9589500412476918793a44d04b040cac9894d8ef Mon Sep 17 00:00:00 2001 From: Pete Duncanson Date: Fri, 6 Jan 2017 20:40:09 +0000 Subject: [PATCH 04/39] Fixed error label showing when you do a retry Should be a nice and easy one, the bool for if the DB connection is valid or not is never cleared on when you do a retry. http://issues.umbraco.org/issue/U4-9193 --- .../installer/steps/database.controller.js | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js index 5b3e174930..c4ac65bff1 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js @@ -1,28 +1,35 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseController", function($scope, $http, installerService){ $scope.checking = false; + $scope.invalidDbDns = false; + $scope.dbs = [ - {name: 'Microsoft SQL Server Compact (SQL CE)', id: 0}, - {name: 'Microsoft SQL Server', id: 1}, - { name: 'Microsoft SQL Azure', id: 3 }, - { name: 'MySQL', id: 2 }, - {name: 'Custom connection string', id: -1}]; + { name: 'Microsoft SQL Server Compact (SQL CE)', id: 0}, + { name: 'Microsoft SQL Server', id: 1}, + { name: 'Microsoft SQL Azure', id: 3 }, + { name: 'MySQL', id: 2 }, + { name: 'Custom connection string', id: -1} + ]; - if(installerService.status.current.model.dbType === undefined){ + if ( installerService.status.current.model.dbType === undefined ) { installerService.status.current.model.dbType = 0; } - $scope.validateAndForward = function(){ - if(!$scope.checking && this.myForm.$valid){ + $scope.validateAndForward = function(){ + if ( !$scope.checking && this.myForm.$valid ) { $scope.checking = true; + $scope.invalidDbDns = false; + var model = installerService.status.current.model; - $http.post(Umbraco.Sys.ServerVariables.installApiBaseUrl + "PostValidateDatabaseConnection", - model).then(function(response){ + $http.post( + Umbraco.Sys.ServerVariables.installApiBaseUrl + "PostValidateDatabaseConnection", + model ).then( function( response ) { - if(response.data === "true"){ + if ( response.data === "true" ) { installerService.forward(); - }else{ + } + else { $scope.invalidDbDns = true; } @@ -33,4 +40,4 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseControll }); } }; -}); \ No newline at end of file +}); From dd40dd964c6d0bdb9fedc540d836714d9d46d277 Mon Sep 17 00:00:00 2001 From: AndyButland Date: Wed, 10 May 2017 17:44:30 +0200 Subject: [PATCH 05/39] Ordered media types when returned for create dialog --- src/Umbraco.Web/Editors/MediaTypeController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index 879ffd3d0a..32d3ba6f34 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -230,7 +230,7 @@ namespace Umbraco.Web.Editors basic.Description = TranslateItem(basic.Description); } - return basics; + return basics.OrderBy(x => x.Name); } /// From 3cf8ef9513d271b6d3ffe216ddc4c2bda8fb5517 Mon Sep 17 00:00:00 2001 From: Callum Whyte Date: Thu, 18 May 2017 22:54:19 +0100 Subject: [PATCH 06/39] Including key property in model when selecting items in list view --- .../src/common/services/listviewhelper.service.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js index 0bdc3bb524..84bb4333a2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js @@ -269,12 +269,12 @@ var isSelected = false; for (var i = 0; selection.length > i; i++) { var selectedItem = selection[i]; - if (item.id === selectedItem.id) { + if (item.id === selectedItem.id || item.key === selectedItem.key) { isSelected = true; } } if (!isSelected) { - selection.push({ id: item.id }); + selection.push({ id: item.id, key: item.key }); item.selected = true; } } From 4b945f355a428bab702790e13ae66b4c958d5e93 Mon Sep 17 00:00:00 2001 From: Callum Whyte Date: Thu, 18 May 2017 22:54:44 +0100 Subject: [PATCH 07/39] Modifying Members list view to use key instead of Id --- .../propertyeditors/listview/listview.controller.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index f4068c0f02..a50a0f620e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -20,8 +20,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie getListResultsCallback = contentResource.getPagedResults; deleteItemCallback = contentResource.deleteByKey; getIdCallback = function (selected) { - var selectedKey = getItemKey(selected.id); - return selectedKey; + return selected.key; }; createEditUrlCallback = function (item) { return "/" + $scope.entityType + "/" + $scope.entityType + "/edit/" + item.key + "?page=" + $scope.options.pageNumber + "&listName=" + $scope.contentId; @@ -650,15 +649,6 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie return alias; } - function getItemKey(itemId) { - for (var i = 0; i < $scope.listViewResultSet.items.length; i++) { - var item = $scope.listViewResultSet.items[i]; - if (item.id === itemId) { - return item.key; - } - } - } - //GO! initView(); } From 290f34f034dba04cd6a2e7f5c7ecfeefd3dbe6a6 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 1 Jun 2017 17:24:10 +0200 Subject: [PATCH 08/39] FileSystemTreeController compatibility --- .../Trees/FileSystemTreeController.cs | 134 +++++++----------- .../Trees/FileSystemTreeController2.cs | 128 +++++++++++++++++ .../Trees/PartialViewMacrosTreeController.cs | 2 +- .../Trees/PartialViewsTreeController.cs | 2 +- src/Umbraco.Web/Trees/ScriptTreeController.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 3 +- 6 files changed, 181 insertions(+), 90 deletions(-) create mode 100644 src/Umbraco.Web/Trees/FileSystemTreeController2.cs diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController.cs b/src/Umbraco.Web/Trees/FileSystemTreeController.cs index 54979990b7..1201e33401 100644 --- a/src/Umbraco.Web/Trees/FileSystemTreeController.cs +++ b/src/Umbraco.Web/Trees/FileSystemTreeController.cs @@ -1,70 +1,84 @@ using System; using System.IO; -using System.Linq; -using System.Net.Http.Formatting; -using umbraco.BusinessLogic.Actions; -using Umbraco.Core; using Umbraco.Core.IO; -using Umbraco.Core.Services; using Umbraco.Web.Models.Trees; -using System.Web; namespace Umbraco.Web.Trees { public abstract class FileSystemTreeController : TreeController { - protected abstract IFileSystem2 FileSystem { get; } - protected abstract string[] Extensions { get; } - protected abstract string FileIcon { get; } + protected abstract string FilePath { get; } + protected abstract string FileSearchPattern { get; } /// /// Inheritors can override this method to modify the file node that is created. /// - /// + /// protected virtual void OnRenderFileNode(ref TreeNode treeNode) { } /// /// Inheritors can override this method to modify the folder node that is created. /// - /// + /// protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { } - protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + protected override Models.Trees.TreeNodeCollection GetTreeNodes(string id, System.Net.Http.Formatting.FormDataCollection queryStrings) { - var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString() - ? HttpUtility.UrlDecode(id).TrimStart("/") - : ""; + string orgPath = ""; + string path = ""; + if (!string.IsNullOrEmpty(id) && id != "-1") + { + orgPath = id; + path = IOHelper.MapPath(FilePath + "/" + orgPath); + orgPath += "/"; + } + else + { + path = IOHelper.MapPath(FilePath); + } - var directories = FileSystem.GetDirectories(path); + DirectoryInfo dirInfo = new DirectoryInfo(path); + DirectoryInfo[] dirInfos = dirInfo.GetDirectories(); var nodes = new TreeNodeCollection(); - foreach (var directory in directories) + foreach (DirectoryInfo dir in dirInfos) { - var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any(); + if ((dir.Attributes & FileAttributes.Hidden) == 0) + { + var HasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0; + var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", HasChildren); - var name = Path.GetFileName(directory); - var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren); - OnRenderFolderNode(ref node); - if(node != null) - nodes.Add(node); + OnRenderFolderNode(ref node); + if (node != null) + nodes.Add(node); + } } //this is a hack to enable file system tree to support multiple file extension look-up //so the pattern both support *.* *.xml and xml,js,vb for lookups - var files = FileSystem.GetFiles(path).Where(x => - { - var extension = Path.GetExtension(x); - return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase); - }); + string[] allowedExtensions = new string[0]; + bool filterByMultipleExtensions = FileSearchPattern.Contains(","); + FileInfo[] fileInfo; - foreach (var file in files) - { - var withoutExt = Path.GetFileNameWithoutExtension(file); - if (withoutExt.IsNullOrWhiteSpace() == false) + if (filterByMultipleExtensions) + { + fileInfo = dirInfo.GetFiles(); + allowedExtensions = FileSearchPattern.ToLower().Split(','); + } + else + fileInfo = dirInfo.GetFiles(FileSearchPattern); + + foreach (FileInfo file in fileInfo) + { + if ((file.Attributes & FileAttributes.Hidden) == 0) { - var name = Path.GetFileName(file); - var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false); + if (filterByMultipleExtensions && Array.IndexOf(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0) + continue; + + var node = CreateTreeNode(orgPath + file.Name, orgPath, queryStrings, file.Name, "icon-file", false); + OnRenderFileNode(ref node); + if (node != null) nodes.Add(node); } @@ -72,57 +86,5 @@ namespace Umbraco.Web.Trees return nodes; } - - protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - { - var menu = new MenuItemCollection(); - - //if root node no need to visit the filesystem so lets just create the menu and return it - if (id == Constants.System.Root.ToInvariantString()) - { - //set the default to create - menu.DefaultMenuAlias = ActionNew.Instance.Alias; - //create action - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); - //refresh action - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); - - return menu; - } - - var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString() - ? System.Web.HttpUtility.UrlDecode(id).TrimStart("/") - : ""; - - var isFile = FileSystem.FileExists(path); - var isDirectory = FileSystem.DirectoryExists(path); - - if (isDirectory) - { - //set the default to create - menu.DefaultMenuAlias = ActionNew.Instance.Alias; - //create action - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); - - var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any(); - - //We can only delete folders if it doesn't have any children (folders or files) - if (hasChildren == false) - { - //delete action - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); - } - - //refresh action - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); - } - else if (isFile) - { - //if it's not a directory then we only allow to delete the item - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias))); - } - - return menu; - } } } diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController2.cs b/src/Umbraco.Web/Trees/FileSystemTreeController2.cs new file mode 100644 index 0000000000..b8c7681df5 --- /dev/null +++ b/src/Umbraco.Web/Trees/FileSystemTreeController2.cs @@ -0,0 +1,128 @@ +using System; +using System.IO; +using System.Linq; +using System.Net.Http.Formatting; +using umbraco.BusinessLogic.Actions; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Core.Services; +using Umbraco.Web.Models.Trees; +using System.Web; + +namespace Umbraco.Web.Trees +{ + public abstract class FileSystemTreeController2 : TreeController + { + protected abstract IFileSystem2 FileSystem { get; } + protected abstract string[] Extensions { get; } + protected abstract string FileIcon { get; } + + /// + /// Inheritors can override this method to modify the file node that is created. + /// + /// + protected virtual void OnRenderFileNode(ref TreeNode treeNode) { } + + /// + /// Inheritors can override this method to modify the folder node that is created. + /// + /// + protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { } + + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString() + ? HttpUtility.UrlDecode(id).TrimStart("/") + : ""; + + var directories = FileSystem.GetDirectories(path); + + var nodes = new TreeNodeCollection(); + foreach (var directory in directories) + { + var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any(); + + var name = Path.GetFileName(directory); + var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren); + OnRenderFolderNode(ref node); + if(node != null) + nodes.Add(node); + } + + //this is a hack to enable file system tree to support multiple file extension look-up + //so the pattern both support *.* *.xml and xml,js,vb for lookups + var files = FileSystem.GetFiles(path).Where(x => + { + var extension = Path.GetExtension(x); + return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase); + }); + + foreach (var file in files) + { + var withoutExt = Path.GetFileNameWithoutExtension(file); + if (withoutExt.IsNullOrWhiteSpace() == false) + { + var name = Path.GetFileName(file); + var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false); + OnRenderFileNode(ref node); + if (node != null) + nodes.Add(node); + } + } + + return nodes; + } + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + var menu = new MenuItemCollection(); + + //if root node no need to visit the filesystem so lets just create the menu and return it + if (id == Constants.System.Root.ToInvariantString()) + { + //set the default to create + menu.DefaultMenuAlias = ActionNew.Instance.Alias; + //create action + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + //refresh action + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); + + return menu; + } + + var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString() + ? System.Web.HttpUtility.UrlDecode(id).TrimStart("/") + : ""; + + var isFile = FileSystem.FileExists(path); + var isDirectory = FileSystem.DirectoryExists(path); + + if (isDirectory) + { + //set the default to create + menu.DefaultMenuAlias = ActionNew.Instance.Alias; + //create action + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + + var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any(); + + //We can only delete folders if it doesn't have any children (folders or files) + if (hasChildren == false) + { + //delete action + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); + } + + //refresh action + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); + } + else if (isFile) + { + //if it's not a directory then we only allow to delete the item + menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias))); + } + + return menu; + } + } +} diff --git a/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs index b4cc2eb2fd..9b2bf0eb0d 100644 --- a/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs +++ b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees /// Tree for displaying partial view macros in the developer app /// [Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)] - public class PartialViewMacrosTreeController : FileSystemTreeController + public class PartialViewMacrosTreeController : FileSystemTreeController2 { protected override IFileSystem2 FileSystem { diff --git a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs index 264b44ad73..971ff4026b 100644 --- a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs +++ b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees /// Tree for displaying partial views in the settings app /// [Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)] - public class PartialViewsTreeController : FileSystemTreeController + public class PartialViewsTreeController : FileSystemTreeController2 { protected override IFileSystem2 FileSystem { diff --git a/src/Umbraco.Web/Trees/ScriptTreeController.cs b/src/Umbraco.Web/Trees/ScriptTreeController.cs index 616106a625..dcfa195131 100644 --- a/src/Umbraco.Web/Trees/ScriptTreeController.cs +++ b/src/Umbraco.Web/Trees/ScriptTreeController.cs @@ -5,7 +5,7 @@ using Umbraco.Web.Models.Trees; namespace Umbraco.Web.Trees { [Tree(Constants.Applications.Settings, "scripts", "Scripts", sortOrder: 4)] - public class ScriptTreeController : FileSystemTreeController + public class ScriptTreeController : FileSystemTreeController2 { protected override IFileSystem2 FileSystem { diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0b5652e509..59ad401f5c 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -435,6 +435,7 @@ + @@ -712,7 +713,7 @@ - + From ce618d289b8239d7c4396b34d2c334f2cead6acf Mon Sep 17 00:00:00 2001 From: AndyButland Date: Mon, 5 Jun 2017 16:43:17 +0200 Subject: [PATCH 09/39] Extended HttpsCheck healthcheck to check for expiring SSL certificate --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 4 +- .../umbraco/config/lang/en_us.xml | 4 +- .../HealthCheck/Checks/Security/HttpsCheck.cs | 42 ++++++++++++++++--- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index d99cd8f43f..22a97054e4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1474,8 +1474,10 @@ To manage your website, simply open the Umbraco back office and start adding con Media - Total XML: %0%, Total: %1%, Total invalid: %2% Content - Total XML: %0%, Total published: %1%, Total invalid: %2% - Your site certificate was marked as valid. + Your website's certificate is valid. Certificate validation error: '%0%' + Your website's SSL certificate has expired. + Your website's SSL certificate is expiring in %0% days. Error pinging the URL %0% - '%1%' You are currently %0% viewing the site using the HTTPS scheme. The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. 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 63fc12101f..1847892530 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -1469,8 +1469,10 @@ To manage your website, simply open the Umbraco back office and start adding con Media - Total XML: %0%, Total: %1%, Total invalid: %2% Content - Total XML: %0%, Total published: %1%, Total invalid: %2% - Your site certificate was marked as valid. + Your website's certificate is valid. Certificate validation error: '%0%' + Your website's SSL certificate has expired. + Your website's SSL certificate is expiring in %0% days. Error pinging the URL %0% - '%1%' You are currently %0% viewing the site using the HTTPS scheme. The appSetting 'umbracoUseSSL' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. diff --git a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs index 4e2dc4f8f5..b50fc99a6e 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Security.Cryptography.X509Certificates; using System.Web; using Umbraco.Core.IO; using Umbraco.Core.Services; @@ -53,7 +54,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Security private HealthCheckStatus CheckForValidCertificate() { var message = string.Empty; - var success = false; + StatusResultType result; var url = HealthCheckContext.HttpContext.Request.Url; // Attempt to access the site over HTTPS to see if it HTTPS is supported @@ -65,7 +66,37 @@ namespace Umbraco.Web.HealthCheck.Checks.Security try { var response = (HttpWebResponse)request.GetResponse(); - success = response.StatusCode == HttpStatusCode.OK; + if (response.StatusCode == HttpStatusCode.OK) + { + // Got a valid response, check now for if certificate expiring within 14 days + // Hat-tip: https://stackoverflow.com/a/15343898/489433 + const int NumberOfDaysForExpiryWarning = 14; + var cert = request.ServicePoint.Certificate; + var cert2 = new X509Certificate2(cert); + var expirationDate = cert2.NotAfter; + + var daysToExpiry = (int)Math.Floor((cert2.NotAfter - DateTime.Now).TotalDays); + if (daysToExpiry <= 0) + { + result = StatusResultType.Error; + message = _textService.Localize("healthcheck/httpsCheckExpiredCertificate"); + } + else if (daysToExpiry < NumberOfDaysForExpiryWarning) + { + result = StatusResultType.Warning; + message = _textService.Localize("healthcheck/httpsCheckExpiringCertificate", new[] { daysToExpiry.ToString() }); + } + else + { + result = StatusResultType.Success; + message = _textService.Localize("healthcheck/httpsCheckValidCertificate"); + } + } + else + { + result = StatusResultType.Error; + message = _textService.Localize("healthcheck/httpsCheckInvalidUrl", new[] { address, response.StatusDescription }); + } } catch (Exception ex) { @@ -80,17 +111,16 @@ namespace Umbraco.Web.HealthCheck.Checks.Security { message = _textService.Localize("healthcheck/httpsCheckInvalidUrl", new[] { address, ex.Message }); } + + result = StatusResultType.Error; } var actions = new List(); - if (success) - message = _textService.Localize("healthcheck/httpsCheckValidCertificate"); - return new HealthCheckStatus(message) { - ResultType = success ? StatusResultType.Success : StatusResultType.Error, + ResultType = result, Actions = actions }; } From 993513b1388d2725cc11dcd864da30665d98cc6d Mon Sep 17 00:00:00 2001 From: Harvey Williams Date: Thu, 8 Jun 2017 15:17:34 +0100 Subject: [PATCH 10/39] Fix for `IsDocumentTypeRecursive` - U4-9997 Potential fix to issue logged on: http://issues.umbraco.org/issue/U4-9997 --- src/Umbraco.Web/PublishedContentExtensions.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 36d1306ab6..1c1aa2d5a2 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -634,14 +634,10 @@ namespace Umbraco.Web private static bool IsDocumentTypeRecursive(IPublishedContent content, string docTypeAlias) { var contentTypeService = UmbracoContext.Current.Application.Services.ContentTypeService; - var type = contentTypeService.GetContentType(content.DocumentTypeAlias); - while (type != null && type.ParentId > 0) - { - type = contentTypeService.GetContentType(type.ParentId); - if (type.Alias.InvariantEquals(docTypeAlias)) - return true; - } - return false; + var type = contentTypeService.GetContentType(content.DocumentTypeAlias); + if (type.Alias.InvariantEquals(docTypeAlias) || content.IsComposedOf(docTypeAlias)) + return true; + return false; } public static bool IsNull(this IPublishedContent content, string alias, bool recurse) @@ -912,14 +908,14 @@ namespace Umbraco.Web #region Axes: ancestors, ancestors-or-self - // as per XPath 1.0 specs 2.2, + // as per XPath 1.0 specs §2.2, // - the ancestor axis contains the ancestors of the context node; the ancestors of the context node consist // of the parent of context node and the parent's parent and so on; thus, the ancestor axis will always // include the root node, unless the context node is the root node. // - the ancestor-or-self axis contains the context node and the ancestors of the context node; thus, // the ancestor axis will always include the root node. // - // as per XPath 2.0 specs 3.2.1.1, + // as per XPath 2.0 specs §3.2.1.1, // - the ancestor axis is defined as the transitive closure of the parent axis; it contains the ancestors // of the context node (the parent, the parent of the parent, and so on) - The ancestor axis includes the // root node of the tree in which the context node is found, unless the context node is the root node. @@ -929,7 +925,7 @@ namespace Umbraco.Web // the ancestor and ancestor-or-self axis are reverse axes ie they contain the context node or nodes that // are before the context node in document order. // - // document order is defined by 2.4.1 as: + // document order is defined by §2.4.1 as: // - the root node is the first node. // - every node occurs before all of its children and descendants. // - the relative order of siblings is the order in which they occur in the children property of their parent node. @@ -1240,12 +1236,12 @@ namespace Umbraco.Web } - // as per XPath 1.0 specs 2.2, + // as per XPath 1.0 specs §2.2, // - the descendant axis contains the descendants of the context node; a descendant is a child or a child of a child and so on; thus // the descendant axis never contains attribute or namespace nodes. // - the descendant-or-self axis contains the context node and the descendants of the context node. // - // as per XPath 2.0 specs 3.2.1.1, + // as per XPath 2.0 specs §3.2.1.1, // - the descendant axis is defined as the transitive closure of the child axis; it contains the descendants of the context node (the // children, the children of the children, and so on). // - the descendant-or-self axis contains the context node and the descendants of the context node. @@ -1253,7 +1249,7 @@ namespace Umbraco.Web // the descendant and descendant-or-self axis are forward axes ie they contain the context node or nodes that are after the context // node in document order. // - // document order is defined by 2.4.1 as: + // document order is defined by §2.4.1 as: // - the root node is the first node. // - every node occurs before all of its children and descendants. // - the relative order of siblings is the order in which they occur in the children property of their parent node. From 047eb893eb54b0198761d42cb1599773dd2ef466 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Tue, 13 Jun 2017 12:28:59 +0100 Subject: [PATCH 11/39] Switches Umbraco.MediaPicker (double legacy) to being converted by MultipleMediaPickerPropertyConverter so that it actually works Renames MultipleMediaPickerPropertyConverter to LegacyMediaPickerPropertyConverter (delete for v8) --- .../Cache/DataTypeCacheRefresher.cs | 2 +- ...s => LegacyMediaPickerPropertyConverter.cs} | 18 ++++++++++++------ .../MediaPickerPropertyConverter.cs | 4 ---- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) rename src/Umbraco.Web/PropertyEditors/ValueConverters/{MultipleMediaPickerPropertyConverter.cs => LegacyMediaPickerPropertyConverter.cs} (91%) diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index 34ca2ceec0..12fd41a83d 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -114,7 +114,7 @@ namespace Umbraco.Web.Cache }); TagsValueConverter.ClearCaches(); - MultipleMediaPickerPropertyConverter.ClearCaches(); + LegacyMediaPickerPropertyConverter.ClearCaches(); SliderValueConverter.ClearCaches(); MediaPickerPropertyConverter.ClearCaches(); diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs similarity index 91% rename from src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs rename to src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs index 161e7178e7..db115f58de 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/LegacyMediaPickerPropertyConverter.cs @@ -1,5 +1,5 @@ // -------------------------------------------------------------------------------------------------------------------- -// +// // Umbraco // // @@ -24,20 +24,20 @@ using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors.ValueConverters { /// - /// The multiple media picker property value converter. + /// The multiple media picker and double legacy media picker property value converter, should be deleted for v8 /// [DefaultPropertyValueConverter(typeof(MustBeStringValueConverter))] - public class MultipleMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + public class LegacyMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta { private readonly IDataTypeService _dataTypeService; //TODO: Remove this ctor in v8 since the other one will use IoC - public MultipleMediaPickerPropertyConverter() + public LegacyMediaPickerPropertyConverter() : this(ApplicationContext.Current.Services.DataTypeService) { } - public MultipleMediaPickerPropertyConverter(IDataTypeService dataTypeService) + public LegacyMediaPickerPropertyConverter(IDataTypeService dataTypeService) { if (dataTypeService == null) throw new ArgumentNullException("dataTypeService"); _dataTypeService = dataTypeService; @@ -58,6 +58,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters { return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias); } + + if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters) + { + // this is the double legacy media picker, it can pick only single media items + return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias); + } return false; } @@ -109,7 +115,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById( propertyType.DataTypeId).Name); - LogHelper.Warn(error); + LogHelper.Warn(error); throw new Exception(error); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs index 5f54363975..2e9d0c7d96 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs @@ -126,10 +126,6 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPicker2Alias)) return true; - if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters) - { - return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias); - } return false; } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0b5652e509..0ee2bfd37d 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -411,7 +411,7 @@ - + From 33f76d25f7bed97594647822065b58e91b60e8d7 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 14 Jun 2017 15:04:56 +0200 Subject: [PATCH 12/39] U4-9993 - fix upgrade issues --- .../UpdateUniqueIdToHaveCorrectIndexType.cs | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs index 79d7b3111c..dc8415a9f8 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs @@ -1,5 +1,4 @@ using System.Linq; -using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -11,15 +10,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe { public UpdateUniqueIdToHaveCorrectIndexType(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) - { - } + { } - //see: http://issues.umbraco.org/issue/U4-6188, http://issues.umbraco.org/issue/U4-6187 public override void Up() { - - - var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database) + var indexes = SqlSyntax.GetDefinedIndexes(Context.Database) .Select(x => new DbIndexDefinition() { TableName = x.Item1, @@ -28,24 +23,19 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe IsUnique = x.Item4 }).ToArray(); - //must be non-nullable + // drop the index if it exists + if (indexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID"))) + Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode"); + + // set uniqueID to be non-nullable + // the index *must* be dropped else 'one or more objects access this column' exception Alter.Table("umbracoNode").AlterColumn("uniqueID").AsGuid().NotNullable(); - //make sure it already exists - if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID"))) - { - Delete.Index("IX_umbracoNodeUniqueID").OnTable("umbracoNode"); - } - //make sure it doesn't already exist - if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNode_uniqueID")) == false) - { - //must be a uniqe index - Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique(); - } + // create the index + Create.Index("IX_umbracoNode_uniqueID").OnTable("umbracoNode").OnColumn("uniqueID").Unique(); } public override void Down() - { - } + { } } } \ No newline at end of file From 51997d0651af0005f412142c7052ca5e13c150e3 Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 4 Jul 2017 14:28:15 +0200 Subject: [PATCH 13/39] U4-10098 Update FileService to support legacy MacroScript and UserControl folders --- .../IO/FileSystemProviderManager.cs | 10 ++ src/Umbraco.Core/Models/IUserControl.cs | 7 + src/Umbraco.Core/Models/PartialViewType.cs | 3 +- src/Umbraco.Core/Models/UserControl.cs | 32 +++++ .../Interfaces/IUserControlRepository.cs | 13 ++ .../Repositories/MacroScriptRepository.cs | 15 ++ .../Repositories/UserControlRepository.cs | 135 ++++++++++++++++++ .../Persistence/RepositoryFactory.cs | 12 ++ src/Umbraco.Core/Services/FileService.cs | 20 +++ src/Umbraco.Core/Services/IFileService.cs | 4 + src/Umbraco.Core/UdiEntityType.cs | 8 +- src/Umbraco.Core/UdiGetterExtensions.cs | 11 ++ src/Umbraco.Core/Umbraco.Core.csproj | 5 + src/Umbraco.Web/umbraco.presentation/macro.cs | 1 + .../developer/Macros/assemblyBrowser.aspx.cs | 1 + 15 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Core/Models/IUserControl.cs create mode 100644 src/Umbraco.Core/Models/UserControl.cs create mode 100644 src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserControlRepository.cs create mode 100644 src/Umbraco.Core/Persistence/Repositories/MacroScriptRepository.cs create mode 100644 src/Umbraco.Core/Persistence/Repositories/UserControlRepository.cs diff --git a/src/Umbraco.Core/IO/FileSystemProviderManager.cs b/src/Umbraco.Core/IO/FileSystemProviderManager.cs index df922fb2b0..aa693232a8 100644 --- a/src/Umbraco.Core/IO/FileSystemProviderManager.cs +++ b/src/Umbraco.Core/IO/FileSystemProviderManager.cs @@ -19,6 +19,8 @@ namespace Umbraco.Core.IO private ShadowWrapper _macroPartialFileSystem; private ShadowWrapper _partialViewsFileSystem; + private ShadowWrapper _macroScriptsFileSystem; + private ShadowWrapper _userControlsFileSystem; private ShadowWrapper _stylesheetsFileSystem; private ShadowWrapper _scriptsFileSystem; private ShadowWrapper _xsltFileSystem; @@ -61,6 +63,8 @@ namespace Umbraco.Core.IO { var macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials); var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews); + var macroScriptsFileSystem = new PhysicalFileSystem(SystemDirectories.MacroScripts); + var userControlsFileSystem = new PhysicalFileSystem(SystemDirectories.UserControls); var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css); var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts); var xsltFileSystem = new PhysicalFileSystem(SystemDirectories.Xslt); @@ -69,6 +73,8 @@ namespace Umbraco.Core.IO _macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", ScopeProvider); _partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", ScopeProvider); + _macroScriptsFileSystem = new ShadowWrapper(macroScriptsFileSystem, "macroScripts", ScopeProvider); + _userControlsFileSystem = new ShadowWrapper(userControlsFileSystem, "usercontrols", ScopeProvider); _stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", ScopeProvider); _scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", ScopeProvider); _xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", ScopeProvider); @@ -85,6 +91,10 @@ namespace Umbraco.Core.IO public IFileSystem2 MacroPartialsFileSystem { get { return _macroPartialFileSystem; } } public IFileSystem2 PartialViewsFileSystem { get { return _partialViewsFileSystem; } } + // Legacy /macroScripts folder + public IFileSystem2 MacroScriptsFileSystem { get { return _macroScriptsFileSystem; } } + // Legacy /usercontrols folder + public IFileSystem2 UserControlsFileSystem { get { return _userControlsFileSystem; } } public IFileSystem2 StylesheetsFileSystem { get { return _stylesheetsFileSystem; } } public IFileSystem2 ScriptsFileSystem { get { return _scriptsFileSystem; } } public IFileSystem2 XsltFileSystem { get { return _xsltFileSystem; } } diff --git a/src/Umbraco.Core/Models/IUserControl.cs b/src/Umbraco.Core/Models/IUserControl.cs new file mode 100644 index 0000000000..2660567258 --- /dev/null +++ b/src/Umbraco.Core/Models/IUserControl.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Core.Models +{ + public interface IUserControl : IFile + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Models/PartialViewType.cs b/src/Umbraco.Core/Models/PartialViewType.cs index 6204b6e165..6740d1fdd9 100644 --- a/src/Umbraco.Core/Models/PartialViewType.cs +++ b/src/Umbraco.Core/Models/PartialViewType.cs @@ -4,6 +4,7 @@ { Unknown = 0, // default PartialView = 1, - PartialViewMacro = 2 + PartialViewMacro = 2, + MacroScript = 3 } } diff --git a/src/Umbraco.Core/Models/UserControl.cs b/src/Umbraco.Core/Models/UserControl.cs new file mode 100644 index 0000000000..6af4cd74cc --- /dev/null +++ b/src/Umbraco.Core/Models/UserControl.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.Serialization; + +namespace Umbraco.Core.Models +{ + /// + /// Represents a UserControl file + /// + [Serializable] + [DataContract(IsReference = true)] + public class UserControl : File, IUserControl + { + public UserControl(string path) + : this(path, (Func)null) + { } + + internal UserControl(string path, Func getFileContent) + : base(path, getFileContent) + { } + + /// + /// Indicates whether the current entity has an identity, which in this case is a path/name. + /// + /// + /// Overrides the default Entity identity check. + /// + public override bool HasIdentity + { + get { return string.IsNullOrEmpty(Path) == false; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserControlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserControlRepository.cs new file mode 100644 index 0000000000..7efb29b0a5 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserControlRepository.cs @@ -0,0 +1,13 @@ +using System.IO; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Persistence.Repositories +{ + public interface IUserControlRepository : IRepository + { + bool ValidateUserControl(UserControl userControl); + Stream GetFileContentStream(string filepath); + void SetFileContent(string filepath, Stream content); + long GetFileSize(string filepath); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MacroScriptRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MacroScriptRepository.cs new file mode 100644 index 0000000000..0f335173ad --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/MacroScriptRepository.cs @@ -0,0 +1,15 @@ +using Umbraco.Core.IO; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Persistence.Repositories +{ + internal class MacroScriptRepository : PartialViewRepository + { + public MacroScriptRepository(IUnitOfWork work, IFileSystem fileSystem) + : base(work, fileSystem) + { } + + protected override PartialViewType ViewType { get { return PartialViewType.MacroScript; } } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/UserControlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserControlRepository.cs new file mode 100644 index 0000000000..77ad09cb57 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/UserControlRepository.cs @@ -0,0 +1,135 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Umbraco.Core.IO; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Persistence.Repositories +{ + /// + /// Represents the UserControl Repository + /// + internal class UserControlRepository : FileRepository, IUserControlRepository + { + public UserControlRepository(IUnitOfWork work, IFileSystem fileSystem) + : base(work, fileSystem) + { + } + + public override UserControl Get(string id) + { + var path = FileSystem.GetRelativePath(id); + + path = path.EnsureEndsWith(".ascx"); + + if (FileSystem.FileExists(path) == false) + return null; + + var created = FileSystem.GetCreated(path).UtcDateTime; + var updated = FileSystem.GetLastModified(path).UtcDateTime; + + var userControl = new UserControl(path, file => GetFileContent(file.OriginalPath)) + { + Key = path.EncodeAsGuid(), + CreateDate = created, + UpdateDate = updated, + Id = path.GetHashCode(), + VirtualPath = FileSystem.GetUrl(path) + }; + + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + userControl.ResetDirtyProperties(false); + + return userControl; + } + + public override void AddOrUpdate(UserControl entity) + { + base.AddOrUpdate(entity); + + // ensure that from now on, content is lazy-loaded + if (entity.GetFileContent == null) + entity.GetFileContent = file => GetFileContent(file.OriginalPath); + } + + public override IEnumerable GetAll(params string[] ids) + { + ids = ids + .Select(x => StringExtensions.EnsureEndsWith(x, ".ascx")) + .Distinct() + .ToArray(); + + if (ids.Any()) + { + foreach (var id in ids) + { + yield return Get(id); + } + } + else + { + var files = FindAllFiles("", "*.ascx"); + foreach (var file in files) + { + yield return Get(file); + } + } + } + + /// + /// Gets a list of all that exist at the relative path specified. + /// + /// + /// If null or not specified, will return the UserControl files at the root path relative to the IFileSystem + /// + /// + public IEnumerable GetUserControlsAtPath(string rootPath = null) + { + return FileSystem.GetFiles(rootPath ?? string.Empty, "*.ascx").Select(Get); + } + + private static readonly List ValidExtensions = new List { "ascx" }; + + public bool ValidateUserControl(UserControl userControl) + { + // get full path + string fullPath; + try + { + // may throw for security reasons + fullPath = FileSystem.GetFullPath(userControl.Path); + } + catch + { + return false; + } + + // validate path and extension + var validDir = SystemDirectories.UserControls; + var isValidPath = IOHelper.VerifyEditPath(fullPath, validDir); + var isValidExtension = IOHelper.VerifyFileExtension(userControl.Path, ValidExtensions); + return isValidPath && isValidExtension; + } + + public Stream GetFileContentStream(string filepath) + { + if (FileSystem.FileExists(filepath) == false) return null; + + try + { + return FileSystem.OpenFile(filepath); + } + catch + { + return null; // deal with race conds + } + } + + public void SetFileContent(string filepath, Stream content) + { + FileSystem.AddFile(filepath, content, true); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index afb93f620f..631c292eac 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -231,6 +231,18 @@ namespace Umbraco.Core.Persistence return new PartialViewMacroRepository(uow, FileSystemProviderManager.Current.MacroPartialsFileSystem); } + [Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")] + internal virtual IPartialViewRepository CreateMacroScriptRepository(IUnitOfWork uow) + { + return new MacroScriptRepository(uow, FileSystemProviderManager.Current.MacroScriptsFileSystem); + } + + [Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")] + internal virtual IUserControlRepository CreateUserControlRepository(IUnitOfWork uow) + { + return new UserControlRepository(uow, FileSystemProviderManager.Current.UserControlsFileSystem); + } + public virtual IStylesheetRepository CreateStylesheetRepository(IUnitOfWork uow) { return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem); diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index 28fb07fe9e..f76ecb0c88 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -783,6 +783,26 @@ namespace Umbraco.Core.Services } } + [Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")] + public IPartialView GetMacroScript(string path) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateMacroScriptRepository(uow); + return repository.Get(path); + } + } + + [Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")] + public IUserControl GetUserControl(string path) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateUserControlRepository(uow); + return repository.Get(path); + } + } + public IEnumerable GetPartialViewMacros(params string[] names) { using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index e8f1065219..cc653624f2 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -17,6 +17,10 @@ namespace Umbraco.Core.Services void DeletePartialViewMacroFolder(string folderPath); IPartialView GetPartialView(string path); IPartialView GetPartialViewMacro(string path); + [Obsolete("MacroScripts are obsolete - this is for backwards compatibility with upgraded sites.")] + IPartialView GetMacroScript(string path); + [Obsolete("UserControls are obsolete - this is for backwards compatibility with upgraded sites.")] + IUserControl GetUserControl(string path); IEnumerable GetPartialViewMacros(params string[] names); IXsltFile GetXsltFile(string path); IEnumerable GetXsltFiles(params string[] names); diff --git a/src/Umbraco.Core/UdiEntityType.cs b/src/Umbraco.Core/UdiEntityType.cs index 0119e83b24..8fb5d99338 100644 --- a/src/Umbraco.Core/UdiEntityType.cs +++ b/src/Umbraco.Core/UdiEntityType.cs @@ -69,6 +69,10 @@ namespace Umbraco.Core [UdiType(UdiType.StringUdi)] public const string AnyString = "any-string"; // that one is for tests + [UdiType(UdiType.StringUdi)] + public const string Language = "language"; + [UdiType(UdiType.StringUdi)] + public const string MacroScript = "macroscript"; [UdiType(UdiType.StringUdi)] public const string MediaFile = "media-file"; [UdiType(UdiType.StringUdi)] @@ -82,9 +86,9 @@ namespace Umbraco.Core [UdiType(UdiType.StringUdi)] public const string PartialViewMacro = "partial-view-macro"; [UdiType(UdiType.StringUdi)] - public const string Xslt = "xslt"; + public const string UserControl = "usercontrol"; [UdiType(UdiType.StringUdi)] - public const string Language = "language"; + public const string Xslt = "xslt"; public static string FromUmbracoObjectType(UmbracoObjectTypes umbracoObjectType) { diff --git a/src/Umbraco.Core/UdiGetterExtensions.cs b/src/Umbraco.Core/UdiGetterExtensions.cs index d663acba9d..4ae6b05dca 100644 --- a/src/Umbraco.Core/UdiGetterExtensions.cs +++ b/src/Umbraco.Core/UdiGetterExtensions.cs @@ -190,6 +190,17 @@ namespace Umbraco.Core return new GuidUdi(Constants.UdiEntityType.Macro, entity.Key).EnsureClosed(); } + /// + /// Gets the entity identifier of the entity. + /// + /// The entity. + /// The entity identifier of the entity. + public static StringUdi GetUdi(this IUserControl entity) + { + if (entity == null) throw new ArgumentNullException("entity"); + return new StringUdi(Constants.UdiEntityType.UserControl, entity.Path.TrimStart('/')).EnsureClosed(); + } + /// /// Gets the entity identifier of the entity. /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index d5a9ea33cc..24fdf32150 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -344,7 +344,9 @@ + + @@ -576,12 +578,15 @@ + + + diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 6d2936cd9a..dac3c0e1bf 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -46,6 +46,7 @@ using System.Linq; using File = System.IO.File; using MacroTypes = umbraco.cms.businesslogic.macro.MacroTypes; using Member = umbraco.cms.businesslogic.member.Member; +using UserControl = System.Web.UI.UserControl; namespace umbraco { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs index d186d9ef50..273318cbff 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/assemblyBrowser.aspx.cs @@ -19,6 +19,7 @@ using Umbraco.Core.PropertyEditors; using umbraco.BusinessLogic; using System.Collections.Generic; using MacroProperty = umbraco.cms.businesslogic.macro.MacroProperty; +using UserControl = System.Web.UI.UserControl; namespace umbraco.developer { From b840a0992cfd4e445b56badf3beaccf287fcc8ca Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 4 Jul 2017 14:47:29 +0200 Subject: [PATCH 14/39] adding shadow filesystems. --- src/Umbraco.Core/IO/FileSystemProviderManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Core/IO/FileSystemProviderManager.cs b/src/Umbraco.Core/IO/FileSystemProviderManager.cs index aa693232a8..d1c779dcff 100644 --- a/src/Umbraco.Core/IO/FileSystemProviderManager.cs +++ b/src/Umbraco.Core/IO/FileSystemProviderManager.cs @@ -266,9 +266,11 @@ namespace Umbraco.Core.IO var i = 0; while (i < typed.Length) wrappers[i] = typed[i++]; wrappers[i++] = _macroPartialFileSystem; + wrappers[i++] = _macroScriptsFileSystem; wrappers[i++] = _partialViewsFileSystem; wrappers[i++] = _stylesheetsFileSystem; wrappers[i++] = _scriptsFileSystem; + wrappers[i++] = _userControlsFileSystem; wrappers[i++] = _xsltFileSystem; wrappers[i++] = _masterPagesFileSystem; wrappers[i] = _mvcViewsFileSystem; From ca752f74bc0de3a038fc0053ac553399471ddd8d Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 4 Jul 2017 17:29:32 +0200 Subject: [PATCH 15/39] updating array length. --- src/Umbraco.Core/IO/FileSystemProviderManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/IO/FileSystemProviderManager.cs b/src/Umbraco.Core/IO/FileSystemProviderManager.cs index d1c779dcff..d2ae8a0612 100644 --- a/src/Umbraco.Core/IO/FileSystemProviderManager.cs +++ b/src/Umbraco.Core/IO/FileSystemProviderManager.cs @@ -262,7 +262,7 @@ namespace Umbraco.Core.IO internal ICompletable Shadow(Guid id) { var typed = _wrappers.ToArray(); - var wrappers = new ShadowWrapper[typed.Length + 7]; + var wrappers = new ShadowWrapper[typed.Length + 9]; var i = 0; while (i < typed.Length) wrappers[i] = typed[i++]; wrappers[i++] = _macroPartialFileSystem; From cfa7b0a092c96de6eaf04956d0d4f7be9e459b8c Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 6 Jul 2017 10:44:51 +0200 Subject: [PATCH 16/39] U4-10124 Update IFileService to handle MacroScripts and UserControls --- src/Umbraco.Core/Services/FileService.cs | 56 +++++++++++++++++++++++ src/Umbraco.Core/Services/IFileService.cs | 42 +++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index f76ecb0c88..4833401df8 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -621,6 +621,34 @@ namespace Umbraco.Core.Services } } + public Stream GetMacroScriptFileContentStream(string filepath) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateMacroScriptRepository(uow); + return repository.GetFileContentStream(filepath); + } + } + + public void SetMacroScriptFileContent(string filepath, Stream content) + { + using (var uow = UowProvider.GetUnitOfWork()) + { + var repository = RepositoryFactory.CreateMacroScriptRepository(uow); + repository.SetFileContent(filepath, content); + uow.Commit(); + } + } + + public long GetMacroScriptFileSize(string filepath) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateMacroScriptRepository(uow); + return repository.GetFileSize(filepath); + } + } + #endregion public Stream GetStylesheetFileContentStream(string filepath) @@ -679,6 +707,34 @@ namespace Umbraco.Core.Services } } + public Stream GetUserControlFileContentStream(string filepath) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateUserControlRepository(uow); + return repository.GetFileContentStream(filepath); + } + } + + public void SetUserControlFileContent(string filepath, Stream content) + { + using (var uow = UowProvider.GetUnitOfWork()) + { + var repository = RepositoryFactory.CreateUserControlRepository(uow); + repository.SetFileContent(filepath, content); + uow.Commit(); + } + } + + public long GetUserControlFileSize(string filepath) + { + using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) + { + var repository = RepositoryFactory.CreateUserControlRepository(uow); + return repository.GetFileSize(filepath); + } + } + public Stream GetXsltFileContentStream(string filepath) { using (var uow = UowProvider.GetUnitOfWork(readOnly: true)) diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index cc653624f2..74de0861d8 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -267,6 +267,27 @@ namespace Umbraco.Core.Services /// The size of the template. long GetTemplateFileSize(string filepath); + /// + /// Gets the content of a macroscript as a stream. + /// + /// The filesystem path to the macroscript. + /// The content of the macroscript. + Stream GetMacroScriptFileContentStream(string filepath); + + /// + /// Sets the content of a macroscript. + /// + /// The filesystem path to the macroscript. + /// The content of the macroscript. + void SetMacroScriptFileContent(string filepath, Stream content); + + /// + /// Gets the size of a macroscript. + /// + /// The filesystem path to the macroscript. + /// The size of the macroscript. + long GetMacroScriptFileSize(string filepath); + /// /// Gets the content of a stylesheet as a stream. /// @@ -309,6 +330,27 @@ namespace Umbraco.Core.Services /// The size of the script file. long GetScriptFileSize(string filepath); + /// + /// Gets the content of a usercontrol as a stream. + /// + /// The filesystem path to the usercontrol. + /// The content of the usercontrol. + Stream GetUserControlFileContentStream(string filepath); + + /// + /// Sets the content of a usercontrol. + /// + /// The filesystem path to the usercontrol. + /// The content of the usercontrol. + void SetUserControlFileContent(string filepath, Stream content); + + /// + /// Gets the size of a usercontrol. + /// + /// The filesystem path to the usercontrol. + /// The size of the usercontrol. + long GetUserControlFileSize(string filepath); + /// /// Gets the content of a XSLT file as a stream. /// From 4d316cf0ce670929644f2dd58c1fee7eb6ab0f7a Mon Sep 17 00:00:00 2001 From: mikkelhm Date: Thu, 6 Jul 2017 15:06:55 +0200 Subject: [PATCH 17/39] Reverts the change for the installer screen which needs to be ready for the new starterkit and Lessons --- .../src/installer/steps/starterkit.html | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html b/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html index 6ccf99be7f..0b9e22a0f3 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html @@ -1,16 +1,23 @@
-

Would you like to learn or demo Umbraco?

+

Install a starter website

+ +

+ Installing a starter website helps you learn how Umbraco works, and gives you a solid + and simple foundation to build on top of. +

+ + Loading... + + - {{pck.name}} -

The Starter Kit is a great way to experience some of the ways you can use Umbraco. It's a complete website with textpages, landing pages, blog, product listings and more that's easy to get started with Umbraco. -

-

- It's also a great way to learn Umbraco as the Starter Kit comes with a set of Lessons that'll teach you how to implement and extend Umbraco using short 5-15 minute tasks. -

-

- Yes, I'd like a Starter Kit -   - No thanks + No thanks, I do not want to install a starter website -

\ No newline at end of file + From 1e6d50a86ba904cdccbe7232e31c3ec5d7015727 Mon Sep 17 00:00:00 2001 From: srmooney Date: Thu, 6 Jul 2017 10:50:19 -0400 Subject: [PATCH 18/39] Add option for Listview to change the tab name --- .../Models/Mapping/TabsAndPropertiesResolver.cs | 7 ++++++- src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index 0671f59273..930e420374 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -170,7 +170,12 @@ namespace Umbraco.Web.Models.Mapping var listViewConfig = editor.PreValueEditor.ConvertDbToEditor(editor.DefaultPreValues, preVals); //add the entity type to the config - listViewConfig["entityType"] = entityType; + listViewConfig["entityType"] = entityType; + + //Override Tab Label if tabName is provided + if (listViewConfig.ContainsKey("tabName") && !String.IsNullOrWhiteSpace(listViewConfig["tabName"].ToString())) { + listViewTab.Label = listViewConfig["tabName"].ToString(); + } var listViewProperties = new List(); listViewProperties.Add(new ContentPropertyDisplay diff --git a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs index f744e4d807..9d897501b1 100644 --- a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs @@ -50,7 +50,10 @@ namespace Umbraco.Web.PropertyEditors } internal class ListViewPreValueEditor : PreValueEditor - { + { + [PreValueField("tabName", "Tab Name", "textstring", Description = "The name of the tab that the list of child items will be displayed")] + public int TabName { get; set; } + [PreValueField("displayAtTabNumber", "Display At Tab Number", "number", Description = "Which tab position that the list of child items will be displayed")] public int DisplayAtTabNumber { get; set; } From 733aab6eb5327a11322a7fa54e725caf9187559e Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 18:57:57 +0200 Subject: [PATCH 19/39] Fix vertical separator color and height of icon in custom section --- src/Umbraco.Web.UI.Client/src/less/sections.less | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/sections.less b/src/Umbraco.Web.UI.Client/src/less/sections.less index 51ec5c7436..371f5ac79d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/sections.less +++ b/src/Umbraco.Web.UI.Client/src/less/sections.less @@ -7,7 +7,7 @@ ul.sections { background: @purple; height: 100%; width: 80px; - border-right: 1px solid @purple; + border-right: 1px solid @purple-d1; } ul.sections li { @@ -22,13 +22,16 @@ ul.sections li [class^="icon-"], ul.sections li [class*=" icon-"], ul.sections li img.icon-section { font-size: 30px; - line-height: 20px; /* set line-height to ensure all icons use same line-height */ display: inline-block; margin: 1px 0 0 0; color: @purple-l2; -webkit-transition: all .3s linear; -moz-transition: all .3s linear; transition: all .3s linear; + + &, &:before { + line-height: 20px; /* set line-height to ensure all icons use same line-height */ + } } ul.sections:hover li [class^="icon-"], @@ -168,7 +171,7 @@ ul.sections-tray { width: 80px; & > li:first-child > a { - border-top: 1px solid @purple; + border-top: 1px solid @purple-d1; } & > li { From dd041a6f0977321d6f5ad864c09550378554e374 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 19:16:42 +0200 Subject: [PATCH 20/39] Ensure it override injected styles from custom font icon --- src/Umbraco.Web.UI.Client/src/less/sections.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/sections.less b/src/Umbraco.Web.UI.Client/src/less/sections.less index 371f5ac79d..d73e24e4ea 100644 --- a/src/Umbraco.Web.UI.Client/src/less/sections.less +++ b/src/Umbraco.Web.UI.Client/src/less/sections.less @@ -30,7 +30,7 @@ ul.sections li img.icon-section { transition: all .3s linear; &, &:before { - line-height: 20px; /* set line-height to ensure all icons use same line-height */ + line-height: 20px !important; /* set line-height to ensure all icons use same line-height */ } } From 60c1052db15fb5531032d6f71f247b3f0357a7a8 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 22:12:27 +0200 Subject: [PATCH 21/39] Make examine search input and button more consistent with UI --- .../src/less/buttons.less | 2 +- src/Umbraco.Web.UI.Client/src/less/forms.less | 1627 ++++++++--------- 2 files changed, 812 insertions(+), 817 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/buttons.less b/src/Umbraco.Web.UI.Client/src/less/buttons.less index e76ffc682c..419a202ceb 100644 --- a/src/Umbraco.Web.UI.Client/src/less/buttons.less +++ b/src/Umbraco.Web.UI.Client/src/less/buttons.less @@ -20,7 +20,7 @@ color: @black; border: none; box-shadow: none; - border-radius: 3px; + .border-radius(@borderRadiusSmall); // Hover/focus state &:hover, diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index 869d0b7740..b8dfbf5e31 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -1,821 +1,816 @@ -// -// Forms -// -------------------------------------------------- - -// UMBRACO STYLES -// -------------- - - - -small.umb-detail, -label small, .guiDialogTiny { - color: @gray-5 !important; - text-decoration: none; - display: block; - font-weight: normal; - font-size: 11px -} - -label.control-label, .control-label { - padding: 0 10px 0 0 !important; - font-weight: bold; - color: @black; -} - - -.umb-status-label{ - color: @gray-3 !important; - } - - -.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} - - - -//utill styll to hide child untill hover -/*.hover-show{visibility: hidden;} -*:hover > .hover-show{visibility: visible;} -*/ - -//breadcrumb modifications - -.breadcrumb{height: 30px; display: block; margin-top: 10px;} -.breadcrumb li{height: 30px; vertical-align: middle;} -.breadcrumb li a{vertical-align: middle; height: 30px;} -.breadcrumb input{font-size: 11px !Important;} - - - -/* SEACH FORM */ -.form-search { - position: relative; - padding: 0; -} -.form-search a{ - text-decoration:none; - cursor:pointer; -} -.form-search a:hover{ - color: @gray-3; -} -.form-search h4 { - color: @gray-3; -} -.form-search small { - color: @gray-8; -} -.form-search .icon, .form-search .icon-search { - position: absolute; - top: 6px; - left: 4px; - color: @gray-8; -} - -.form-search .icon-search { - pointer-events: none; -} - -.form-search input { - width: 90%; +// +// Forms +// -------------------------------------------------- + +// UMBRACO STYLES +// -------------- + + + +small.umb-detail, +label small, .guiDialogTiny { + color: @gray-5 !important; + text-decoration: none; + display: block; + font-weight: normal; + font-size: 11px +} + +label.control-label, .control-label { + padding: 0 10px 0 0 !important; + font-weight: bold; + color: @black; +} + + +.umb-status-label{ + color: @gray-3 !important; + } + + +.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} + + + +//utill styll to hide child untill hover +/*.hover-show{visibility: hidden;} +*:hover > .hover-show{visibility: visible;} +*/ + +//breadcrumb modifications + +.breadcrumb{height: 30px; display: block; margin-top: 10px;} +.breadcrumb li{height: 30px; vertical-align: middle;} +.breadcrumb li a{vertical-align: middle; height: 30px;} +.breadcrumb input{font-size: 11px !Important;} + + + +/* SEACH FORM */ +.form-search { + position: relative; + padding: 0; +} +.form-search a{ + text-decoration:none; + cursor:pointer; +} +.form-search a:hover{ + color: @gray-3; +} +.form-search h4 { + color: @gray-3; +} +.form-search small { + color: @gray-8; +} +.form-search .icon, .form-search .icon-search { + position: absolute; + z-index: 1; + top: 6px; + left: 4px; + color: @gray-8; +} + +.form-search .icon-search { + pointer-events: none; +} + +.form-search input { + width: 90%; font-size: @fontSizeLarge; font-weight: 400; border: 1px solid @gray-8; - padding: 4px 0px 4px 16px; - padding-left: 25px !Important; line-height: 22px; background: @white -} - - -.form-search .search-input { - font-weight: bold; - border-color: @gray-8; - - &:hover, - &:focus, - &:focus:hover { - border-color: @gray-7; - } - - &:-moz-placeholder { - font-weight: normal; - } - &:-ms-input-placeholder { - font-weight: normal; - } - &::-webkit-input-placeholder { - font-weight: normal; - } -} - - -// GENERAL STYLES -// -------------- - -// Make all forms have space below them -form { - margin: 0 0 @baseLineHeight; -} - -form.-no-margin-bottom { - margin-bottom: 0; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -// Groups of fields with labels on top (legends) -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @baseLineHeight; - font-size: @baseFontSize * 1.5; - line-height: @baseLineHeight * 2; - color: @grayDark; - border: 0; - border-bottom: 1px solid @gray-8; - - // Small - small { - font-size: @baseLineHeight * .75; - color: @gray-8; - } -} - - - -// Set font for forms -label, -input, -button, -select, -textarea { - #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here -} -input, -button, -select, -textarea { - font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) -} - -// Identify controls by their labels -label { - display: inline-block; - margin-bottom: 5px; -} - -// Form controls -// ------------------------- - -// Shared size and type resets -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 30px; - padding: 4px 6px; - margin-bottom: @baseLineHeight / 2; - font-size: @baseFontSize; - line-height: @baseLineHeight; - color: @gray-3; - .border-radius(@inputBorderRadius); - vertical-align: middle; - box-sizing: border-box; -} - -input.-full-width-input { - width: 100%; - box-sizing: border-box; - padding: 4px 6px; - height: 30px; -} - -// Reset appearance properties for textual inputs and textarea -// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) -input, -textarea, -.uneditable-input { - width: 206px; // plus 12px padding and 2px border -} -// Reset height since textareas have rows -textarea { - height: auto; -} -// Everything else -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: @inputBackground; - border: 1px solid @inputBorder; - .transition(~"border linear .2s, box-shadow linear .2s"); - - // Focus state - &:focus { - border-color: none; - outline: 0; - outline: none \9; /* IE6-9 */ - } -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; /* IE7 */ - margin-top: 1px \9; /* IE8-9 */ - line-height: normal; -} - -// Reset width of input images, buttons, radios, checkboxes -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; // Override of generic input selector -} - -// Set the height of select and file controls to match text inputs -select, -input[type="file"] { - height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; /* For IE7, add top margin to align select with labels */ - line-height: @inputHeight; -} - -// Make select elements obey height by applying a border -select { - width: 220px; // default input width + 10px of padding that doesn't get applied - border: 1px solid @inputBorder; - background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for select, file, radio, and checkbox -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - - -// Uneditable inputs -// ------------------------- - -// Make uneditable inputs look inactive -.uneditable-input, -.uneditable-textarea { - color: @gray-8; - background-color: darken(@inputBackground, 1%); - border-color: @inputBorder; - .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); - cursor: not-allowed; -} - -// For text that needs to appear as an input but should not be an input -.uneditable-input { - overflow: hidden; // prevent text from wrapping, but still cut it off like an input does - white-space: nowrap; -} - -// Make uneditable textareas behave like a textarea -.uneditable-textarea { - width: auto; - height: auto; -} - - -// Placeholder -// ------------------------- - -// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector -input, -textarea { - .placeholder(@gray-6); -} - - -// CHECKBOXES & RADIOS -// ------------------- - -// Indent the labels to position radios/checkboxes as hanging -.radio, -.checkbox { - min-height: @baseLineHeight; // clear the floating input if there is no label text - padding-left: 20px; -} - -.radio.no-indent, -.checkbox.no-indent { - padding-left: 0; -} - -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: 0px; - margin-right:5px; -} - -// Move the options list down to align with labels -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; // has to be padding because margin collaspes -} - -// Radios and checkboxes on same line -// TODO v3: Convert .inline to .control-inline -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; // space out consecutive inline controls -} - - - -// INPUT SIZES -// ----------- - -// General classes for quick sizes -.input-mini { width: 60px; } -.input-small { width: 90px; } -.input-medium { width: 150px; } -.input-large { width: 210px; } -.input-xlarge { width: 270px; } -.input-xxlarge { width: 530px; } - -input.input--no-border { border: none; } - -// Grid style input sizes -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -// Redeclare since the fluid row class is more specific -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -// Ensure input-prepend/append never wraps -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - -.bigInput, .input-large-type{ - font-size: 20px !important; -} - - -// GRID SIZING FOR INPUTS -// ---------------------- - -// Grid sizes -#grid > .input(@gridColumnWidth, @gridGutterWidth); - -// Control row for multiple inputs per line -.controls-row { - .clearfix(); // Clear the float from controls -} - -// Float to collapse white-space for proper grid alignment -.controls-row [class*="span"], -// Redeclare the fluid grid collapse since we undo the float for inputs -.row-fluid .controls-row [class*="span"] { - float: left; -} -// Explicity set top padding on all checkboxes/radios, not just first-child -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - - - - -// DISABLED STATE -// -------------- - -// Disabled and read-only inputs -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: @inputDisabledBackground; -} -// Explicitly reset the colors here -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - - -//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot -// share colors with the notifications/alerts. Also had to change them so that -// we do not show any errors unless the containing element has the show-validation -// class assigned. - -// FORM FIELD FEEDBACK STATES -// -------------------------- - -// Error -.show-validation.ng-invalid .control-group.error, -.show-validation.ng-invalid .umb-panel-header-content-wrapper { - .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); -} - -//val-highlight directive styling -.highlight-error { - color: @formErrorText !important; - border-color: @red-l1 !important; -} - -//disable the glowing border for the umb-content-name -.show-validation .umb-headline-editor-wrapper input:focus:invalid, -.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, -.show-validation .umb-headline-editor-wrapper select:focus:invalid { - border:none; - color:inherit; - border-color:inherit; - @shadow:inherit; - .box-shadow(@shadow); -} - -.ng-invalid > .umb-headline-editor-wrapper h1{ - border-bottom: 1px dashed @red; color: @red; cursor: pointer; -}; - -// FORM ACTIONS -// ------------ - -.form-actions { - padding: (@baseLineHeight - 1) 20px @baseLineHeight; - margin-top: @baseLineHeight; - margin-bottom: @baseLineHeight; - background-color: @formActionsBackground; - border-top: 1px solid @gray-8; - .clearfix(); // Adding clearfix to allow for .pull-right button containers -} - - - -// HELP TEXT -// --------- - -.help-block, -.help-inline { - color: lighten(@textColor, 15%); // lighten the text some for contrast -} - -.help-block { - display: block; // account for any element using help-block - margin-bottom: @baseLineHeight / 2; -} - -.help-inline { - display: inline-block; - .ie7-inline-block(); - vertical-align: middle; - padding-left: 5px; -} - - - -// INPUT GROUPS -// ------------ - -// Allow us to put symbols and text within the input field for a cleaner look -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: @baseLineHeight / 2; - vertical-align: middle; - font-size: 0; // white space collapse hack - white-space: nowrap; // Prevent span and input from separating - - // Reset the white space collapse hack - input, - select, - .uneditable-input, - .dropdown-menu, - .popover { - font-size: @baseFontSize; - } - - input, - select, - .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms - *margin-left: 0; - vertical-align: top; - // Make input on top when focused so blue border and shadow always show - &:focus { - z-index: 2; - } - } - .add-on { - display: inline-block; - width: auto; - height: @baseLineHeight; - min-width: 16px; - padding: 4px 5px; - font-size: @baseFontSize; - font-weight: normal; - line-height: @baseLineHeight; - text-align: center; - text-shadow: 0 1px 0 @white; - background-color: @gray-10; - border: 1px solid @gray-8; - } - .add-on, - .btn, - .btn-group > .dropdown-toggle { - vertical-align: top; - .border-radius(0); - } - .active { - background-color: lighten(@green, 30); - border-color: @green; - } -} - -.input-prepend { - .add-on, - .btn { - margin-right: -1px; - } -} - -.input-append { - .add-on, - .btn, - .btn-group { - margin-left: -1px; - } -} - -// Remove all border-radius for inputs with both prepend and append -.input-prepend.input-append { - input, - select, - .uneditable-input { - .border-radius(0); - + .btn-group .btn { - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - } - .add-on:first-child, - .btn:first-child { - margin-right: -1px; - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - margin-left: -1px; - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - .btn-group:first-child { - margin-left: 0; - } -} - - - - -// SEARCH FORM -// ----------- - -input.search-query { - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin: 0; // Remove the default margin on all inputs - .border-radius(0px); -} - -/* Allow for input prepend/append in search forms */ -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - .border-radius(0); // Override due to specificity -} -.form-search .input-append .search-query { - .border-radius(14px 0 0 14px); -} -.form-search .input-append .btn { - .border-radius(0 14px 14px 0); -} -.form-search .input-prepend .search-query { - .border-radius(0 14px 14px 0); -} -.form-search .input-prepend .btn { - .border-radius(14px 0 0 14px); -} - - - - -// HORIZONTAL & VERTICAL FORMS -// --------------------------- - -// Common properties -// ----------------- - -.form-search, -.form-inline, -.form-horizontal { - input, - textarea, - select, - .help-inline, - .uneditable-input, - .input-prepend, - .input-append { - display: inline-block; - .ie7-inline-block(); - margin-bottom: 0; - vertical-align: top; - } - // Re-hide hidden elements due to specifity - .hide { - display: none; - } -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -// Remove margin for input-prepend/-append -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -// Inline checkbox/radio labels (remove padding on left) -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -// Remove float and margin, set to inline-block -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - - -// Margin to space out fieldsets -.control-group { - margin-bottom: @baseLineHeight / 2; -} - -//modifier for control group -.control-group.-no-margin { - margin-bottom:0; -} - -// Legend collapses margin, so next element is responsible for spacing -legend + .control-group { - margin-top: @baseLineHeight; - -webkit-margin-top-collapse: separate; -} - -// Horizontal-specific styles -// -------------------------- - -.form-horizontal { - // Increase spacing between groups - .control-group { - margin-bottom: @baseLineHeight; - .clearfix(); - } - // Float the labels left - .control-label { - float: left; - width: @horizontalComponentOffset - 20; - padding-top: 5px; - text-align: right; - } - // Move over all input controls and content - .controls { - // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend - // don't inherit the margin of the parent, in this case .controls - *display: inline-block; - *padding-left: 20px; - margin-left: @horizontalComponentOffset; - *margin-left: 0; - &:first-child { - *padding-left: @horizontalComponentOffset; - } - } - // Remove bottom margin on block level help text since that's accounted for on .control-group - .help-block { - margin-bottom: 0; - } - // And apply it only to .help-block instances that follow a form control - input, - select, - textarea, - .uneditable-input, - .input-prepend, - .input-append { - + .help-block { - margin-top: @baseLineHeight / 2; - } - } - // Move over buttons in .form-actions to align with .controls - .form-actions { - padding-left: @horizontalComponentOffset; - } -} -//make sure buttons are always on top -.umb-panel-buttons .umb-btn-toolbar .btn { - position: relative; - z-index: 1000; -} - - - -@media (max-width: 767px) { - - // Labels on own row - .form-horizontal .control-label { - width: 100%; - } - .form-horizontal .controls { - margin-left: 0; - } - -} +} + +.form-search .icon-search + .search-input { + padding-left: 25px !important; +} + +.form-search .search-input { + font-weight: bold; + border-color: @gray-8; + + &:hover, + &:focus, + &:focus:hover { + border-color: @gray-7; + } + + &:-moz-placeholder { + font-weight: normal; + } + &:-ms-input-placeholder { + font-weight: normal; + } + &::-webkit-input-placeholder { + font-weight: normal; + } +} + + +// GENERAL STYLES +// -------------- + +// Make all forms have space below them +form { + margin: 0 0 @baseLineHeight; +} + +form.-no-margin-bottom { + margin-bottom: 0; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +// Groups of fields with labels on top (legends) +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @baseLineHeight; + font-size: @baseFontSize * 1.5; + line-height: @baseLineHeight * 2; + color: @grayDark; + border: 0; + border-bottom: 1px solid @gray-8; + + // Small + small { + font-size: @baseLineHeight * .75; + color: @gray-8; + } +} + + + +// Set font for forms +label, +input, +button, +select, +textarea { + #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here +} +input, +button, +select, +textarea { + font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) +} + +// Identify controls by their labels +label { + display: inline-block; + margin-bottom: 5px; +} + +// Form controls +// ------------------------- + +// Shared size and type resets +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 32px; + padding: 4px 6px; + margin-bottom: @baseLineHeight / 2; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @gray-3; + .border-radius(@inputBorderRadius); + vertical-align: middle; + box-sizing: border-box; +} + +input.-full-width-input { + width: 100%; + box-sizing: border-box; + padding: 4px 6px; + height: 30px; +} + +// Reset appearance properties for textual inputs and textarea +// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) +input, +textarea, +.uneditable-input { + width: 206px; // plus 12px padding and 2px border +} +// Reset height since textareas have rows +textarea { + height: auto; +} +// Everything else +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: @inputBackground; + border: 1px solid @inputBorder; + .transition(~"border linear .2s, box-shadow linear .2s"); + + // Focus state + &:focus { + border-color: none; + outline: 0; + outline: none \9; /* IE6-9 */ + } +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; /* IE7 */ + margin-top: 1px \9; /* IE8-9 */ + line-height: normal; +} + +// Reset width of input images, buttons, radios, checkboxes +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; // Override of generic input selector +} + +// Set the height of select and file controls to match text inputs +select, +input[type="file"] { + height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; /* For IE7, add top margin to align select with labels */ + line-height: @inputHeight; +} + +// Make select elements obey height by applying a border +select { + width: 220px; // default input width + 10px of padding that doesn't get applied + border: 1px solid @inputBorder; + background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for select, file, radio, and checkbox +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + .tab-focus(); +} + + +// Uneditable inputs +// ------------------------- + +// Make uneditable inputs look inactive +.uneditable-input, +.uneditable-textarea { + color: @gray-8; + background-color: darken(@inputBackground, 1%); + border-color: @inputBorder; + .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); + cursor: not-allowed; +} + +// For text that needs to appear as an input but should not be an input +.uneditable-input { + overflow: hidden; // prevent text from wrapping, but still cut it off like an input does + white-space: nowrap; +} + +// Make uneditable textareas behave like a textarea +.uneditable-textarea { + width: auto; + height: auto; +} + + +// Placeholder +// ------------------------- + +// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector +input, +textarea { + .placeholder(@gray-6); +} + + +// CHECKBOXES & RADIOS +// ------------------- + +// Indent the labels to position radios/checkboxes as hanging +.radio, +.checkbox { + min-height: @baseLineHeight; // clear the floating input if there is no label text + padding-left: 20px; +} + +.radio.no-indent, +.checkbox.no-indent { + padding-left: 0; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: 0px; + margin-right:5px; +} + +// Move the options list down to align with labels +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; // has to be padding because margin collaspes +} + +// Radios and checkboxes on same line +// TODO v3: Convert .inline to .control-inline +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; // space out consecutive inline controls +} + + + +// INPUT SIZES +// ----------- + +// General classes for quick sizes +.input-mini { width: 60px; } +.input-small { width: 90px; } +.input-medium { width: 150px; } +.input-large { width: 210px; } +.input-xlarge { width: 270px; } +.input-xxlarge { width: 530px; } + +input.input--no-border { border: none; } + +// Grid style input sizes +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +// Redeclare since the fluid row class is more specific +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +// Ensure input-prepend/append never wraps +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +.bigInput, .input-large-type{ + font-size: 20px !important; +} + + +// GRID SIZING FOR INPUTS +// ---------------------- + +// Grid sizes +#grid > .input(@gridColumnWidth, @gridGutterWidth); + +// Control row for multiple inputs per line +.controls-row { + .clearfix(); // Clear the float from controls +} + +// Float to collapse white-space for proper grid alignment +.controls-row [class*="span"], +// Redeclare the fluid grid collapse since we undo the float for inputs +.row-fluid .controls-row [class*="span"] { + float: left; +} +// Explicity set top padding on all checkboxes/radios, not just first-child +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + + + + +// DISABLED STATE +// -------------- + +// Disabled and read-only inputs +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: @inputDisabledBackground; +} +// Explicitly reset the colors here +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + + +//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot +// share colors with the notifications/alerts. Also had to change them so that +// we do not show any errors unless the containing element has the show-validation +// class assigned. + +// FORM FIELD FEEDBACK STATES +// -------------------------- + +// Error +.show-validation.ng-invalid .control-group.error, +.show-validation.ng-invalid .umb-panel-header-content-wrapper { + .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); +} + +//val-highlight directive styling +.highlight-error { + color: @formErrorText !important; + border-color: @red-l1 !important; +} + +//disable the glowing border for the umb-content-name +.show-validation .umb-headline-editor-wrapper input:focus:invalid, +.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, +.show-validation .umb-headline-editor-wrapper select:focus:invalid { + border:none; + color:inherit; + border-color:inherit; + @shadow:inherit; + .box-shadow(@shadow); +} + +.ng-invalid > .umb-headline-editor-wrapper h1{ + border-bottom: 1px dashed @red; color: @red; cursor: pointer; +}; + +// FORM ACTIONS +// ------------ + +.form-actions { + padding: (@baseLineHeight - 1) 20px @baseLineHeight; + margin-top: @baseLineHeight; + margin-bottom: @baseLineHeight; + background-color: @formActionsBackground; + border-top: 1px solid @gray-8; + .clearfix(); // Adding clearfix to allow for .pull-right button containers +} + + + +// HELP TEXT +// --------- + +.help-block, +.help-inline { + color: lighten(@textColor, 15%); // lighten the text some for contrast +} + +.help-block { + display: block; // account for any element using help-block + margin-bottom: @baseLineHeight / 2; +} + +.help-inline { + display: inline-block; + .ie7-inline-block(); + vertical-align: middle; + padding-left: 5px; +} + + + +// INPUT GROUPS +// ------------ + +// Allow us to put symbols and text within the input field for a cleaner look +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: @baseLineHeight / 2; + vertical-align: middle; + font-size: 0; // white space collapse hack + white-space: nowrap; // Prevent span and input from separating + + // Reset the white space collapse hack + input, + select, + .uneditable-input, + .dropdown-menu, + .popover { + font-size: @baseFontSize; + } + + input, + select, + .uneditable-input { + position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness + margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms + *margin-left: 0; + vertical-align: top; + // Make input on top when focused so blue border and shadow always show + &:focus { + z-index: 2; + } + } + .add-on { + display: inline-block; + width: auto; + height: @baseLineHeight; + min-width: 16px; + padding: 4px 5px; + font-size: @baseFontSize; + font-weight: normal; + line-height: @baseLineHeight; + text-align: center; + text-shadow: 0 1px 0 @white; + background-color: @gray-10; + border: 1px solid @gray-8; + } + .add-on, + .btn, + .btn-group > .dropdown-toggle { + vertical-align: top; + .border-radius(0); + } + .active { + background-color: lighten(@green, 30); + border-color: @green; + } +} + +.input-prepend { + .add-on, + .btn { + margin-right: -1px; + } +} + +.input-append { + .add-on, + .btn, + .btn-group { + margin-left: -1px; + } +} + +// Remove all border-radius for inputs with both prepend and append +.input-prepend.input-append { + input, + select, + .uneditable-input { + .border-radius(0); + + .btn-group .btn { + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + } + .add-on:first-child, + .btn:first-child { + margin-right: -1px; + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } + .add-on:last-child, + .btn:last-child { + margin-left: -1px; + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + .btn-group:first-child { + margin-left: 0; + } +} + + + + +// SEARCH FORM +// ----------- + +input.search-query { + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin: 0; // Remove the default margin on all inputs +} + +/* Allow for input prepend/append in search forms */ +.form-search { + .input-prepend { + .btn { + .border-radius(0 @borderRadiusSmall @borderRadiusSmall 0); + } + } + .input-append { + .btn { + .border-radius(0 @borderRadiusSmall @borderRadiusSmall 0); + } + } +} + + +// HORIZONTAL & VERTICAL FORMS +// --------------------------- + +// Common properties +// ----------------- + +.form-search, +.form-inline, +.form-horizontal { + input, + textarea, + select, + .help-inline, + .uneditable-input, + .input-prepend, + .input-append { + display: inline-block; + .ie7-inline-block(); + margin-bottom: 0; + vertical-align: top; + } + // Re-hide hidden elements due to specifity + .hide { + display: none; + } +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +// Remove margin for input-prepend/-append +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +// Inline checkbox/radio labels (remove padding on left) +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +// Remove float and margin, set to inline-block +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + + +// Margin to space out fieldsets +.control-group { + margin-bottom: @baseLineHeight / 2; +} + +//modifier for control group +.control-group.-no-margin { + margin-bottom:0; +} + +// Legend collapses margin, so next element is responsible for spacing +legend + .control-group { + margin-top: @baseLineHeight; + -webkit-margin-top-collapse: separate; +} + +// Horizontal-specific styles +// -------------------------- + +.form-horizontal { + // Increase spacing between groups + .control-group { + margin-bottom: @baseLineHeight; + .clearfix(); + } + // Float the labels left + .control-label { + float: left; + width: @horizontalComponentOffset - 20; + padding-top: 5px; + text-align: right; + } + // Move over all input controls and content + .controls { + // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend + // don't inherit the margin of the parent, in this case .controls + *display: inline-block; + *padding-left: 20px; + margin-left: @horizontalComponentOffset; + *margin-left: 0; + &:first-child { + *padding-left: @horizontalComponentOffset; + } + } + // Remove bottom margin on block level help text since that's accounted for on .control-group + .help-block { + margin-bottom: 0; + } + // And apply it only to .help-block instances that follow a form control + input, + select, + textarea, + .uneditable-input, + .input-prepend, + .input-append { + + .help-block { + margin-top: @baseLineHeight / 2; + } + } + // Move over buttons in .form-actions to align with .controls + .form-actions { + padding-left: @horizontalComponentOffset; + } +} +//make sure buttons are always on top +.umb-panel-buttons .umb-btn-toolbar .btn { + position: relative; + z-index: 1000; +} + + + +@media (max-width: 767px) { + + // Labels on own row + .form-horizontal .control-label { + width: 100%; + } + .form-horizontal .controls { + margin-left: 0; + } + +} From a04df8070abe29c3510677537adea58fbe4c30af Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 22:51:32 +0200 Subject: [PATCH 22/39] Revert "Make examine search input and button more consistent with UI" This reverts commit 60c1052db15fb5531032d6f71f247b3f0357a7a8. --- .../src/less/buttons.less | 2 +- src/Umbraco.Web.UI.Client/src/less/forms.less | 1627 +++++++++-------- 2 files changed, 817 insertions(+), 812 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/buttons.less b/src/Umbraco.Web.UI.Client/src/less/buttons.less index 419a202ceb..e76ffc682c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/buttons.less +++ b/src/Umbraco.Web.UI.Client/src/less/buttons.less @@ -20,7 +20,7 @@ color: @black; border: none; box-shadow: none; - .border-radius(@borderRadiusSmall); + border-radius: 3px; // Hover/focus state &:hover, diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index b8dfbf5e31..869d0b7740 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -1,816 +1,821 @@ -// -// Forms -// -------------------------------------------------- - -// UMBRACO STYLES -// -------------- - - - -small.umb-detail, -label small, .guiDialogTiny { - color: @gray-5 !important; - text-decoration: none; - display: block; - font-weight: normal; - font-size: 11px -} - -label.control-label, .control-label { - padding: 0 10px 0 0 !important; - font-weight: bold; - color: @black; -} - - -.umb-status-label{ - color: @gray-3 !important; - } - - -.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} - - - -//utill styll to hide child untill hover -/*.hover-show{visibility: hidden;} -*:hover > .hover-show{visibility: visible;} -*/ - -//breadcrumb modifications - -.breadcrumb{height: 30px; display: block; margin-top: 10px;} -.breadcrumb li{height: 30px; vertical-align: middle;} -.breadcrumb li a{vertical-align: middle; height: 30px;} -.breadcrumb input{font-size: 11px !Important;} - - - -/* SEACH FORM */ -.form-search { - position: relative; - padding: 0; -} -.form-search a{ - text-decoration:none; - cursor:pointer; -} -.form-search a:hover{ - color: @gray-3; -} -.form-search h4 { - color: @gray-3; -} -.form-search small { - color: @gray-8; -} -.form-search .icon, .form-search .icon-search { - position: absolute; - z-index: 1; - top: 6px; - left: 4px; - color: @gray-8; -} - -.form-search .icon-search { - pointer-events: none; -} - -.form-search input { - width: 90%; +// +// Forms +// -------------------------------------------------- + +// UMBRACO STYLES +// -------------- + + + +small.umb-detail, +label small, .guiDialogTiny { + color: @gray-5 !important; + text-decoration: none; + display: block; + font-weight: normal; + font-size: 11px +} + +label.control-label, .control-label { + padding: 0 10px 0 0 !important; + font-weight: bold; + color: @black; +} + + +.umb-status-label{ + color: @gray-3 !important; + } + + +.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} + + + +//utill styll to hide child untill hover +/*.hover-show{visibility: hidden;} +*:hover > .hover-show{visibility: visible;} +*/ + +//breadcrumb modifications + +.breadcrumb{height: 30px; display: block; margin-top: 10px;} +.breadcrumb li{height: 30px; vertical-align: middle;} +.breadcrumb li a{vertical-align: middle; height: 30px;} +.breadcrumb input{font-size: 11px !Important;} + + + +/* SEACH FORM */ +.form-search { + position: relative; + padding: 0; +} +.form-search a{ + text-decoration:none; + cursor:pointer; +} +.form-search a:hover{ + color: @gray-3; +} +.form-search h4 { + color: @gray-3; +} +.form-search small { + color: @gray-8; +} +.form-search .icon, .form-search .icon-search { + position: absolute; + top: 6px; + left: 4px; + color: @gray-8; +} + +.form-search .icon-search { + pointer-events: none; +} + +.form-search input { + width: 90%; font-size: @fontSizeLarge; font-weight: 400; border: 1px solid @gray-8; + padding: 4px 0px 4px 16px; + padding-left: 25px !Important; line-height: 22px; background: @white -} - -.form-search .icon-search + .search-input { - padding-left: 25px !important; -} - -.form-search .search-input { - font-weight: bold; - border-color: @gray-8; - - &:hover, - &:focus, - &:focus:hover { - border-color: @gray-7; - } - - &:-moz-placeholder { - font-weight: normal; - } - &:-ms-input-placeholder { - font-weight: normal; - } - &::-webkit-input-placeholder { - font-weight: normal; - } -} - - -// GENERAL STYLES -// -------------- - -// Make all forms have space below them -form { - margin: 0 0 @baseLineHeight; -} - -form.-no-margin-bottom { - margin-bottom: 0; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -// Groups of fields with labels on top (legends) -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @baseLineHeight; - font-size: @baseFontSize * 1.5; - line-height: @baseLineHeight * 2; - color: @grayDark; - border: 0; - border-bottom: 1px solid @gray-8; - - // Small - small { - font-size: @baseLineHeight * .75; - color: @gray-8; - } -} - - - -// Set font for forms -label, -input, -button, -select, -textarea { - #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here -} -input, -button, -select, -textarea { - font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) -} - -// Identify controls by their labels -label { - display: inline-block; - margin-bottom: 5px; -} - -// Form controls -// ------------------------- - -// Shared size and type resets -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 32px; - padding: 4px 6px; - margin-bottom: @baseLineHeight / 2; - font-size: @baseFontSize; - line-height: @baseLineHeight; - color: @gray-3; - .border-radius(@inputBorderRadius); - vertical-align: middle; - box-sizing: border-box; -} - -input.-full-width-input { - width: 100%; - box-sizing: border-box; - padding: 4px 6px; - height: 30px; -} - -// Reset appearance properties for textual inputs and textarea -// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) -input, -textarea, -.uneditable-input { - width: 206px; // plus 12px padding and 2px border -} -// Reset height since textareas have rows -textarea { - height: auto; -} -// Everything else -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: @inputBackground; - border: 1px solid @inputBorder; - .transition(~"border linear .2s, box-shadow linear .2s"); - - // Focus state - &:focus { - border-color: none; - outline: 0; - outline: none \9; /* IE6-9 */ - } -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; /* IE7 */ - margin-top: 1px \9; /* IE8-9 */ - line-height: normal; -} - -// Reset width of input images, buttons, radios, checkboxes -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; // Override of generic input selector -} - -// Set the height of select and file controls to match text inputs -select, -input[type="file"] { - height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; /* For IE7, add top margin to align select with labels */ - line-height: @inputHeight; -} - -// Make select elements obey height by applying a border -select { - width: 220px; // default input width + 10px of padding that doesn't get applied - border: 1px solid @inputBorder; - background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for select, file, radio, and checkbox -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - - -// Uneditable inputs -// ------------------------- - -// Make uneditable inputs look inactive -.uneditable-input, -.uneditable-textarea { - color: @gray-8; - background-color: darken(@inputBackground, 1%); - border-color: @inputBorder; - .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); - cursor: not-allowed; -} - -// For text that needs to appear as an input but should not be an input -.uneditable-input { - overflow: hidden; // prevent text from wrapping, but still cut it off like an input does - white-space: nowrap; -} - -// Make uneditable textareas behave like a textarea -.uneditable-textarea { - width: auto; - height: auto; -} - - -// Placeholder -// ------------------------- - -// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector -input, -textarea { - .placeholder(@gray-6); -} - - -// CHECKBOXES & RADIOS -// ------------------- - -// Indent the labels to position radios/checkboxes as hanging -.radio, -.checkbox { - min-height: @baseLineHeight; // clear the floating input if there is no label text - padding-left: 20px; -} - -.radio.no-indent, -.checkbox.no-indent { - padding-left: 0; -} - -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: 0px; - margin-right:5px; -} - -// Move the options list down to align with labels -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; // has to be padding because margin collaspes -} - -// Radios and checkboxes on same line -// TODO v3: Convert .inline to .control-inline -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; // space out consecutive inline controls -} - - - -// INPUT SIZES -// ----------- - -// General classes for quick sizes -.input-mini { width: 60px; } -.input-small { width: 90px; } -.input-medium { width: 150px; } -.input-large { width: 210px; } -.input-xlarge { width: 270px; } -.input-xxlarge { width: 530px; } - -input.input--no-border { border: none; } - -// Grid style input sizes -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -// Redeclare since the fluid row class is more specific -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -// Ensure input-prepend/append never wraps -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - -.bigInput, .input-large-type{ - font-size: 20px !important; -} - - -// GRID SIZING FOR INPUTS -// ---------------------- - -// Grid sizes -#grid > .input(@gridColumnWidth, @gridGutterWidth); - -// Control row for multiple inputs per line -.controls-row { - .clearfix(); // Clear the float from controls -} - -// Float to collapse white-space for proper grid alignment -.controls-row [class*="span"], -// Redeclare the fluid grid collapse since we undo the float for inputs -.row-fluid .controls-row [class*="span"] { - float: left; -} -// Explicity set top padding on all checkboxes/radios, not just first-child -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - - - - -// DISABLED STATE -// -------------- - -// Disabled and read-only inputs -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: @inputDisabledBackground; -} -// Explicitly reset the colors here -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - - -//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot -// share colors with the notifications/alerts. Also had to change them so that -// we do not show any errors unless the containing element has the show-validation -// class assigned. - -// FORM FIELD FEEDBACK STATES -// -------------------------- - -// Error -.show-validation.ng-invalid .control-group.error, -.show-validation.ng-invalid .umb-panel-header-content-wrapper { - .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); -} - -//val-highlight directive styling -.highlight-error { - color: @formErrorText !important; - border-color: @red-l1 !important; -} - -//disable the glowing border for the umb-content-name -.show-validation .umb-headline-editor-wrapper input:focus:invalid, -.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, -.show-validation .umb-headline-editor-wrapper select:focus:invalid { - border:none; - color:inherit; - border-color:inherit; - @shadow:inherit; - .box-shadow(@shadow); -} - -.ng-invalid > .umb-headline-editor-wrapper h1{ - border-bottom: 1px dashed @red; color: @red; cursor: pointer; -}; - -// FORM ACTIONS -// ------------ - -.form-actions { - padding: (@baseLineHeight - 1) 20px @baseLineHeight; - margin-top: @baseLineHeight; - margin-bottom: @baseLineHeight; - background-color: @formActionsBackground; - border-top: 1px solid @gray-8; - .clearfix(); // Adding clearfix to allow for .pull-right button containers -} - - - -// HELP TEXT -// --------- - -.help-block, -.help-inline { - color: lighten(@textColor, 15%); // lighten the text some for contrast -} - -.help-block { - display: block; // account for any element using help-block - margin-bottom: @baseLineHeight / 2; -} - -.help-inline { - display: inline-block; - .ie7-inline-block(); - vertical-align: middle; - padding-left: 5px; -} - - - -// INPUT GROUPS -// ------------ - -// Allow us to put symbols and text within the input field for a cleaner look -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: @baseLineHeight / 2; - vertical-align: middle; - font-size: 0; // white space collapse hack - white-space: nowrap; // Prevent span and input from separating - - // Reset the white space collapse hack - input, - select, - .uneditable-input, - .dropdown-menu, - .popover { - font-size: @baseFontSize; - } - - input, - select, - .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms - *margin-left: 0; - vertical-align: top; - // Make input on top when focused so blue border and shadow always show - &:focus { - z-index: 2; - } - } - .add-on { - display: inline-block; - width: auto; - height: @baseLineHeight; - min-width: 16px; - padding: 4px 5px; - font-size: @baseFontSize; - font-weight: normal; - line-height: @baseLineHeight; - text-align: center; - text-shadow: 0 1px 0 @white; - background-color: @gray-10; - border: 1px solid @gray-8; - } - .add-on, - .btn, - .btn-group > .dropdown-toggle { - vertical-align: top; - .border-radius(0); - } - .active { - background-color: lighten(@green, 30); - border-color: @green; - } -} - -.input-prepend { - .add-on, - .btn { - margin-right: -1px; - } -} - -.input-append { - .add-on, - .btn, - .btn-group { - margin-left: -1px; - } -} - -// Remove all border-radius for inputs with both prepend and append -.input-prepend.input-append { - input, - select, - .uneditable-input { - .border-radius(0); - + .btn-group .btn { - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - } - .add-on:first-child, - .btn:first-child { - margin-right: -1px; - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - margin-left: -1px; - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - .btn-group:first-child { - margin-left: 0; - } -} - - - - -// SEARCH FORM -// ----------- - -input.search-query { - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin: 0; // Remove the default margin on all inputs -} - -/* Allow for input prepend/append in search forms */ -.form-search { - .input-prepend { - .btn { - .border-radius(0 @borderRadiusSmall @borderRadiusSmall 0); - } - } - .input-append { - .btn { - .border-radius(0 @borderRadiusSmall @borderRadiusSmall 0); - } - } -} - - -// HORIZONTAL & VERTICAL FORMS -// --------------------------- - -// Common properties -// ----------------- - -.form-search, -.form-inline, -.form-horizontal { - input, - textarea, - select, - .help-inline, - .uneditable-input, - .input-prepend, - .input-append { - display: inline-block; - .ie7-inline-block(); - margin-bottom: 0; - vertical-align: top; - } - // Re-hide hidden elements due to specifity - .hide { - display: none; - } -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -// Remove margin for input-prepend/-append -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -// Inline checkbox/radio labels (remove padding on left) -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -// Remove float and margin, set to inline-block -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - - -// Margin to space out fieldsets -.control-group { - margin-bottom: @baseLineHeight / 2; -} - -//modifier for control group -.control-group.-no-margin { - margin-bottom:0; -} - -// Legend collapses margin, so next element is responsible for spacing -legend + .control-group { - margin-top: @baseLineHeight; - -webkit-margin-top-collapse: separate; -} - -// Horizontal-specific styles -// -------------------------- - -.form-horizontal { - // Increase spacing between groups - .control-group { - margin-bottom: @baseLineHeight; - .clearfix(); - } - // Float the labels left - .control-label { - float: left; - width: @horizontalComponentOffset - 20; - padding-top: 5px; - text-align: right; - } - // Move over all input controls and content - .controls { - // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend - // don't inherit the margin of the parent, in this case .controls - *display: inline-block; - *padding-left: 20px; - margin-left: @horizontalComponentOffset; - *margin-left: 0; - &:first-child { - *padding-left: @horizontalComponentOffset; - } - } - // Remove bottom margin on block level help text since that's accounted for on .control-group - .help-block { - margin-bottom: 0; - } - // And apply it only to .help-block instances that follow a form control - input, - select, - textarea, - .uneditable-input, - .input-prepend, - .input-append { - + .help-block { - margin-top: @baseLineHeight / 2; - } - } - // Move over buttons in .form-actions to align with .controls - .form-actions { - padding-left: @horizontalComponentOffset; - } -} -//make sure buttons are always on top -.umb-panel-buttons .umb-btn-toolbar .btn { - position: relative; - z-index: 1000; -} - - - -@media (max-width: 767px) { - - // Labels on own row - .form-horizontal .control-label { - width: 100%; - } - .form-horizontal .controls { - margin-left: 0; - } - -} +} + + +.form-search .search-input { + font-weight: bold; + border-color: @gray-8; + + &:hover, + &:focus, + &:focus:hover { + border-color: @gray-7; + } + + &:-moz-placeholder { + font-weight: normal; + } + &:-ms-input-placeholder { + font-weight: normal; + } + &::-webkit-input-placeholder { + font-weight: normal; + } +} + + +// GENERAL STYLES +// -------------- + +// Make all forms have space below them +form { + margin: 0 0 @baseLineHeight; +} + +form.-no-margin-bottom { + margin-bottom: 0; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +// Groups of fields with labels on top (legends) +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @baseLineHeight; + font-size: @baseFontSize * 1.5; + line-height: @baseLineHeight * 2; + color: @grayDark; + border: 0; + border-bottom: 1px solid @gray-8; + + // Small + small { + font-size: @baseLineHeight * .75; + color: @gray-8; + } +} + + + +// Set font for forms +label, +input, +button, +select, +textarea { + #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here +} +input, +button, +select, +textarea { + font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) +} + +// Identify controls by their labels +label { + display: inline-block; + margin-bottom: 5px; +} + +// Form controls +// ------------------------- + +// Shared size and type resets +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 30px; + padding: 4px 6px; + margin-bottom: @baseLineHeight / 2; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @gray-3; + .border-radius(@inputBorderRadius); + vertical-align: middle; + box-sizing: border-box; +} + +input.-full-width-input { + width: 100%; + box-sizing: border-box; + padding: 4px 6px; + height: 30px; +} + +// Reset appearance properties for textual inputs and textarea +// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) +input, +textarea, +.uneditable-input { + width: 206px; // plus 12px padding and 2px border +} +// Reset height since textareas have rows +textarea { + height: auto; +} +// Everything else +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: @inputBackground; + border: 1px solid @inputBorder; + .transition(~"border linear .2s, box-shadow linear .2s"); + + // Focus state + &:focus { + border-color: none; + outline: 0; + outline: none \9; /* IE6-9 */ + } +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; /* IE7 */ + margin-top: 1px \9; /* IE8-9 */ + line-height: normal; +} + +// Reset width of input images, buttons, radios, checkboxes +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; // Override of generic input selector +} + +// Set the height of select and file controls to match text inputs +select, +input[type="file"] { + height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; /* For IE7, add top margin to align select with labels */ + line-height: @inputHeight; +} + +// Make select elements obey height by applying a border +select { + width: 220px; // default input width + 10px of padding that doesn't get applied + border: 1px solid @inputBorder; + background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for select, file, radio, and checkbox +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + .tab-focus(); +} + + +// Uneditable inputs +// ------------------------- + +// Make uneditable inputs look inactive +.uneditable-input, +.uneditable-textarea { + color: @gray-8; + background-color: darken(@inputBackground, 1%); + border-color: @inputBorder; + .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); + cursor: not-allowed; +} + +// For text that needs to appear as an input but should not be an input +.uneditable-input { + overflow: hidden; // prevent text from wrapping, but still cut it off like an input does + white-space: nowrap; +} + +// Make uneditable textareas behave like a textarea +.uneditable-textarea { + width: auto; + height: auto; +} + + +// Placeholder +// ------------------------- + +// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector +input, +textarea { + .placeholder(@gray-6); +} + + +// CHECKBOXES & RADIOS +// ------------------- + +// Indent the labels to position radios/checkboxes as hanging +.radio, +.checkbox { + min-height: @baseLineHeight; // clear the floating input if there is no label text + padding-left: 20px; +} + +.radio.no-indent, +.checkbox.no-indent { + padding-left: 0; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: 0px; + margin-right:5px; +} + +// Move the options list down to align with labels +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; // has to be padding because margin collaspes +} + +// Radios and checkboxes on same line +// TODO v3: Convert .inline to .control-inline +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; // space out consecutive inline controls +} + + + +// INPUT SIZES +// ----------- + +// General classes for quick sizes +.input-mini { width: 60px; } +.input-small { width: 90px; } +.input-medium { width: 150px; } +.input-large { width: 210px; } +.input-xlarge { width: 270px; } +.input-xxlarge { width: 530px; } + +input.input--no-border { border: none; } + +// Grid style input sizes +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +// Redeclare since the fluid row class is more specific +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +// Ensure input-prepend/append never wraps +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +.bigInput, .input-large-type{ + font-size: 20px !important; +} + + +// GRID SIZING FOR INPUTS +// ---------------------- + +// Grid sizes +#grid > .input(@gridColumnWidth, @gridGutterWidth); + +// Control row for multiple inputs per line +.controls-row { + .clearfix(); // Clear the float from controls +} + +// Float to collapse white-space for proper grid alignment +.controls-row [class*="span"], +// Redeclare the fluid grid collapse since we undo the float for inputs +.row-fluid .controls-row [class*="span"] { + float: left; +} +// Explicity set top padding on all checkboxes/radios, not just first-child +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + + + + +// DISABLED STATE +// -------------- + +// Disabled and read-only inputs +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: @inputDisabledBackground; +} +// Explicitly reset the colors here +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + + +//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot +// share colors with the notifications/alerts. Also had to change them so that +// we do not show any errors unless the containing element has the show-validation +// class assigned. + +// FORM FIELD FEEDBACK STATES +// -------------------------- + +// Error +.show-validation.ng-invalid .control-group.error, +.show-validation.ng-invalid .umb-panel-header-content-wrapper { + .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); +} + +//val-highlight directive styling +.highlight-error { + color: @formErrorText !important; + border-color: @red-l1 !important; +} + +//disable the glowing border for the umb-content-name +.show-validation .umb-headline-editor-wrapper input:focus:invalid, +.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, +.show-validation .umb-headline-editor-wrapper select:focus:invalid { + border:none; + color:inherit; + border-color:inherit; + @shadow:inherit; + .box-shadow(@shadow); +} + +.ng-invalid > .umb-headline-editor-wrapper h1{ + border-bottom: 1px dashed @red; color: @red; cursor: pointer; +}; + +// FORM ACTIONS +// ------------ + +.form-actions { + padding: (@baseLineHeight - 1) 20px @baseLineHeight; + margin-top: @baseLineHeight; + margin-bottom: @baseLineHeight; + background-color: @formActionsBackground; + border-top: 1px solid @gray-8; + .clearfix(); // Adding clearfix to allow for .pull-right button containers +} + + + +// HELP TEXT +// --------- + +.help-block, +.help-inline { + color: lighten(@textColor, 15%); // lighten the text some for contrast +} + +.help-block { + display: block; // account for any element using help-block + margin-bottom: @baseLineHeight / 2; +} + +.help-inline { + display: inline-block; + .ie7-inline-block(); + vertical-align: middle; + padding-left: 5px; +} + + + +// INPUT GROUPS +// ------------ + +// Allow us to put symbols and text within the input field for a cleaner look +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: @baseLineHeight / 2; + vertical-align: middle; + font-size: 0; // white space collapse hack + white-space: nowrap; // Prevent span and input from separating + + // Reset the white space collapse hack + input, + select, + .uneditable-input, + .dropdown-menu, + .popover { + font-size: @baseFontSize; + } + + input, + select, + .uneditable-input { + position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness + margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms + *margin-left: 0; + vertical-align: top; + // Make input on top when focused so blue border and shadow always show + &:focus { + z-index: 2; + } + } + .add-on { + display: inline-block; + width: auto; + height: @baseLineHeight; + min-width: 16px; + padding: 4px 5px; + font-size: @baseFontSize; + font-weight: normal; + line-height: @baseLineHeight; + text-align: center; + text-shadow: 0 1px 0 @white; + background-color: @gray-10; + border: 1px solid @gray-8; + } + .add-on, + .btn, + .btn-group > .dropdown-toggle { + vertical-align: top; + .border-radius(0); + } + .active { + background-color: lighten(@green, 30); + border-color: @green; + } +} + +.input-prepend { + .add-on, + .btn { + margin-right: -1px; + } +} + +.input-append { + .add-on, + .btn, + .btn-group { + margin-left: -1px; + } +} + +// Remove all border-radius for inputs with both prepend and append +.input-prepend.input-append { + input, + select, + .uneditable-input { + .border-radius(0); + + .btn-group .btn { + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + } + .add-on:first-child, + .btn:first-child { + margin-right: -1px; + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } + .add-on:last-child, + .btn:last-child { + margin-left: -1px; + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + .btn-group:first-child { + margin-left: 0; + } +} + + + + +// SEARCH FORM +// ----------- + +input.search-query { + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin: 0; // Remove the default margin on all inputs + .border-radius(0px); +} + +/* Allow for input prepend/append in search forms */ +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + .border-radius(0); // Override due to specificity +} +.form-search .input-append .search-query { + .border-radius(14px 0 0 14px); +} +.form-search .input-append .btn { + .border-radius(0 14px 14px 0); +} +.form-search .input-prepend .search-query { + .border-radius(0 14px 14px 0); +} +.form-search .input-prepend .btn { + .border-radius(14px 0 0 14px); +} + + + + +// HORIZONTAL & VERTICAL FORMS +// --------------------------- + +// Common properties +// ----------------- + +.form-search, +.form-inline, +.form-horizontal { + input, + textarea, + select, + .help-inline, + .uneditable-input, + .input-prepend, + .input-append { + display: inline-block; + .ie7-inline-block(); + margin-bottom: 0; + vertical-align: top; + } + // Re-hide hidden elements due to specifity + .hide { + display: none; + } +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +// Remove margin for input-prepend/-append +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +// Inline checkbox/radio labels (remove padding on left) +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +// Remove float and margin, set to inline-block +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + + +// Margin to space out fieldsets +.control-group { + margin-bottom: @baseLineHeight / 2; +} + +//modifier for control group +.control-group.-no-margin { + margin-bottom:0; +} + +// Legend collapses margin, so next element is responsible for spacing +legend + .control-group { + margin-top: @baseLineHeight; + -webkit-margin-top-collapse: separate; +} + +// Horizontal-specific styles +// -------------------------- + +.form-horizontal { + // Increase spacing between groups + .control-group { + margin-bottom: @baseLineHeight; + .clearfix(); + } + // Float the labels left + .control-label { + float: left; + width: @horizontalComponentOffset - 20; + padding-top: 5px; + text-align: right; + } + // Move over all input controls and content + .controls { + // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend + // don't inherit the margin of the parent, in this case .controls + *display: inline-block; + *padding-left: 20px; + margin-left: @horizontalComponentOffset; + *margin-left: 0; + &:first-child { + *padding-left: @horizontalComponentOffset; + } + } + // Remove bottom margin on block level help text since that's accounted for on .control-group + .help-block { + margin-bottom: 0; + } + // And apply it only to .help-block instances that follow a form control + input, + select, + textarea, + .uneditable-input, + .input-prepend, + .input-append { + + .help-block { + margin-top: @baseLineHeight / 2; + } + } + // Move over buttons in .form-actions to align with .controls + .form-actions { + padding-left: @horizontalComponentOffset; + } +} +//make sure buttons are always on top +.umb-panel-buttons .umb-btn-toolbar .btn { + position: relative; + z-index: 1000; +} + + + +@media (max-width: 767px) { + + // Labels on own row + .form-horizontal .control-label { + width: 100%; + } + .form-horizontal .controls { + margin-left: 0; + } + +} From e73fda14b547c7549d60e298a1dce8b4c2980ae8 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 23:16:11 +0200 Subject: [PATCH 23/39] Adjust height of input fields --- src/Umbraco.Web.UI.Client/src/less/forms.less | 9 ++++----- src/Umbraco.Web.UI.Client/src/less/variables.less | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index b8dfbf5e31..f7be2cc927 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -193,7 +193,7 @@ input[type="tel"], input[type="color"], .uneditable-input { display: inline-block; - height: 32px; + height: @inputHeight; padding: 4px 6px; margin-bottom: @baseLineHeight / 2; font-size: @baseFontSize; @@ -208,7 +208,6 @@ input.-full-width-input { width: 100%; box-sizing: border-box; padding: 4px 6px; - height: 30px; } // Reset appearance properties for textual inputs and textarea @@ -581,9 +580,9 @@ input[type="checkbox"][readonly] { .add-on { display: inline-block; width: auto; - height: @baseLineHeight; - min-width: 16px; - padding: 4px 5px; + height: 22px; + min-width: 18px; + padding: 4px 6px; font-size: @baseFontSize; font-weight: normal; line-height: @baseLineHeight; diff --git a/src/Umbraco.Web.UI.Client/src/less/variables.less b/src/Umbraco.Web.UI.Client/src/less/variables.less index c173f122cb..666941b914 100644 --- a/src/Umbraco.Web.UI.Client/src/less/variables.less +++ b/src/Umbraco.Web.UI.Client/src/less/variables.less @@ -190,7 +190,7 @@ @inputBorderRadius: 0; @inputDisabledBackground: @gray-10; @formActionsBackground: @gray-9; -@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border +@inputHeight: @baseLineHeight + 12px; // base line-height + 8px vertical padding + 2px top/bottom border @controlRequiredColor: @red; From 0f22c41eee2d5e0606e71c150314dae2accf3a5e Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 23:21:19 +0200 Subject: [PATCH 24/39] Update height of input in header --- src/Umbraco.Web.UI.Client/src/less/panel.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 6bc2a2b2de..7c18b79c81 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -446,8 +446,8 @@ input.umb-panel-header-name-input { margin-bottom: 0; font-weight: bold; box-sizing: border-box; - height: 30px; - line-height: 30px; + height: 32px; + line-height: 32px; width: 100%; &:hover { background: @white; From 8626e4337fdc67b71dc770370bffe8c28ebd367e Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 23:40:02 +0200 Subject: [PATCH 25/39] Adjust search icon position --- src/Umbraco.Web.UI.Client/src/less/forms.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index f7be2cc927..fcc8890a5d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -68,7 +68,7 @@ label.control-label, .control-label { position: absolute; z-index: 1; top: 6px; - left: 4px; + left: 6px; color: @gray-8; } From 5fb8d990f88ce36dad9f55d33740b7b4429dceb6 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Fri, 7 Jul 2017 22:12:27 +0200 Subject: [PATCH 26/39] Include original missing changes --- src/Umbraco.Web.UI.Client/src/less/forms.less | 1586 ++++++++--------- 1 file changed, 793 insertions(+), 793 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index fcc8890a5d..7e4b83b108 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -1,662 +1,662 @@ -// -// Forms -// -------------------------------------------------- - -// UMBRACO STYLES -// -------------- - - - -small.umb-detail, -label small, .guiDialogTiny { - color: @gray-5 !important; - text-decoration: none; - display: block; - font-weight: normal; - font-size: 11px -} - -label.control-label, .control-label { - padding: 0 10px 0 0 !important; - font-weight: bold; - color: @black; -} - - -.umb-status-label{ - color: @gray-3 !important; - } - - -.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} - - - -//utill styll to hide child untill hover -/*.hover-show{visibility: hidden;} -*:hover > .hover-show{visibility: visible;} -*/ - -//breadcrumb modifications - -.breadcrumb{height: 30px; display: block; margin-top: 10px;} -.breadcrumb li{height: 30px; vertical-align: middle;} -.breadcrumb li a{vertical-align: middle; height: 30px;} -.breadcrumb input{font-size: 11px !Important;} - - - -/* SEACH FORM */ -.form-search { - position: relative; - padding: 0; -} -.form-search a{ - text-decoration:none; - cursor:pointer; -} -.form-search a:hover{ - color: @gray-3; -} -.form-search h4 { - color: @gray-3; -} -.form-search small { - color: @gray-8; -} -.form-search .icon, .form-search .icon-search { - position: absolute; - z-index: 1; - top: 6px; - left: 6px; - color: @gray-8; -} - -.form-search .icon-search { - pointer-events: none; -} - -.form-search input { - width: 90%; +// +// Forms +// -------------------------------------------------- + +// UMBRACO STYLES +// -------------- + + + +small.umb-detail, +label small, .guiDialogTiny { + color: @gray-5 !important; + text-decoration: none; + display: block; + font-weight: normal; + font-size: 11px +} + +label.control-label, .control-label { + padding: 0 10px 0 0 !important; + font-weight: bold; + color: @black; +} + + +.umb-status-label{ + color: @gray-3 !important; + } + + +.controls-row label{padding: 0 10px 0 10px; vertical-align: middle;} + + + +//utill styll to hide child untill hover +/*.hover-show{visibility: hidden;} +*:hover > .hover-show{visibility: visible;} +*/ + +//breadcrumb modifications + +.breadcrumb{height: 30px; display: block; margin-top: 10px;} +.breadcrumb li{height: 30px; vertical-align: middle;} +.breadcrumb li a{vertical-align: middle; height: 30px;} +.breadcrumb input{font-size: 11px !Important;} + + + +/* SEACH FORM */ +.form-search { + position: relative; + padding: 0; +} +.form-search a{ + text-decoration:none; + cursor:pointer; +} +.form-search a:hover{ + color: @gray-3; +} +.form-search h4 { + color: @gray-3; +} +.form-search small { + color: @gray-8; +} +.form-search .icon, .form-search .icon-search { + position: absolute; + z-index: 1; + top: 6px; + left: 6px; + color: @gray-8; +} + +.form-search .icon-search { + pointer-events: none; +} + +.form-search input { + width: 90%; font-size: @fontSizeLarge; font-weight: 400; border: 1px solid @gray-8; line-height: 22px; background: @white -} - +} + .form-search .icon-search + .search-input { padding-left: 25px !important; -} - -.form-search .search-input { - font-weight: bold; - border-color: @gray-8; - - &:hover, - &:focus, - &:focus:hover { - border-color: @gray-7; - } - - &:-moz-placeholder { - font-weight: normal; - } - &:-ms-input-placeholder { - font-weight: normal; - } - &::-webkit-input-placeholder { - font-weight: normal; - } -} - - -// GENERAL STYLES -// -------------- - -// Make all forms have space below them -form { - margin: 0 0 @baseLineHeight; -} - -form.-no-margin-bottom { - margin-bottom: 0; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -// Groups of fields with labels on top (legends) -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: @baseLineHeight; - font-size: @baseFontSize * 1.5; - line-height: @baseLineHeight * 2; - color: @grayDark; - border: 0; - border-bottom: 1px solid @gray-8; - - // Small - small { - font-size: @baseLineHeight * .75; - color: @gray-8; - } -} - - - -// Set font for forms -label, -input, -button, -select, -textarea { - #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here -} -input, -button, -select, -textarea { - font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) -} - -// Identify controls by their labels -label { - display: inline-block; - margin-bottom: 5px; -} - -// Form controls -// ------------------------- - -// Shared size and type resets -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; +} + +.form-search .search-input { + font-weight: bold; + border-color: @gray-8; + + &:hover, + &:focus, + &:focus:hover { + border-color: @gray-7; + } + + &:-moz-placeholder { + font-weight: normal; + } + &:-ms-input-placeholder { + font-weight: normal; + } + &::-webkit-input-placeholder { + font-weight: normal; + } +} + + +// GENERAL STYLES +// -------------- + +// Make all forms have space below them +form { + margin: 0 0 @baseLineHeight; +} + +form.-no-margin-bottom { + margin-bottom: 0; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +// Groups of fields with labels on top (legends) +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @baseLineHeight; + font-size: @baseFontSize * 1.5; + line-height: @baseLineHeight * 2; + color: @grayDark; + border: 0; + border-bottom: 1px solid @gray-8; + + // Small + small { + font-size: @baseLineHeight * .75; + color: @gray-8; + } +} + + + +// Set font for forms +label, +input, +button, +select, +textarea { + #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here +} +input, +button, +select, +textarea { + font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element) +} + +// Identify controls by their labels +label { + display: inline-block; + margin-bottom: 5px; +} + +// Form controls +// ------------------------- + +// Shared size and type resets +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; height: @inputHeight; - padding: 4px 6px; - margin-bottom: @baseLineHeight / 2; - font-size: @baseFontSize; - line-height: @baseLineHeight; - color: @gray-3; - .border-radius(@inputBorderRadius); - vertical-align: middle; - box-sizing: border-box; -} - -input.-full-width-input { - width: 100%; - box-sizing: border-box; - padding: 4px 6px; -} - -// Reset appearance properties for textual inputs and textarea -// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) -input, -textarea, -.uneditable-input { - width: 206px; // plus 12px padding and 2px border -} -// Reset height since textareas have rows -textarea { - height: auto; -} -// Everything else -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: @inputBackground; - border: 1px solid @inputBorder; - .transition(~"border linear .2s, box-shadow linear .2s"); - - // Focus state - &:focus { - border-color: none; - outline: 0; - outline: none \9; /* IE6-9 */ - } -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; /* IE7 */ - margin-top: 1px \9; /* IE8-9 */ - line-height: normal; -} - -// Reset width of input images, buttons, radios, checkboxes -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; // Override of generic input selector -} - -// Set the height of select and file controls to match text inputs -select, -input[type="file"] { - height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; /* For IE7, add top margin to align select with labels */ - line-height: @inputHeight; -} - -// Make select elements obey height by applying a border -select { - width: 220px; // default input width + 10px of padding that doesn't get applied - border: 1px solid @inputBorder; - background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for select, file, radio, and checkbox -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - .tab-focus(); -} - - -// Uneditable inputs -// ------------------------- - -// Make uneditable inputs look inactive -.uneditable-input, -.uneditable-textarea { - color: @gray-8; - background-color: darken(@inputBackground, 1%); - border-color: @inputBorder; - .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); - cursor: not-allowed; -} - -// For text that needs to appear as an input but should not be an input -.uneditable-input { - overflow: hidden; // prevent text from wrapping, but still cut it off like an input does - white-space: nowrap; -} - -// Make uneditable textareas behave like a textarea -.uneditable-textarea { - width: auto; - height: auto; -} - - -// Placeholder -// ------------------------- - -// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector -input, -textarea { - .placeholder(@gray-6); -} - - -// CHECKBOXES & RADIOS -// ------------------- - -// Indent the labels to position radios/checkboxes as hanging -.radio, -.checkbox { - min-height: @baseLineHeight; // clear the floating input if there is no label text - padding-left: 20px; -} - -.radio.no-indent, -.checkbox.no-indent { - padding-left: 0; -} - -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: 0px; - margin-right:5px; -} - -// Move the options list down to align with labels -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; // has to be padding because margin collaspes -} - -// Radios and checkboxes on same line -// TODO v3: Convert .inline to .control-inline -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; // space out consecutive inline controls -} - - - -// INPUT SIZES -// ----------- - -// General classes for quick sizes -.input-mini { width: 60px; } -.input-small { width: 90px; } -.input-medium { width: 150px; } -.input-large { width: 210px; } -.input-xlarge { width: 270px; } -.input-xxlarge { width: 530px; } - -input.input--no-border { border: none; } - -// Grid style input sizes -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -// Redeclare since the fluid row class is more specific -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -// Ensure input-prepend/append never wraps -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - -.bigInput, .input-large-type{ - font-size: 20px !important; -} - - -// GRID SIZING FOR INPUTS -// ---------------------- - -// Grid sizes -#grid > .input(@gridColumnWidth, @gridGutterWidth); - -// Control row for multiple inputs per line -.controls-row { - .clearfix(); // Clear the float from controls -} - -// Float to collapse white-space for proper grid alignment -.controls-row [class*="span"], -// Redeclare the fluid grid collapse since we undo the float for inputs -.row-fluid .controls-row [class*="span"] { - float: left; -} -// Explicity set top padding on all checkboxes/radios, not just first-child -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - - - - -// DISABLED STATE -// -------------- - -// Disabled and read-only inputs -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: @inputDisabledBackground; -} -// Explicitly reset the colors here -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - - -//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot -// share colors with the notifications/alerts. Also had to change them so that -// we do not show any errors unless the containing element has the show-validation -// class assigned. - -// FORM FIELD FEEDBACK STATES -// -------------------------- - -// Error -.show-validation.ng-invalid .control-group.error, -.show-validation.ng-invalid .umb-panel-header-content-wrapper { - .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); -} - -//val-highlight directive styling -.highlight-error { - color: @formErrorText !important; - border-color: @red-l1 !important; -} - -//disable the glowing border for the umb-content-name -.show-validation .umb-headline-editor-wrapper input:focus:invalid, -.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, -.show-validation .umb-headline-editor-wrapper select:focus:invalid { - border:none; - color:inherit; - border-color:inherit; - @shadow:inherit; - .box-shadow(@shadow); -} - -.ng-invalid > .umb-headline-editor-wrapper h1{ - border-bottom: 1px dashed @red; color: @red; cursor: pointer; -}; - -// FORM ACTIONS -// ------------ - -.form-actions { - padding: (@baseLineHeight - 1) 20px @baseLineHeight; - margin-top: @baseLineHeight; - margin-bottom: @baseLineHeight; - background-color: @formActionsBackground; - border-top: 1px solid @gray-8; - .clearfix(); // Adding clearfix to allow for .pull-right button containers -} - - - -// HELP TEXT -// --------- - -.help-block, -.help-inline { - color: lighten(@textColor, 15%); // lighten the text some for contrast -} - -.help-block { - display: block; // account for any element using help-block - margin-bottom: @baseLineHeight / 2; -} - -.help-inline { - display: inline-block; - .ie7-inline-block(); - vertical-align: middle; - padding-left: 5px; -} - - - -// INPUT GROUPS -// ------------ - -// Allow us to put symbols and text within the input field for a cleaner look -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: @baseLineHeight / 2; - vertical-align: middle; - font-size: 0; // white space collapse hack - white-space: nowrap; // Prevent span and input from separating - - // Reset the white space collapse hack - input, - select, - .uneditable-input, - .dropdown-menu, - .popover { - font-size: @baseFontSize; - } - - input, - select, - .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms - *margin-left: 0; - vertical-align: top; - // Make input on top when focused so blue border and shadow always show - &:focus { - z-index: 2; - } - } - .add-on { - display: inline-block; - width: auto; + padding: 4px 6px; + margin-bottom: @baseLineHeight / 2; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @gray-3; + .border-radius(@inputBorderRadius); + vertical-align: middle; + box-sizing: border-box; +} + +input.-full-width-input { + width: 100%; + box-sizing: border-box; + padding: 4px 6px; +} + +// Reset appearance properties for textual inputs and textarea +// Declare width for legacy (can't be on input[type=*] selectors or it's too specific) +input, +textarea, +.uneditable-input { + width: 206px; // plus 12px padding and 2px border +} +// Reset height since textareas have rows +textarea { + height: auto; +} +// Everything else +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: @inputBackground; + border: 1px solid @inputBorder; + .transition(~"border linear .2s, box-shadow linear .2s"); + + // Focus state + &:focus { + border-color: none; + outline: 0; + outline: none \9; /* IE6-9 */ + } +} + +// Position radios and checkboxes better +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; /* IE7 */ + margin-top: 1px \9; /* IE8-9 */ + line-height: normal; +} + +// Reset width of input images, buttons, radios, checkboxes +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; // Override of generic input selector +} + +// Set the height of select and file controls to match text inputs +select, +input[type="file"] { + height: @inputHeight; /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; /* For IE7, add top margin to align select with labels */ + line-height: @inputHeight; +} + +// Make select elements obey height by applying a border +select { + width: 220px; // default input width + 10px of padding that doesn't get applied + border: 1px solid @inputBorder; + background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Focus for select, file, radio, and checkbox +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + .tab-focus(); +} + + +// Uneditable inputs +// ------------------------- + +// Make uneditable inputs look inactive +.uneditable-input, +.uneditable-textarea { + color: @gray-8; + background-color: darken(@inputBackground, 1%); + border-color: @inputBorder; + .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); + cursor: not-allowed; +} + +// For text that needs to appear as an input but should not be an input +.uneditable-input { + overflow: hidden; // prevent text from wrapping, but still cut it off like an input does + white-space: nowrap; +} + +// Make uneditable textareas behave like a textarea +.uneditable-textarea { + width: auto; + height: auto; +} + + +// Placeholder +// ------------------------- + +// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector +input, +textarea { + .placeholder(@gray-6); +} + + +// CHECKBOXES & RADIOS +// ------------------- + +// Indent the labels to position radios/checkboxes as hanging +.radio, +.checkbox { + min-height: @baseLineHeight; // clear the floating input if there is no label text + padding-left: 20px; +} + +.radio.no-indent, +.checkbox.no-indent { + padding-left: 0; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: 0px; + margin-right:5px; +} + +// Move the options list down to align with labels +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; // has to be padding because margin collaspes +} + +// Radios and checkboxes on same line +// TODO v3: Convert .inline to .control-inline +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; // space out consecutive inline controls +} + + + +// INPUT SIZES +// ----------- + +// General classes for quick sizes +.input-mini { width: 60px; } +.input-small { width: 90px; } +.input-medium { width: 150px; } +.input-large { width: 210px; } +.input-xlarge { width: 270px; } +.input-xxlarge { width: 530px; } + +input.input--no-border { border: none; } + +// Grid style input sizes +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +// Redeclare since the fluid row class is more specific +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +// Ensure input-prepend/append never wraps +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +.bigInput, .input-large-type{ + font-size: 20px !important; +} + + +// GRID SIZING FOR INPUTS +// ---------------------- + +// Grid sizes +#grid > .input(@gridColumnWidth, @gridGutterWidth); + +// Control row for multiple inputs per line +.controls-row { + .clearfix(); // Clear the float from controls +} + +// Float to collapse white-space for proper grid alignment +.controls-row [class*="span"], +// Redeclare the fluid grid collapse since we undo the float for inputs +.row-fluid .controls-row [class*="span"] { + float: left; +} +// Explicity set top padding on all checkboxes/radios, not just first-child +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + + + + +// DISABLED STATE +// -------------- + +// Disabled and read-only inputs +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: @inputDisabledBackground; +} +// Explicitly reset the colors here +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + + +//SD: NOTE: Had to change these to use our 'form' prefixed colors since we cannot +// share colors with the notifications/alerts. Also had to change them so that +// we do not show any errors unless the containing element has the show-validation +// class assigned. + +// FORM FIELD FEEDBACK STATES +// -------------------------- + +// Error +.show-validation.ng-invalid .control-group.error, +.show-validation.ng-invalid .umb-panel-header-content-wrapper { + .formFieldState(@formErrorText, @formErrorText, @formErrorBackground); +} + +//val-highlight directive styling +.highlight-error { + color: @formErrorText !important; + border-color: @red-l1 !important; +} + +//disable the glowing border for the umb-content-name +.show-validation .umb-headline-editor-wrapper input:focus:invalid, +.show-validation .umb-headline-editor-wrapper textarea:focus:invalid, +.show-validation .umb-headline-editor-wrapper select:focus:invalid { + border:none; + color:inherit; + border-color:inherit; + @shadow:inherit; + .box-shadow(@shadow); +} + +.ng-invalid > .umb-headline-editor-wrapper h1{ + border-bottom: 1px dashed @red; color: @red; cursor: pointer; +}; + +// FORM ACTIONS +// ------------ + +.form-actions { + padding: (@baseLineHeight - 1) 20px @baseLineHeight; + margin-top: @baseLineHeight; + margin-bottom: @baseLineHeight; + background-color: @formActionsBackground; + border-top: 1px solid @gray-8; + .clearfix(); // Adding clearfix to allow for .pull-right button containers +} + + + +// HELP TEXT +// --------- + +.help-block, +.help-inline { + color: lighten(@textColor, 15%); // lighten the text some for contrast +} + +.help-block { + display: block; // account for any element using help-block + margin-bottom: @baseLineHeight / 2; +} + +.help-inline { + display: inline-block; + .ie7-inline-block(); + vertical-align: middle; + padding-left: 5px; +} + + + +// INPUT GROUPS +// ------------ + +// Allow us to put symbols and text within the input field for a cleaner look +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: @baseLineHeight / 2; + vertical-align: middle; + font-size: 0; // white space collapse hack + white-space: nowrap; // Prevent span and input from separating + + // Reset the white space collapse hack + input, + select, + .uneditable-input, + .dropdown-menu, + .popover { + font-size: @baseFontSize; + } + + input, + select, + .uneditable-input { + position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness + margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms + *margin-left: 0; + vertical-align: top; + // Make input on top when focused so blue border and shadow always show + &:focus { + z-index: 2; + } + } + .add-on { + display: inline-block; + width: auto; height: 22px; min-width: 18px; padding: 4px 6px; - font-size: @baseFontSize; - font-weight: normal; - line-height: @baseLineHeight; - text-align: center; - text-shadow: 0 1px 0 @white; - background-color: @gray-10; - border: 1px solid @gray-8; - } - .add-on, - .btn, - .btn-group > .dropdown-toggle { - vertical-align: top; - .border-radius(0); - } - .active { - background-color: lighten(@green, 30); - border-color: @green; - } -} - -.input-prepend { - .add-on, - .btn { - margin-right: -1px; - } -} - -.input-append { - .add-on, - .btn, - .btn-group { - margin-left: -1px; - } -} - -// Remove all border-radius for inputs with both prepend and append -.input-prepend.input-append { - input, - select, - .uneditable-input { - .border-radius(0); - + .btn-group .btn { - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - } - .add-on:first-child, - .btn:first-child { - margin-right: -1px; - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - margin-left: -1px; - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } - .btn-group:first-child { - margin-left: 0; - } -} - - - - -// SEARCH FORM -// ----------- - -input.search-query { - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin: 0; // Remove the default margin on all inputs -} - -/* Allow for input prepend/append in search forms */ + font-size: @baseFontSize; + font-weight: normal; + line-height: @baseLineHeight; + text-align: center; + text-shadow: 0 1px 0 @white; + background-color: @gray-10; + border: 1px solid @gray-8; + } + .add-on, + .btn, + .btn-group > .dropdown-toggle { + vertical-align: top; + .border-radius(0); + } + .active { + background-color: lighten(@green, 30); + border-color: @green; + } +} + +.input-prepend { + .add-on, + .btn { + margin-right: -1px; + } +} + +.input-append { + .add-on, + .btn, + .btn-group { + margin-left: -1px; + } +} + +// Remove all border-radius for inputs with both prepend and append +.input-prepend.input-append { + input, + select, + .uneditable-input { + .border-radius(0); + + .btn-group .btn { + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + } + .add-on:first-child, + .btn:first-child { + margin-right: -1px; + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } + .add-on:last-child, + .btn:last-child { + margin-left: -1px; + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } + .btn-group:first-child { + margin-left: 0; + } +} + + + + +// SEARCH FORM +// ----------- + +input.search-query { + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin: 0; // Remove the default margin on all inputs +} + +/* Allow for input prepend/append in search forms */ .form-search { .input-prepend { .btn { @@ -668,148 +668,148 @@ input.search-query { .border-radius(0 @borderRadiusSmall @borderRadiusSmall 0); } } -} - - -// HORIZONTAL & VERTICAL FORMS -// --------------------------- - -// Common properties -// ----------------- - -.form-search, -.form-inline, -.form-horizontal { - input, - textarea, - select, - .help-inline, - .uneditable-input, - .input-prepend, - .input-append { - display: inline-block; - .ie7-inline-block(); - margin-bottom: 0; - vertical-align: top; - } - // Re-hide hidden elements due to specifity - .hide { - display: none; - } -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -// Remove margin for input-prepend/-append -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -// Inline checkbox/radio labels (remove padding on left) -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -// Remove float and margin, set to inline-block -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - - -// Margin to space out fieldsets -.control-group { - margin-bottom: @baseLineHeight / 2; -} - -//modifier for control group -.control-group.-no-margin { - margin-bottom:0; -} - -// Legend collapses margin, so next element is responsible for spacing -legend + .control-group { - margin-top: @baseLineHeight; - -webkit-margin-top-collapse: separate; -} - -// Horizontal-specific styles -// -------------------------- - -.form-horizontal { - // Increase spacing between groups - .control-group { - margin-bottom: @baseLineHeight; - .clearfix(); - } - // Float the labels left - .control-label { - float: left; - width: @horizontalComponentOffset - 20; - padding-top: 5px; - text-align: right; - } - // Move over all input controls and content - .controls { - // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend - // don't inherit the margin of the parent, in this case .controls - *display: inline-block; - *padding-left: 20px; - margin-left: @horizontalComponentOffset; - *margin-left: 0; - &:first-child { - *padding-left: @horizontalComponentOffset; - } - } - // Remove bottom margin on block level help text since that's accounted for on .control-group - .help-block { - margin-bottom: 0; - } - // And apply it only to .help-block instances that follow a form control - input, - select, - textarea, - .uneditable-input, - .input-prepend, - .input-append { - + .help-block { - margin-top: @baseLineHeight / 2; - } - } - // Move over buttons in .form-actions to align with .controls - .form-actions { - padding-left: @horizontalComponentOffset; - } -} -//make sure buttons are always on top -.umb-panel-buttons .umb-btn-toolbar .btn { - position: relative; - z-index: 1000; -} - - - -@media (max-width: 767px) { - - // Labels on own row - .form-horizontal .control-label { - width: 100%; - } - .form-horizontal .controls { - margin-left: 0; - } - -} +} + + +// HORIZONTAL & VERTICAL FORMS +// --------------------------- + +// Common properties +// ----------------- + +.form-search, +.form-inline, +.form-horizontal { + input, + textarea, + select, + .help-inline, + .uneditable-input, + .input-prepend, + .input-append { + display: inline-block; + .ie7-inline-block(); + margin-bottom: 0; + vertical-align: top; + } + // Re-hide hidden elements due to specifity + .hide { + display: none; + } +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +// Remove margin for input-prepend/-append +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +// Inline checkbox/radio labels (remove padding on left) +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +// Remove float and margin, set to inline-block +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + + +// Margin to space out fieldsets +.control-group { + margin-bottom: @baseLineHeight / 2; +} + +//modifier for control group +.control-group.-no-margin { + margin-bottom:0; +} + +// Legend collapses margin, so next element is responsible for spacing +legend + .control-group { + margin-top: @baseLineHeight; + -webkit-margin-top-collapse: separate; +} + +// Horizontal-specific styles +// -------------------------- + +.form-horizontal { + // Increase spacing between groups + .control-group { + margin-bottom: @baseLineHeight; + .clearfix(); + } + // Float the labels left + .control-label { + float: left; + width: @horizontalComponentOffset - 20; + padding-top: 5px; + text-align: right; + } + // Move over all input controls and content + .controls { + // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend + // don't inherit the margin of the parent, in this case .controls + *display: inline-block; + *padding-left: 20px; + margin-left: @horizontalComponentOffset; + *margin-left: 0; + &:first-child { + *padding-left: @horizontalComponentOffset; + } + } + // Remove bottom margin on block level help text since that's accounted for on .control-group + .help-block { + margin-bottom: 0; + } + // And apply it only to .help-block instances that follow a form control + input, + select, + textarea, + .uneditable-input, + .input-prepend, + .input-append { + + .help-block { + margin-top: @baseLineHeight / 2; + } + } + // Move over buttons in .form-actions to align with .controls + .form-actions { + padding-left: @horizontalComponentOffset; + } +} +//make sure buttons are always on top +.umb-panel-buttons .umb-btn-toolbar .btn { + position: relative; + z-index: 1000; +} + + + +@media (max-width: 767px) { + + // Labels on own row + .form-horizontal .control-label { + width: 100%; + } + .form-horizontal .controls { + margin-left: 0; + } + +} From c645a2cf153f4c12b2b163f5d78fabaec4c23d09 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 8 Jul 2017 00:45:18 +0200 Subject: [PATCH 27/39] Update styles of datepicker --- src/Umbraco.Web.UI.Client/src/less/main.less | 21 +++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less index 1b573bbe0b..222fa2474e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/main.less +++ b/src/Umbraco.Web.UI.Client/src/less/main.less @@ -47,10 +47,25 @@ h5.-black { background: none; border: none } -.datepicker td.active, -.datepicker td span.active { - background: @turquoise !important; +.bootstrap-datetimepicker-widget { + td { + &.active, span.active { + background: @turquoise !important; + } + &.today:not(.active):before { + border-bottom-color: @purple-l1 !important; + } + a[data-action] { + padding: 0 !important; + } + .timepicker-hour, + .timepicker-minute, + .timepicker-second { + margin: 8px 0; + } + } } + .umb-datetime-picker div.info { vertical-align: middle } From e28ba446a0a0562f7b9da40220f8cec716b269a5 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 8 Jul 2017 01:20:26 +0200 Subject: [PATCH 28/39] Open context menu when clicking "Do something else" --- src/Umbraco.Web.UI.Client/src/views/member/create.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/member/create.html b/src/Umbraco.Web.UI.Client/src/views/member/create.html index 2ef2b5f04f..188c6214eb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/member/create.html @@ -20,7 +20,7 @@ From c87e880b641decbb15b4c7dfe974fea9bfc11c9a Mon Sep 17 00:00:00 2001 From: Alexander Bryukhov Date: Tue, 11 Jul 2017 14:15:07 +0700 Subject: [PATCH 29/39] Minor localization issues U4-10139 --- .../src/views/common/dialogs/rteembed.html | 6 +++--- .../src/views/common/overlays/embed/embed.html | 10 +++++----- .../common/overlays/mediaPicker/mediapicker.html | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 15 ++++++++++++--- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html index 9acb92401b..ba1adcbb88 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html @@ -2,13 +2,13 @@
[Tree(Constants.Applications.Developer, "partialViewMacros", null, sortOrder: 6)] - public class PartialViewMacrosTreeController : FileSystemTreeController2 + public class PartialViewMacrosTreeController : FileSystemTreeController2 { protected override IFileSystem2 FileSystem { get { return FileSystemProviderManager.Current.MacroPartialsFileSystem; } } - private static readonly string[] ExtensionsStatic = { "cshtml" }; + private static readonly string[] ExtensionsStatic = {"cshtml"}; protected override string[] Extensions { diff --git a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs index 81bef4b13e..bf4ec65a2e 100644 --- a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs +++ b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs @@ -8,14 +8,14 @@ namespace Umbraco.Web.Trees /// Tree for displaying partial views in the settings app /// [Tree(Constants.Applications.Settings, "partialViews", null, sortOrder: 2)] - public class PartialViewsTreeController : FileSystemTreeController2 + public class PartialViewsTreeController : FileSystemTreeController2 { - protected override IFileSystem2 FileSystem - { - get { return FileSystemProviderManager.Current.PartialViewsFileSystem; } - } + protected override IFileSystem2 FileSystem + { + get { return FileSystemProviderManager.Current.PartialViewsFileSystem; } + } - private static readonly string[] ExtensionsStatic = { "cshtml" }; + private static readonly string[] ExtensionsStatic = {"cshtml"}; protected override string[] Extensions { From 7bc52b39485cfae50134d088f5d988bcda489b84 Mon Sep 17 00:00:00 2001 From: Claus Date: Wed, 12 Jul 2017 15:06:29 +0200 Subject: [PATCH 33/39] localization fixes. --- .../src/views/common/dialogs/rteembed.html | 2 +- .../src/views/common/overlays/embed/embed.html | 2 +- .../src/views/common/overlays/mediaPicker/mediapicker.html | 1 - src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 - src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 - src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 3 +-- 7 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html index ba1adcbb88..7bf24c086f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/rteembed.html @@ -2,7 +2,7 @@