diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
index 7cd55b268a..bb1dad1dbd 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
@@ -243,6 +243,77 @@ function codefileResource($q, $http, umbDataFormatter, umbRequestHelper) {
"PostCreateContainer",
{ type: type, parentId: parentId, name: encodeURIComponent(name) })),
'Failed to create a folder under parent id ' + parentId);
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.codefileResource#interpolateStylesheetRules
+ * @methodOf umbraco.resources.codefileResource
+ *
+ * @description
+ * Takes all rich text editor styling rules and turns them into css
+ *
+ * ##usage
+ *
+ * codefileResource.interpolateStylesheetRules(".box{background:purple;}", "[{name: "heading", selector: "h1", styles: "color: red"}]")
+ * .then(function(data) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @param {string} content The style sheet content.
+ * @param {string} rules The rich text editor rules
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ interpolateStylesheetRules: function (content, rules) {
+ var payload = {
+ content: content,
+ rules: rules
+ };
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "codeFileApiBaseUrl",
+ "PostInterpolateStylesheetRules"),
+ payload),
+ "Failed to interpolate sheet rules");
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.codefileResource#extractStylesheetRules
+ * @methodOf umbraco.resources.codefileResource
+ *
+ * @description
+ * Find all rich text editor styles in the style sheets and turns them into "rules"
+ *
+ * ##usage
+ *
+ *
+ * var conntent
+ * codefileResource.extractStylesheetRules(".box{background:purple;}")
+ * .then(function(data) {
+ * alert('its here!');
+ * });
+ *
+ *
+ * @param {string} content The style sheet content.
+ * @returns {Promise} resourcePromise object.
+ *
+ */
+ extractStylesheetRules: function(content) {
+ var payload = {
+ content: content,
+ rules: null
+ };
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "codeFileApiBaseUrl",
+ "PostExtractStylesheetRules"),
+ payload),
+ "Failed to extract style sheet rules");
}
};
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less
index 407cfaf6a7..3b49dceeb2 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less
@@ -43,7 +43,7 @@
font-size: 24px;
display: block;
text-align: center;
- margin-bottom: 5px;
+ margin-bottom: 7px;
}
.umb-sub-views-nav-item-text {
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-stylesheet.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-stylesheet.less
index 31824590e8..59ded555a6 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-stylesheet.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-stylesheet.less
@@ -8,6 +8,7 @@
margin: 10px 0 !important;
background: @gray-10;
cursor: pointer;
+ border-radius: @baseBorderRadius;
}
.umb-stylesheet-rules__listitem i {
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.controller.js b/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.controller.js
index 229587cc63..8695935062 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.controller.js
@@ -7,11 +7,17 @@
var node = $scope.dialogOptions.currentNode;
vm.createFile = createFile;
+ vm.createRichtextStyle = createRichtextStyle;
function createFile() {
$location.path("/settings/stylesheets/edit/" + node.id).search("create", "true");
navigationService.hideMenu();
}
+
+ function createRichtextStyle() {
+ $location.path("/settings/stylesheets/edit/" + node.id).search("create", "true").search("rtestyle", "true");
+ navigationService.hideMenu();
+ }
}
angular.module("umbraco").controller("Umbraco.Editors.StyleSheets.CreateController", StyleSheetsCreateController);
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.html b/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.html
index 82854635f9..c735d2fe3c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.html
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/create.html
@@ -10,6 +10,12 @@
+
+
+
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/stylesheets/edit.controller.js
index 2705294d54..a05836be06 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/edit.controller.js
@@ -12,24 +12,6 @@
vm.page.menu.currentNode = null;
vm.page.saveButtonState = "init";
- localizationService.localizeMany(["stylesheet_tabCode", "stylesheet_tabRules"]).then(function (data) {
- vm.page.navigation = [
- {
- "name": data[0],
- "alias": "code",
- "icon": "icon-brackets",
- "view": "views/stylesheets/views/code/code.html",
- "active": true
- },
- {
- "name": data[1],
- "alias": "rules",
- "icon": "icon-font",
- "view": "views/stylesheets/views/rules/rules.html"
- }
- ];
- });
-
//Used to toggle the keyboard shortcut modal
//From a custom keybinding in ace editor - that conflicts with our own to show the dialog
vm.showKeyboardShortcut = false;
@@ -45,7 +27,10 @@
vm.page.keyboardShortcutsOverview.push(shortcuts);
});
- vm.stylesheet = {};
+ vm.stylesheet = {
+ content: "",
+ rules: []
+ };
// bind functions to view model
vm.save = interpolateAndSave;
@@ -139,16 +124,47 @@
if ($routeParams.create) {
codefileResource.getScaffold("stylesheets", $routeParams.id).then(function (stylesheet) {
+ const mode = $routeParams.rtestyle ? "RTE" : null;
ready(stylesheet, false);
+ generateNavigation(mode);
});
} else {
codefileResource.getByPath('stylesheets', $routeParams.id).then(function (stylesheet) {
ready(stylesheet, true);
+ extractRules().then(rules => {
+ vm.stylesheet.rules = rules;
+ const mode = rules && rules.length > 0 ? "RTE" : null;
+ generateNavigation(mode);
+ });
});
}
}
+ function generateNavigation(mode) {
+ localizationService.localizeMany(["stylesheet_tabRules", "stylesheet_tabCode"]).then(function (data) {
+ vm.page.navigation = [
+ {
+ "name": data[0],
+ "alias": "rules",
+ "icon": "icon-font",
+ "view": "views/stylesheets/views/rules/rules.html"
+ },
+ {
+ "name": data[1],
+ "alias": "code",
+ "icon": "icon-brackets",
+ "view": "views/stylesheets/views/code/code.html"
+ }
+ ];
+ if(mode === "RTE") {
+ vm.page.navigation[0].active = true;
+ } else {
+ vm.page.navigation[1].active = true;
+ }
+ });
+ }
+
function ready(stylesheet, syncTree) {
vm.page.loading = false;
@@ -240,31 +256,11 @@
}
function interpolateRules() {
- var payload = {
- content: vm.stylesheet.content,
- rules: vm.stylesheet.rules
- };
- return umbRequestHelper.resourcePromise(
- $http.post(
- umbRequestHelper.getApiUrl(
- "codeFileApiBaseUrl",
- "PostInterpolateStylesheetRules"),
- payload),
- "Failed to interpolate sheet rules");
+ return codefileResource.interpolateStylesheetRules(vm.stylesheet.content, vm.stylesheet.rules);
}
function extractRules() {
- var payload = {
- content: vm.stylesheet.content,
- rules: null
- };
- return umbRequestHelper.resourcePromise(
- $http.post(
- umbRequestHelper.getApiUrl(
- "codeFileApiBaseUrl",
- "PostExtractStylesheetRules"),
- payload),
- "Failed to extract style sheet rules");
+ return codefileResource.extractStylesheetRules(vm.stylesheet.content);
}
$scope.selectApp = function (app) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.controller.js b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.controller.js
new file mode 100644
index 0000000000..092cdaa55e
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.controller.js
@@ -0,0 +1,27 @@
+(function() {
+ "use strict";
+
+ function RichTextRuleController($scope, formHelper) {
+
+ const vm = this;
+
+ vm.submit = submit;
+ vm.close = close;
+
+ function submit() {
+ if ($scope.model && $scope.model.submit && formHelper.submitForm({scope: $scope})) {
+ $scope.model.submit($scope.model);
+ }
+ }
+
+ function close() {
+ if ($scope.model && $scope.model.close) {
+ $scope.model.close();
+ }
+ }
+
+ }
+
+ angular.module("umbraco").controller("Umbraco.Editors.RichTextRuleController", RichTextRuleController);
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html
new file mode 100644
index 0000000000..a36f3ef6a2
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html
@@ -0,0 +1,72 @@
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.controller.js b/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.controller.js
index 28d1724b64..b3aeedeb6e 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.controller.js
@@ -1,5 +1,5 @@
angular.module("umbraco").controller("Umbraco.Editors.StyleSheets.RulesController",
- function ($scope, localizationService) {
+ function ($scope, localizationService, editorService) {
$scope.sortableOptions = {
axis: 'y',
containment: 'parent',
@@ -16,6 +16,9 @@ angular.module("umbraco").controller("Umbraco.Editors.StyleSheets.RulesControlle
evt.preventDefault();
openOverlay({}, $scope.labels.addRule, (newRule) => {
+ if(!$scope.model.stylesheet.rules) {
+ $scope.model.stylesheet.rules = [];
+ }
$scope.model.stylesheet.rules.push(newRule);
setDirty();
});
@@ -40,17 +43,23 @@ angular.module("umbraco").controller("Umbraco.Editors.StyleSheets.RulesControlle
}
function openOverlay(rule, title, onSubmit) {
- $scope.model.overlay = {
+
+ const ruleDialog = {
title: title,
- submit: function (model) {
+ rule: _.clone(rule),
+ view: "views/stylesheets/infiniteeditors/richtextrule/richtextrule.html",
+ size: "small",
+ submit: function(model) {
onSubmit(model.rule);
- $scope.model.overlay = null;
+ editorService.close();
},
- close: function (oldModel) {
- $scope.model.overlay = null;
- },
- rule: _.clone(rule)
+ close: function() {
+ editorService.close();
+ }
};
+
+ editorService.open(ruleDialog);
+
}
function setDirty() {
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.html b/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.html
index 17b52f064e..018d4d3741 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.html
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/views/rules/rules.html
@@ -18,24 +18,15 @@
-
- Add
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index a7a7c7d8e5..a75fe839ab 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -309,13 +309,14 @@
Document Type without a template
New folder
New data type
- New JavaScript file
+ New JavaScript file
New empty partial view
New partial view macro
New partial view from snippet
New partial view macro from snippet
New partial view macro (without macro)
New style sheet file
+ New Rich Text Editor style sheet file
Browse your website
@@ -1357,7 +1358,9 @@ To manage your website, simply open the Umbraco back office and start adding con
Styles
The CSS that should be applied in the rich text editor, e.g. "color:red;"
Code
- Editor
+ Rich Text Editor
+ Preview
+ How the text will look like in the rich text editor.
Edit template