Initial commit of the grid
This commit is contained in:
@@ -130,6 +130,12 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string FolderBrowserAlias = "Umbraco.FolderBrowser";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the grid datatype.
|
||||
/// </summary>
|
||||
public const string GridAlias = "Umbraco.Grid";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Image Cropper datatype.
|
||||
/// </summary>
|
||||
|
||||
@@ -371,7 +371,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//template.CreateDate = _viewsFileSystem.GetCreated(path).UtcDateTime;
|
||||
//template.Key = new FileInfo(path).Name.EncodeAsGuid();
|
||||
|
||||
template.Path = path;
|
||||
template.Content = content;
|
||||
}
|
||||
|
||||
|
||||
3
src/Umbraco.Web.UI.Client/.bowerrc
Normal file
3
src/Umbraco.Web.UI.Client/.bowerrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory" : "lib"
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"typeahead.js": "~0.10.2"
|
||||
"typeahead.js": "~0.10.2",
|
||||
"codemirror": "~4.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,14 +109,6 @@ module.exports = function (grunt) {
|
||||
clean: ['<%= distdir %>/*'],
|
||||
|
||||
copy: {
|
||||
|
||||
// Copies over the files downloaded by bower
|
||||
bower: {
|
||||
files: [
|
||||
{ dest: '<%= distdir %>/lib/typeahead/typeahead.bundle.min.js', src: '<%= bowerfiles %>/typeahead.js/dist/typeahead.bundle.min.js' }
|
||||
]
|
||||
},
|
||||
|
||||
assets: {
|
||||
files: [{ dest: '<%= distdir %>/assets', src : '**', expand: true, cwd: 'src/assets/' }]
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
// Inline and block code styles
|
||||
code,
|
||||
pre {
|
||||
pre.code {
|
||||
padding: 0 3px 2px;
|
||||
#font > #family > .monospace;
|
||||
font-size: @baseFontSize - 2;
|
||||
@@ -23,7 +23,7 @@ code {
|
||||
}
|
||||
|
||||
// Blocks of code
|
||||
pre {
|
||||
pre.code {
|
||||
display: block;
|
||||
padding: (@baseLineHeight - 1) / 2;
|
||||
margin: 0 0 @baseLineHeight / 2;
|
||||
|
||||
5495
src/Umbraco.Web.UI.Client/lib/cssparser/cssparser.js
Normal file
5495
src/Umbraco.Web.UI.Client/lib/cssparser/cssparser.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,240 @@
|
||||
angular.module("umbraco")
|
||||
.directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout) {
|
||||
return {
|
||||
scope: {
|
||||
uniqueId: '=',
|
||||
value: '=',
|
||||
ctrlOp: '&',
|
||||
ctrlCl: '&'
|
||||
},
|
||||
template: "<textarea ng-model=\"value\" rows=\"10\" class=\"mceNoEditor\" id=\"{{uniqueId}}\"></textarea>",
|
||||
replace: true,
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
var initTiny = function () {
|
||||
|
||||
tinyMceService.configuration().then(function (tinyMceConfig) {
|
||||
|
||||
//config value from general tinymce.config file
|
||||
var validElements = tinyMceConfig.validElements;
|
||||
var fallbackStyles = [{title: "Page header", block: "h2"}, {title: "Section header", block: "h3"}, {title: "Paragraph header", block: "h4"}, {title: "Normal", block: "p"}, {title: "Quote", block: "blockquote"}, {title: "Code", block: "code"}];
|
||||
//These are absolutely required in order for the macros to render inline
|
||||
//we put these as extended elements because they get merged on top of the normal allowed elements by tiny mce
|
||||
var extendedValidElements = "@[id|class|style],-div[id|dir|class|align|style],ins[datetime|cite],-ul[class|style],-li[class|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align]";
|
||||
|
||||
var invalidElements = tinyMceConfig.inValidElements;
|
||||
var plugins = _.map(tinyMceConfig.plugins, function (plugin) {
|
||||
if (plugin.useOnFrontend) {
|
||||
return plugin.name;
|
||||
}
|
||||
}).join(" ") + " autoresize";
|
||||
|
||||
//config value on the data type
|
||||
var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"].join(" | ");
|
||||
var stylesheets = [];
|
||||
var styleFormats = [];
|
||||
var await = [];
|
||||
|
||||
//queue file loading
|
||||
if (typeof (tinymce) === "undefined") {
|
||||
await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope));
|
||||
}
|
||||
|
||||
//queue rules loading
|
||||
stylesheets.push("/views/propertyeditors/grid/config/grid.default.rtestyles.css?" + new Date().getTime());
|
||||
angular.forEach(["umbraco.grid.rte"], function (val, key) {
|
||||
stylesheets.push("/css/" + val + ".css?" + new Date().getTime());
|
||||
|
||||
await.push(stylesheetResource.getRulesByName(val).then(function (rules) {
|
||||
|
||||
if(rules.length > 0){
|
||||
angular.forEach(rules, function (rule) {
|
||||
var r = {};
|
||||
r.title = rule.name;
|
||||
if (rule.selector[0] === ".") {
|
||||
r.inline = "span";
|
||||
r.classes = rule.selector.substring(1);
|
||||
}
|
||||
else if (rule.selector[0] === "#") {
|
||||
r.inline = "span";
|
||||
r.attributes = { id: rule.selector.substring(1) };
|
||||
}
|
||||
else {
|
||||
r.block = rule.selector;
|
||||
}
|
||||
|
||||
styleFormats.push(r);
|
||||
});
|
||||
}else{
|
||||
styleFormats = fallbackStyles;
|
||||
}
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
//stores a reference to the editor
|
||||
var tinyMceEditor = null;
|
||||
|
||||
$q.all(await).then(function () {
|
||||
|
||||
var uniqueId = scope.uniqueId;
|
||||
|
||||
//create a baseline Config to exten upon
|
||||
var baseLineConfigObj = {
|
||||
mode: "exact",
|
||||
skin: "umbraco",
|
||||
plugins: plugins,
|
||||
valid_elements: validElements,
|
||||
invalid_elements: invalidElements,
|
||||
extended_valid_elements: extendedValidElements,
|
||||
menubar: false,
|
||||
statusbar: false,
|
||||
relative_urls: false,
|
||||
autoresize_min_height: 30,
|
||||
toolbar: toolbar,
|
||||
content_css: stylesheets.join(','),
|
||||
style_formats: styleFormats
|
||||
};
|
||||
|
||||
|
||||
if (tinyMceConfig.customConfig) {
|
||||
angular.extend(baseLineConfigObj, tinyMceConfig.customConfig);
|
||||
}
|
||||
|
||||
//set all the things that user configs should not be able to override
|
||||
baseLineConfigObj.elements = uniqueId;
|
||||
baseLineConfigObj.setup = function (editor) {
|
||||
|
||||
//set the reference
|
||||
tinyMceEditor = editor;
|
||||
|
||||
//enable browser based spell checking
|
||||
editor.on('init', function (e) {
|
||||
editor.getBody().setAttribute('spellcheck', true);
|
||||
var toolbarHeight = -$(editor.editorContainer).find(".mce-toolbar").height() - 2;
|
||||
$(editor.editorContainer).find(".mce-toolbar").css("margin-top", toolbarHeight + "px");
|
||||
});
|
||||
|
||||
//when we leave the editor (maybe)
|
||||
editor.on('blur', function (e) {
|
||||
editor.save();
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.value = editor.getContent();
|
||||
scope.ctrlCl();
|
||||
});
|
||||
});
|
||||
|
||||
// Focus on editor
|
||||
editor.on('focus', function (e) {
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.ctrlOp();
|
||||
var toolbarHeight = -$(editor.editorContainer).find(".mce-toolbar").height() - 2;
|
||||
$(editor.editorContainer).find(".mce-toolbar").css("margin-top", toolbarHeight + "px");
|
||||
});
|
||||
});
|
||||
|
||||
// Click on editor
|
||||
editor.on('click', function (e) {
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.ctrlOp();
|
||||
var toolbarHeight = -$(editor.editorContainer).find(".mce-toolbar").height() - 2;
|
||||
$(editor.editorContainer).find(".mce-toolbar").css("margin-top", toolbarHeight + "px");
|
||||
});
|
||||
});
|
||||
|
||||
//when buttons modify content
|
||||
editor.on('ExecCommand', function (e) {
|
||||
editor.save();
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.value = editor.getContent();
|
||||
});
|
||||
});
|
||||
|
||||
// Update model on keypress
|
||||
editor.on('KeyUp', function (e) {
|
||||
editor.save();
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.value = editor.getContent();
|
||||
});
|
||||
});
|
||||
|
||||
// Update model on change, i.e. copy/pasted text, plugins altering content
|
||||
editor.on('SetContent', function (e) {
|
||||
if (!e.initial) {
|
||||
editor.save();
|
||||
angularHelper.safeApply(scope, function () {
|
||||
scope.value = editor.getContent();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
editor.on('ObjectResized', function (e) {
|
||||
var qs = "?width=" + e.width + "px&height=" + e.height + "px";
|
||||
var srcAttr = $(e.target).attr("src");
|
||||
var path = srcAttr.split("?")[0];
|
||||
$(e.target).attr("data-mce-src", path + qs);
|
||||
});
|
||||
|
||||
|
||||
//Create the insert media plugin
|
||||
tinyMceService.createMediaPicker(editor, scope);
|
||||
|
||||
//Create the embedded plugin
|
||||
tinyMceService.createInsertEmbeddedMedia(editor, scope);
|
||||
|
||||
//Create the insert link plugin
|
||||
tinyMceService.createLinkPicker(editor, scope);
|
||||
|
||||
//Create the insert macro plugin
|
||||
tinyMceService.createInsertMacro(editor, scope);
|
||||
|
||||
};
|
||||
|
||||
/** Loads in the editor */
|
||||
function loadTinyMce() {
|
||||
|
||||
//we need to add a timeout here, to force a redraw so TinyMCE can find
|
||||
//the elements needed
|
||||
$timeout(function () {
|
||||
tinymce.DOM.events.domLoaded = true;
|
||||
tinymce.init(baseLineConfigObj);
|
||||
}, 150, false);
|
||||
}
|
||||
|
||||
loadTinyMce();
|
||||
|
||||
//here we declare a special method which will be called whenever the value has changed from the server
|
||||
//this is instead of doing a watch on the model.value = faster
|
||||
//scope.model.onValueChanged = function (newVal, oldVal) {
|
||||
// //update the display val again if it has changed from the server;
|
||||
// tinyMceEditor.setContent(newVal, { format: 'raw' });
|
||||
// //we need to manually fire this event since it is only ever fired based on loading from the DOM, this
|
||||
// // is required for our plugins listening to this event to execute
|
||||
// tinyMceEditor.fire('LoadContent', null);
|
||||
//};
|
||||
|
||||
//listen for formSubmitting event (the result is callback used to remove the event subscription)
|
||||
var unsubscribe = scope.$on("formSubmitting", function () {
|
||||
//TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer
|
||||
// we do parse it out on the server side but would be nice to do that on the client side before as well.
|
||||
scope.value = tinyMceEditor.getContent();
|
||||
});
|
||||
|
||||
//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 () {
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
initTiny();
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.stylesheetResource
|
||||
* @description service to retrieve available stylesheets
|
||||
*
|
||||
*
|
||||
**/
|
||||
function templateResource($q, $http, umbRequestHelper) {
|
||||
|
||||
//the factory object returned
|
||||
return {
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.stylesheetResource#getAll
|
||||
* @methodOf umbraco.resources.stylesheetResource
|
||||
*
|
||||
* @description
|
||||
* Gets all registered stylesheets
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* stylesheetResource.getAll()
|
||||
* .then(function(stylesheets) {
|
||||
* alert('its here!');
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @returns {Promise} resourcePromise object containing the stylesheets.
|
||||
*
|
||||
*/
|
||||
getAll: function () {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"templateApiBaseUrl",
|
||||
"GetAll")),
|
||||
'Failed to retrieve stylesheets ');
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.stylesheetResource#getRulesByName
|
||||
* @methodOf umbraco.resources.stylesheetResource
|
||||
*
|
||||
* @description
|
||||
* Returns all defined child rules for a stylesheet with a given name
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* stylesheetResource.getRulesByName("ie7stylesheet")
|
||||
* .then(function(rules) {
|
||||
* alert('its here!');
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @returns {Promise} resourcePromise object containing the rules.
|
||||
*
|
||||
*/
|
||||
getById: function (id) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"templateApiBaseUrl",
|
||||
"GetById",
|
||||
[{ id: id }])),
|
||||
'Failed to retreive template ');
|
||||
},
|
||||
|
||||
saveAndRender: function(html, templateId, pageId){
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"templateApiBaseUrl",
|
||||
"PostSaveAndRender"),
|
||||
{templateId: templateId, pageId: pageId, html: html }),
|
||||
'Failed to retreive template ');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.resources').factory('templateResource', templateResource);
|
||||
@@ -1,56 +1,591 @@
|
||||
// Gridview
|
||||
// -------------------------
|
||||
|
||||
.editor {
|
||||
border: 1px solid #cdcdcd;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
position: relative;
|
||||
-webkit-transition: all 500ms ease-in-out;
|
||||
-moz-transition: all 500ms ease-in-out;
|
||||
-ms-transition: all 500ms ease-in-out;
|
||||
-o-transition: all 500ms ease-in-out;
|
||||
transition: all 500ms ease-in-out;
|
||||
margin: 0 0 1.5% 0
|
||||
.usky-grid {
|
||||
|
||||
}
|
||||
|
||||
.usky-grid .ui-sortable-helper {
|
||||
border: dashed 1px #000;
|
||||
background: #ccc;
|
||||
opacity: 0.4;
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
.usky-grid .ui-sortable-helper *{
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.usky-grid .ui-sortable-helper .cell-tools{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.usky-grid .ui-sortable-placeholder{
|
||||
border-bottom: 2px solid #000;
|
||||
}
|
||||
|
||||
.usky-grid-width {
|
||||
margin: 0 auto;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.usky-grid .right {
|
||||
float:right;
|
||||
}
|
||||
|
||||
.usky-grid .tb {
|
||||
display:table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.usky-grid .td {
|
||||
display:table-cell;
|
||||
vertical-align:top;
|
||||
border-right:1px dashed rgba(182, 182, 182, 0.0);
|
||||
}
|
||||
|
||||
.usky-grid .tb:hover .td{
|
||||
border-right:1px dashed rgba(182, 182, 182, 0.3);
|
||||
}
|
||||
|
||||
.usky-grid .td.last {
|
||||
border-right:1px dashed rgba(182, 182, 182, 0.0) !important;
|
||||
}
|
||||
|
||||
.usky-grid .tr {
|
||||
display:table-row;
|
||||
}
|
||||
|
||||
.usky-grid .td2{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.usky-grid .td3{
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.usky-grid .td4{
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.usky-grid .td5{
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.usky-grid .td6{
|
||||
width: 16.6%;
|
||||
}
|
||||
|
||||
.usky-grid .middle {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.usky-grid .mainTb {
|
||||
border-collapse: separate;
|
||||
margin-bottom: -1px;
|
||||
cursor:move;
|
||||
}
|
||||
|
||||
.usky-grid .mainTd {
|
||||
margin:0px;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.usky-grid .backColor {
|
||||
|
||||
}
|
||||
|
||||
.usky-grid .usky-row{margin-bottom: 10px;}
|
||||
|
||||
.usky-grid textarea{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.usky-grid .cellPanel {
|
||||
min-height: 100px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
text-align: -moz-center;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.usky-grid .cellPanel .placeholder{
|
||||
font-size: 14px; opacity: 0.7; text-align: left;
|
||||
padding: 10px;
|
||||
border:1px solid rgba(182, 182, 182, 0.3);
|
||||
}
|
||||
|
||||
.usky-grid .cellPanel:hover .placeholder{
|
||||
border:1px solid rgba(182, 182, 182, 0.8);
|
||||
}
|
||||
|
||||
.usky-grid .cellMacro {
|
||||
min-height: 65px;
|
||||
padding-top: 45px;
|
||||
position: relative;
|
||||
background-color: rgba(100, 100, 100, 0.35);
|
||||
text-align: center;
|
||||
text-align: -moz-center;
|
||||
}
|
||||
|
||||
.usky-grid .cellMacro .tools{
|
||||
margin: auto;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .controlContainer {
|
||||
transition: all .20s ease-in-out;
|
||||
-moz-transition: all .20s ease-in-out;
|
||||
-webkit-transition: all .20s ease-in-out;
|
||||
position:relative;
|
||||
display:block;
|
||||
|
||||
padding: 20px;
|
||||
margin-top: 10px;
|
||||
border-bottom: 2px solid rgba(255, 0, 0, .0);
|
||||
-webkit-background-clip: padding-box; /* for Safari */
|
||||
background-clip: padding-box; /* for IE9+, Firefox 4+, Opera, Chrome */
|
||||
}
|
||||
|
||||
.usky-grid .controlContainer:hover{
|
||||
border-bottom:2px solid rgba(182, 182, 182, 0.3);
|
||||
}
|
||||
|
||||
.usky-grid .selectedControl {
|
||||
|
||||
}
|
||||
|
||||
.usky-grid .cellPanelRte {
|
||||
min-height:60px;
|
||||
}
|
||||
|
||||
.usky-grid .cellPanelMacro {
|
||||
padding: 90px 0 0 0;
|
||||
height:96px;
|
||||
background-color: rgba(233, 233, 233, 0.35);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.usky-grid .iconBoxBig {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.usky-grid .iconBoxBig i {
|
||||
font-size:24px !important;
|
||||
color: #5F5F5F;
|
||||
}
|
||||
|
||||
.usky-grid .iconBoxBig i:hover {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.usky-grid .iconBox {
|
||||
padding: 2px 5px 2px 5px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border-radius: 200px;
|
||||
background: rgba(255,255,255, 1);
|
||||
border:1px solid rgb(182, 182, 182);
|
||||
}
|
||||
|
||||
.usky-grid .iconBox a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.usky-grid .iconBox.selected {
|
||||
-webkit-appearance: none;
|
||||
background-image: -moz-linear-gradient(top,#e6e6e6,#bfbfbf);
|
||||
background-image: -webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));
|
||||
background-image: -webkit-linear-gradient(top,#e6e6e6,#bfbfbf);
|
||||
background-image: -o-linear-gradient(top,#e6e6e6,#bfbfbf);
|
||||
background-image: linear-gradient(to bottom,#e6e6e6,#bfbfbf);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);
|
||||
zoom: 1;
|
||||
border-color: #bfbfbf #bfbfbf #999;
|
||||
border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);
|
||||
-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
||||
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
||||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.usky-grid .iconBox i {
|
||||
font-size:14px !important;
|
||||
color: #5F5F5F;
|
||||
}
|
||||
|
||||
.usky-grid .iconBox i:hover {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Row tools */
|
||||
|
||||
.usky-grid .row-tools {
|
||||
width: 30px;
|
||||
position: absolute;
|
||||
border: 1px solid rgba(207, 207, 207, 0.7);
|
||||
margin: 0px 0 0 -35px;
|
||||
padding: 2px;
|
||||
z-index: 100;
|
||||
background-color: rgba(250, 250, 250, 1);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editor:hover {
|
||||
border-color: #000
|
||||
}
|
||||
.usky-grid .row-tools.selected {
|
||||
width: 65px;
|
||||
margin: 0px 0 0 -35px;
|
||||
z-index: 200;
|
||||
z-index: 99999999;
|
||||
-webkit-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
|
||||
-moz-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
|
||||
box-shadow: 2px 2px 10px 0px rgba(500, 50, 50, 0.14);
|
||||
}
|
||||
|
||||
.editor:hover i {
|
||||
opacity: 1
|
||||
}
|
||||
.usky-grid .cell-tools {
|
||||
transition: all .20s ease-in-out;
|
||||
-moz-transition: all .20s ease-in-out;
|
||||
-webkit-transition: all .20s ease-in-out;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.editor i {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
font-size: 20px;
|
||||
color: @white;
|
||||
background: @black;
|
||||
padding: 10px;
|
||||
-webkit-transition: all 500ms ease-in-out;
|
||||
-moz-transition: all 500ms ease-in-out;
|
||||
-ms-transition: all 500ms ease-in-out;
|
||||
-o-transition: all 500ms ease-in-out;
|
||||
transition: all 500ms ease-in-out;
|
||||
opacity: 0
|
||||
}
|
||||
.usky-grid .cell-tools-add {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom: -14px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
.editor i:hover {
|
||||
}
|
||||
.usky-grid .cell-tools-remove {
|
||||
display:inline-block;
|
||||
position: absolute;
|
||||
top: -13px;
|
||||
right: -13px;
|
||||
text-align: right;
|
||||
z-index: 500;
|
||||
}
|
||||
.usky-grid .cell-tools-remove:hover i:before{color: red; font-weight: normal }
|
||||
|
||||
.editor i.icon-move {
|
||||
left: 0;
|
||||
cursor: move
|
||||
}
|
||||
.usky-grid .div-macro {
|
||||
display: inline-table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.editor i.icon-edit {
|
||||
right: 36px;
|
||||
cursor: pointer
|
||||
}
|
||||
.usky-grid .div-media {
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.editor i.icon-trash {
|
||||
right: 0;
|
||||
cursor: pointer
|
||||
}
|
||||
.usky-grid .div-macro .td {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.usky-grid .iconoff {
|
||||
color:rgb(186, 186, 192)
|
||||
}
|
||||
|
||||
.usky-grid ul {
|
||||
display:inline-block;
|
||||
list-style:none;
|
||||
padding:0;
|
||||
margin: 10px 0 0 0;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.usky-grid ul li {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
margin: 8px 8px 0px 8px;
|
||||
}
|
||||
|
||||
.usky-grid .mainTbpt:hover {
|
||||
border:2px solid #53a93f;
|
||||
}
|
||||
|
||||
.usky-grid .mainTbpt {
|
||||
cursor:pointer;
|
||||
border-spacing: 5px;
|
||||
border-collapse: separate;
|
||||
height: 35px;
|
||||
border: 2px solid rgb(219, 219, 219);
|
||||
margin:0px;
|
||||
background-color: rgba(228, 228, 228, 0.41);
|
||||
}
|
||||
|
||||
.usky-grid .icon-color {
|
||||
color: rgb(109, 109, 109);
|
||||
}
|
||||
|
||||
.usky-grid .mainTdpt {
|
||||
height: 35px;
|
||||
border: 1px dashed rgba(102, 102, 102, 0.3);
|
||||
margin:0px;
|
||||
background-color: rgba(228, 228, 228, 0.41);
|
||||
}
|
||||
|
||||
.usky-grid .hideRTEToolbar .mce-toolbar {
|
||||
/*display:none !important;*/
|
||||
visibility:hidden !important;
|
||||
}
|
||||
|
||||
.usky-grid .mce-panel {
|
||||
border:none !important;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.usky-grid .mce-btn button {
|
||||
padding: 8px 6px;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.usky-grid .mce-toolbar {
|
||||
border: 1px solid rgba(207, 207, 207, 0.7);
|
||||
background-color: rgba(250, 250, 250, 1);
|
||||
z-index: 100;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
padding: -1px;
|
||||
position: absolute;
|
||||
margin: -1px -1px 0 -1px;
|
||||
-webkit-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
|
||||
-moz-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
|
||||
box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
|
||||
z-index: 9999999;
|
||||
}
|
||||
|
||||
|
||||
.mce-flow-layout-item {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.usky-grid .mce-panel {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.usky-grid .mce-floatpanel {
|
||||
background-color: #F7F7F7 !important;
|
||||
}
|
||||
|
||||
.usky-grid .fullSizeImage {
|
||||
width:100%
|
||||
}
|
||||
|
||||
.usky-grid .usky-column {
|
||||
padding:20px 20px 20px 20px;
|
||||
margin-left:-1px;
|
||||
}
|
||||
|
||||
.usky-grid .usky-column.last {
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* Width */
|
||||
/**************************************************************************************************/
|
||||
|
||||
.usky-grid .boxWidth {
|
||||
text-align:right;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.usky-grid .boxWidth input {
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.usky-grid .boxWidth label {
|
||||
font-size: 10px;
|
||||
padding: 0;
|
||||
margin: 5px 5px 0 0;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* Margin control */
|
||||
/**************************************************************************************************/
|
||||
|
||||
/* Margin default */
|
||||
.usky-grid .mainContainer {
|
||||
/*overflow:hidden;*/
|
||||
|
||||
/*
|
||||
padding-left:10px;
|
||||
padding-right:10px;
|
||||
padding-top:10px;
|
||||
padding-bottom:10px;
|
||||
*/
|
||||
/*background-color:#fff;*/
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd > div.controlContainer,
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd > div.cellPanel {
|
||||
/*overflow:hidden;*/
|
||||
margin-top:20px;
|
||||
margin-bottom:10px;
|
||||
margin-left:10px;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd > div.controlContainer.first,
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd > div.cellPanel {
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd.first > div.controlContainer,
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd.first > div.cellPanel {
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd.last > div.controlContainer,
|
||||
.usky-grid .mainContainer > .mainTb > .tb > .tr > .mainTd.last > div.cellPanel {
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
/* Control margin less */
|
||||
|
||||
.usky-grid .mainContainer.marginControlLess {
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginControlLess > .mainTb > .tb > .tr > .mainTd > div.controlContainer {
|
||||
margin:-1px -1px 0 -1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginControlLess > .mainTb > .tb > .tr > .mainTd > div.cellPanel {
|
||||
margin:-1px -1px 0 -1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginControlLess > .mainTb > .tb > .tr > .mainTd > div > .aA4 {
|
||||
margin: 8px 61px 0 0px;
|
||||
}
|
||||
|
||||
/* Margin less */
|
||||
|
||||
.usky-grid .mainContainer.marginLeftLess {
|
||||
padding-left:0px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginLeftLess > .mainTb > .tb > .tr > .mainTd.first > div {
|
||||
margin-left:-1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginRightLess {
|
||||
padding-right:0px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginRightLess > .mainTb > .tb > .tr > .mainTd.last > div,
|
||||
.usky-grid .mainContainer.marginRightLess > .mainTb > .tb > .tr > .mainTd.last > div.first,
|
||||
.usky-grid .mainContainer.marginRightLess > .mainTb > .tb > .tr > .mainTd.last > div.last,
|
||||
.usky-grid .mainContainer.marginRightLess > .mainTb > .tb > .tr > .mainTd.last > div.cellPanel {
|
||||
margin-right:-1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginRightLess > .mainTb > .tb > .tr > .mainTd.last > div > .cell-tools {
|
||||
margin: -1px -1px 0 0;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginTopLess {
|
||||
padding-top:0px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginTopLess > .mainTb > .tb > .tr > .mainTd > div.controlContainer.first,
|
||||
.usky-grid .mainContainer.marginTopLess > .mainTb > .tb > .tr > .mainTd > div.cellPanel {
|
||||
margin-top:-1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginBottomLess {
|
||||
padding-bottom:0px;
|
||||
}
|
||||
|
||||
.usky-grid .mainContainer.marginBottomLess > .mainTb > .tb > .tr > .mainTd > div.controlContainer.last,
|
||||
.usky-grid .mainContainer.marginBottomLess > .mainTb > .tb > .tr > .mainTd > div.cellPanel {
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* template */
|
||||
/**************************************************************************************************/
|
||||
|
||||
.usky-grid .uSky-templates {
|
||||
text-align:center;
|
||||
overflow:hidden;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template {
|
||||
display:inline-block;
|
||||
margin:20px;
|
||||
width:100px;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tb:hover {
|
||||
border:5px solid #53a93f;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tb {
|
||||
width:100%;
|
||||
height:150px;
|
||||
padding:10px;
|
||||
background-color:rgba(228, 228, 228, 0.41);
|
||||
border: 5px solid rgb(219, 219, 219);
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tb .uSky-templates-column {
|
||||
height:100%;
|
||||
border-top: 2px dashed rgba(102, 102, 102, 0.3);
|
||||
border-bottom: 2px dashed rgba(102, 102, 102, 0.3);
|
||||
border-left: 2px dashed rgba(102, 102, 102, 0.3);
|
||||
margin: 0px 10px 0 10px;
|
||||
background-color: rgba(228, 228, 228, 0.41)
|
||||
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tb .uSky-templates-column.last {
|
||||
border: 2px dashed rgba(102, 102, 102, 0.3);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* jumbotron */
|
||||
/**************************************************************************************************/
|
||||
|
||||
.usky-grid .jumbotron {
|
||||
border: 7px solid rgb(235, 235, 235);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* Color picker dialog for grid */
|
||||
/**************************************************************************************************/
|
||||
|
||||
.CssClassPickerBox{
|
||||
border: 2px solid #F3F2F2;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.CssClassPickerBox:hover, .CssClassPickerBox.select {
|
||||
border: 2px solid #0F9746;
|
||||
}
|
||||
|
||||
.CssClassPickerBox div{
|
||||
height: 80px;
|
||||
width: 196px;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
/*wft ms?*/
|
||||
*{ -ms-touch-action: none;}
|
||||
|
||||
.ace_editor { height: 200px; }
|
||||
|
||||
.nounderline {text-decoration: none !important}
|
||||
.nounderline:hover {text-decoration: underline !important}
|
||||
.nounderline * {text-decoration: none !important; border: none}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Dialogs.ApprovedColorPickerController", function ($scope, $http, umbPropEditorHelper, assetsService) {
|
||||
assetsService.loadJs("lib/cssparser/cssparser.js")
|
||||
.then(function () {
|
||||
|
||||
var cssPath = $scope.dialogData.cssPath;
|
||||
$scope.cssClass = $scope.dialogData.cssClass;
|
||||
|
||||
$scope.classes = [];
|
||||
|
||||
$scope.change = function (newClass) {
|
||||
$scope.model.value = newClass;
|
||||
}
|
||||
|
||||
$http.get(cssPath)
|
||||
.success(function (data) {
|
||||
var parser = new CSSParser();
|
||||
$scope.classes = parser.parse(data, false, false).cssRules;
|
||||
$scope.classes.splice(0, 0, "noclass");
|
||||
})
|
||||
|
||||
assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/uSky.Grid.ApprovedColorPicker.css");
|
||||
assetsService.loadCss(cssPath);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
<div ng-controller="Umbraco.Dialogs.ApprovedColorController">
|
||||
<div class='CssClassPickerBox {{(class.mSelectorText.substring(1) == cssClass)? "select" : "" }}'
|
||||
ng-click="submit(class.mSelectorText.substring(1))" ng-repeat='class in classes'>
|
||||
<div class='{{class.mSelectorText.substring(1)}}'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
.background-content-approved-color-1 { background-color: rgba(52, 52, 52, 1); }
|
||||
.background-content-approved-color-2 { background-color: rgba(52, 52, 52, 0.4); }
|
||||
.background-content-approved-color-3 { background-color: rgba(227, 227, 227, 1); }
|
||||
.background-content-approved-color-4 { background-color: rgba(248, 248, 248, 1); }
|
||||
.background-content-approved-color-5 { background-color: rgba(230, 126, 34, 1); }
|
||||
.background-content-approved-color-6 { background-color: rgba(158, 22, 23, 1); }
|
||||
.background-content-approved-color-7 { background-color: rgba(138, 198, 10, 1); }
|
||||
.background-content-approved-color-8 { background-color: rgba(24, 94, 101, 1); }
|
||||
@@ -0,0 +1,322 @@
|
||||
var uSkyGridConfig =
|
||||
[
|
||||
{
|
||||
columns: [
|
||||
{
|
||||
grid: 12,
|
||||
percentage: 100,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}, {
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, ]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}, {
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
columns: [
|
||||
{
|
||||
grid: 9,
|
||||
percentage: 70,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}, {
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, ]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}, {
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
grid: 3,
|
||||
percentage: 30,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
columns: [
|
||||
{
|
||||
grid: 3,
|
||||
percentage: 30,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
grid: 9,
|
||||
percentage: 70,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}, {
|
||||
grid: 6,
|
||||
percentage: 50
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 33.3
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, {
|
||||
grid: 3,
|
||||
percentage: 25
|
||||
}, ]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}, {
|
||||
grid: 2,
|
||||
percentage: 16.6
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}, {
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}]
|
||||
}, {
|
||||
models: [{
|
||||
grid: 4,
|
||||
percentage: 40
|
||||
}, {
|
||||
grid: 8,
|
||||
percentage: 60
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
columns: [
|
||||
{
|
||||
grid: 4,
|
||||
percentage: 33.3,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
grid: 4,
|
||||
percentage: 33.3,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
grid: 4,
|
||||
percentage: 33.3,
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,15 @@
|
||||
body.mce-content-body {
|
||||
background: transparent !important;
|
||||
overflow-x:hidden !important;
|
||||
padding-bottom: 10px !important;
|
||||
/*margin:0px;*/
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
border-radius:4px;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
|
||||
body{
|
||||
background: white;
|
||||
}
|
||||
|
||||
.editor{padding: 20px; margin: 20px; border: 3px dashed black; }
|
||||
.editor:hover{border-color: red;}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -1,52 +1,421 @@
|
||||
'use strict';
|
||||
//this controller simply tells the dialogs service to open a mediaPicker window
|
||||
//with a specified callback, this callback will receive an object with a selection on it
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridController",
|
||||
function($rootScope, $scope, dialogService, $log){
|
||||
//we most likely will need some iframe-motherpage interop here
|
||||
|
||||
//we most likely will need some iframe-motherpage interop here
|
||||
$scope.openMediaPicker =function(){
|
||||
var d = dialogService.mediaPicker({scope: $scope, callback: renderImages});
|
||||
};
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridController",
|
||||
function ($scope, $http, assetsService, $rootScope, dialogService, mediaResource, imageHelper, $timeout) {
|
||||
|
||||
$scope.openPropertyDialog =function(){
|
||||
var d = dialogService.property({scope: $scope, callback: renderProperty});
|
||||
};
|
||||
var gridConfigPath = $scope.model.config.items.gridConfigPath;
|
||||
|
||||
$scope.openMacroDialog =function(){
|
||||
var d = dialogService.macroPicker({scope: $scope, callback: renderMacro});
|
||||
};
|
||||
if(!gridConfigPath){
|
||||
gridConfigPath = "views/propertyeditors/grid/grid.default.config.js";
|
||||
}
|
||||
|
||||
function renderProperty(data){
|
||||
$scope.currentElement.html("<h1>boom, property!</h1>");
|
||||
}
|
||||
assetsService.loadJs(gridConfigPath).then(function(){
|
||||
|
||||
function renderMacro(data){
|
||||
// $scope.currentElement.html( macroFactory.renderMacro(data.macro, -1) );
|
||||
}
|
||||
|
||||
function renderImages(data){
|
||||
var list = $("<ul class='thumbnails'></ul>")
|
||||
$.each(data.selection, function(i, image) {
|
||||
list.append( $("<li class='span2'><img class='thumbnail' src='" + image.src + "'></li>") );
|
||||
});
|
||||
// Grid config
|
||||
$scope.uSkyGridConfig = uSkyGridConfig;
|
||||
|
||||
$scope.currentElement.html( list[0].outerHTML);
|
||||
}
|
||||
// Grid status variables
|
||||
$scope.currentRow = null;
|
||||
$scope.currentCell = null;
|
||||
$scope.currentToolsControl = null;
|
||||
$scope.currentControl = null;
|
||||
$scope.openRTEToolbarId = null;
|
||||
|
||||
$(window).bind("umbraco.grid.click", function(event){
|
||||
// *********************************************
|
||||
// Sortable options
|
||||
// *********************************************
|
||||
|
||||
$scope.$apply(function () {
|
||||
$scope.currentEditor = event.editor;
|
||||
$scope.currentElement = $(event.element);
|
||||
$scope.sortableOptions = {
|
||||
distance: 10,
|
||||
cursor: "move",
|
||||
placeholder: 'ui-sortable-placeholder',
|
||||
start: function (e, ui) {
|
||||
ui.item.find('.mceNoEditor').each(function () {
|
||||
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
|
||||
|
||||
if(event.editor == "macro")
|
||||
$scope.openMacroDialog();
|
||||
else if(event.editor == "image")
|
||||
$scope.openMediaPicker();
|
||||
else
|
||||
$scope.propertyDialog();
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
},
|
||||
stop: function (e, ui) {
|
||||
ui.item.find('.mceNoEditor').each(function () {
|
||||
tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id'));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// *********************************************
|
||||
// Template management functions
|
||||
// *********************************************
|
||||
|
||||
$scope.checkContent = function() {
|
||||
|
||||
var isEmpty = true;
|
||||
if ($scope.model.value &&
|
||||
$scope.model.value.columns) {
|
||||
angular.forEach($scope.model.value.columns, function (value, key) {
|
||||
if ( value.rows && value.rows.length > 0) {
|
||||
isEmpty = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isEmpty)
|
||||
{
|
||||
$scope.model.value = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$scope.addTemplate = function (template) {
|
||||
|
||||
$scope.model.value = {
|
||||
gridWidth: "",
|
||||
columns: []
|
||||
}
|
||||
|
||||
angular.forEach(template.columns, function (value, key) {
|
||||
$scope.model.value.columns.splice($scope.model.value.columns.length + 1, 0, {
|
||||
id: value.name,
|
||||
grid: value.grid,
|
||||
percentage: value.percentage,
|
||||
cellModels: value.cellModels,
|
||||
rows: []
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// *********************************************
|
||||
// RTE toolbar management functions
|
||||
// *********************************************
|
||||
|
||||
$scope.openRTEToolbar = function (control) {
|
||||
$scope.openRTEToolbarId = control.tinyMCE.uniqueId;
|
||||
}
|
||||
|
||||
$scope.closeRTEToolbar = function (control) {
|
||||
$scope.openRTEToolbarId = null;
|
||||
}
|
||||
|
||||
$scope.isOpenRTEToolbar = function (control) {
|
||||
if (control != undefined && control.tinyMCE != undefined) {
|
||||
if ($scope.openRTEToolbarId == control.tinyMCE.uniqueId) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************
|
||||
// Row management function
|
||||
// *********************************************
|
||||
|
||||
$scope.setCurrentRow = function (row) {
|
||||
$scope.currentRow = row;
|
||||
}
|
||||
|
||||
$scope.disableCurrentRow = function () {
|
||||
$scope.currentRow = null;
|
||||
}
|
||||
|
||||
$scope.setBackGroundRow = function (row) {
|
||||
var dialog = dialogService.open({
|
||||
template: '/views/common/dialogs//approvedcolorpicker.html',
|
||||
show: true,
|
||||
dialogData: {
|
||||
cssPath: $scope.model.config.items.approvedBackgroundCss,
|
||||
cssClass: row.cssClass
|
||||
},
|
||||
callback: function (data) {
|
||||
row.cssClass = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.boxed = function (cell) {
|
||||
if (cell.boxed == true) {
|
||||
cell.boxed = false;
|
||||
}
|
||||
else {
|
||||
cell.boxed = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.skipTopMargin = function (row) {
|
||||
if (row.skipTopMargin == true) {
|
||||
row.skipTopMargin = false;
|
||||
}
|
||||
else {
|
||||
row.skipTopMargin = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.skipBottomMargin = function (row) {
|
||||
if (row.skipBottomMargin == true) {
|
||||
row.skipBottomMargin = false;
|
||||
}
|
||||
else {
|
||||
row.skipBottomMargin = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.skipLeftMargin = function (row) {
|
||||
if (row.skipLeftMargin == true) {
|
||||
row.skipLeftMargin = false;
|
||||
}
|
||||
else {
|
||||
row.skipLeftMargin = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.skipRightMargin = function (row) {
|
||||
if (row.skipRightMargin == true) {
|
||||
row.skipRightMargin = false;
|
||||
}
|
||||
else {
|
||||
row.skipRightMargin = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.skipControlMargin = function (row) {
|
||||
if (row.skipControlMargin == true) {
|
||||
row.skipControlMargin = false;
|
||||
}
|
||||
else {
|
||||
row.skipControlMargin = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.fullScreen = function (row) {
|
||||
if (row.fullScreen == true) {
|
||||
row.fullScreen = false;
|
||||
}
|
||||
else {
|
||||
row.fullScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.addRow = function (column, cellModel) {
|
||||
|
||||
column.rows.splice(column.rows.length + 1, 0,
|
||||
{
|
||||
cells: [],
|
||||
cssClass: '',
|
||||
boxed: $scope.model.config.items.defaultBoxed,
|
||||
skipTopMargin: $scope.model.config.items.defaultSkipTopMargin,
|
||||
skipBottomMargin: $scope.model.config.items.defaultSkipBottomMargin,
|
||||
skipLeftMargin: $scope.model.config.items.defaultSkipLeftMargin,
|
||||
skipRightMargin: $scope.model.config.items.defaultSkipRightMargin,
|
||||
skipControlMargin: $scope.model.config.items.defaultSkipControlMargin,
|
||||
fullScreen: $scope.model.config.items.defaultFullScreen
|
||||
});
|
||||
|
||||
for (var i = 0; i < cellModel.models.length; i++) {
|
||||
|
||||
var cells = column.rows[column.rows.length - 1].cells
|
||||
|
||||
cells.splice(
|
||||
cells.length + 1, 0,
|
||||
{
|
||||
model: {
|
||||
grid: cellModel.models[i].grid,
|
||||
percentage: cellModel.models[i].percentage,
|
||||
},
|
||||
boxed: false,
|
||||
controls: []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.removeRow = function (column, $index) {
|
||||
if (column.rows.length > 0) {
|
||||
column.rows.splice($index, 1);
|
||||
$scope.openRTEToolbarId = null
|
||||
$scope.checkContent();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************
|
||||
// Cell management functions
|
||||
// *********************************************
|
||||
|
||||
$scope.setCurrentCell = function (cell) {
|
||||
$scope.currentCell = cell;
|
||||
}
|
||||
|
||||
$scope.disableCurrentCell = function (cell) {
|
||||
$scope.currentCell = null;
|
||||
}
|
||||
|
||||
// *********************************************
|
||||
// Control management functions
|
||||
// *********************************************
|
||||
|
||||
$scope.setCurrentControl = function (Control) {
|
||||
$scope.currentControl = Control;
|
||||
}
|
||||
|
||||
$scope.disableCurrentControl = function (Control) {
|
||||
$scope.currentControl = null;
|
||||
}
|
||||
|
||||
$scope.setCurrentToolsControl = function (Control) {
|
||||
$scope.currentToolsControl = Control;
|
||||
}
|
||||
|
||||
$scope.disableCurrentToolsControl = function (Control) {
|
||||
$scope.currentToolsControl = null;
|
||||
}
|
||||
|
||||
$scope.setUniqueId = function (cell, index) {
|
||||
|
||||
var date = new Date();
|
||||
var components = [
|
||||
date.getYear(),
|
||||
date.getMonth(),
|
||||
date.getDate(),
|
||||
date.getHours(),
|
||||
date.getMinutes(),
|
||||
date.getSeconds(),
|
||||
date.getMilliseconds()
|
||||
];
|
||||
|
||||
return components.join("");
|
||||
|
||||
}
|
||||
|
||||
$scope.addTinyMce = function (cell, index) {
|
||||
|
||||
var newId = $scope.setUniqueId();
|
||||
var newControl = {
|
||||
uniqueId: newId,
|
||||
tinyMCE: {
|
||||
uniqueId: newId,
|
||||
value: "",
|
||||
label: 'cellText',
|
||||
description: 'Load some stuff here',
|
||||
view: 'rte',
|
||||
config: {
|
||||
editor: {
|
||||
toolbar: [], //TODO
|
||||
stylesheets: [], //TODO
|
||||
dimensions: { height: 0, width: 0 } //TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index == undefined) {
|
||||
index = cell.controls.length
|
||||
}
|
||||
|
||||
cell.controls.splice(index + 1, 0, newControl);
|
||||
|
||||
$scope.openRTEToolbar(newControl);
|
||||
|
||||
$timeout(function(){
|
||||
tinymce.get(newId).focus();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
$scope.addMedia = function (cell, index) {
|
||||
|
||||
dialogService.mediaPicker({
|
||||
multiPicker: false,
|
||||
callback: function (data) {
|
||||
|
||||
if (!false) {
|
||||
data = [data];
|
||||
}
|
||||
|
||||
_.each(data, function (media, i) {
|
||||
media.src = imageHelper.getImagePropertyValue({ imageModel: media });
|
||||
media.thumbnail = imageHelper.getThumbnailFromPath(media.src);
|
||||
var newControl = {
|
||||
uniqueId: $scope.setUniqueId(),
|
||||
media: {
|
||||
id: media.id,
|
||||
src: media.src,
|
||||
thumbnail: media.thumbnail
|
||||
}
|
||||
}
|
||||
if (index == undefined) {
|
||||
index = cell.controls.length
|
||||
}
|
||||
|
||||
cell.controls.splice(index + 1, 0, newControl);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$scope.addEmbed = function (cell, index) {
|
||||
dialogService.embedDialog({
|
||||
callback: function (data) {
|
||||
var newControl = {
|
||||
uniqueId: $scope.setUniqueId(),
|
||||
embed: {
|
||||
content: data
|
||||
}
|
||||
}
|
||||
if (index == undefined) {
|
||||
index = cell.controls.length
|
||||
}
|
||||
|
||||
cell.controls.splice(index + 1, 0, newControl);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$scope.addMacro = function (cell, index) {
|
||||
var dialogData = {};
|
||||
dialogService.macroPicker({
|
||||
dialogData: dialogData,
|
||||
callback: function (data) {
|
||||
var newControl = {
|
||||
uniqueId: $scope.setUniqueId(),
|
||||
macro: {
|
||||
syntax: data.syntax,
|
||||
macroAlias: data.macroAlias,
|
||||
marcoParamsDictionary: data.macroParamsDictionary
|
||||
}
|
||||
}
|
||||
if (index == undefined) {
|
||||
index = cell.controls.length
|
||||
}
|
||||
|
||||
cell.controls.splice(index + 1, 0, newControl);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$scope.removeControl = function (cell, $index) {
|
||||
cell.controls.splice($index, 1);
|
||||
};
|
||||
|
||||
// *********************************************
|
||||
// Init grid
|
||||
// *********************************************
|
||||
|
||||
/* init grid data */
|
||||
if ($scope.model.value && $scope.model.value != "") {
|
||||
if (!$scope.model.config.items.enableGridWidth) {
|
||||
$scope.model.value.gridWidth = $scope.model.config.items.defaultGridWith;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.checkContent();
|
||||
|
||||
});
|
||||
|
||||
// *********************************************
|
||||
// asset styles
|
||||
// *********************************************
|
||||
|
||||
//assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/jquery-ui-1.10.4.custom/css/ui-lightness/jquery-ui-1.10.4.custom.min.css");
|
||||
assetsService.loadCss($scope.model.config.items.approvedBackgroundCss);
|
||||
|
||||
});
|
||||
@@ -1,3 +1,198 @@
|
||||
<div class="umb-editor umb-grid" ng-controller="Umbraco.PropertyEditors.GridController" auto-scale="10">
|
||||
<iframe style="width: 100%; height: 100%;" src="views/propertyeditors/grid/iframe.html"></iframe>
|
||||
<div ng-controller="Umbraco.PropertyEditors.GridController" class="usky-grid">
|
||||
<!-- Template picker -->
|
||||
<div class="uSky-templates tb" ng-show="!model.value || model.value == ''">
|
||||
<div class="tr">
|
||||
<div class="td middle">
|
||||
<div class="uSky-templates-template" ng-repeat="template in uSkyGridConfig" style="">
|
||||
<div class="tb" ng-click="addTemplate(template)">
|
||||
<div class="tr">
|
||||
<div class="td uSky-templates-column" ng-class="{last:$index==template.columns.length-1}" ng-repeat="column in template.columns" style="width:{{ column.percentage }}%">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grids -->
|
||||
<div class="usky-grid-width" style="width:{{ model.value.gridWidth }}px">
|
||||
<div ng-if="model.config.items.enableGridWidth" class="boxWidth">
|
||||
<label for="">width (px):</label><input type="text" ng-model="model.value.gridWidth" />
|
||||
</div>
|
||||
|
||||
<div class="tb">
|
||||
|
||||
<div class="usky-column td" ng-class="{last:$index==model.value.columns.length-1}" ng-repeat="column in model.value.columns" style="width:{{column .percentage}}%">
|
||||
|
||||
<div ui-sortable="sortableOptions" ng-model="column.rows">
|
||||
|
||||
<div ng-repeat="row in column.rows" class="usky-row">
|
||||
|
||||
<div ng-class="{selected:row == currentRow}" class="row-tools" ng-mouseover="setCurrentRow(row)" ng-mouseleave="disableCurrentRow()">
|
||||
<div class="iconBox"><a title="row setting"><i class="icon icon-settings"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableBackground" class="iconBox" ng-click="setBackGroundRow(row)"><a title="background color/image"><i class="icon icon-paint-roller"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableSkipTopMargin" ng-class="{iconBox:1==1,selected:row.skipTopMargin}" ng-click="skipTopMargin(row)"><a title="remove top margin"><i class="icon icon-navigation-top"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableSkipBottomMargin" ng-class="{iconBox:1==1,selected:row.skipBottomMargin}" ng-click="skipBottomMargin(row)"><a title="remove bottom margin"><i class="icon icon-navigation-bottom"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableSkipLeftMargin" ng-class="{iconBox:1==1,selected:row.skipLeftMargin}" ng-click="skipLeftMargin(row)"><a title="remove left margin"><i class="icon icon-navigation-first"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableSkipRightMargin" ng-class="{iconBox:1==1,selected:row.skipRightMargin}" ng-click="skipRightMargin(row)"><a title="remove right margin"><i class="icon icon-navigation-last"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableSkipControlMargin" ng-class="{iconBox:1==1,selected:row.skipControlMargin}" ng-click="skipControlMargin(row)"><a title="remove cell margins"><i class="icon icon-exit-fullscreen"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableFullScreen" ng-class="{iconBox:1==1,selected:row.fullScreen}" ng-click="fullScreen(row)"><a title="full width/height"><i class="icon icon-width"></i></a></div>
|
||||
<div ng-if="row == currentRow && model.config.items.enableBoxed" ng-class="{iconBox:1==1,selected:row.boxed}" ng-click="boxed(row)"><a title="cells boxed"><i class="icon icon-frame"></i></a></div>
|
||||
<div ng-if="row == currentRow" class="iconBox" ng-click="removeRow(column, $index)"><a title="remove row"><i class="icon icon-trash"></i></a></div>
|
||||
</div>
|
||||
|
||||
<div ng-class="{last:$index==model.value.length-1,first:$index==0,
|
||||
marginTopLess:row.skipTopMargin || row.fullScreen,
|
||||
marginBottomLess:row.skipBottomMargin || row.fullScreen,
|
||||
marginLeftLess:row.skipLeftMargin || row.fullScreen,
|
||||
marginRightLess:row.skipRightMargin || row.fullScreen,
|
||||
marginControlLess:row.skipControlMargin}" class="{{row.cssClass}} mainContainer">
|
||||
|
||||
<div class="mainTb">
|
||||
|
||||
<div class="tb">
|
||||
|
||||
<div class="tr">
|
||||
<div style="width:{{ cell.model.percentage }}%"
|
||||
ng-class="{last:$index==row.cells.length-1,first:$index==0}"
|
||||
class="td mainTd"
|
||||
|
||||
ng-repeat="cell in row.cells">
|
||||
|
||||
<div ng-repeat="control in cell.controls"
|
||||
ng-class="{backColor:!control.tinyMCE,
|
||||
last:$index==cell.controls.length-1,
|
||||
first:$index==0,
|
||||
selectedControl:currentControl == control || isOpenRTEToolbar(control),
|
||||
jumbotron:row.boxed}"
|
||||
ng-mouseover="setCurrentControl(control)" ng-mouseleave="disableCurrentControl(control)"
|
||||
class="controlContainer">
|
||||
|
||||
|
||||
<!-- Empty cell tools -->
|
||||
<div class="cell-tools" ng-if="control && ( currentControl == control || isOpenRTEToolbar(control) )">
|
||||
|
||||
<div class="cell-tools-add" ng-if="model.config.items.enableMultiCells" ng-mouseover="setCurrentToolsControl(control)" ng-mouseleave="disableCurrentToolsControl(control)">
|
||||
<div class="iconBox" ng-click="addTinyMce(cell, $index)" ng-if="(currentToolsControl == control) && model.config.items.enableRte">
|
||||
<i class="icon icon-edit"></i>
|
||||
</div>
|
||||
<div class="iconBox" ng-click="addMedia(cell, $index)" ng-if="(currentToolsControl == control) && model.config.items.enableMedia">
|
||||
<i class="icon icon-picture"></i>
|
||||
</div>
|
||||
<div class="iconBox" ng-click="addMacro(cell, $index)" ng-if="(currentToolsControl == control) && model.config.items.enableMacro">
|
||||
<i class="icon icon-settings-alt"></i>
|
||||
</div>
|
||||
<div class="iconBox" ng-if="currentToolsControl != control">
|
||||
<i class=" icon icon-add"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell-tools-remove">
|
||||
<div class="iconBox">
|
||||
<i class="icon icon-trash" ng-click="removeControl(cell, $index)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tiny cell -->
|
||||
<div ng-if="control && control.tinyMCE"
|
||||
ng-class="{cellPanelRte:1==1,hideRTEToolbar:!isOpenRTEToolbar(control)}">
|
||||
|
||||
<!--<div ng-controller="uSky.Grid.Rte.controler">
|
||||
<textarea ng-model="control.tinyMCE" rows="10" id="{{control.tinyMCE.uniqueId}}"></textarea>
|
||||
</div>-->
|
||||
|
||||
<div ng-if="control.tinyMCE"
|
||||
unique-id="control.tinyMCE.uniqueId"
|
||||
value="control.tinyMCE.value"
|
||||
ctrl-op="openRTEToolbar(control)"
|
||||
ctrl-cl="closeRTEToolbar(control)"
|
||||
grid-rte></div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Macro cell -->
|
||||
<div ng-if="control && control.media" class="cellMedia">
|
||||
<img ng-src="{{control.media.src}}" class="fullSizeImage" />
|
||||
</div>
|
||||
|
||||
<!-- Macro cell -->
|
||||
<div ng-if="control && control.macro" class="cellMacro">
|
||||
<div class="tools">
|
||||
<i class="icon icon-settings-alt"></i>
|
||||
{{control.macro.macroAlias}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Empty cell tools -->
|
||||
<div class="cellPanel"
|
||||
ng-if="cell.controls.length == 0">
|
||||
|
||||
|
||||
<p class="placeholder"
|
||||
ng-click="addTinyMce(cell)">
|
||||
Start writing here...
|
||||
</p>
|
||||
|
||||
<div class="iconBox" ng-click="addTinyMce(cell)" ng-if="(cell.controls.length == 0 || currentCell == cell) && model.config.items.enableRte">
|
||||
<i class="icon icon-edit"></i>
|
||||
</div>
|
||||
|
||||
<div class="iconBox" ng-click="addMedia(cell)" ng-if="(cell.controls.length == 0 || currentCell == cell) && model.config.items.enableMedia">
|
||||
<i class="icon icon-picture"></i>
|
||||
</div>
|
||||
|
||||
<div class="iconBox" ng-click="addMacro(cell)" ng-if="(cell.controls.length == 0 || currentCell == cell) && model.config.items.enableMacro">
|
||||
<i class="icon icon-settings-alt"></i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="tb">
|
||||
<div class="tr">
|
||||
<div class="td middle">
|
||||
<i class="icon-color icon icon-add large"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td middle">
|
||||
<ul>
|
||||
<li ng-repeat="cellModel in column.cellModels">
|
||||
<div class="tb mainTbpt" ng-click="addRow(column, cellModel)">
|
||||
<div class="tr">
|
||||
<div style="width:{{ cell.percentage; }}%" class="middle mainTdpt td" ng-repeat="cell in cellModel.models"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridPrevalueEditorController",
|
||||
function ($scope, $http, assetsService, $rootScope, dialogService, mediaResource, imageHelper, $timeout) {
|
||||
|
||||
var emptyModel = {
|
||||
enableGridWidth: true,
|
||||
defaultGridWith: "",
|
||||
enableBackground: true,
|
||||
enableSkipTopMargin: true,
|
||||
defaultSkipTopMargin: false,
|
||||
enableSkipBottomMargin: true,
|
||||
defaultSkipBottomMargin: false,
|
||||
enableSkipLeftMargin: true,
|
||||
defaultSkipLeftMargin: false,
|
||||
enableSkipRightMargin: true,
|
||||
defaultSkipRightMargin: false,
|
||||
enableSkipControlMargin: true,
|
||||
defaultSkipControlMargin: false,
|
||||
enableFullScreen: true,
|
||||
defaultFullScreen: false,
|
||||
enableBoxed: true,
|
||||
defaultBoxed: false,
|
||||
enableRte: true,
|
||||
enableMedia: true,
|
||||
enableMacro: true,
|
||||
enableMultiCells: true,
|
||||
approvedBackgroundCss: "views/propertyeditors/grid/config/grid.default.backgrounds.css",
|
||||
gridConfigPath: "views/propertyeditors/grid/config/grid.default.config.js"
|
||||
}
|
||||
|
||||
/* init grid data */
|
||||
if (!$scope.model.value || $scope.model.value == "") {
|
||||
$scope.model.value = emptyModel;
|
||||
}
|
||||
|
||||
})
|
||||
@@ -0,0 +1,122 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.GridPrevalueEditorController">
|
||||
|
||||
<p><strong>Config file path:</strong></p>
|
||||
<table cellpadding="20" style="margin-bottom:20px">
|
||||
<tr>
|
||||
<td>
|
||||
<input ng-model="model.value.gridConfigPath" type="text" style="width:500px;">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><strong>Grid width:</strong></p>
|
||||
<table cellpadding="20" style="margin-bottom:20px">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<input ng-model="model.value.enableGridWidth" type="checkbox">
|
||||
<label for="">Enable editing</label>
|
||||
</p>
|
||||
<p>
|
||||
Default grid width in pixels:
|
||||
<input ng-model="model.value.defaultGridWith" type="text" style="width:50px"><br />
|
||||
(if empty: grid's width is 100% of his container)
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><strong>Allowed row settings:</strong></p>
|
||||
<table cellpadding="20" style="margin-bottom:20px">
|
||||
<tr>
|
||||
<td>
|
||||
<p><i class="icon icon-paint-roller"></i> Enable/Disable row background</p>
|
||||
<input ng-model="model.value.enableBackground" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
</td>
|
||||
<td>
|
||||
<p><i class="icon icon-navigation-top"></i> Enable/Disable top margin</p>
|
||||
<input ng-model="model.value.enableSkipTopMargin" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultSkipTopMargin" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
<td>
|
||||
<p><i class="icon icon-navigation-bottom"></i> Enable/Disable bottom margin</p>
|
||||
<input ng-model="model.value.enableSkipBottomMargin" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultSkipBottomMargin" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p><i class="icon icon-navigation-first"></i> Enable/Disable left margin</p>
|
||||
<input ng-model="model.value.enableSkipLeftMargin" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultSkipLeftMargin" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
<td>
|
||||
<p><i class="icon icon-navigation-last"></i> Enable/Disable right margin</p>
|
||||
<input ng-model="model.value.enableSkipRightMargin" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultSkipRightMargin" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
<td>
|
||||
<p><i class="icon icon-fullscreen"></i> Enable/Disable control margin</p>
|
||||
<input ng-model="model.value.enableSkipControlMargin" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultSkipControlMargin" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p><i class="icon icon-width"></i> Enable/Disable full screen</p>
|
||||
<input ng-model="model.value.enableFullScreen" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultFullScreen" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
<td>
|
||||
<p><i class="icon icon-frame"></i> Enable/Disable boxed</p>
|
||||
<input ng-model="model.value.enableBoxed" type="checkbox">
|
||||
<label for="">Enable</label>
|
||||
<br />
|
||||
<input ng-model="model.value.defaultBoxed" type="checkbox">
|
||||
<label for="">Default value</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><strong>Allowed controls:</strong></p>
|
||||
<table cellpadding="20" style="margin-bottom:20px">
|
||||
<tr>
|
||||
<td>
|
||||
<p><input ng-model="model.value.enableRte" type="checkbox"> <i class="icon icon-edit"></i> Ritchtext (html)</p>
|
||||
<p><input ng-model="model.value.enableMedia" type="checkbox"> <i class="icon icon-picture"></i> Media</p>
|
||||
<p><input ng-model="model.value.enableMacro" type="checkbox"> <i class="icon icon-settings-alt"></i> Macro</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p><strong>Others settings:</strong></p>
|
||||
<table cellpadding="20" style="margin-bottom:20px">
|
||||
<tr>
|
||||
<td>
|
||||
<p><input ng-model="model.value.enableMultiCells" type="checkbox"> <i class="icon icon-edit"></i> Multiple controls in cell</p>
|
||||
<p>Approved background stylesheet path: <input ng-model="model.value.approvedBackgroundCss" type="text" style="width:300px;"></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
@@ -1,69 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../../assets/css/umbraco.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="row-fluid">
|
||||
<div class="span12" data-editor="rte">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Headline
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span6" data-editor="rte">
|
||||
Rich Text editor
|
||||
</div>
|
||||
<div class="span6" data-editor="macro">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Insert macro
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span4" data-editor="macro">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Insert Macro
|
||||
</div>
|
||||
<div class="span4" data-editor="image">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Insert image
|
||||
</div>
|
||||
<div class="span4" data-editor="image">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Insert image
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12" data-editor="rte">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Rich Text editor
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12" data-editor="rte">
|
||||
<i class="icon-move"></i>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="icon-trash"></i>
|
||||
Footer
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../../lib/jquery/jquery-2.0.3.min.js"></script>
|
||||
<script src="js/iframe.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,19 +0,0 @@
|
||||
$(function(){
|
||||
var editors = $('[data-editor]');
|
||||
var p = parent.$(parent.document);
|
||||
|
||||
|
||||
editors.addClass("editor");
|
||||
|
||||
editors.on("click", function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
// parent.document.fire("umbraco.grid.click");
|
||||
var el = this;
|
||||
var e = jQuery.Event("umbraco.grid.click", {editor: $(el).data("editor"), element: el});
|
||||
p.trigger( e );
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name Umbraco.Editors.Template.EditController
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* The controller for editing templates
|
||||
*/
|
||||
function TemplateEditController($scope, $http, assetsService, templateResource, $routeParams, $log) {
|
||||
|
||||
$scope.pageId = 1069;
|
||||
|
||||
$scope.rendering = false;
|
||||
$scope.aceLoaded = function(_editor) {
|
||||
// Options
|
||||
};
|
||||
|
||||
var render = _.throttle(function(){
|
||||
templateResource.saveAndRender($scope.template.content, $scope.template.id, $scope.pageId).then(
|
||||
function(response){
|
||||
var iframe = document.getElementById('mockingbird');
|
||||
iframe = (iframe.contentWindow) ? iframe.contentWindow : (iframe.contentDocument.document) ? iframe.contentDocument.document : iframe.contentDocument;
|
||||
iframe.document.open();
|
||||
iframe.document.write(response);
|
||||
iframe.document.close();
|
||||
$scope.rendering = false;
|
||||
},
|
||||
function(response){
|
||||
$log.log(response);
|
||||
$scope.rendering = false;
|
||||
}
|
||||
);
|
||||
|
||||
}, 1000);
|
||||
|
||||
$scope.aceChanged = function(e) {
|
||||
if(!$scope.rendering){
|
||||
$scope.rendering = true;
|
||||
render();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
templateResource.getById($routeParams.id).then(function(template){
|
||||
$scope.template = template;
|
||||
if(!$scope.rendering){
|
||||
$scope.rendering = true;
|
||||
render();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Template.EditController", TemplateEditController);
|
||||
26
src/Umbraco.Web.UI.Client/src/views/template/edit.html
Normal file
26
src/Umbraco.Web.UI.Client/src/views/template/edit.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<div ng-form name="contentForm" val-form-manager>
|
||||
<umb-panel ng-controller="Umbraco.Editors.Template.EditController">
|
||||
|
||||
<umb-header>
|
||||
<h1>{{template.name}}</h1>
|
||||
</umb-header>
|
||||
|
||||
<div class="umb-panel-body umb-scrollable row-fluid">
|
||||
<div class="span6" style="position: relative; height: 100%">
|
||||
|
||||
<div style="width: 100%; height: 100%; top: 0; bottom: 0; position: absolute" ng-model="template.content" ui-ace="{
|
||||
useWrapMode : true,
|
||||
showGutter: true,
|
||||
theme:'twilight',
|
||||
mode: 'xml',
|
||||
onLoad: aceLoaded,
|
||||
onChange: aceChanged
|
||||
}"></div>
|
||||
</div>
|
||||
<div class="span6" style="position: relative; height: 100%">
|
||||
<iframe id="mockingbird" style="width: 100%; height: 100%; top: 0; bottom: 0; position: absolute" id="preview" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</umb-panel>
|
||||
</div>
|
||||
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name Umbraco.Editors.Settings.Template.EditController
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* The controller for editing templates
|
||||
*/
|
||||
function TemplateEditController($scope, navigationService) {
|
||||
$scope.template = "<html><body><h1>Hej</h1></body></html>";
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Settings.Template.EditController", TemplateEditController);
|
||||
@@ -1,19 +0,0 @@
|
||||
<div ng-form name="contentForm" val-form-manager>
|
||||
<umb-panel ng-controller="Umbraco.Editors.Settings.Template.EditController">
|
||||
<umb-header>
|
||||
<h1>woop</h1>
|
||||
</umb-header>
|
||||
|
||||
<div class="umb-pane row-fluid">
|
||||
<div class="span6">
|
||||
<div ace="html" ng-model="template">
|
||||
<textarea></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<iframe style="width: 100%; height: 100%" id="preview" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</umb-panel>
|
||||
</div>
|
||||
@@ -7,7 +7,7 @@ module.exports = function(karma) {
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'lib/jquery/jquery-2.0.3.min.js',
|
||||
'lib/jquery/dist/jquery.min.js',
|
||||
'lib/angular/1.1.5/angular.js',
|
||||
'lib/angular/1.1.5/angular-cookies.min.js',
|
||||
'lib/angular/1.1.5/angular-mocks.js',
|
||||
|
||||
@@ -185,6 +185,10 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
"stylesheetApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<StylesheetController>(
|
||||
controller => controller.GetAll())
|
||||
},
|
||||
{
|
||||
"templateApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<TemplateController>(
|
||||
controller => controller.GetById(0))
|
||||
},
|
||||
{
|
||||
"memberTypeApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<MemberTypeController>(
|
||||
|
||||
117
src/Umbraco.Web/Editors/TemplateController.cs
Normal file
117
src/Umbraco.Web/Editors/TemplateController.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
[PluginController("UmbracoApi")]
|
||||
[UmbracoApplicationAuthorize(Core.Constants.Applications.Settings)]
|
||||
public class TemplateController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the content json for the content id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public TemplateDisplay GetById(int id)
|
||||
{
|
||||
var template = Services.FileService.GetTemplate(id);
|
||||
if (template == null)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
TemplateDisplay t = new TemplateDisplay();
|
||||
t.Alias = template.Alias;
|
||||
t.Content = template.Content;
|
||||
t.Id = template.Id;
|
||||
t.Name = template.Name;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a data type wth a given ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[HttpPost]
|
||||
public HttpResponseMessage DeleteById(int id)
|
||||
{
|
||||
var foundTemplate = Services.FileService.GetTemplate(id);
|
||||
if (foundTemplate == null)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
Services.FileService.DeleteTemplate(foundTemplate.Alias);
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public HttpResponseMessage PostSaveAndRender(dynamic model)
|
||||
{
|
||||
var foundTemplate = Services.FileService.GetTemplate((int)model.templateId);
|
||||
if (foundTemplate == null)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
foundTemplate.Content = model.html;
|
||||
Services.FileService.SaveTemplate(foundTemplate);
|
||||
|
||||
string result = string.Empty;
|
||||
try
|
||||
{
|
||||
var url = "http://" + Request.RequestUri.Host + "/" + model.pageId + ".aspx?altTemplate=" + foundTemplate.Alias;
|
||||
result = url;
|
||||
|
||||
WebClient wc = new WebClient();
|
||||
result = wc.DownloadString(new Uri(url));
|
||||
}
|
||||
catch (WebException exception)
|
||||
{
|
||||
if (exception.Response != null)
|
||||
{
|
||||
var responseStream = exception.Response.GetResponseStream();
|
||||
|
||||
if (responseStream != null)
|
||||
{
|
||||
using (var reader = new StreamReader(responseStream))
|
||||
{
|
||||
result = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result += ex.ToString();
|
||||
}
|
||||
|
||||
|
||||
return new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(
|
||||
result,
|
||||
Encoding.UTF8,
|
||||
"text/html"
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
16
src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs
Normal file
16
src/Umbraco.Web/Models/ContentEditing/TemplateDisplay.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
[DataContract(Name = "template", Namespace = "")]
|
||||
public class TemplateDisplay : EntityBasic
|
||||
{
|
||||
[DataMember(Name = "content")]
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
36
src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
Normal file
36
src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
[PropertyEditor(Core.Constants.PropertyEditors.GridAlias, "Grid", "grid", HideLabel=true, IsParameterEditor = false, ValueType="JSON")]
|
||||
public class GridPropertyEditor : PropertyEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Overridden to ensure that the value is validated
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override PropertyValueEditor CreateValueEditor()
|
||||
{
|
||||
var editor = base.CreateValueEditor();
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
protected override PreValueEditor CreatePreValueEditor()
|
||||
{
|
||||
return new gridPreValueEditor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class gridPreValueEditor : PreValueEditor
|
||||
{
|
||||
[PreValueField("items", "Grid Configuration", "views/propertyeditors/grid/grid.prevalues.html", Description = "General grid configuration")]
|
||||
public string Items { get; set; }
|
||||
}
|
||||
}
|
||||
94
src/Umbraco.Web/Trees/FileSystemTreeController.cs
Normal file
94
src/Umbraco.Web/Trees/FileSystemTreeController.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
public abstract class FileSystemTreeController : TreeController
|
||||
{
|
||||
protected abstract string FilePath { get; }
|
||||
protected abstract string FileSearchPattern { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Inheritors can override this method to modify the file node that is created.
|
||||
/// </summary>
|
||||
/// <param name="xNode"></param>
|
||||
protected virtual void OnRenderFileNode(ref TreeNode treeNode) { }
|
||||
|
||||
/// <summary>
|
||||
/// Inheritors can override this method to modify the folder node that is created.
|
||||
/// </summary>
|
||||
/// <param name="xNode"></param>
|
||||
protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { }
|
||||
|
||||
protected override Models.Trees.TreeNodeCollection GetTreeNodes(string id, System.Net.Http.Formatting.FormDataCollection queryStrings)
|
||||
{
|
||||
string orgPath = "";
|
||||
string path = "";
|
||||
if (!string.IsNullOrEmpty(id) && id != "-1")
|
||||
{
|
||||
orgPath = id;
|
||||
path = IOHelper.MapPath(FilePath + "/" + orgPath);
|
||||
orgPath += "/";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = IOHelper.MapPath(FilePath);
|
||||
}
|
||||
|
||||
DirectoryInfo dirInfo = new DirectoryInfo(path);
|
||||
DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
|
||||
|
||||
var nodes = new TreeNodeCollection();
|
||||
foreach (DirectoryInfo dir in dirInfos)
|
||||
{
|
||||
if ((dir.Attributes & FileAttributes.Hidden) == 0)
|
||||
{
|
||||
var HasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0;
|
||||
var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", HasChildren);
|
||||
|
||||
OnRenderFolderNode(ref node);
|
||||
if(node != null)
|
||||
nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
//this is a hack to enable file system tree to support multiple file extension look-up
|
||||
//so the pattern both support *.* *.xml and xml,js,vb for lookups
|
||||
string[] allowedExtensions = new string[0];
|
||||
bool filterByMultipleExtensions = FileSearchPattern.Contains(",");
|
||||
FileInfo[] fileInfo;
|
||||
|
||||
if (filterByMultipleExtensions)
|
||||
{
|
||||
fileInfo = dirInfo.GetFiles();
|
||||
allowedExtensions = FileSearchPattern.ToLower().Split(',');
|
||||
}
|
||||
else
|
||||
fileInfo = dirInfo.GetFiles(FileSearchPattern);
|
||||
|
||||
foreach (FileInfo file in fileInfo)
|
||||
{
|
||||
if ((file.Attributes & FileAttributes.Hidden) == 0)
|
||||
{
|
||||
if (filterByMultipleExtensions && Array.IndexOf<string>(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0)
|
||||
continue;
|
||||
|
||||
var node = CreateTreeNode(orgPath + file.Name, orgPath, queryStrings, file.Name, "icon-file", false);
|
||||
|
||||
OnRenderFileNode(ref node);
|
||||
|
||||
if(node != null)
|
||||
nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/Umbraco.Web/Trees/TemplateTreeController.cs
Normal file
52
src/Umbraco.Web/Trees/TemplateTreeController.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web.Mvc;
|
||||
using umbraco.cms.businesslogic.template;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
[UmbracoApplicationAuthorize(Constants.Applications.Settings)]
|
||||
[Tree(Constants.Applications.Settings, Constants.Trees.Templates, "Templates")]
|
||||
[PluginController("UmbracoTrees")]
|
||||
[CoreTree]
|
||||
public class TemplateTreeController : TreeController
|
||||
{
|
||||
protected override Models.Trees.MenuItemCollection GetMenuForNode(string id, System.Net.Http.Formatting.FormDataCollection queryStrings)
|
||||
{
|
||||
return new Models.Trees.MenuItemCollection();
|
||||
}
|
||||
|
||||
protected override Models.Trees.TreeNodeCollection GetTreeNodes(string id, System.Net.Http.Formatting.FormDataCollection queryStrings)
|
||||
{
|
||||
IEnumerable<Umbraco.Core.Models.EntityBase.IUmbracoEntity> templates;
|
||||
var nodes = new TreeNodeCollection();
|
||||
|
||||
|
||||
if (id == "-1")
|
||||
templates = Services.EntityService.GetRootEntities(Core.Models.UmbracoObjectTypes.Template);
|
||||
else
|
||||
templates = Services.EntityService.GetChildren(int.Parse(id), Core.Models.UmbracoObjectTypes.Template);
|
||||
|
||||
foreach (var t in templates)
|
||||
{
|
||||
var node = CreateTreeNode(t.Id.ToString(), t.ParentId.ToString(), queryStrings, t.Name);
|
||||
node.Icon = "icon-newspaper-alt";
|
||||
node.HasChildren = Services.EntityService.GetChildren(t.Id, Core.Models.UmbracoObjectTypes.Template).Any();
|
||||
|
||||
if (node.HasChildren)
|
||||
node.Icon = "icon-newspaper";
|
||||
|
||||
nodes.Add(node);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
[
|
||||
'lib/jquery/jquery-2.0.3.min.js',
|
||||
'lib/jquery/dist/jquery.min.js',
|
||||
'lib/angular/1.1.5/angular.min.js',
|
||||
'lib/underscore/underscore.js',
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
'lib/angular/1.1.5/angular-sanitize.min.js',
|
||||
|
||||
'lib/angular/angular-ui-sortable.js',
|
||||
|
||||
'lib/ace-builds/src-min-noconflict/ace.js',
|
||||
|
||||
'lib/jquery/jquery.upload/js/jquery.fileupload.js',
|
||||
'lib/jquery/jquery.upload/js/load-image.min.js',
|
||||
'lib/jquery/jquery.upload/js/jquery.fileupload-process.js',
|
||||
|
||||
@@ -306,8 +306,10 @@
|
||||
<Compile Include="Editors\EntityControllerActionSelector.cs" />
|
||||
<Compile Include="Editors\EntityControllerConfigurationAttribute.cs" />
|
||||
<Compile Include="Editors\ImagesController.cs" />
|
||||
<Compile Include="Editors\TemplateController.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentBaseItemSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\MediaItemSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\TemplateDisplay.cs" />
|
||||
<Compile Include="Models\DetachedContent.cs" />
|
||||
<Compile Include="Models\ImageCropAnchor.cs" />
|
||||
<Compile Include="Models\ImageCropCoordinates.cs" />
|
||||
@@ -356,6 +358,7 @@
|
||||
<Compile Include="Models\PostRedirectModel.cs" />
|
||||
<Compile Include="Models\PublishedProperty.cs" />
|
||||
<Compile Include="Mvc\RedirectToUmbracoUrlResult.cs" />
|
||||
<Compile Include="PropertyEditors\GridPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\TagsDataController.cs" />
|
||||
<Compile Include="PublishedCache\MemberPublishedContent.cs" />
|
||||
<Compile Include="PublishedCache\RawValueProperty.cs" />
|
||||
@@ -470,11 +473,13 @@
|
||||
<Compile Include="TagQuery.cs" />
|
||||
<Compile Include="Trees\CoreTreeAttribute.cs" />
|
||||
<Compile Include="Trees\DataTypeTreeController.cs" />
|
||||
<Compile Include="Trees\FileSystemTreeController.cs" />
|
||||
<Compile Include="Trees\LegacyBaseTreeAttribute.cs" />
|
||||
<Compile Include="Trees\MemberTreeController.cs" />
|
||||
<Compile Include="Trees\MenuRenderingEventArgs.cs" />
|
||||
<Compile Include="Models\Trees\CreateChildEntity.cs" />
|
||||
<Compile Include="Models\Trees\MenuItemList.cs" />
|
||||
<Compile Include="Trees\TemplateTreeController.cs" />
|
||||
<Compile Include="Trees\TreeControllerBase.cs" />
|
||||
<Compile Include="UI\JavaScript\AssetInitialization.cs" />
|
||||
<Compile Include="UI\JavaScript\CssInitialization.cs" />
|
||||
|
||||
@@ -32,7 +32,7 @@ using umbraco.BusinessLogic.Actions;
|
||||
|
||||
namespace umbraco
|
||||
{
|
||||
[Tree(Constants.Applications.Settings, "templates", "Templates", sortOrder: 1)]
|
||||
/* [Tree(Constants.Applications.Settings, "templates", "Templates", sortOrder: 1)]*/
|
||||
public class loadTemplates : BaseTree
|
||||
{
|
||||
public loadTemplates(string application) : base(application) {}
|
||||
|
||||
Reference in New Issue
Block a user