diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index e95a5992d1ab..dee3cfdab71b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -13,7 +13,12 @@ angular.module("umbraco.directives") // TODO: A lot of the code below should be shared between the grid rte and the normal rte var promises = []; - + + //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.uniqueId + "_" + String.CreateGuid(); + //queue file loading if (typeof (tinymce) === "undefined") { promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); @@ -34,7 +39,7 @@ angular.module("umbraco.directives") var tinyMceEditor = null; promises.push(tinyMceService.getTinyMceEditorConfig({ - htmlId: scope.uniqueId, + htmlId: scope.textAreaHtmlId, stylesheets: editorConfig.stylesheets, toolbar: editorConfig.toolbar, mode: editorConfig.mode @@ -145,17 +150,11 @@ angular.module("umbraco.directives") } }); - - //listen for formSubmitting event (the result is callback used to remove the event subscription) - var formSubmittingListener = scope.$on("formSubmitting", function () { - scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null; - }); - + //when the element is disposed we need to unsubscribe! // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom // element might still be there even after the modal has been hidden. scope.$on('$destroy', function () { - formSubmittingListener(); eventsService.unsubscribe(tabShownListener); //ensure we unbind this in case the blur doesn't fire above $('.umb-panel-body').off('scroll', pinToolbar); diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less index d6db204ff224..b5abbe06bcd2 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less @@ -128,9 +128,10 @@ position: relative; margin-bottom: 40px; padding-top: 10px; + border: 1px solid @grayLighter; &:hover { - background-color: @grayLighter; + border-color: @grayLight; } &[ng-click], @@ -161,15 +162,16 @@ } .umb-grid .umb-row .umb-cell-placeholder { - min-height: 130px; - background-color: @gray-10; - border-width: 2px; + min-height: 88px; + border-width: 1px; border-style: dashed; - border-color: @gray-8; + border-color: @ui-action-discreet-border; + color: @ui-action-discreet-type; transition: border-color 100ms linear; &:hover { - border-color: @blueMid; + border-color: @ui-action-discreet-border-hover; + color: @ui-action-discreet-type-hover; cursor: pointer; } } @@ -207,9 +209,9 @@ } .umb-grid .cell-tools-add { - color: @ui-action-type; + color: @ui-action-discreet-type; &:focus, &:hover { - color: @ui-action-type-hover; + color: @ui-action-discreet-type-hover; text-decoration: none; } } @@ -219,16 +221,18 @@ top: 50%; left: 50%; transform: translate(-50%, -50%); - color: @ui-action-type; + color: @ui-action-discreet-type; } .umb-grid .cell-tools-add.-bar { display: block; - background: @gray-10; text-align: center; padding: 5px; - border: 1px dashed @gray-7; + border: 1px dashed @ui-action-discreet-border; margin: 10px; + &:focus, &:hover { + border-color: @ui-action-discreet-border-hover; + } } @@ -249,7 +253,6 @@ .umb-grid .cell-tools-edit { display: inline-block; - color: @white; } .umb-grid .drop-overlay { @@ -412,36 +415,17 @@ // Row states .umb-grid .umb-row.-active { - background-color: @ui-action-type; + border-color: @ui-action-type; .umb-row-title-bar { cursor: move; } - - .row-tool, - .umb-row-title { - color: @white; - } - - .umb-grid-has-config { - color: fade(@white, 66); - } - - .umb-cell { - .umb-grid-has-config { - color: fade(@black, 44); - } - } - - .umb-cell .umb-cell-content { - border-color: transparent; - } } .umb-grid .umb-row.-active-child { background-color: @gray-10; - + .umb-row-title-bar { cursor: inherit; } @@ -449,22 +433,7 @@ .umb-row-title { color: @gray-3; } - - .row-tool { - color: fade(@black, 23); - } - - .umb-grid-has-config { - color: fade(@black, 44); - } - - .umb-cell-content.-placeholder { - border-color: @gray-8; - - &:hover { - border-color: fade(@gray, 44); - } - } + } @@ -573,14 +542,13 @@ display: inline-block; cursor: pointer; border-radius: 200px; - background: @gray-10; - border: 1px solid @gray-7; + border: 1px solid @ui-action-discreet-border; margin: 2px; &:hover, &:hover * { - background: @ui-action-type-hover !important; + background: @ui-action-discreet-type-hover !important; color: @white !important; - border-color: @ui-action-type-hover !important; + border-color: @ui-action-discreet-border-hover !important; text-decoration: none; } } diff --git a/src/Umbraco.Web.UI.Client/src/preview/preview.controller.js b/src/Umbraco.Web.UI.Client/src/preview/preview.controller.js index 4733c58556ed..7d6584d2f1bc 100644 --- a/src/Umbraco.Web.UI.Client/src/preview/preview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/preview/preview.controller.js @@ -113,12 +113,7 @@ var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.servi $scope.exitPreview = function () { var culture = $location.search().culture || getParameterByName("culture"); - var relativeUrl = "/" + $scope.pageId; - - if(culture){ - relativeUrl +='?culture='+ culture; - } - + var relativeUrl = "/" + $scope.pageId +'?culture='+ culture; window.top.location.href = "../preview/end?redir=" + encodeURIComponent(relativeUrl); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html b/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html index 889c4133d53a..519c11f76b67 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html @@ -1,3 +1,3 @@ 
+ id="{{textAreaHtmlId}}">
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.controller.js index beb8edab204a..a45e569897a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.controller.js @@ -1,25 +1,26 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.Grid.EmbedController", function ($scope, $timeout, $sce, editorService) { - - function onInit() { - $scope.trustedValue = null; - $scope.trustedValue = $sce.trustAsHtml($scope.control.value); - - if(!$scope.control.value) { - $timeout(function(){ - if($scope.control.$initializing){ - $scope.setEmbed(); - } - }, 200); - } + + + + function getEmbed() { + return $sce.trustAsHtml($scope.control.value); } - - $scope.setEmbed = function(){ + + + $scope.embedHtml = getEmbed(); + $scope.$watch('control.value', function(newValue, oldValue) { + if(angular.equals(newValue, oldValue)){ + return; // simply skip that + } + + $scope.embedHtml = getEmbed(); + }, false); + $scope.setEmbed = function() { var embed = { submit: function(model) { $scope.control.value = model.embed.preview; - $scope.trustedValue = $sce.trustAsHtml(model.embed.preview); editorService.close(); }, close: function() { @@ -28,6 +29,5 @@ angular.module("umbraco") }; editorService.embed(embed); }; - - onInit(); + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.html index 87109e1eb9ee..8cfa71f08288 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/embed.html @@ -1,10 +1,10 @@
-
+
Click to embed
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js index e267133cf4f5..eb1032a9c7fd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js @@ -1,20 +1,18 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.Grid.MediaController", function ($scope, $timeout, userService, editorService) { - + + + $scope.thumbnailUrl = getThumbnailUrl(); + + if (!$scope.model.config.startNodeId) { userService.getCurrentUser().then(function (userData) { $scope.model.config.startNodeId = userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0]; $scope.model.config.startNodeIsVirtual = userData.startMediaIds.length !== 1; }); } - - function onInit() { - if($scope.control.value){ - $scope.setUrl(); - } - } - + $scope.setImage = function(){ var startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined; var startNodeIsVirtual = startNodeId ? $scope.model.config.startNodeIsVirtual : undefined; @@ -34,10 +32,8 @@ angular.module("umbraco") id: selectedImage.id, udi: selectedImage.udi, image: selectedImage.image, - altText: selectedImage.altText - }; - - $scope.setUrl(); + caption: selectedImage.altText + }; editorService.close(); }, @@ -48,10 +44,18 @@ angular.module("umbraco") editorService.mediaPicker(mediaPicker); }; + + $scope.$watch('control.value', function(newValue, oldValue) { + if(angular.equals(newValue, oldValue)){ + return; // simply skip that + } + + $scope.thumbnailUrl = getThumbnailUrl(); + }, true); + + function getThumbnailUrl() { - $scope.setUrl = function(){ - - if($scope.control.value.image){ + if($scope.control.value && $scope.control.value.image) { var url = $scope.control.value.image; if($scope.control.editor.config && $scope.control.editor.config.size){ @@ -70,10 +74,10 @@ angular.module("umbraco") { url += "?width=800&upscale=false&animationprocessmode=false" } - $scope.url = url; + return url; } + + return null; }; - onInit(); - }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.html index 7ffb26d83173..184f707ebfb6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.html @@ -5,11 +5,10 @@
Click to insert image
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index c23c2cd212bf..6b267205b4cb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -13,11 +13,16 @@ angular.module("umbraco") // Grid status variables var placeHolder = ""; var currentForm = angularHelper.getCurrentForm($scope); - + + $scope.currentRowWithActiveChild = null; + $scope.currentCellWithActiveChild = null; + $scope.active = null; + $scope.currentRow = null; $scope.currentCell = null; $scope.currentToolsControl = null; $scope.currentControl = null; + $scope.openRTEToolbarId = null; $scope.hasSettings = false; $scope.showRowConfigurations = true; @@ -237,10 +242,13 @@ angular.module("umbraco") }); $scope.$apply(function () { - var cell = event.target.getScope_HackForSortable().area; - cell.hasActiveChild = hasActiveChild(cell, cell.controls); - cell.active = false; + + if(hasActiveChild(cell, cell.controls)) { + $scope.currentCellWithActiveChild = cell; + } + $scope.active = cell; + }); } @@ -309,12 +317,12 @@ angular.module("umbraco") // Row management function // ********************************************* - $scope.clickRow = function (index, rows) { - rows[index].active = true; - }; - - $scope.clickOutsideRow = function (index, rows) { - rows[index].active = false; + $scope.clickRow = function(index, rows, $event) { + + $scope.currentRowWithActiveChild = null; + $scope.active = rows[index]; + + $event.stopPropagation(); }; function getAllowedLayouts(section) { @@ -361,6 +369,7 @@ angular.module("umbraco") if (section.rows.length > 0) { section.rows.splice($index, 1); $scope.currentRow = null; + $scope.currentRowWithActiveChild = null; $scope.openRTEToolbarId = null; currentForm.$setDirty(); } @@ -515,14 +524,13 @@ angular.module("umbraco") // Area management functions // ********************************************* - $scope.clickCell = function (index, cells, row) { - cells[index].active = true; - row.hasActiveChild = true; - }; - - $scope.clickOutsideCell = function (index, cells, row) { - cells[index].active = false; - row.hasActiveChild = hasActiveChild(row, cells); + $scope.clickCell = function(index, cells, row, $event) { + + $scope.currentCellWithActiveChild = null; + + $scope.active = cells[index]; + $scope.currentRowWithActiveChild = row; + $event.stopPropagation(); }; $scope.cellPreview = function (cell) { @@ -538,14 +546,12 @@ angular.module("umbraco") // ********************************************* // Control management functions // ********************************************* - $scope.clickControl = function (index, controls, cell) { - controls[index].active = true; - cell.hasActiveChild = true; - }; - - $scope.clickOutsideControl = function (index, controls, cell) { - controls[index].active = false; - cell.hasActiveChild = hasActiveChild(cell, controls); + $scope.clickControl = function (index, controls, cell, $event) { + + $scope.active = controls[index]; + $scope.currentCellWithActiveChild = cell; + + $event.stopPropagation(); }; function hasActiveChild(item, children) { @@ -596,8 +602,8 @@ angular.module("umbraco") if (index === undefined) { index = cell.controls.length; } - - newControl.active = true; + + $scope.active = newControl; //populate control $scope.initControl(newControl, index + 1); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 068a60462c15..fb7ffaf81aef 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -68,13 +68,13 @@
@@ -88,7 +88,7 @@
-
+
@@ -122,17 +122,17 @@ ng-style="{width: area.$percentage + '%'}" ng-class="{ '-has-config': area.hasConfig, - '-active': area.active, - '-active-child': area.hasActiveChild}" + '-active': area === active, + '-active-child': area === currentCellWithActiveChild}" ng-model="area.controls" - ng-click="clickCell($index, row.areas, row)" - on-outside-click="clickOutsideCell($index, row.areas, row)" - bind-click-on="{{area.active}}"> + ng-click="clickCell($index, row.areas, row, $event)" + + bind-click-on="{{area === active}}">
@@ -152,7 +152,7 @@
-
+
@@ -172,14 +172,14 @@
-
+
{{control.editor.name}} @@ -189,11 +189,11 @@
-
+
{{control.editor.name}}
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index b61452245b7a..3c34890fa95b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -9,9 +9,7 @@ angular.module("umbraco") //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. - var d = new Date(); - var n = d.getTime(); - $scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte"; + $scope.textAreaHtmlId = $scope.model.alias + "_" + String.CreateGuid(); var editorConfig = $scope.model.config ? $scope.model.config.editor : null; if (!editorConfig || angular.isString(editorConfig)) {