Merge branch 'v8/8.2-rc' into v8/8.2

# Conflicts:
#	src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
This commit is contained in:
Bjarke Berg
2019-10-08 11:41:14 +02:00
5 changed files with 142 additions and 35 deletions

View File

@@ -588,12 +588,15 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
var selectedElm = editor.selection.getNode(),
currentTarget;
currentTarget,
imgDomElement;
if (selectedElm.nodeName === 'IMG') {
var img = $(selectedElm);
imgDomElement = selectedElm;
var hasUdi = img.attr("data-udi") ? true : false;
var hasDataTmpImg = img.attr("data-tmpimg") ? true : false;
currentTarget = {
altText: img.attr("alt"),
@@ -605,12 +608,16 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
} else {
currentTarget["id"] = img.attr("rel");
}
if(hasDataTmpImg){
currentTarget["tmpimg"] = img.attr("data-tmpimg");
}
}
userService.getCurrentUser().then(function (userData) {
if (callback) {
angularHelper.safeApply($rootScope, function() {
callback(currentTarget, userData);
callback(currentTarget, userData, imgDomElement);
});
}
});
@@ -618,25 +625,77 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
},
insertMediaInEditor: function (editor, img) {
insertMediaInEditor: function (editor, img, imgDomElement) {
if (img) {
// imgElement is only definied if updating an image
// if null/undefinied then its a BRAND new image
if(imgDomElement){
// Check if the img src has changed
// If it has we will need to do some resizing/recalc again
var hasImageSrcChanged = false;
var data = {
alt: img.altText || "",
src: (img.url) ? img.url : "nothing.jpg",
id: '__mcenew',
'data-udi': img.udi
};
if(img.url !== editor.dom.getAttrib(imgDomElement, "src")){
hasImageSrcChanged = true;
}
editor.selection.setContent(editor.dom.createHTML('img', data));
// If null/undefinied it will remove the attribute
editor.dom.setAttrib(imgDomElement, "alt", img.altText);
$timeout(function () {
var imgElm = editor.dom.get('__mcenew');
sizeImageInEditor(editor, imgElm, img.url);
editor.dom.setAttrib(imgElm, 'id', null);
editor.fire('Change');
// It's possible to pick a NEW image - so need to ensure this gets updated
if(img.udi){
editor.dom.setAttrib(imgDomElement, "data-udi", img.udi);
}
}, 500);
// It's possible to pick a NEW image - so need to ensure this gets updated
if(img.url){
editor.dom.setAttrib(imgDomElement, "src", img.url);
}
// Remove width & height attributes (ONLY if imgSrc changed)
// So native image size is used as this needed to re-calc width & height
// For the function sizeImageInEditor() & apply the image resizing querystrings etc..
if(hasImageSrcChanged){
editor.dom.setAttrib(imgDomElement, "width", null);
editor.dom.setAttrib(imgDomElement, "height", null);
//Re-calc the image dimensions
sizeImageInEditor(editor, imgDomElement, img.url);
}
} else{
// We need to create a NEW DOM <img> element to insert
// setting an attribute of ID to __mcenew, so we can gather a reference to the node, to be able to update its size accordingly to the size of the image.
var data = {
alt: img.altText || "",
src: (img.url) ? img.url : "nothing.jpg",
id: "__mcenew",
"data-udi": img.udi
};
editor.selection.setContent(editor.dom.createHTML('img', data));
// Using settimeout to wait for a DoM-render, so we can find the new element by ID.
$timeout(function () {
var imgElm = editor.dom.get("__mcenew");
editor.dom.setAttrib(imgElm, "id", null);
// When image is loaded we are ready to call sizeImageInEditor.
var onImageLoaded = function() {
sizeImageInEditor(editor, imgElm, img.url);
editor.fire("Change");
}
// Check if image already is loaded.
if(imgElm.complete === true) {
onImageLoaded();
} else {
imgElm.onload = onImageLoaded;
}
});
}
}
},
@@ -1402,7 +1461,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
//Create the insert media plugin
self.createMediaPicker(args.editor, function (currentTarget, userData) {
self.createMediaPicker(args.editor, function (currentTarget, userData, imgDomElement) {
var startNodeId, startNodeIsVirtual;
if (!args.model.config.startNodeId) {
@@ -1425,7 +1484,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
startNodeIsVirtual: startNodeIsVirtual,
dataTypeKey: args.model.dataTypeKey,
submit: function (model) {
self.insertMediaInEditor(args.editor, model.selection[0]);
self.insertMediaInEditor(args.editor, model.selection[0], imgDomElement);
editorService.close();
},
close: function () {

View File

@@ -98,11 +98,15 @@ angular.module("umbraco")
gotoStartNode();
}
} else {
//if a target is specified, go look it up - generally this target will just contain ids not the actual full
//media object so we need to look it up
// if a target is specified, go look it up - generally this target will just contain ids not the actual full
// media object so we need to look it up
var id = $scope.target.udi ? $scope.target.udi : $scope.target.id;
var altText = $scope.target.altText;
entityResource.getById(id, "Media")
// ID of a UDI or legacy int ID still could be null/undefinied here
// As user may dragged in an image that has not been saved to media section yet
if(id){
entityResource.getById(id, "Media")
.then(function (node) {
$scope.target = node;
if (ensureWithinStartNode(node)) {
@@ -113,6 +117,12 @@ angular.module("umbraco")
}
},
gotoStartNode);
}
else {
// No ID set - then this is going to be a tmpimg that has not been uploaded
// User editing this will want to be changing the ALT text
$scope.openDetailsDialog();
}
}
}
@@ -508,4 +518,4 @@ angular.module("umbraco")
onInit();
});
});

View File

@@ -27,7 +27,7 @@ function mediaFolderPickerController($scope, editorService, entityResource) {
$scope.add = function() {
var mediaPickerOptions = {
view: "mediapicker",
multiPicker: true,
multiPicker: false, // We only want to allow you to pick one folder at a given time
disableFolderSelect: false,
onlyImages: false,
onlyFolders: true,

View File

@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
@@ -86,26 +87,63 @@ namespace Umbraco.Web.PropertyEditors
if (rawJson.IsNullOrWhiteSpace())
return null;
var grid = JsonConvert.DeserializeObject<GridValue>(rawJson);
var grid = DeserializeGridValue(rawJson, out var rtes);
// Find all controls that use the RTE editor
var controls = grid.Sections.SelectMany(x => x.Rows.SelectMany(r => r.Areas).SelectMany(a => a.Controls));
var rtes = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "rte");
var userId = _umbracoContextAccessor.UmbracoContext?.Security.CurrentUser.Id ?? Constants.Security.SuperUserId;
foreach(var rte in rtes)
//process the rte values
foreach (var rte in rtes)
{
// Parse the HTML
var html = rte.Value?.ToString();
var userId = _umbracoContextAccessor.UmbracoContext?.Security.CurrentUser.Id ?? Constants.Security.SuperUserId;
var parseAndSavedTempImages = TemplateUtilities.FindAndPersistPastedTempImages(html, mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
var editorValueWithMediaUrlsRemoved = TemplateUtilities.RemoveMediaUrlsFromTextString(parseAndSavedTempImages);
var parsedHtml = TemplateUtilities.FindAndPersistPastedTempImages(html, mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
rte.Value = parsedHtml;
rte.Value = editorValueWithMediaUrlsRemoved;
}
// Convert back to raw JSON for persisting
return JsonConvert.SerializeObject(grid);
}
/// <summary>
/// Ensures that the rich text editor values are processed within the grid
/// </summary>
/// <param name="property"></param>
/// <param name="dataTypeService"></param>
/// <param name="culture"></param>
/// <param name="segment"></param>
/// <returns></returns>
public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
{
var val = property.GetValue(culture, segment);
if (val == null) return string.Empty;
var grid = DeserializeGridValue(val.ToString(), out var rtes);
//process the rte values
foreach (var rte in rtes.ToList())
{
var html = rte.Value?.ToString();
var propertyValueWithMediaResolved = TemplateUtilities.ResolveMediaFromTextString(html);
rte.Value = propertyValueWithMediaResolved;
}
return grid;
}
private GridValue DeserializeGridValue(string rawJson, out IEnumerable<GridValue.GridControl> richTextValues)
{
var grid = JsonConvert.DeserializeObject<GridValue>(rawJson);
// Find all controls that use the RTE editor
var controls = grid.Sections.SelectMany(x => x.Rows.SelectMany(r => r.Areas).SelectMany(a => a.Controls));
richTextValues = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "rte");
return grid;
}
}
}
}

View File

@@ -114,16 +114,16 @@ namespace Umbraco.Web.PropertyEditors
if (editorValue.Value == null)
return null;
var editorValueWithMediaUrlsRemoved = TemplateUtilities.RemoveMediaUrlsFromTextString(editorValue.Value.ToString());
var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValueWithMediaUrlsRemoved);
var userId = _umbracoContextAccessor.UmbracoContext?.Security.CurrentUser.Id ?? Constants.Security.SuperUserId;
var config = editorValue.DataTypeConfiguration as RichTextConfiguration;
var mediaParent = config?.MediaParentId;
var mediaParentId = mediaParent == null ? Guid.Empty : mediaParent.Guid;
parsed = TemplateUtilities.FindAndPersistPastedTempImages(parsed, mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
var parseAndSavedTempImages = TemplateUtilities.FindAndPersistPastedTempImages(editorValue.Value.ToString(), mediaParentId, userId, _mediaService, _contentTypeBaseServiceProvider, _logger);
var editorValueWithMediaUrlsRemoved = TemplateUtilities.RemoveMediaUrlsFromTextString(parseAndSavedTempImages);
var parsed = MacroTagParser.FormatRichTextContentForPersistence(editorValueWithMediaUrlsRemoved);
return parsed;
}
}