abstracting property clearing, so each property editor can registrer their own clear property resolvers.

This commit is contained in:
Niels Lyngsø
2020-05-26 13:48:26 +02:00
parent 1227a3b4ae
commit 220278a322
2 changed files with 99 additions and 33 deletions

View File

@@ -12,6 +12,9 @@
*/
function clipboardService(notificationsService, eventsService, localStorageService, iconHelper) {
var clearPropertyResolvers = [];
var STORAGE_KEY = "umbClipboardService";
@@ -53,42 +56,32 @@ function clipboardService(notificationsService, eventsService, localStorageServi
return false;
}
function removeKeys(values) {
for (var i = 0; i < values.length; i++) {
var obj = values[i];
// Entires with this property are entries of a nested content property. And those keys we can remove.
if (obj.ncContentTypeAlias) {
delete obj.key;
// Loop through all properties:
for (var k in obj) {
// if this property is an array, we need to check if there's more keys to remove.
if (Array.isArray(obj[k])) {
removeKeys(obj[k])
}
}
}
function clearPropertyForStorage(prop) {
for (var i=0; i<clearPropertyResolvers.length; i++) {
clearPropertyResolvers[i](prop, clearPropertyForStorage);
}
}
var prepareEntryForStorage = function(entryData) {
var prepareEntryForStorage = function(entryData, firstLevelClearupMethod) {
var shallowCloneData = Object.assign({}, entryData);// Notice only a shallow copy, since we dont need to deep copy. (that will happen when storing the data)
delete shallowCloneData.key;
delete shallowCloneData.$$hashKey;
var cloneData = Utilities.copy(entryData);
if (firstLevelClearupMethod != undefined) {
firstLevelClearupMethod(cloneData);
}
// remove keys from sub-entries
for (var t = 0; t < shallowCloneData.variants[0].tabs.length; t++) {
var tab = shallowCloneData.variants[0].tabs[t];
for (var t = 0; t < cloneData.variants[0].tabs.length; t++) {
var tab = cloneData.variants[0].tabs[t];
for (var p = 0; p < tab.properties.length; p++) {
var prop = tab.properties[p];
if (prop.view === "nestedcontent") {
removeKeys(prop.value);
}
clearPropertyForStorage(prop);
}
}
return shallowCloneData;
return cloneData;
}
var isEntryCompatible = function(entry, type, allowedAliases) {
@@ -104,6 +97,21 @@ function clipboardService(notificationsService, eventsService, localStorageServi
var service = {};
/**
* @ngdoc method
* @name umbraco.services.clipboardService#registrerPropertyClearingResolver
* @methodOf umbraco.services.clipboardService
*
* @param {string} function A method executed for every property and inner properties copied.
*
* @description
* Executed for all properties including inner properties when performing a copy action.
*/
service.registrerClearPropertyResolver = function(resolver) {
clearPropertyResolvers.push(resolver);
};
/**
* @ngdoc method
* @name umbraco.services.clipboardService#copy
@@ -119,13 +127,13 @@ function clipboardService(notificationsService, eventsService, localStorageServi
* @description
* Saves a single JS-object with a type and alias to the clipboard.
*/
service.copy = function(type, alias, data, displayLabel, displayIcon, uniqueKey) {
service.copy = function(type, alias, data, displayLabel, displayIcon, uniqueKey, firstLevelClearupMethod) {
var storage = retriveStorage();
displayLabel = displayLabel || data.name;
displayIcon = displayIcon || iconHelper.convertFromLegacyIcon(data.icon);
uniqueKey = uniqueKey || data.key || data.$$hashKey || console.error("missing unique key for this content");
uniqueKey = uniqueKey || data.key || console.error("missing unique key for this content");
// remove previous copies of this entry:
storage.entries = storage.entries.filter(
@@ -134,7 +142,7 @@ function clipboardService(notificationsService, eventsService, localStorageServi
}
);
var entry = {unique:uniqueKey, type:type, alias:alias, data:prepareEntryForStorage(data), label:displayLabel, icon:displayIcon};
var entry = {unique:uniqueKey, type:type, alias:alias, data:prepareEntryForStorage(data, firstLevelClearupMethod), label:displayLabel, icon:displayIcon};
storage.entries.push(entry);
if (saveStorage(storage) === true) {
@@ -157,16 +165,17 @@ function clipboardService(notificationsService, eventsService, localStorageServi
* @param {string} displayLabel A string setting the label to display when showing paste entries.
* @param {string} displayIcon A string setting the icon to display when showing paste entries.
* @param {string} uniqueKey A string prodiving an identifier for this entry, existing entries with this key will be removed to ensure that you only have the latest copy of this data.
* @param {string} firstLevelClearupMethod A string prodiving an identifier for this entry, existing entries with this key will be removed to ensure that you only have the latest copy of this data.
*
* @description
* Saves a single JS-object with a type and alias to the clipboard.
*/
service.copyArray = function(type, aliases, datas, displayLabel, displayIcon, uniqueKey) {
service.copyArray = function(type, aliases, datas, displayLabel, displayIcon, uniqueKey, firstLevelClearupMethod) {
var storage = retriveStorage();
// Clean up each entry
var copiedDatas = datas.map(data => prepareEntryForStorage(data));
var copiedDatas = datas.map(data => prepareEntryForStorage(data, firstLevelClearupMethod));
// remove previous copies of this entry:
storage.entries = storage.entries.filter(

View File

@@ -1,6 +1,58 @@
(function () {
'use strict';
/**
* When performing a copy, we do copy the ElementType Data Model, but each inner Nested Content property is still stored as the Nested Content Model, aka. each property is just storing its value. To handle this we need to ensure we handle both scenarios.
*/
angular.module('umbraco').run(['clipboardService', function (clipboardService) {
function clearNestedContentPropertiesForStorage(prop, propClearingMethod) {
// if prop.editor is "Umbraco.NestedContent"
if ((typeof prop === 'object' && prop.editor === "Umbraco.NestedContent")) {
var value = prop.value;
for (var i = 0; i < value.length; i++) {
var obj = value[i];
// remove the key
delete obj.key;
// Loop through all inner properties:
for (var k in obj) {
propClearingMethod(obj[k]);
}
}
}
}
clipboardService.registrerClearPropertyResolver(clearNestedContentPropertiesForStorage)
function clearInnerNestedContentPropertiesForStorage(prop, propClearingMethod) {
// if we got an array, and it has a entry with ncContentTypeAlias this meants that we are dealing with a NestedContent property inside a NestedContent property.
if ((Array.isArray(prop) && prop.length > 0 && prop[0].ncContentTypeAlias !== undefined)) {
for (var i = 0; i < prop.length; i++) {
var obj = prop[i];
// remove the key
delete obj.key;
// Loop through all inner properties:
for (var k in obj) {
propClearingMethod(obj[k]);
}
}
}
}
clipboardService.registrerClearPropertyResolver(clearInnerNestedContentPropertiesForStorage)
}]);
angular
.module('umbraco')
.component('nestedContentPropertyEditor', {
@@ -13,7 +65,7 @@
}
});
function NestedContentController($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService, overlayService, $routeParams, editorState) {
function NestedContentController($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService, overlayService) {
var vm = this;
var model = $scope.$parent.$parent.model;
@@ -76,7 +128,7 @@
}
localizationService.localize("clipboard_labelForArrayOfItemsFrom", [model.label, nodeName]).then(function (data) {
clipboardService.copyArray("elementTypeArray", aliases, vm.nodes, data, "icon-thumbnail-list", model.id);
clipboardService.copyArray("elementTypeArray", aliases, vm.nodes, data, "icon-thumbnail-list", model.id, clearNodeForCopy);
});
}
@@ -385,6 +437,11 @@
});
}
function clearNodeForCopy(clonedData) {
delete clonedData.key;
delete clonedData.$$hashKey;
}
vm.showCopy = clipboardService.isSupported();
vm.showPaste = false;
@@ -392,7 +449,7 @@
syncCurrentNode();
clipboardService.copy("elementType", node.contentTypeAlias, node);
clipboardService.copy("elementType", node.contentTypeAlias, node, null, null, null, clearNodeForCopy);
$event.stopPropagation();
}