Initial commit of the grid

This commit is contained in:
per ploug
2014-05-09 12:23:59 +02:00
parent 3c09cd7674
commit 4baf3ed99a
37 changed files with 7965 additions and 240 deletions

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -0,0 +1,3 @@
{
"directory" : "lib"
}

View File

@@ -16,6 +16,7 @@
"tests"
],
"dependencies": {
"typeahead.js": "~0.10.2"
"typeahead.js": "~0.10.2",
"codemirror": "~4.1.0"
}
}

View File

@@ -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/' }]
},

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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();
}
};
});

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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}

View File

@@ -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);
});
});

View File

@@ -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>

View File

@@ -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); }

View File

@@ -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
}]
}
]
}
]
}
];

View File

@@ -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;
}

View File

@@ -1,13 +0,0 @@
/*
body{
background: white;
}
.editor{padding: 20px; margin: 20px; border: 3px dashed black; }
.editor:hover{border-color: red;}
*/

View File

@@ -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);
});

View File

@@ -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>

View File

@@ -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;
}
})

View File

@@ -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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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">&nbsp;<i class="icon icon-edit"></i>&nbsp;Ritchtext (html)</p>
<p><input ng-model="model.value.enableMedia" type="checkbox">&nbsp;<i class="icon icon-picture"></i>&nbsp;Media</p>
<p><input ng-model="model.value.enableMacro" type="checkbox">&nbsp;<i class="icon icon-settings-alt"></i>&nbsp;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">&nbsp;<i class="icon icon-edit"></i>&nbsp;Multiple controls in cell</p>
<p>Approved background stylesheet path:&nbsp;<input ng-model="model.value.approvedBackgroundCss" type="text" style="width:300px;"></p>
</td>
</tr>
</table>
</div>

View File

@@ -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>

View File

@@ -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 );
});
});

View File

@@ -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);

View 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>

View File

@@ -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);

View File

@@ -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>

View File

@@ -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',

View File

@@ -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>(

View 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"
)
};
}
}
}

View 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; }
}
}

View 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; }
}
}

View 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;
}
}
}

View 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;
}
}
}

View File

@@ -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',

View File

@@ -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" />

View File

@@ -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) {}