Merge pull request #6341 from umbraco/v8/feature/2558AB-NonEditable-OEmbed
Wraps all OEmbed items in a div with the magic CSS class of mceNonEdi…
This commit is contained in:
@@ -9,14 +9,15 @@ module.exports = {
|
||||
installer: { files: ["./src/less/installer.less"], out: "installer.css" },
|
||||
nonodes: { files: ["./src/less/pages/nonodes.less"], out: "nonodes.style.min.css"},
|
||||
preview: { files: ["./src/less/canvas-designer.less"], out: "canvasdesigner.css" },
|
||||
umbraco: { files: ["./src/less/belle.less"], out: "umbraco.css" }
|
||||
umbraco: { files: ["./src/less/belle.less"], out: "umbraco.css" },
|
||||
rteContent: { files: ["./src/less/rte-content.less"], out: "rte-content.css" }
|
||||
},
|
||||
|
||||
//js files for backoffie
|
||||
//processed in the js task
|
||||
js: {
|
||||
preview: { files: ["./src/preview/**/*.js"], out: "umbraco.preview.js" },
|
||||
installer: { files: ["./src/installer/**/*.js"], out: "umbraco.installer.js" },
|
||||
installer: { files: ["./src/installer/**/*.js"], out: "umbraco.installer.js" },
|
||||
filters: { files: ["./src/common/filters/**/*.js"], out: "umbraco.filters.js" },
|
||||
resources: { files: ["./src/common/resources/**/*.js"], out: "umbraco.resources.js" },
|
||||
services: { files: ["./src/common/services/**/*.js"], out: "umbraco.services.js" },
|
||||
@@ -24,13 +25,13 @@ module.exports = {
|
||||
|
||||
//the controllers for views
|
||||
controllers: {
|
||||
files: [
|
||||
files: [
|
||||
"./src/views/**/*.controller.js",
|
||||
"./src/*.controller.js"
|
||||
], out: "umbraco.controllers.js"
|
||||
},
|
||||
|
||||
//directives/components
|
||||
//directives/components
|
||||
// - any JS file found in common / directives or common/ components
|
||||
// - any JS file found inside views that has the suffix .directive.js or .component.js
|
||||
directives: {
|
||||
|
||||
@@ -94,6 +94,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
}
|
||||
|
||||
return $q.all(promises).then(function() {
|
||||
// Always push our Umbraco RTE stylesheet
|
||||
// So we can style macros, embed items etc...
|
||||
stylesheets.push(`${Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath}/assets/css/rte-content.css`);
|
||||
|
||||
return $q.when({ stylesheets: stylesheets, styleFormats: styleFormats});
|
||||
});
|
||||
}
|
||||
@@ -324,10 +328,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
//see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix
|
||||
cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster,
|
||||
|
||||
//this is used to style the inline macro bits, sorry hard coding this form now since we don't have a standalone
|
||||
//stylesheet to load in for this with only these styles (the color is @pinkLight)
|
||||
content_style: ".mce-content-body .umb-macro-holder { border: 3px dotted #f5c1bc; padding: 7px; display: block; margin: 3px; } .umb-rte .mce-content-body .umb-macro-holder.loading {background: url(assets/img/loader.gif) right no-repeat; background-size: 18px; background-position-x: 99%;}",
|
||||
|
||||
// This allows images to be pasted in & stored as Base64 until they get uploaded to server
|
||||
paste_data_images: true,
|
||||
|
||||
@@ -429,18 +429,60 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
editor.addButton('umbembeddialog', {
|
||||
icon: 'custom icon-tv',
|
||||
tooltip: 'Embed',
|
||||
stateSelector: 'div[data-embed-url]',
|
||||
onclick: function () {
|
||||
|
||||
// Get the selected element
|
||||
// Check nodename is a DIV and the claslist contains 'embeditem'
|
||||
var selectedElm = editor.selection.getNode();
|
||||
var nodeName = selectedElm.nodeName;
|
||||
var modify = null;
|
||||
|
||||
if(nodeName.toUpperCase() === "DIV" && selectedElm.classList.contains("embeditem")){
|
||||
// See if we can go and get the attributes
|
||||
var embedUrl = editor.dom.getAttrib(selectedElm, "data-embed-url");
|
||||
var embedWidth = editor.dom.getAttrib(selectedElm, "data-embed-width");
|
||||
var embedHeight = editor.dom.getAttrib(selectedElm, "data-embed-height");
|
||||
var embedConstrain = editor.dom.getAttrib(selectedElm, "data-embed-constrain");
|
||||
|
||||
modify = {
|
||||
url: embedUrl,
|
||||
width: parseInt(embedWidth) || 0,
|
||||
height: parseInt(embedHeight) || 0,
|
||||
constrain: embedConstrain
|
||||
};
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
angularHelper.safeApply($rootScope, function() {
|
||||
callback();
|
||||
// pass the active element along so we can retrieve it later
|
||||
callback(selectedElm, modify);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
insertEmbeddedMediaInEditor: function (editor, preview) {
|
||||
editor.insertContent(preview);
|
||||
insertEmbeddedMediaInEditor: function (editor, embed, activeElement) {
|
||||
// Wrap HTML preview content here in a DIV with non-editable class of .mceNonEditable
|
||||
// This turns it into a selectable/cutable block to move about
|
||||
var wrapper = tinymce.activeEditor.dom.create('div',
|
||||
{
|
||||
'class': 'mceNonEditable embeditem',
|
||||
'data-embed-url': embed.url,
|
||||
'data-embed-height': embed.height,
|
||||
'data-embed-width': embed.width,
|
||||
'data-embed-constrain': embed.constrain,
|
||||
'contenteditable': false
|
||||
},
|
||||
embed.preview);
|
||||
|
||||
if (activeElement) {
|
||||
activeElement.replaceWith(wrapper); // directly replaces the html node
|
||||
}
|
||||
else {
|
||||
editor.selection.setNode(wrapper);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1262,10 +1304,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
});
|
||||
|
||||
//Create the embedded plugin
|
||||
self.createInsertEmbeddedMedia(args.editor, function () {
|
||||
self.createInsertEmbeddedMedia(args.editor, function (activeElement, modify) {
|
||||
var embed = {
|
||||
modify: modify,
|
||||
submit: function (model) {
|
||||
self.insertEmbeddedMediaInEditor(args.editor, model.embed.preview);
|
||||
self.insertEmbeddedMediaInEditor(args.editor, model.embed, activeElement);
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
|
||||
44
src/Umbraco.Web.UI.Client/src/less/rte-content.less
Normal file
44
src/Umbraco.Web.UI.Client/src/less/rte-content.less
Normal file
@@ -0,0 +1,44 @@
|
||||
@import "variables.less";
|
||||
|
||||
.mce-content-body .umb-macro-holder {
|
||||
border: 3px dotted @pinkLight;
|
||||
padding: 7px;
|
||||
display: block;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
|
||||
.umb-rte .mce-content-body .umb-macro-holder.loading {
|
||||
background: url(assets/img/loader.gif) right no-repeat;
|
||||
background-size: 18px; background-position-x: 99%;
|
||||
}
|
||||
|
||||
|
||||
.umb-rte .embeditem {
|
||||
position:relative;
|
||||
> * {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-rte .embeditem[data-mce-selected] {
|
||||
outline: 2px solid @pinkLight;
|
||||
}
|
||||
|
||||
.umb-rte .embeditem::before {
|
||||
z-index:1000;
|
||||
width:100%;
|
||||
height:100%;
|
||||
position:absolute;
|
||||
content:' ';
|
||||
}
|
||||
|
||||
.umb-rte .embeditem[data-mce-selected]::before {
|
||||
background:rgba(0,0,0,0.025);
|
||||
}
|
||||
|
||||
.umb-rte *[data-mce-selected="inline-boundary"] {
|
||||
background:rgba(0,0,0,0.025);
|
||||
outline: 2px solid @pinkLight;
|
||||
}
|
||||
@@ -21,8 +21,8 @@
|
||||
supportsDimensions: false
|
||||
};
|
||||
|
||||
if ($scope.model.original) {
|
||||
angular.extend($scope.model.embed, $scope.model.original);
|
||||
if ($scope.model.modify) {
|
||||
angular.extend($scope.model.embed, $scope.model.modify);
|
||||
|
||||
showPreview();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user