Merge branch 'v8/dev' into v8/contrib
This commit is contained in:
@@ -12,6 +12,11 @@
|
||||
var isLeftColumnAbove = false;
|
||||
scope.editors = [];
|
||||
|
||||
/* we need to keep a count of open editors because the length of the editors array is first changed when animations are done
|
||||
we do this because some infinite editors close more than one editor at the time and we get the wrong count from editors.length
|
||||
because of the animation */
|
||||
let editorCount = 0;
|
||||
|
||||
function addEditor(editor) {
|
||||
editor.inFront = true;
|
||||
editor.moveRight = true;
|
||||
@@ -51,13 +56,16 @@
|
||||
|
||||
updateEditors(-1);
|
||||
|
||||
if(scope.editors.length === 1){
|
||||
if(scope.editors.length === 1) {
|
||||
if(isLeftColumnAbove){
|
||||
$('#leftcolumn').addClass(aboveBackDropCssClass);
|
||||
}
|
||||
|
||||
isLeftColumnAbove = false;
|
||||
}
|
||||
|
||||
// when the last editor is closed remove the focus lock
|
||||
if (editorCount === 0) {
|
||||
// Remove the inert attribute from the #mainwrapper
|
||||
focusLockService.removeInertAttribute();
|
||||
}
|
||||
@@ -105,16 +113,19 @@
|
||||
}
|
||||
|
||||
evts.push(eventsService.on("appState.editors.open", function (name, args) {
|
||||
editorCount = editorCount + 1;
|
||||
addEditor(args.editor);
|
||||
}));
|
||||
|
||||
evts.push(eventsService.on("appState.editors.close", function (name, args) {
|
||||
// remove the closed editor
|
||||
if (args && args.editor) {
|
||||
editorCount = editorCount - 1;
|
||||
removeEditor(args.editor);
|
||||
}
|
||||
// close all editors
|
||||
if (args && !args.editor && args.editors.length === 0) {
|
||||
editorCount = 0;
|
||||
scope.editors = [];
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -26,7 +26,7 @@ angular.module("umbraco.directives")
|
||||
forceUpdate: '@?'
|
||||
},
|
||||
|
||||
link: function (scope, element, attrs) {
|
||||
link: function (scope, element, attrs, windowResizeListener) {
|
||||
|
||||
var unsubscribe = [];
|
||||
let sliderRef = null;
|
||||
|
||||
@@ -48,8 +48,6 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
|
||||
});
|
||||
}
|
||||
else if (value[0]) {
|
||||
//notificationsService.error("Validation", value[0]);
|
||||
console.log({type:messageType, header:"Validation", message:value[0]})
|
||||
notificationsService.showNotification({type:messageType, header:"Validation", message:value[0]})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
// We are not ready to limit the pasted elements further than default, we will return to this feature. ( TODO: Make this feature an option. )
|
||||
// We keep spans here, cause removing spans here also removes b-tags inside of them, instead we strip them out later. (TODO: move this definition to the config file... )
|
||||
var validPasteElements = "-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody,img[src|alt|width|height],ul,ol,li,hr,pre,dl,dt,figure,figcaption,wbr"
|
||||
|
||||
|
||||
// add elements from user configurated styleFormats to our list of validPasteElements.
|
||||
// (This means that we only allow H3-element if its configured as a styleFormat on this specific propertyEditor.)
|
||||
var style, i = 0;
|
||||
@@ -605,7 +605,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
'contenteditable': false
|
||||
},
|
||||
embed.preview);
|
||||
|
||||
|
||||
// Only replace if activeElement is an Embed element.
|
||||
if (activeElement && activeElement.nodeName.toUpperCase() === "DIV" && activeElement.classList.contains("embeditem")){
|
||||
activeElement.replaceWith(wrapper); // directly replaces the html node
|
||||
@@ -733,9 +733,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
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 () {
|
||||
|
||||
@@ -756,7 +756,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1396,11 +1396,26 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
function syncContent() {
|
||||
|
||||
if(args.model.value === args.editor.getContent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//stop watching before we update the value
|
||||
stopWatch();
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
args.model.value = args.editor.getContent();
|
||||
|
||||
//make the form dirty manually so that the track changes works, setting our model doesn't trigger
|
||||
// the angular bits because tinymce replaces the textarea.
|
||||
if (args.currentForm) {
|
||||
args.currentForm.$setDirty();
|
||||
}
|
||||
// With complex validation we need to set a input field to dirty, not the form. but we will keep the old code for backwards compatibility.
|
||||
if (args.currentFormInput) {
|
||||
args.currentFormInput.$setDirty();
|
||||
}
|
||||
});
|
||||
|
||||
//re-watch the value
|
||||
startWatch();
|
||||
}
|
||||
@@ -1425,7 +1440,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
// Upload BLOB images (dragged/pasted ones)
|
||||
// find src attribute where value starts with `blob:`
|
||||
// search is case-insensitive and allows single or double quotes
|
||||
// search is case-insensitive and allows single or double quotes
|
||||
if(content.search(/src=["']blob:.*?["']/gi) !== -1){
|
||||
args.editor.uploadImages(function(data) {
|
||||
// Once all images have been uploaded
|
||||
@@ -1491,6 +1506,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
args.editor.on('Change', function (e) {
|
||||
syncContent();
|
||||
});
|
||||
args.editor.on('Keyup', function (e) {
|
||||
syncContent();
|
||||
});
|
||||
|
||||
//when we leave the editor (maybe)
|
||||
args.editor.on('blur', function (e) {
|
||||
@@ -1508,12 +1526,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
args.editor.on('Dirty', function (e) {
|
||||
syncContent(); // Set model.value to the RTE's content
|
||||
|
||||
//make the form dirty manually so that the track changes works, setting our model doesn't trigger
|
||||
// the angular bits because tinymce replaces the textarea.
|
||||
if (args.currentForm) {
|
||||
args.currentForm.$setDirty();
|
||||
}
|
||||
});
|
||||
|
||||
let self = this;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
padding: 2px 6px;
|
||||
}
|
||||
.umb-range-slider .noUi-handle {
|
||||
outline: none;
|
||||
cursor: grab;
|
||||
border-radius: 100px;
|
||||
border: none;
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
width="{{crop.width}}"
|
||||
max-size="75">
|
||||
</umb-image-thumbnail>
|
||||
<span class="__text">{{crop.alias}}</span>
|
||||
<span class="__text">{{crop.label}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<p style="background-color: #fee4e1; padding: 8px;"><strong>Important:</strong> switching from the (Obsolete) Media Picker to Media Picker will mean all data (references to previously selected media items) will be deleted and no longer available.</p>
|
||||
@@ -5,12 +5,12 @@ angular.module("umbraco")
|
||||
// TODO: A lot of the code below should be shared between the grid rte and the normal rte
|
||||
|
||||
$scope.isLoading = true;
|
||||
|
||||
|
||||
//To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias
|
||||
// because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because
|
||||
// we have this mini content editor panel that can be launched with MNTP.
|
||||
$scope.textAreaHtmlId = $scope.model.alias + "_" + String.CreateGuid();
|
||||
|
||||
|
||||
var editorConfig = $scope.model.config ? $scope.model.config.editor : null;
|
||||
if (!editorConfig || Utilities.isString(editorConfig)) {
|
||||
editorConfig = tinyMceService.defaultPrevalues();
|
||||
@@ -28,14 +28,14 @@ angular.module("umbraco")
|
||||
$scope.containerOverflow = editorConfig.mode === "distraction-free" ? (height ? "auto" : "inherit") : "inherit";
|
||||
|
||||
var promises = [];
|
||||
|
||||
|
||||
// we need to make sure that the element is initialized before we can init TinyMCE, because we find the placeholder by ID, so it needs to be appended to document before.
|
||||
var initPromise = $q((resolve, reject) => {
|
||||
this.$onInit = resolve;
|
||||
});
|
||||
|
||||
|
||||
promises.push(initPromise);
|
||||
|
||||
|
||||
//queue file loading
|
||||
tinyMceAssets.forEach(function (tinyJsAsset) {
|
||||
promises.push(assetsService.loadJs(tinyJsAsset, $scope));
|
||||
@@ -50,50 +50,50 @@ angular.module("umbraco")
|
||||
toolbar: editorConfig.toolbar,
|
||||
mode: editorConfig.mode
|
||||
}));
|
||||
|
||||
|
||||
//wait for queue to end
|
||||
$q.all(promises).then(function (result) {
|
||||
|
||||
|
||||
var standardConfig = result[promises.length - 1];
|
||||
|
||||
|
||||
if (height !== null) {
|
||||
standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1);
|
||||
}
|
||||
|
||||
|
||||
//create a baseline Config to extend upon
|
||||
var baseLineConfigObj = {
|
||||
maxImageSize: editorConfig.maxImageSize,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
|
||||
|
||||
baseLineConfigObj.setup = function (editor) {
|
||||
|
||||
|
||||
//set the reference
|
||||
tinyMceEditor = editor;
|
||||
|
||||
|
||||
tinyMceEditor.on('init', function (e) {
|
||||
$timeout(function () {
|
||||
$scope.isLoading = false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//initialize the standard editor functionality for Umbraco
|
||||
tinyMceService.initializeEditor({
|
||||
editor: editor,
|
||||
model: $scope.model,
|
||||
currentForm: angularHelper.getCurrentForm($scope)
|
||||
currentFormInput: $scope.rteForm.modelValue
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
angular.extend(baseLineConfigObj, standardConfig);
|
||||
|
||||
|
||||
// We need to wait for DOM to have rendered before we can find the element by ID.
|
||||
$timeout(function () {
|
||||
tinymce.init(baseLineConfigObj);
|
||||
}, 150);
|
||||
|
||||
|
||||
//listen for formSubmitting event (the result is callback used to remove the event subscription)
|
||||
var unsubscribe = $scope.$on("formSubmitting", function () {
|
||||
if (tinyMceEditor !== undefined && tinyMceEditor != null && !$scope.isLoading) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.RTEController" class="umb-property-editor umb-rte" ng-class="{'--initialized': !isLoading}">
|
||||
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
|
||||
|
||||
<div class="umb-rte-editor-con">
|
||||
<input type="text" id="{{model.alias}}" ng-focus="focus()" style="position:absolute;top:0;width:0;height:0;" />
|
||||
<div disable-hotkeys id="{{textAreaHtmlId}}" class="umb-rte-editor" ng-style="{ width: containerWidth, height: containerHeight, overflow: containerOverflow}"></div>
|
||||
</div>
|
||||
<ng-form name="rteForm">
|
||||
<div class="umb-rte-editor-con">
|
||||
<input type="text" id="{{model.alias}}" ng-focus="focus()" name="modelValue" ng-model="model.value" style="position:absolute;top:0;width:0;height:0;" />
|
||||
<div disable-hotkeys id="{{textAreaHtmlId}}" class="umb-rte-editor" ng-style="{ width: containerWidth, height: containerHeight, overflow: containerOverflow}"></div>
|
||||
</div>
|
||||
</ng-form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user