diff --git a/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs b/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs
index 8432c8dce0..af6860412c 100644
--- a/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs
+++ b/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs
@@ -8,7 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models;
public class RichTextEditorSettings
{
internal const string StaticValidElements =
- "+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-s[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*],figure,figcaption,video[*],audio[*],picture[*],source[*],canvas[*]";
+ "+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-s[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*],figure,figcaption,cite,video[*],audio[*],picture[*],source[*],canvas[*]";
internal const string StaticInvalidElements = "font";
diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/ro.xml b/src/Umbraco.Core/EmbeddedResources/Lang/ro.xml
index 5dda77d477..62d8d7c0b6 100644
--- a/src/Umbraco.Core/EmbeddedResources/Lang/ro.xml
+++ b/src/Umbraco.Core/EmbeddedResources/Lang/ro.xml
@@ -15,4 +15,43 @@
Traduceri
Utilizatori
+
+ Conţinut
+ Șabloane de conținut
+ Media
+ Cache Browser
+ Cos de gunoi
+ Pachete create
+ Tipuri de date
+ Dicţionar
+ Pachete instalate
+ Instalare skin
+ Instalați trusa de pornire
+ Limbi
+ Instalați pachetul local
+ Macros
+ Tipuri media
+ Membrii
+ Grupuri de membri
+ Rolurile membrilor
+ Tipuri de membri
+ Tipuri de documente
+ Tipuri de relații
+ Pachete
+ Pachete
+ Vizualizări parțiale
+ Vizualizare parțială fișiere macro
+ Instalați din depozit
+ Instalați pista
+ Module piste
+ Fișiere de scriptare
+ Scripturi
+ Stylesheets
+ Șabloane
+ Vizualizator de jurnal
+ Utilizatori
+ Setări
+ Modelare
+ Terț
+
diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
index f2a3afdbe3..f860bafd2c 100644
--- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
+++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Umbraco.
+// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Reflection;
@@ -125,6 +125,7 @@ public abstract class ConfigurationEditor : ConfigurationEditor
PropertyType = property.PropertyType,
Description = attribute.Description,
HideLabel = attribute.HideLabel,
+ SortOrder = attribute.SortOrder,
View = attributeView,
};
@@ -150,6 +151,8 @@ public abstract class ConfigurationEditor : ConfigurationEditor
field.PropertyName = property.Name;
field.PropertyType = property.PropertyType;
+ field.SortOrder = attribute.SortOrder;
+
if (!string.IsNullOrWhiteSpace(attribute.Key))
{
field.Key = attribute.Key;
@@ -182,6 +185,6 @@ public abstract class ConfigurationEditor : ConfigurationEditor
}
}
- return fields;
+ return fields.OrderBy(x => x.SortOrder).ToList();
}
}
diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs
index 40bd0c0ca9..def2135bbd 100644
--- a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs
+++ b/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs
@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using System.Runtime.Serialization;
+using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors;
@@ -47,6 +48,7 @@ public class ConfigurationField
HideLabel = attribute.HideLabel;
Key = attribute.Key;
View = attribute.View;
+ SortOrder = attribute.SortOrder;
}
///
@@ -77,6 +79,12 @@ public class ConfigurationField
[DataMember(Name = "description")]
public string? Description { get; set; }
+ ///
+ /// Gets or sets the sort order of the field.
+ ///
+ [DataMember(Name = "sortOrder")]
+ public int SortOrder { get; set; }
+
///
/// Gets or sets a value indicating whether to hide the label of the field.
///
diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs
index 07433d1504..9eec779c2c 100644
--- a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs
+++ b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs
@@ -124,6 +124,11 @@ public class ConfigurationFieldAttribute : Attribute
///
public string? View { get; }
+ ///
+ /// Gets or sets the sort order to use to render the field editor.
+ ///
+ public int SortOrder { get; set; }
+
///
/// Gets or sets the description of the field.
///
diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index ddad88b482..c32a1a4183 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -1146,6 +1146,8 @@ public class ContentService : RepositoryService, IContentService
var allLangs = _languageRepository.GetMany().ToList();
+ // Change state to publishing
+ content.PublishedState = PublishedState.Publishing;
var savingNotification = new ContentSavingNotification(content, evtMsgs);
if (scope.Notifications.PublishCancelable(savingNotification))
{
diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TagRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TagRepository.cs
index ecc6600d4c..bc78596762 100644
--- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TagRepository.cs
+++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TagRepository.cs
@@ -131,7 +131,7 @@ internal class TagRepository : EntityRepositoryBase, ITagRepository
var sql1 = $@"INSERT INTO cmsTags (tag, {group}, languageId)
SELECT tagSet.tag, tagSet.{group}, tagSet.languageId
FROM {tagSetSql}
-LEFT OUTER JOIN cmsTags ON (tagSet.tag = cmsTags.tag AND tagSet.{group} = cmsTags.{group} AND COALESCE(tagSet.languageId, -1) = COALESCE(cmsTags.languageId, -1))
+LEFT OUTER JOIN cmsTags ON (tagSet.tag LIKE cmsTags.tag AND tagSet.{group} = cmsTags.{group} AND COALESCE(tagSet.languageId, -1) = COALESCE(cmsTags.languageId, -1))
WHERE cmsTags.id IS NULL";
Database.Execute(sql1);
@@ -321,7 +321,7 @@ WHERE r.tagId IS NULL";
Sql sql = GetTaggedEntitiesSql(objectType, culture);
sql = sql
- .Where(dto => dto.Text == tag);
+ .WhereLike(dto => dto.Text, tag);
if (group.IsNullOrWhiteSpace() == false)
{
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
index 02f6164f64..7a681c07f4 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
@@ -941,15 +941,13 @@
const openPreviewWindow = () => {
// Chromes popup blocker will kick in if a window is opened
// without the initial scoped request. This trick will fix that.
- //
- const previewWindow = $window.open('preview/?init=true', 'umbpreview');
+
+ const previewWindow = $window.open(`preview/?id=${content.id}${$scope.culture ? `&culture=${$scope.culture}` : ''}`, 'umbpreview');
+
+ previewWindow.addEventListener('load', () => {
+ previewWindow.location.href = previewWindow.document.URL;
+ });
- // Build the correct path so both /#/ and #/ work.
- let query = 'id=' + content.id;
- if ($scope.culture) {
- query += "#?culture=" + $scope.culture;
- }
- previewWindow.location.href = Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + '/preview/?' + query;
}
//The user cannot save if they don't have access to do that, in which case we just want to preview
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/keyboard.service.js b/src/Umbraco.Web.UI.Client/src/common/services/keyboard.service.js
index 66babe03b8..3102a92449 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/keyboard.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/keyboard.service.js
@@ -2,324 +2,329 @@
// http://www.openjs.com/scripts/events/keyboard_shortcuts/index.php
function keyboardService($window, $timeout) {
-
- var keyboardManagerService = {};
-
- var defaultOpt = {
- 'type': 'keydown',
- 'propagate': false,
- 'inputDisabled': false,
- 'target': $window.document,
- 'keyCode': false
- };
- // Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
- var shift_nums = {
- "`": "~",
- "1": "!",
- "2": "@",
- "3": "#",
- "4": "$",
- "5": "%",
- "6": "^",
- "7": "&",
- "8": "*",
- "9": "(",
- "0": ")",
- "-": "_",
- "=": "+",
- ";": ":",
- "'": "\"",
- ",": "<",
- ".": ">",
- "/": "?",
- "\\": "|"
- };
+ var keyboardManagerService = {};
- // Special Keys - and their codes
- var special_keys = {
- 'esc': 27,
- 'escape': 27,
- 'tab': 9,
- 'space': 32,
- 'return': 13,
- 'enter': 13,
- 'backspace': 8,
+ var defaultOpt = {
+ 'type': 'keydown',
+ 'propagate': false,
+ 'inputDisabled': false,
+ 'target': $window.document,
+ 'keyCode': false
+ };
- 'scrolllock': 145,
- 'scroll_lock': 145,
- 'scroll': 145,
- 'capslock': 20,
- 'caps_lock': 20,
- 'caps': 20,
- 'numlock': 144,
- 'num_lock': 144,
- 'num': 144,
+ // Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
+ var shift_nums = {
+ "`": "~",
+ "1": "!",
+ "2": "@",
+ "3": "#",
+ "4": "$",
+ "5": "%",
+ "6": "^",
+ "7": "&",
+ "8": "*",
+ "9": "(",
+ "0": ")",
+ "-": "_",
+ "=": "+",
+ ";": ":",
+ "'": "\"",
+ ",": "<",
+ ".": ">",
+ "/": "?",
+ "\\": "|"
+ };
- 'pause': 19,
- 'break': 19,
+ // Special Keys - and their codes
+ var special_keys = {
+ 'esc': 27,
+ 'escape': 27,
+ 'tab': 9,
+ 'space': 32,
+ 'return': 13,
+ 'enter': 13,
+ 'backspace': 8,
- 'insert': 45,
- 'home': 36,
- 'delete': 46,
- 'end': 35,
+ 'scrolllock': 145,
+ 'scroll_lock': 145,
+ 'scroll': 145,
+ 'capslock': 20,
+ 'caps_lock': 20,
+ 'caps': 20,
+ 'numlock': 144,
+ 'num_lock': 144,
+ 'num': 144,
- 'pageup': 33,
- 'page_up': 33,
- 'pu': 33,
+ 'pause': 19,
+ 'break': 19,
- 'pagedown': 34,
- 'page_down': 34,
- 'pd': 34,
+ 'insert': 45,
+ 'home': 36,
+ 'delete': 46,
+ 'end': 35,
- 'left': 37,
- 'up': 38,
- 'right': 39,
- 'down': 40,
+ 'pageup': 33,
+ 'page_up': 33,
+ 'pu': 33,
- 'f1': 112,
- 'f2': 113,
- 'f3': 114,
- 'f4': 115,
- 'f5': 116,
- 'f6': 117,
- 'f7': 118,
- 'f8': 119,
- 'f9': 120,
- 'f10': 121,
- 'f11': 122,
- 'f12': 123
- };
+ 'pagedown': 34,
+ 'page_down': 34,
+ 'pd': 34,
- var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
+ 'left': 37,
+ 'up': 38,
+ 'right': 39,
+ 'down': 40,
- // The event handler for bound element events
- function eventHandler(e) {
- e = e || $window.event;
+ 'f1': 112,
+ 'f2': 113,
+ 'f3': 114,
+ 'f4': 115,
+ 'f5': 116,
+ 'f6': 117,
+ 'f7': 118,
+ 'f8': 119,
+ 'f9': 120,
+ 'f10': 121,
+ 'f11': 122,
+ 'f12': 123
+ };
- var code, k;
+ var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
- // Find out which key is pressed
- if (e.keyCode)
- {
- code = e.keyCode;
- }
- else if (e.which) {
- code = e.which;
- }
+ // The event handler for bound element events
+ function eventHandler(e) {
+ e = e || $window.event;
- var character = String.fromCharCode(code).toLowerCase();
+ var code, k;
- if (code === 188){character = ",";} // If the user presses , when the type is onkeydown
- if (code === 190){character = ".";} // If the user presses , when the type is onkeydown
-
- var propagate = true;
-
- //Now we need to determine which shortcut this event is for, we'll do this by iterating over each
- //registered shortcut to find the match. We use Find here so that the loop exits as soon
- //as we've found the one we're looking for
- _.find(_.keys(keyboardManagerService.keyboardEvent), function(key) {
-
- var shortcutLabel = key;
- var shortcutVal = keyboardManagerService.keyboardEvent[key];
-
- // Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
- var kp = 0;
-
- // Some modifiers key
- var modifiers = {
- shift: {
- wanted: false,
- pressed: e.shiftKey ? true : false
- },
- ctrl: {
- wanted: false,
- pressed: e.ctrlKey ? true : false
- },
- alt: {
- wanted: false,
- pressed: e.altKey ? true : false
- },
- meta: { //Meta is Mac specific
- wanted: false,
- pressed: e.metaKey ? true : false
- }
- };
-
- var keys = shortcutLabel.split("+");
- var opt = shortcutVal.opt;
- var callback = shortcutVal.callback;
-
- // Foreach keys in label (split on +)
- var l = keys.length;
- for (var i = 0; i < l; i++) {
-
- var k = keys[i];
- switch (k) {
- case 'ctrl':
- case 'control':
- kp++;
- modifiers.ctrl.wanted = true;
- break;
- case 'shift':
- case 'alt':
- case 'meta':
- kp++;
- modifiers[k].wanted = true;
- break;
- }
-
- if (k.length > 1) { // If it is a special key
- if (special_keys[k] === code) {
- kp++;
- }
- }
- else if (opt['keyCode']) { // If a specific key is set into the config
- if (opt['keyCode'] === code) {
- kp++;
- }
- }
- else { // The special keys did not match
- if (character === k) {
- kp++;
- }
- else {
- if (shift_nums[character] && e.shiftKey) { // Stupid Shift key bug created by using lowercase
- character = shift_nums[character];
- if (character === k) {
- kp++;
- }
- }
- }
- }
-
- } //for end
-
- if (kp === keys.length &&
- modifiers.ctrl.pressed === modifiers.ctrl.wanted &&
- modifiers.shift.pressed === modifiers.shift.wanted &&
- modifiers.alt.pressed === modifiers.alt.wanted &&
- modifiers.meta.pressed === modifiers.meta.wanted) {
-
- //found the right callback!
-
- // Disable event handler when focus input and textarea
- if (opt['inputDisabled']) {
- var elt;
- if (e.target) {
- elt = e.target;
- } else if (e.srcElement) {
- elt = e.srcElement;
- }
-
- if (elt.nodeType === 3) { elt = elt.parentNode; }
- if (elt.tagName === 'INPUT' || elt.tagName === 'TEXTAREA' || elt.hasAttribute('disable-hotkeys')) {
- //This exits the Find loop
- return true;
- }
- }
-
- $timeout(function () {
- callback(e);
- }, 1);
-
- if (!opt['propagate']) { // Stop the event
- propagate = false;
- }
-
- //This exits the Find loop
- return true;
- }
-
- //we haven't found one so continue looking
- return false;
-
- });
-
- // Stop the event if required
- if (!propagate) {
- // e.cancelBubble is supported by IE - this will kill the bubbling process.
- e.cancelBubble = true;
- e.returnValue = false;
-
- // e.stopPropagation works in Firefox.
- if (e.stopPropagation) {
- e.stopPropagation();
- e.preventDefault();
- }
- return false;
- }
+ // Find out which key is pressed
+ if (e.keyCode) {
+ code = e.keyCode;
+ } else if (e.which) {
+ code = e.which;
}
- // Store all keyboard combination shortcuts
- keyboardManagerService.keyboardEvent = {};
+ var character = String.fromCharCode(code).toLowerCase();
- // Add a new keyboard combination shortcut
- keyboardManagerService.bind = function (label, callback, opt) {
+ if (code === 188) {
+ character = ",";
+ } // If the user presses , when the type is onkeydown
+ if (code === 190) {
+ character = ".";
+ } // If the user presses , when the type is onkeydown
- //replace ctrl key with meta key
- if(isMac && label !== "ctrl+space"){
- label = label.replace("ctrl","meta");
+ var propagate = true;
+
+ //Now we need to determine which shortcut this event is for, we'll do this by iterating over each
+ //registered shortcut to find the match. We use Find here so that the loop exits as soon
+ //as we've found the one we're looking for
+ _.find(_.keys(keyboardManagerService.keyboardEvent), function (key) {
+
+ var shortcutLabel = key;
+ var shortcutVal = keyboardManagerService.keyboardEvent[key];
+
+ // Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
+ var kp = 0;
+
+ // Some modifiers key
+ var modifiers = {
+ shift: {
+ wanted: false,
+ pressed: e.shiftKey ? true : false
+ },
+ ctrl: {
+ wanted: false,
+ pressed: e.ctrlKey ? true : false
+ },
+ alt: {
+ wanted: false,
+ pressed: e.altKey ? true : false
+ },
+ meta: { //Meta is Mac specific
+ wanted: false,
+ pressed: e.metaKey ? true : false
+ }
+ };
+
+ var keys = shortcutLabel.split("+");
+ var opt = shortcutVal.opt;
+ var callback = shortcutVal.callback;
+
+ // Foreach keys in label (split on +)
+ var l = keys.length;
+ for (var i = 0; i < l; i++) {
+
+ var k = keys[i];
+ switch (k) {
+ case 'ctrl':
+ case 'control':
+ kp++;
+ modifiers.ctrl.wanted = true;
+ break;
+ case 'shift':
+ case 'alt':
+ case 'meta':
+ kp++;
+ modifiers[k].wanted = true;
+ break;
}
- var elt;
- // Initialize opt object
- opt = Utilities.extend({}, defaultOpt, opt);
- label = label.toLowerCase();
- elt = opt.target;
- if(typeof opt.target === 'string'){
- elt = document.getElementById(opt.target);
- }
-
- //Ensure we aren't double binding to the same element + type otherwise we'll end up multi-binding
- // and raising events for now reason. So here we'll check if the event is already registered for the element
- var boundValues = _.values(keyboardManagerService.keyboardEvent);
- var found = _.find(boundValues, function (i) {
- return i.target === elt && i.event === opt['type'];
- });
-
- // Store shortcut
- keyboardManagerService.keyboardEvent[label] = {
- 'callback': callback,
- 'target': elt,
- 'opt': opt
- };
-
- if (!found) {
- //Attach the function with the event
- if (elt.addEventListener) {
- elt.addEventListener(opt['type'], eventHandler, false);
- } else if (elt.attachEvent) {
- elt.attachEvent('on' + opt['type'], eventHandler);
- } else {
- elt['on' + opt['type']] = eventHandler;
+ if (k.length > 1) { // If it is a special key
+ if (special_keys[k] === code) {
+ kp++;
+ }
+ } else if (opt['keyCode']) { // If a specific key is set into the config
+ if (opt['keyCode'] === code) {
+ kp++;
+ }
+ } else { // The special keys did not match
+ if (character === k) {
+ kp++;
+ } else {
+ if (shift_nums[character] && e.shiftKey) { // Stupid Shift key bug created by using lowercase
+ character = shift_nums[character];
+ if (character === k) {
+ kp++;
+ }
}
+ }
}
-
- };
- // Remove the shortcut - just specify the shortcut and I will remove the binding
- keyboardManagerService.unbind = function (label) {
- label = label.toLowerCase();
- var binding = keyboardManagerService.keyboardEvent[label];
- delete(keyboardManagerService.keyboardEvent[label]);
- if(!binding){return;}
+ } //for end
- var type = binding['event'],
- elt = binding['target'],
- callback = binding['callback'];
+ if (kp === keys.length &&
+ modifiers.ctrl.pressed === modifiers.ctrl.wanted &&
+ modifiers.shift.pressed === modifiers.shift.wanted &&
+ modifiers.alt.pressed === modifiers.alt.wanted &&
+ modifiers.meta.pressed === modifiers.meta.wanted) {
- if(elt.detachEvent){
- elt.detachEvent('on' + type, callback);
- }else if(elt.removeEventListener){
- elt.removeEventListener(type, callback, false);
- }else{
- elt['on'+type] = false;
+ //found the right callback!
+
+ // Disable event handler when focus input and textarea
+ if (opt['inputDisabled']) {
+ var elt;
+ if (e.composedPath()) {
+ elt = e.composedPath()[0];
+ } else if (e.target) {
+ elt = e.target;
+ } else if (e.srcElement) {
+ elt = e.srcElement;
+ }
+
+ if (elt.nodeType === 3) {
+ elt = elt.parentNode;
+ }
+ if (elt.tagName === 'INPUT' || elt.tagName === 'TEXTAREA' || elt.hasAttribute('disable-hotkeys')) {
+ //This exits the Find loop
+ return true;
+ }
}
- };
- //
- return keyboardManagerService;
+ $timeout(function () {
+ callback(e);
+ }, 1);
+
+ if (!opt['propagate']) { // Stop the event
+ propagate = false;
+ }
+
+ //This exits the Find loop
+ return true;
+ }
+
+ //we haven't found one so continue looking
+ return false;
+
+ });
+
+ // Stop the event if required
+ if (!propagate) {
+ // e.cancelBubble is supported by IE - this will kill the bubbling process.
+ e.cancelBubble = true;
+ e.returnValue = false;
+
+ // e.stopPropagation works in Firefox.
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ return false;
+ }
+ }
+
+ // Store all keyboard combination shortcuts
+ keyboardManagerService.keyboardEvent = {};
+
+ // Add a new keyboard combination shortcut
+ keyboardManagerService.bind = function (label, callback, opt) {
+
+ //replace ctrl key with meta key
+ if (isMac && label !== "ctrl+space") {
+ label = label.replace("ctrl", "meta");
+ }
+
+ var elt;
+ // Initialize opt object
+ opt = Utilities.extend({}, defaultOpt, opt);
+ label = label.toLowerCase();
+ elt = opt.target;
+ if (typeof opt.target === 'string') {
+ elt = document.getElementById(opt.target);
+ }
+
+ //Ensure we aren't double binding to the same element + type otherwise we'll end up multi-binding
+ // and raising events for now reason. So here we'll check if the event is already registered for the element
+ var boundValues = _.values(keyboardManagerService.keyboardEvent);
+ var found = _.find(boundValues, function (i) {
+ return i.target === elt && i.event === opt['type'];
+ });
+
+ // Store shortcut
+ keyboardManagerService.keyboardEvent[label] = {
+ 'callback': callback,
+ 'target': elt,
+ 'opt': opt
+ };
+
+ if (!found) {
+ //Attach the function with the event
+ if (elt.addEventListener) {
+ elt.addEventListener(opt['type'], eventHandler, false);
+ } else if (elt.attachEvent) {
+ elt.attachEvent('on' + opt['type'], eventHandler);
+ } else {
+ elt['on' + opt['type']] = eventHandler;
+ }
+ }
+
+ };
+ // Remove the shortcut - just specify the shortcut and I will remove the binding
+ keyboardManagerService.unbind = function (label) {
+ label = label.toLowerCase();
+ var binding = keyboardManagerService.keyboardEvent[label];
+ delete (keyboardManagerService.keyboardEvent[label]);
+
+ if (!binding) {
+ return;
+ }
+
+ var type = binding['event'],
+ elt = binding['target'],
+ callback = binding['callback'];
+
+ if (elt.detachEvent) {
+ elt.detachEvent('on' + type, callback);
+ } else if (elt.removeEventListener) {
+ elt.removeEventListener(type, callback, false);
+ } else {
+ elt['on' + type] = false;
+ }
+ };
+ //
+
+ return keyboardManagerService;
}
angular.module('umbraco.services').factory('keyboardService', ['$window', '$timeout', keyboardService]);
diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less
index 024a668874..2fce7dfe65 100644
--- a/src/Umbraco.Web.UI.Client/src/less/main.less
+++ b/src/Umbraco.Web.UI.Client/src/less/main.less
@@ -165,7 +165,7 @@ h6.-black {
}
}
-umb-property:last-of-type .umb-control-group {
+umb-property:last-of-type > .umb-property > ng-form > .umb-control-group {
&::after {
margin-top: 0px;
height: 0;
diff --git a/src/Umbraco.Web.UI.Client/src/less/pages/login.less b/src/Umbraco.Web.UI.Client/src/less/pages/login.less
index 74b28dabcb..e565e7d8ab 100644
--- a/src/Umbraco.Web.UI.Client/src/less/pages/login.less
+++ b/src/Umbraco.Web.UI.Client/src/less/pages/login.less
@@ -118,6 +118,11 @@
line-height: 36px;
}
+.login-overlay .btn-social > .umb-icon {
+ padding: 2px;
+ box-sizing: border-box;
+}
+
.login-overlay .text-error,
.login-overlay .text-info
{
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js
index 730e7a5142..98755c4090 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js
@@ -128,6 +128,13 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
eventsService.emit("dialogs.linkPicker.select", args);
if ($scope.currentNode) {
+ if ($scope.currentNode.id == args.node.id && $scope.currentNode.selected) {
+ $scope.model.target = {};
+ $scope.currentNode.selected = false;
+
+ return;
+ }
+
//un-select if there's a current one selected
$scope.currentNode.selected = false;
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html
index 8215c66691..c54d692850 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html
@@ -18,10 +18,10 @@
+ ng-attr-readonly="{{property.readonly || !allowUpdate || undefined}}">
@@ -52,10 +52,10 @@
+ ng-attr-readonly="{{property.readonly || !allowUpdate || undefined}}">
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstringlimited.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstringlimited.html
index 4dd5b693b8..9ec218bba5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstringlimited.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textstringlimited.html
@@ -5,7 +5,7 @@
ng-model="model.value"
val-server="value"
min="0"
- max="500"
+ max="512"
fix-number />
@@ -13,5 +13,5 @@
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridblock.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridblock.component.js
index 1a918638ca..3dfbdab0ff 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridblock.component.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridblock.component.js
@@ -51,7 +51,7 @@
`
${ model.stylesheet ? `
`
: ''
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridroot.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridroot.component.js
index fbda5cf92e..bfa0746a30 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridroot.component.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/umbblockgridroot.component.js
@@ -35,8 +35,8 @@
shadowRoot.innerHTML =
`