Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 306a30265e | |||
| 1ee6fc8514 | |||
| 1003ac42df | |||
| db4495cf50 | |||
| ed8cccdf5a | |||
| 9cd8ce5626 | |||
| 990f271c63 | |||
| adfdbaec46 | |||
| 0f4436a465 | |||
| 8ccbf70b39 | |||
| ddd26f3ad4 | |||
| 316e7531a0 | |||
| 0f068f5fb1 | |||
| 8f6b76f9fc | |||
| 468c281d7d | |||
| f7cb188210 | |||
| 00518d0de7 | |||
| 892a8d2a8a | |||
| ced6c011aa | |||
| efc2008783 | |||
| acb987a451 | |||
| 4a1ea6e2d8 | |||
| cc23d57803 | |||
| 81fdae3dc4 | |||
| 2859eb560c | |||
| 7c5ad67a9f |
+1
-1
@@ -4,7 +4,7 @@ IF NOT EXIST UmbracoVersion.txt (
|
||||
GOTO :showerror
|
||||
)
|
||||
SET /p release=<UmbracoVersion.txt
|
||||
SET comment=beta
|
||||
SET comment=beta2
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
views/dashboard/default/startupdashboardintro.html
|
||||
</control>
|
||||
</tab>
|
||||
<tab caption="Change password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
|
||||
<tab caption="Change Password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
|
||||
<tab caption="Change Password" xdt:Transform="Insert">
|
||||
<control showOnce="false" addPanel="false" panelCaption="">
|
||||
|
||||
@@ -52,8 +52,6 @@
|
||||
<compilation>
|
||||
<assemblies xdt:Transform="InsertIfMissing" />
|
||||
<assemblies>
|
||||
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
|
||||
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
|
||||
<add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xdt:Locator="Match(assembly)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
<add assembly="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" xdt:Locator="Match(assembly)" xdt:Transform="InsertIfMissing" />
|
||||
@@ -71,6 +69,13 @@
|
||||
</assemblies>
|
||||
</compilation>
|
||||
|
||||
<compilation>
|
||||
<assemblies>
|
||||
<remove assembly="System.Web.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
|
||||
<remove assembly="System.Net.Http" xdt:Locator="Match(assembly)" xdt:Transform="InsertBefore(/configuration/system.web/compilation/assemblies/add)" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
|
||||
<xhtmlConformance xdt:Transform="Remove" />
|
||||
|
||||
<httpModules xdt:Transform="InsertIfMissing" />
|
||||
@@ -126,36 +131,31 @@
|
||||
|
||||
<runtime xdt:Transform="InsertIfMissing" />
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" xdt:Transform="SetAttributes()">
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http')" xdt:Transform="InsertIfMissing">
|
||||
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Newtonsoft.Json')" xdt:Transform="InsertIfMissing">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Mvc')" xdt:Transform="InsertIfMissing">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" xdt:Transform="InsertIfMissing" />
|
||||
</runtime>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Newtonsoft.Json')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Mvc')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http')" xdt:Transform="Replace">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Newtonsoft.Json')" xdt:Transform="Replace">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Mvc')" xdt:Transform="Replace">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.1" />
|
||||
</dependentAssembly>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -63,8 +63,7 @@ if ($project) {
|
||||
|
||||
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
|
||||
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
|
||||
if ($prop -eq $null) { return }
|
||||
@@ -91,10 +90,8 @@ if ($project) {
|
||||
# get reference to the window, then smart output console provider
|
||||
# copy web.config if messages in buffered console contains "installing...UmbracoCms" in last operation
|
||||
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
|
||||
|
||||
$instance = $instanceField.GetValue($null)
|
||||
@@ -105,8 +102,7 @@ if ($project) {
|
||||
|
||||
$console = $consoleProvider.CreateOutputConsole($false)
|
||||
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($messagesField -eq $null) { return }
|
||||
|
||||
$messages = $messagesField.GetValue($console)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
public static string CurrentComment { get { return "beta2"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -17,37 +17,30 @@ namespace Umbraco.Core.Sync
|
||||
/// status. This will attempt to determine the internal umbraco base url that can be used by the current
|
||||
/// server to send a request to itself if it is in a load balanced environment.
|
||||
/// </summary>
|
||||
/// <returns>The full base url including schema (i.e. http://myserver:80/umbraco )</returns>
|
||||
/// <returns>The full base url including schema (i.e. http://myserver:80/umbraco ) - or <c>null</c> if the url
|
||||
/// cannot be determined at the moment (usually because the first request has not properly completed yet).</returns>
|
||||
public static string GetCurrentServerUmbracoBaseUrl()
|
||||
{
|
||||
var status = GetStatus();
|
||||
|
||||
if (status == CurrentServerEnvironmentStatus.Single)
|
||||
{
|
||||
//if it's a single install, then the base url has to be the first url registered. Use HTTP or HTTPS as appropriate.
|
||||
if (GlobalSettings.UseSSL)
|
||||
{
|
||||
return string.Format("https://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
// single install, return null if no original url, else use original url as base
|
||||
// use http or https as appropriate
|
||||
return string.IsNullOrWhiteSpace(ApplicationContext.Current.OriginalRequestUrl)
|
||||
? null // not initialized yet
|
||||
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
|
||||
var servers = UmbracoConfig.For.UmbracoSettings().DistributedCall.Servers.ToArray();
|
||||
|
||||
if (servers.Any() == false)
|
||||
{
|
||||
//cannot be determined, then the base url has to be the first url registered. Use HTTP or HTTPS as appropriate.
|
||||
if (GlobalSettings.UseSSL)
|
||||
{
|
||||
return string.Format("https://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
// cannot be determined, return null if no original url, else use original url as base
|
||||
// use http or https as appropriate
|
||||
return string.IsNullOrWhiteSpace(ApplicationContext.Current.OriginalRequestUrl)
|
||||
? null // not initialized yet
|
||||
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
|
||||
foreach (var server in servers)
|
||||
@@ -72,15 +65,11 @@ namespace Umbraco.Core.Sync
|
||||
}
|
||||
}
|
||||
|
||||
//cannot be determined, then the base url has to be the first url registered. Use HTTP or HTTPS as appropriate.
|
||||
if (GlobalSettings.UseSSL)
|
||||
{
|
||||
return string.Format("https://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("http://{0}", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
// cannot be determined, return null if no original url, else use original url as base
|
||||
// use http or https as appropriate
|
||||
return string.IsNullOrWhiteSpace(ApplicationContext.Current.OriginalRequestUrl)
|
||||
? null // not initialized yet
|
||||
: string.Format("http{0}://{1}", GlobalSettings.UseSSL ? "s" : "", ApplicationContext.Current.OriginalRequestUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"typeahead.js": "~0.10.5",
|
||||
"ace-builds": "~1.1.3",
|
||||
"rgrove-lazyload": "*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ module.exports = function (grunt) {
|
||||
|
||||
//triggered from grunt dev or grunt
|
||||
grunt.registerTask('build', ['clean', 'concat', 'recess:min', 'recess:installer', 'recess:canvasdesigner', 'bower', 'copy']);
|
||||
//build-dev doesn't min - we are trying to speed this up and we don't want minified stuff when we are in dev mode
|
||||
grunt.registerTask('build-dev', ['clean', 'concat', 'recess:build', 'recess:installer', 'copy']);
|
||||
|
||||
//build-dev doesn't min - we are trying to speed this up and we don't want minified stuff when we are in dev mode
|
||||
grunt.registerTask('build-dev', ['clean', 'concat', 'recess:build', 'recess:installer', 'copy']);
|
||||
|
||||
//utillity tasks
|
||||
grunt.registerTask('docs', ['ngdocs']);
|
||||
@@ -31,9 +32,9 @@ module.exports = function (grunt) {
|
||||
grunt.log.subhead(Date());
|
||||
});
|
||||
|
||||
// Custom task to run the bower dependency installer
|
||||
// tried, a few other things but this seems to work the best.
|
||||
// https://coderwall.com/p/xnkdqw
|
||||
// Custom task to run the bower dependency installer
|
||||
// tried, a few other things but this seems to work the best.
|
||||
// https://coderwall.com/p/xnkdqw
|
||||
grunt.registerTask('bower', 'Get js packages listed in bower.json',
|
||||
function () {
|
||||
var bower = require('bower');
|
||||
@@ -108,7 +109,7 @@ module.exports = function (grunt) {
|
||||
vsdir: '../Umbraco.Web.UI/umbraco',
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner:
|
||||
'/*! <%= pkg.title || pkg.name %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
||||
'/*! <%= pkg.title || pkg.name %>\n' +
|
||||
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
|
||||
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' +
|
||||
' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n',
|
||||
@@ -137,6 +138,9 @@ module.exports = function (grunt) {
|
||||
files: [{ dest: '<%= distdir %>/assets', src : '**', expand: true, cwd: 'src/assets/' }]
|
||||
},
|
||||
|
||||
config: {
|
||||
files: [{ dest: '<%= distdir %>/../config', src : '**', expand: true, cwd: 'src/config/' }]
|
||||
},
|
||||
|
||||
// Copies over the files downloaded by bower
|
||||
bower: {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/* Canvasdesigner panel app and controller */
|
||||
/*********************************************************************************************************/
|
||||
|
||||
var app = angular.module("Umbraco.canvasdesigner", ['spectrumcolorpicker', 'ui.slider', 'umbraco.resources', 'umbraco.services'])
|
||||
var app = angular.module("Umbraco.canvasdesigner", ['colorpicker', 'ui.slider', 'umbraco.resources', 'umbraco.services'])
|
||||
|
||||
.controller("Umbraco.canvasdesignerController", function ($scope, $http, $window, $timeout, $location, dialogService) {
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<div ng-controller="Umbraco.canvasdesigner.background">
|
||||
|
||||
<div class="box-slider">
|
||||
<spectrum colorselected="item.values.color"></spectrum>
|
||||
</div>
|
||||
<div colorpicker ng-model="item.values.color"></div>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div class="imagePickerPreview" ng-click="open(item.values)" style="background-image:{{ item.values.imageorpattern }}">
|
||||
|
||||
@@ -10,7 +10,7 @@ angular.module("Umbraco.canvasdesigner")
|
||||
if (!$scope.item.values) {
|
||||
$scope.item.values = {
|
||||
imageorpattern: '',
|
||||
color:''
|
||||
color: ''
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
<div class="box-slider">
|
||||
<ul class="box-preview">
|
||||
<li ng-repeat="border in borderList" class="border-{{border}}" ng-class="{selected: selectedBorder.name == border}" ng-click="setselectedBorder(border)"></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<spectrum colorselected="selectedBorder.color"></spectrum>
|
||||
<div class="box-slider" ng-repeat="border in borderList" ng-show="selectedBorder.name == border">
|
||||
<div colorpicker ng-model="item.values[(border !== 'all' ? border : '') + 'bordercolor']"></div>
|
||||
<select class="borderStyleSelect" ng-model="selectedBorder.type" ng-options="bordertype for bordertype in bordertypes"></select>
|
||||
<!--<i ng-if="selectedBorder.color != ''" ng-click="selectedBorder.color= ''" class="icon icon-delete colorPickerDelete"></i>-->
|
||||
</div>
|
||||
|
||||
@@ -92,35 +92,30 @@ angular.module("Umbraco.canvasdesigner")
|
||||
$scope.setselectedBorder($scope.borderList[0]);
|
||||
}, false);
|
||||
|
||||
$scope.$watch( "selectedBorder", function () {
|
||||
$scope.$watch("selectedBorder", function () {
|
||||
|
||||
if ($scope.selectedBorder.name == "all") {
|
||||
$scope.item.values.bordersize = $scope.selectedBorder.size;
|
||||
$scope.item.values.bordercolor = $scope.selectedBorder.color;
|
||||
$scope.item.values.bordertype =$scope.selectedBorder.type;
|
||||
$scope.item.values.bordertype = $scope.selectedBorder.type;
|
||||
}
|
||||
|
||||
if ($scope.selectedBorder.name == "left") {
|
||||
$scope.item.values.leftbordersize = $scope.selectedBorder.size;
|
||||
$scope.item.values.leftbordercolor = $scope.selectedBorder.color;
|
||||
$scope.item.values.leftbordertype = $scope.selectedBorder.type;
|
||||
}
|
||||
|
||||
if ($scope.selectedBorder.name == "right") {
|
||||
$scope.item.values.rightbordersize = $scope.selectedBorder.size;
|
||||
$scope.item.values.rightbordercolor = $scope.selectedBorder.color;
|
||||
$scope.item.values.rightbordertype = $scope.selectedBorder.type;
|
||||
}
|
||||
|
||||
if ($scope.selectedBorder.name == "top") {
|
||||
$scope.item.values.topbordersize = $scope.selectedBorder.size;
|
||||
$scope.item.values.topbordercolor = $scope.selectedBorder.color;
|
||||
$scope.item.values.topbordertype = $scope.selectedBorder.type;
|
||||
}
|
||||
|
||||
if ($scope.selectedBorder.name == "bottom") {
|
||||
$scope.item.values.bottombordersize = $scope.selectedBorder.size;
|
||||
$scope.item.values.bottombordercolor = $scope.selectedBorder.color;
|
||||
$scope.item.values.bottombordertype = $scope.selectedBorder.type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.color">
|
||||
|
||||
<div class="box-slider">
|
||||
<spectrum colorselected="item.values.color"></spectrum>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div colorpicker ng-model="item.values.color"></div>
|
||||
</div>
|
||||
@@ -9,7 +9,7 @@ angular.module("Umbraco.canvasdesigner")
|
||||
|
||||
if (!$scope.item.values) {
|
||||
$scope.item.values = {
|
||||
color: '',
|
||||
color: ''
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
/*********************************************************************************************************/
|
||||
/* spectrum color picker directive */
|
||||
/*********************************************************************************************************/
|
||||
|
||||
angular.module('colorpicker', ['spectrumcolorpicker'])
|
||||
.directive('colorpicker', ['dialogService', function (dialogService) {
|
||||
return {
|
||||
restrict: 'EA',
|
||||
scope: {
|
||||
ngModel: '='
|
||||
},
|
||||
link: function (scope, $element) {
|
||||
|
||||
scope.openColorDialog = function () {
|
||||
var config = {
|
||||
template: "colorModal.html",
|
||||
change: function (data) {
|
||||
scope.ngModel = data;
|
||||
},
|
||||
callback: function (data) {
|
||||
scope.ngModel = data;
|
||||
},
|
||||
cancel: function (data) {
|
||||
scope.ngModel = data;
|
||||
},
|
||||
dialogItem: scope.ngModel,
|
||||
scope: scope
|
||||
};
|
||||
|
||||
dialogService.open(config);
|
||||
}
|
||||
|
||||
scope.setColor = false;
|
||||
|
||||
scope.submitAndClose = function () {
|
||||
if (scope.ngModel != "") {
|
||||
scope.setColor = true;
|
||||
scope.submit(scope.ngModel);
|
||||
} else {
|
||||
scope.cancel();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
scope.cancelAndClose = function () {
|
||||
scope.cancel();
|
||||
}
|
||||
|
||||
},
|
||||
template:
|
||||
'<div>' +
|
||||
'<div class="color-picker-preview" ng-click="openColorDialog()" style="background: {{ngModel}} !important;"></div>' +
|
||||
'<script type="text/ng-template" id="colorModal.html">' +
|
||||
'<div class="modal-header">' +
|
||||
'<h1>Header</h1>' +
|
||||
'</div>' +
|
||||
'<div class="modal-body">' +
|
||||
'<spectrum colorselected="ngModel" set-color="setColor" flat="true" show-palette="true"></spectrum>' +
|
||||
'</div>' +
|
||||
'<div class="right">' +
|
||||
'<a class="btn" href="#" ng-click="cancelAndClose()">Cancel</a>' +
|
||||
'<a class="btn btn-success" href="#" ng-click="submitAndClose()">Done</a>' +
|
||||
'</div>' +
|
||||
'</script>' +
|
||||
'</div>',
|
||||
replace: true
|
||||
};
|
||||
}])
|
||||
@@ -5,12 +5,14 @@
|
||||
|
||||
angular.module("Umbraco.canvasdesigner").factory('dialogService', function ($rootScope, $q, $http, $timeout, $compile, $templateCache) {
|
||||
|
||||
|
||||
function closeDialog(dialog) {
|
||||
function closeDialog(dialog, destroyScope) {
|
||||
if (dialog.element) {
|
||||
dialog.element.removeClass("selected");
|
||||
dialog.element.html("");
|
||||
dialog.scope.$destroy();
|
||||
|
||||
if (destroyScope) {
|
||||
dialog.scope.$destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +34,11 @@ angular.module("Umbraco.canvasdesigner").factory('dialogService', function ($roo
|
||||
};
|
||||
|
||||
var dialog = angular.extend(defaults, options);
|
||||
var destroyScope = true;
|
||||
|
||||
if (options && options.scope) {
|
||||
destroyScope = false;
|
||||
}
|
||||
var scope = (options && options.scope) || $rootScope.$new();
|
||||
|
||||
// Save original value for cancel action
|
||||
@@ -42,10 +48,11 @@ angular.module("Umbraco.canvasdesigner").factory('dialogService', function ($roo
|
||||
|
||||
|
||||
/************************************/
|
||||
// Close dialog if the user clicks outside the dialog. (Not working well with colorpickers and datepickers)
|
||||
$(document).mousedown(function (e) {
|
||||
var container = dialog.element;
|
||||
if (!container.is(e.target) && container.has(e.target).length === 0) {
|
||||
closeDialog(dialog);
|
||||
closeDialog(dialog, destroyScope);
|
||||
}
|
||||
});
|
||||
/************************************/
|
||||
@@ -66,7 +73,7 @@ angular.module("Umbraco.canvasdesigner").factory('dialogService', function ($roo
|
||||
if (dialog.cancel) {
|
||||
dialog.cancel(originalDialogItem);
|
||||
}
|
||||
closeDialog(dialog);
|
||||
closeDialog(dialog, destroyScope);
|
||||
}
|
||||
|
||||
scope.change = function (data) {
|
||||
@@ -79,11 +86,11 @@ angular.module("Umbraco.canvasdesigner").factory('dialogService', function ($roo
|
||||
if (dialog.callback) {
|
||||
dialog.callback(data);
|
||||
}
|
||||
closeDialog(dialog);
|
||||
closeDialog(dialog, destroyScope);
|
||||
};
|
||||
|
||||
scope.close = function () {
|
||||
closeDialog(dialog);
|
||||
closeDialog(dialog, destroyScope);
|
||||
}
|
||||
|
||||
scope.dialogData = dialog.dialogData;
|
||||
|
||||
@@ -9,7 +9,10 @@ angular.module('spectrumcolorpicker', [])
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
scope: {
|
||||
colorselected: '='
|
||||
colorselected: '=',
|
||||
setColor: '=',
|
||||
flat: '=',
|
||||
showPalette: '='
|
||||
},
|
||||
link: function (scope, $element) {
|
||||
|
||||
@@ -18,9 +21,13 @@ angular.module('spectrumcolorpicker', [])
|
||||
$element.find("input").spectrum({
|
||||
color: scope.colorselected,
|
||||
allowEmpty: true,
|
||||
preferredFormat: "rgb",
|
||||
preferredFormat: "hex",
|
||||
showAlpha: true,
|
||||
showInput: true,
|
||||
flat: scope.flat,
|
||||
localStorageKey: "spectrum.panel",
|
||||
showPalette: scope.showPalette,
|
||||
palette: [],
|
||||
change: function (color) {
|
||||
|
||||
if (color) {
|
||||
@@ -45,8 +52,10 @@ angular.module('spectrumcolorpicker', [])
|
||||
|
||||
});
|
||||
|
||||
scope.$watch('colorselected', function () {
|
||||
$element.find("input").spectrum("set", scope.colorselected);
|
||||
scope.$watch('setcolor', function (setColor) {
|
||||
if (scope.$eval(setColor) === true) {
|
||||
$element.find("input").spectrum("set", scope.colorselected);
|
||||
}
|
||||
}, true);
|
||||
|
||||
},
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
angular.module('umbraco')
|
||||
.constant('uiAceConfig', {})
|
||||
.directive('uiAce', ['uiAceConfig', function (uiAceConfig) {
|
||||
|
||||
if (angular.isUndefined(window.ace)) {
|
||||
throw new Error('ui-ace need ace to work... (o rly?)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets editor options such as the wrapping mode or the syntax checker.
|
||||
*
|
||||
* The supported options are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>showGutter</li>
|
||||
* <li>useWrapMode</li>
|
||||
* <li>onLoad</li>
|
||||
* <li>theme</li>
|
||||
* <li>mode</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param acee
|
||||
* @param session ACE editor session
|
||||
* @param {object} opts Options to be set
|
||||
*/
|
||||
var setOptions = function(acee, session, opts) {
|
||||
|
||||
// Boolean options
|
||||
if (angular.isDefined(opts.showGutter)) {
|
||||
acee.renderer.setShowGutter(opts.showGutter);
|
||||
}
|
||||
if (angular.isDefined(opts.useWrapMode)) {
|
||||
session.setUseWrapMode(opts.useWrapMode);
|
||||
}
|
||||
if (angular.isDefined(opts.showInvisibles)) {
|
||||
acee.renderer.setShowInvisibles(opts.showInvisibles);
|
||||
}
|
||||
if (angular.isDefined(opts.showIndentGuides)) {
|
||||
acee.renderer.setDisplayIndentGuides(opts.showIndentGuides);
|
||||
}
|
||||
if (angular.isDefined(opts.useSoftTabs)) {
|
||||
session.setUseSoftTabs(opts.useSoftTabs);
|
||||
}
|
||||
|
||||
// commands
|
||||
if (angular.isDefined(opts.disableSearch) && opts.disableSearch) {
|
||||
acee.commands.addCommands([
|
||||
{
|
||||
name: 'unfind',
|
||||
bindKey: {
|
||||
win: 'Ctrl-F',
|
||||
mac: 'Command-F'
|
||||
},
|
||||
exec: function () {
|
||||
return false;
|
||||
},
|
||||
readOnly: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
// onLoad callback
|
||||
if (angular.isFunction(opts.onLoad)) {
|
||||
opts.onLoad(acee);
|
||||
}
|
||||
|
||||
// Basic options
|
||||
if (angular.isString(opts.theme)) {
|
||||
acee.setTheme('ace/theme/' + opts.theme);
|
||||
}
|
||||
if (angular.isString(opts.mode)) {
|
||||
session.setMode('ace/mode/' + opts.mode);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
restrict: 'EA',
|
||||
require: '?ngModel',
|
||||
link: function (scope, elm, attrs, ngModel) {
|
||||
|
||||
/**
|
||||
* Corresponds the uiAceConfig ACE configuration.
|
||||
* @type object
|
||||
*/
|
||||
var options = uiAceConfig.ace || {};
|
||||
|
||||
/**
|
||||
* uiAceConfig merged with user options via json in attribute or data binding
|
||||
* @type object
|
||||
*/
|
||||
var opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
||||
|
||||
/**
|
||||
* ACE editor
|
||||
* @type object
|
||||
*/
|
||||
var acee = window.ace.edit(elm[0]);
|
||||
|
||||
/**
|
||||
* ACE editor session.
|
||||
* @type object
|
||||
* @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session}
|
||||
*/
|
||||
var session = acee.getSession();
|
||||
|
||||
/**
|
||||
* Reference to a change listener created by the listener factory.
|
||||
* @function
|
||||
* @see listenerFactory.onChange
|
||||
*/
|
||||
var onChangeListener;
|
||||
|
||||
/**
|
||||
* Reference to a blur listener created by the listener factory.
|
||||
* @function
|
||||
* @see listenerFactory.onBlur
|
||||
*/
|
||||
var onBlurListener;
|
||||
|
||||
/**
|
||||
* Calls a callback by checking its existing. The argument list
|
||||
* is variable and thus this function is relying on the arguments
|
||||
* object.
|
||||
* @throws {Error} If the callback isn't a function
|
||||
*/
|
||||
var executeUserCallback = function () {
|
||||
|
||||
/**
|
||||
* The callback function grabbed from the array-like arguments
|
||||
* object. The first argument should always be the callback.
|
||||
*
|
||||
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
||||
* @type {*}
|
||||
*/
|
||||
var callback = arguments[0];
|
||||
|
||||
/**
|
||||
* Arguments to be passed to the callback. These are taken
|
||||
* from the array-like arguments object. The first argument
|
||||
* is stripped because that should be the callback function.
|
||||
*
|
||||
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
||||
* @type {Array}
|
||||
*/
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
if (angular.isDefined(callback)) {
|
||||
scope.$apply(function () {
|
||||
if (angular.isFunction(callback)) {
|
||||
callback(args);
|
||||
} else {
|
||||
throw new Error('ui-ace use a function as callback.');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Listener factory. Until now only change listeners can be created.
|
||||
* @type object
|
||||
*/
|
||||
var listenerFactory = {
|
||||
/**
|
||||
* Creates a change listener which propagates the change event
|
||||
* and the editor session to the callback from the user option
|
||||
* onChange. It might be exchanged during runtime, if this
|
||||
* happens the old listener will be unbound.
|
||||
*
|
||||
* @param callback callback function defined in the user options
|
||||
* @see onChangeListener
|
||||
*/
|
||||
onChange: function (callback) {
|
||||
return function (e) {
|
||||
var newValue = session.getValue();
|
||||
if (newValue !== scope.$eval(attrs.value) && !scope.$$phase && !scope.$root.$$phase) {
|
||||
if (angular.isDefined(ngModel)) {
|
||||
scope.$apply(function () {
|
||||
ngModel.$setViewValue(newValue);
|
||||
});
|
||||
}
|
||||
executeUserCallback(callback, e, acee);
|
||||
}
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Creates a blur listener which propagates the editor session
|
||||
* to the callback from the user option onBlur. It might be
|
||||
* exchanged during runtime, if this happens the old listener
|
||||
* will be unbound.
|
||||
*
|
||||
* @param callback callback function defined in the user options
|
||||
* @see onBlurListener
|
||||
*/
|
||||
onBlur: function (callback) {
|
||||
return function () {
|
||||
executeUserCallback(callback, acee);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
attrs.$observe('readonly', function (value) {
|
||||
acee.setReadOnly(value === 'true');
|
||||
});
|
||||
|
||||
// Value Blind
|
||||
if (angular.isDefined(ngModel)) {
|
||||
ngModel.$formatters.push(function (value) {
|
||||
if (angular.isUndefined(value) || value === null) {
|
||||
return '';
|
||||
}
|
||||
else if (angular.isObject(value) || angular.isArray(value)) {
|
||||
throw new Error('ui-ace cannot use an object or an array as a model');
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
ngModel.$render = function () {
|
||||
session.setValue(ngModel.$viewValue);
|
||||
};
|
||||
}
|
||||
|
||||
// set the options here, even if we try to watch later, if this
|
||||
// line is missing things go wrong (and the tests will also fail)
|
||||
setOptions(acee, session, opts);
|
||||
|
||||
// Listen for option updates
|
||||
scope.$watch( attrs.uiAce, function() {
|
||||
opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
||||
|
||||
// unbind old change listener
|
||||
session.removeListener('change', onChangeListener);
|
||||
|
||||
// bind new change listener
|
||||
onChangeListener = listenerFactory.onChange(opts.onChange);
|
||||
session.on('change', onChangeListener);
|
||||
|
||||
// unbind old blur listener
|
||||
//session.removeListener('blur', onBlurListener);
|
||||
acee.removeListener('blur', onBlurListener);
|
||||
|
||||
// bind new blur listener
|
||||
onBlurListener = listenerFactory.onBlur(opts.onBlur);
|
||||
acee.on('blur', onBlurListener);
|
||||
|
||||
setOptions(acee, session, opts);
|
||||
}, /* deep watch */ true );
|
||||
|
||||
// EVENTS
|
||||
onChangeListener = listenerFactory.onChange(opts.onChange);
|
||||
session.on('change', onChangeListener);
|
||||
|
||||
onBlurListener = listenerFactory.onBlur(opts.onBlur);
|
||||
acee.on('blur', onBlurListener);
|
||||
|
||||
elm.on('$destroy', function () {
|
||||
acee.session.$stopWorker();
|
||||
acee.destroy();
|
||||
});
|
||||
|
||||
scope.$watch(function() {
|
||||
return [elm[0].offsetWidth, elm[0].offsetHeight];
|
||||
}, function() {
|
||||
acee.resize();
|
||||
acee.renderer.updateFull();
|
||||
}, true);
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
example usage: <textarea json-edit="myObject" rows="8" class="form-control"></textarea>
|
||||
|
||||
jsonEditing is a string which we edit in a textarea. we try parsing to JSON with each change. when it is valid, propagate model changes via ngModelCtrl
|
||||
|
||||
use isolate scope to prevent model propagation when invalid - will update manually. cannot replace with template, or will override ngModelCtrl, and not hide behind facade
|
||||
|
||||
will override element type to textarea and add own attribute ngModel tied to jsonEditing
|
||||
*/
|
||||
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbRawModel', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
template: '<textarea ng-model="jsonEditing"></textarea>',
|
||||
replace : true,
|
||||
scope: {
|
||||
model: '=umbRawModel',
|
||||
validateOn:'='
|
||||
},
|
||||
link: function (scope, element, attrs, ngModelCtrl) {
|
||||
|
||||
function setEditing (value) {
|
||||
scope.jsonEditing = angular.copy( jsonToString(value));
|
||||
}
|
||||
|
||||
function updateModel (value) {
|
||||
scope.model = stringToJson(value);
|
||||
}
|
||||
|
||||
function setValid() {
|
||||
ngModelCtrl.$setValidity('json', true);
|
||||
}
|
||||
|
||||
function setInvalid () {
|
||||
ngModelCtrl.$setValidity('json', false);
|
||||
}
|
||||
|
||||
function stringToJson(text) {
|
||||
try {
|
||||
return angular.fromJson(text);
|
||||
} catch (err) {
|
||||
setInvalid();
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function jsonToString(object) {
|
||||
// better than JSON.stringify(), because it formats + filters $$hashKey etc.
|
||||
// NOTE that this will remove all $-prefixed values
|
||||
return angular.toJson(object, true);
|
||||
}
|
||||
|
||||
function isValidJson(model) {
|
||||
var flag = true;
|
||||
try {
|
||||
angular.fromJson(model);
|
||||
} catch (err) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
//init
|
||||
setEditing(scope.model);
|
||||
|
||||
var onInputChange = function(newval,oldval){
|
||||
if (newval !== oldval) {
|
||||
if (isValidJson(newval)) {
|
||||
setValid();
|
||||
updateModel(newval);
|
||||
} else {
|
||||
setInvalid();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(scope.validateOn){
|
||||
element.on(scope.validateOn, function(){
|
||||
scope.$apply(function(){
|
||||
onInputChange(scope.jsonEditing);
|
||||
});
|
||||
});
|
||||
}else{
|
||||
//check for changes going out
|
||||
scope.$watch('jsonEditing', onInputChange, true);
|
||||
}
|
||||
|
||||
//check for changes coming in
|
||||
scope.$watch('model', function (newval, oldval) {
|
||||
if (newval !== oldval) {
|
||||
setEditing(newval);
|
||||
}
|
||||
}, true);
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -55,11 +55,91 @@ angular.module('umbraco.mocks').
|
||||
allowedActions: ["U", "H", "A"],
|
||||
tabs: [
|
||||
{
|
||||
label: "Child documents",
|
||||
label: "Grid",
|
||||
id: 1,
|
||||
active: true,
|
||||
properties: [
|
||||
{ alias: "list", label: "List", view: "listview", value: "", hideLabel: true, config:{entityType: "content"} },
|
||||
{ alias: "grid",
|
||||
label: "Grid",
|
||||
view: "grid",
|
||||
value: "",
|
||||
hideLabel: true,
|
||||
config: {
|
||||
items:{
|
||||
|
||||
styles:[
|
||||
{
|
||||
label: "Set a background image",
|
||||
description: "Set a row background",
|
||||
key: "background-image",
|
||||
view: "imagepicker",
|
||||
modifier: "url({0})"
|
||||
}
|
||||
],
|
||||
config:[
|
||||
{
|
||||
label: "Class",
|
||||
description: "Set a css class",
|
||||
key: "class",
|
||||
view: "textstring"
|
||||
}
|
||||
],
|
||||
columns: 12,
|
||||
templates:[
|
||||
{
|
||||
name: "1 column layout",
|
||||
sections: [
|
||||
{
|
||||
grid: 12,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "2 column layout",
|
||||
sections: [
|
||||
{
|
||||
grid: 4,
|
||||
},
|
||||
{
|
||||
grid: 8
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
layouts:[
|
||||
{
|
||||
name: "Headline",
|
||||
areas: [
|
||||
{
|
||||
grid: 12,
|
||||
editors: ["headline"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Article",
|
||||
areas: [
|
||||
{
|
||||
grid: 12
|
||||
},
|
||||
{
|
||||
grid: 4
|
||||
},
|
||||
{
|
||||
grid: 8
|
||||
},
|
||||
{
|
||||
grid: 12
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -111,22 +191,6 @@ angular.module('umbraco.mocks').
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Tab # 7",
|
||||
id: 7,
|
||||
properties: [
|
||||
{ alias: "valTest7", label: "Validation test", view: "validationtest", value: "asdfasdf" },
|
||||
{ alias: "bodyText7", label: "Body Text", description: "Here you enter the primary article contents", view: "rte", value: "<p>askjdkasj lasjd</p>", config: {} },
|
||||
{ alias: "textarea7", label: "textarea", view: "textarea", value: "ajsdka sdjkds", config: { rows: 4 } },
|
||||
{ alias: "content7", label: "Content picker", view: "contentpicker", value: "1234,23242,23232,23231" }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Grid",
|
||||
id: 8,
|
||||
properties: [
|
||||
{ alias: "canvas", label: "Grid", view: "canvas", value: "test", hideLabel: true }
|
||||
]
|
||||
}, {
|
||||
label: "Generic Properties",
|
||||
id: 0,
|
||||
properties: [
|
||||
|
||||
@@ -78,7 +78,7 @@ angular.module('umbraco.mocks').
|
||||
{ name: "Multiple textstring", childNodesUrl: null, id: 11, icon: "icon-document", children: [], expanded: false, hasChildren: false, level: 1, menuUrl: null },
|
||||
{ name: "Yes/No", childNodesUrl: null, id: 12, icon: "icon-document", children: [], expanded: false, hasChildren: false, level: 1, menuUrl: null },
|
||||
{ name: "Rich Text Editor", childNodesUrl: null, id: 13, icon: "icon-document", children: [], expanded: false, hasChildren: false, level: 1, menuUrl: null }
|
||||
];
|
||||
];
|
||||
|
||||
return [200, children, null];
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ function initBackEnd($httpBackend, contentMocks, mediaMocks, treeMocks, userMock
|
||||
prevaluesMocks.register();
|
||||
entityMocks.register();
|
||||
|
||||
$httpBackend.whenGET(/^..\/config\//).passThrough();
|
||||
$httpBackend.whenGET(/^views\//).passThrough();
|
||||
$httpBackend.whenGET(/^js\//).passThrough();
|
||||
$httpBackend.whenGET(/^lib\//).passThrough();
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"name": "Rich text editor",
|
||||
"alias": "rte",
|
||||
"view": "rte",
|
||||
"icon": "icon-article"
|
||||
},
|
||||
{
|
||||
"name": "Image",
|
||||
"alias": "media",
|
||||
"view": "media",
|
||||
"icon": "icon-picture"
|
||||
},
|
||||
{
|
||||
"name": "Macro",
|
||||
"alias": "macro",
|
||||
"view": "macro",
|
||||
"icon": "icon-settings-alt"
|
||||
},
|
||||
{
|
||||
"name": "Embed",
|
||||
"alias": "embed",
|
||||
"view": "embed",
|
||||
"icon": "icon-movie-alt"
|
||||
},
|
||||
{
|
||||
"name": "Headline",
|
||||
"alias": "headline",
|
||||
"view": "textstring",
|
||||
"icon": "icon-coin",
|
||||
"config": {
|
||||
"style": "font-size: 36px; line-height: 45px; font-weight: bold",
|
||||
"markup": "<h1>#value#</h1>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Quote",
|
||||
"alias": "quote",
|
||||
"view": "textstring",
|
||||
"icon": "icon-quote",
|
||||
"config": {
|
||||
"style": "border-left: 3px solid #ccc; padding: 10px; color: #ccc; font-family: serif; font-variant: italic; font-size: 18px",
|
||||
"markup": "<blockquote>#value#</blockquote>"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -700,6 +700,46 @@ h4.panel-title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.canvasdesigner .color-picker-preview {
|
||||
height: 26px;
|
||||
border: 1px solid #CDCDCD;
|
||||
border-radius: 1px;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.canvasdesigner .spectrumcolorpicker {
|
||||
|
||||
}
|
||||
|
||||
.canvasdesigner .float-panel .sp-container.sp-flat {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canvasdesigner .float-panel .sp-container.sp-flat .sp-picker-container {
|
||||
padding: 0;
|
||||
margin: 0px;
|
||||
margin-bottom: 10px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.canvasdesigner .float-panel .sp-container.sp-flat .sp-palette-container {
|
||||
padding: 0;
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.canvasdesigner .float-panel .sp-container.sp-flat .sp-button-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.colorPickerDelete {
|
||||
position: absolute;
|
||||
margin: -23px 0 0 0;
|
||||
@@ -987,7 +1027,7 @@ iframe {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.bordereditor .spectrumcolorpicker {
|
||||
.bordereditor .color-picker-preview {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
float: left;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
overflow-y:hidden!important;
|
||||
}
|
||||
|
||||
IFRAME {overflow:hidden;}
|
||||
IFRAME {overflow:hidden;}
|
||||
|
||||
|
||||
// Sortabel
|
||||
@@ -18,7 +18,7 @@
|
||||
width: 160px !important;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
border-radius:50px;
|
||||
border-radius:5px;
|
||||
-webkit-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
-moz-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
@@ -29,7 +29,7 @@
|
||||
background: none !important;
|
||||
color: #999 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.usky-grid .ui-sortable-helper .cell-tools{
|
||||
@@ -66,20 +66,22 @@
|
||||
.usky-grid .right {
|
||||
float:right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// general layout components
|
||||
// -------------------------
|
||||
.usky-grid .tb {
|
||||
display:table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.usky-grid .td {
|
||||
display:table-cell;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align:top;
|
||||
border-right:1px dashed rgba(182, 182, 182, 0.0);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.usky-grid .tb:hover .td{
|
||||
border-right:1px dashed rgba(182, 182, 182, 0.3);
|
||||
}
|
||||
@@ -87,31 +89,16 @@
|
||||
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 {
|
||||
.usky-grid .mainTb {
|
||||
border-collapse: separate;
|
||||
}
|
||||
.usky-grid .mainTd {
|
||||
.usky-grid .mainTd {
|
||||
position:relative;
|
||||
}
|
||||
|
||||
@@ -120,10 +107,10 @@
|
||||
// COLUMN
|
||||
// -------------------------
|
||||
.usky-grid .usky-column {
|
||||
|
||||
|
||||
}
|
||||
.usky-grid .usky-column.last {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +149,7 @@
|
||||
right: 0;
|
||||
width: 150px;
|
||||
opacity: 0.3;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.usky-grid .cell-tools:hover{
|
||||
@@ -171,11 +159,9 @@
|
||||
.usky-grid .cell-tools-add {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom: -20px;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 500;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.usky-grid .usky-control:hover .cell-tools-add{
|
||||
@@ -206,6 +192,11 @@
|
||||
cursor: move
|
||||
}
|
||||
|
||||
.usky-grid .cell-tools-edit{
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
|
||||
// CONTROL
|
||||
@@ -216,9 +207,9 @@
|
||||
-webkit-transition: all .20s ease-in-out;*/
|
||||
position:relative;
|
||||
display:block;
|
||||
|
||||
|
||||
/*
|
||||
border: 1px dashed rgba(255, 0, 0, .0);
|
||||
border: 1px dashed rgba(255, 0, 0, .0);
|
||||
border-bottom-width: 1px;
|
||||
*/
|
||||
|
||||
@@ -247,7 +238,7 @@
|
||||
}
|
||||
|
||||
.usky-grid .usky-control-inner{
|
||||
min-height: 60px;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +246,7 @@
|
||||
// CONTROL PLACEHOLDER
|
||||
// -------------------------
|
||||
.usky-grid .usky-control-placeholder {
|
||||
min-height: 50px;
|
||||
min-height: 20px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
text-align: -moz-center;
|
||||
@@ -266,7 +257,7 @@
|
||||
font-size: 14px; opacity: 0.7; text-align: left;
|
||||
padding: 5px;
|
||||
border:1px solid rgba(182, 182, 182, 0.3);
|
||||
height: 50px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.usky-grid .usky-control-placeholder:hover .placeholder{
|
||||
@@ -293,7 +284,7 @@
|
||||
.usky-grid .usky-editor-placeholder i{
|
||||
color: @grayLight;
|
||||
font-size: 85px;
|
||||
line-height: 85px;
|
||||
line-height: 85px;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -326,7 +317,7 @@
|
||||
resize: none;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .cellPanelRte {
|
||||
min-height:60px;
|
||||
}
|
||||
@@ -382,7 +373,7 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.usky-grid ul {
|
||||
@@ -450,7 +441,7 @@
|
||||
background-color: #F7F7F7 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MEDIA EDITOR
|
||||
// -------------------------
|
||||
.usky-grid .fullSizeImage {
|
||||
@@ -488,18 +479,18 @@
|
||||
/**************************************************************************************************/
|
||||
|
||||
.usky-grid .usky-cell{
|
||||
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.usky-grid .usky-row{
|
||||
|
||||
|
||||
}
|
||||
|
||||
.usky-grid .usky-control{
|
||||
margin: 10px 0 0 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .usky-templates-columns{
|
||||
margin-top: 30px;
|
||||
}
|
||||
@@ -526,7 +517,7 @@
|
||||
overflow:hidden;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .uSky-templates-template {
|
||||
display:inline-block;
|
||||
width:100px;
|
||||
@@ -538,9 +529,9 @@
|
||||
border:5px solid @blue;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tb {
|
||||
width:100%;
|
||||
height:150px;
|
||||
.usky-grid .uSky-templates-template .tb {
|
||||
width:100%;
|
||||
height:150px;
|
||||
padding:10px;
|
||||
background-color: @grayLighter;
|
||||
border: 5px solid @grayLight;
|
||||
@@ -548,11 +539,11 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.usky-grid .uSky-templates-template .tr {
|
||||
.usky-grid .uSky-templates-template .tr {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .uSky-templates-template .tb .uSky-templates-column {
|
||||
height:100%;
|
||||
border: 1px dashed @grayLight;
|
||||
@@ -577,33 +568,154 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.usky-grid .usky-templates-columns .td i{
|
||||
.usky-grid .usky-templates-columns .td i{
|
||||
color: @gray;
|
||||
opacity: 0.8
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.usky-grid .mainTbpt:hover {
|
||||
.usky-grid .mainTbpt:hover {
|
||||
border-color:@blue;
|
||||
}
|
||||
}
|
||||
|
||||
.usky-grid .mainTbpt {
|
||||
.usky-grid .mainTbpt {
|
||||
cursor:pointer;
|
||||
border-spacing: 3px;
|
||||
border-collapse: separate;
|
||||
height: 35px;
|
||||
border: 2px solid @grayLight;
|
||||
min-height: 35px;
|
||||
border: 2px solid @grayLight;
|
||||
margin:0px;
|
||||
background-color: @grayLighter;
|
||||
}
|
||||
.usky-grid .mainTdpt {
|
||||
height: 35px;
|
||||
border: 1px dashed @grayLight;
|
||||
margin:0px;
|
||||
background-color: rgba(228, 228, 228, 0.41);
|
||||
overflow: hidden;
|
||||
}
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainTdpt {
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.usky-grid .mainTbpt {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.usky-grid .mainTdpt {
|
||||
height: 11px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border: 1px dashed #d9d9d9;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mainTdpt span{
|
||||
width: 100%;
|
||||
display: block;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
margin: 0 1px;
|
||||
height: 10px;
|
||||
background: @grayLight
|
||||
}
|
||||
|
||||
/* New template preview */
|
||||
.usky-grid {
|
||||
|
||||
.templates-preview {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
small {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: -25px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
margin: 35px 35px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-rows {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 125px;
|
||||
margin: 35px 40px 15px 0;
|
||||
border: 2px solid @grayLight; /* @grayLight */
|
||||
transition: border 200ms linear;
|
||||
|
||||
&:hover {
|
||||
border-color: @blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.preview-row {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-rows.layout {
|
||||
height: 180px;
|
||||
padding: 2px;
|
||||
|
||||
.preview-row {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.preview-col {
|
||||
height: 100%;
|
||||
border: dashed 1px @grayLight;
|
||||
}
|
||||
|
||||
.preview-cell {
|
||||
background-color: @grayLighter;
|
||||
}
|
||||
.preview-overlay {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-rows.columns {
|
||||
min-height: 18px;
|
||||
line-height: 11px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.preview-col {
|
||||
display: block;
|
||||
float: left;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 33.3%; /* temp value */
|
||||
height: 10px;
|
||||
margin: 0;
|
||||
border: 1px solid @white; /* @white */
|
||||
|
||||
.preview-cell {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: @grayLight; /* @grayLight */
|
||||
margin: 0 1px 1px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
border: 3px solid white;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/* overlay */
|
||||
@@ -614,14 +726,13 @@
|
||||
height: 380px;
|
||||
overflow: auto;
|
||||
border: 1px solid #ccc;
|
||||
margin-top: -190px;
|
||||
margin-top: -270px;
|
||||
margin-left: -150px;
|
||||
background: white;
|
||||
padding: 7px;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
|
||||
z-index: 666;
|
||||
z-index: 6660;
|
||||
-webkit-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
-moz-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
|
||||
@@ -674,7 +785,7 @@
|
||||
/**************************************************************************************************/
|
||||
.usky-grid-configuration .uSky-templates{
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.usky-grid-configuration ul{
|
||||
display: block;
|
||||
@@ -688,14 +799,21 @@
|
||||
|
||||
.usky-grid-configuration .uSky-templates .uSky-templates-template{
|
||||
margin: 0px 20px 20px 0px;
|
||||
width: 60px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
|
||||
.usky-grid-configuration .uSky-templates .uSky-templates-template .tb{
|
||||
height: 50px;
|
||||
max-height: 50px;
|
||||
border-width: 2px !important;
|
||||
padding: 0px;
|
||||
border-spacing:2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.usky-grid-configuration .uSky-templates .uSky-templates-template span{
|
||||
background: @grayLight;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.usky-grid-configuration .uSky-templates .uSky-templates-template .tb:hover{
|
||||
@@ -706,6 +824,8 @@
|
||||
display: block;
|
||||
float: left;
|
||||
margin-left: -1px;
|
||||
border: 1px white solid !important;
|
||||
background: @grayLighter;
|
||||
}
|
||||
|
||||
.usky-grid-configuration .uSky-templates-column.last{
|
||||
@@ -717,9 +837,14 @@
|
||||
font-size: 20px;
|
||||
line-height: 70px;
|
||||
color: #ccc;
|
||||
text-decoration: none
|
||||
text-decoration: none;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.usky-grid-configuration .mainTdpt{
|
||||
height: initial;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.usky-grid-configuration .uSky-templates-rows .uSky-templates-row{
|
||||
margin: 0px 50px 20px 0px;
|
||||
@@ -737,4 +862,3 @@
|
||||
}
|
||||
|
||||
.usky-grid-configuration a.uSky-templates-column{height: 70px !important;}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
function imageFilePickerController($scope, dialogService, mediaHelper) {
|
||||
|
||||
$scope.pick = function() {
|
||||
dialogService.mediaPicker({
|
||||
multiPicker: false,
|
||||
callback: function(data) {
|
||||
$scope.model.value = mediaHelper.resolveFile(data, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco').controller("Umbraco.PrevalueEditors.ImageFilePickerController",imageFilePickerController);
|
||||
@@ -0,0 +1,14 @@
|
||||
<div ng-controller="Umbraco.PrevalueEditors.ImageFilePickerController" class="umb-editor umb-mediapicker">
|
||||
<ul class="umb-sortable-thumbnails">
|
||||
<li style="width: 120px; height: 100px; overflow: hidden;">
|
||||
|
||||
<a href ng-click="pick()" class="icon-holder" ng-hide="model.value">
|
||||
<i class="icon icon-add large" ></i>
|
||||
<small>Choose...</small>
|
||||
</a>
|
||||
|
||||
<img ng-src="{{model.value}}" alt="" ng-show="model.value">
|
||||
<a href class="picked-image" ng-click="model.value = null" ng-show="model.value"><i class="icon icon-delete"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
+39
-5
@@ -1,11 +1,45 @@
|
||||
var uSkyGridConfig = [
|
||||
{
|
||||
|
||||
style:[
|
||||
{
|
||||
label: "Set a background image",
|
||||
description: "Set a row background",
|
||||
key: "background-image",
|
||||
view: "imagepicker",
|
||||
modifier: "url({0})"
|
||||
},
|
||||
|
||||
{
|
||||
label: "Set a font color",
|
||||
description: "Pick a color",
|
||||
key: "color",
|
||||
view: "colorpicker"
|
||||
}
|
||||
],
|
||||
|
||||
config:[
|
||||
{
|
||||
label: "Preview",
|
||||
description: "Display a live preview",
|
||||
key: "preview",
|
||||
view: "boolean"
|
||||
},
|
||||
|
||||
{
|
||||
label: "Class",
|
||||
description: "Set a css class",
|
||||
key: "class",
|
||||
view: "textstring"
|
||||
}
|
||||
],
|
||||
|
||||
layouts: [
|
||||
{
|
||||
grid: 12,
|
||||
percentage: 100,
|
||||
|
||||
|
||||
|
||||
|
||||
rows: [
|
||||
{
|
||||
name: "Single column",
|
||||
@@ -13,7 +47,7 @@ var uSkyGridConfig = [
|
||||
grid: 12,
|
||||
percentage: 100
|
||||
}]
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Article",
|
||||
@@ -96,7 +130,7 @@ var uSkyGridConfig = [
|
||||
{
|
||||
grid: 9,
|
||||
percentage: 70,
|
||||
|
||||
|
||||
cellModels: [
|
||||
{
|
||||
models: [{
|
||||
@@ -326,4 +360,4 @@ var uSkyGridConfig = [
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
];
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridController.Dialogs.Config",
|
||||
function ($scope, $http) {
|
||||
|
||||
var placeHolder = "{0}";
|
||||
var addModifier = function(val, modifier){
|
||||
if (!modifier || modifier.indexOf(placeHolder) < 0) {
|
||||
return val;
|
||||
} else {
|
||||
return modifier.replace(placeHolder, val);
|
||||
}
|
||||
}
|
||||
|
||||
var stripModifier = function (val, modifier) {
|
||||
if (!val || !modifier || modifier.indexOf(placeHolder) < 0) {
|
||||
return val;
|
||||
} else {
|
||||
var paddArray = modifier.split(placeHolder);
|
||||
if(paddArray.length == 1){
|
||||
if (modifier.indexOf(placeHolder) === 0) {
|
||||
return val.slice(0, -paddArray[0].length);
|
||||
} else {
|
||||
return val.slice(paddArray[0].length, 0);
|
||||
}
|
||||
}else{
|
||||
return val.slice(paddArray[0].length, -paddArray[1].length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$scope.styles = angular.copy($scope.dialogOptions.config.items.styles);
|
||||
$scope.config = angular.copy($scope.dialogOptions.config.items.config);
|
||||
|
||||
var element = $scope.dialogOptions.gridItem;
|
||||
if(angular.isObject(element.config)){
|
||||
_.each($scope.config, function(cfg){
|
||||
var val = element.config[cfg.key];
|
||||
if(val){
|
||||
cfg.value = stripModifier(val, cfg.modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(angular.isObject(element.styles)){
|
||||
_.each($scope.styles, function(style){
|
||||
var val = element.styles[style.key];
|
||||
if(val){
|
||||
style.value = stripModifier(val, style.modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.saveAndClose = function(){
|
||||
var styleObject = {};
|
||||
var configObject = {};
|
||||
|
||||
_.each($scope.styles, function(style){
|
||||
if(style.value){
|
||||
styleObject[style.key] = addModifier(style.value, style.modifier);
|
||||
}
|
||||
});
|
||||
_.each($scope.config, function (cfg) {
|
||||
if (cfg.value) {
|
||||
configObject[cfg.key] = addModifier(cfg.value, cfg.modifier);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.submit({config: configObject, styles: styleObject});
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
<div class="umb-panel" ng-controller="Umbraco.PropertyEditors.GridController.Dialogs.Config">
|
||||
|
||||
<div class="umb-panel-body no-header with-footer compact">
|
||||
|
||||
<umb-pane>
|
||||
|
||||
<div ng-if="config">
|
||||
<h4>Settings</h4>
|
||||
<umb-property
|
||||
property="configValue"
|
||||
ng-repeat="configValue in config">
|
||||
<umb-editor model="configValue" is-pre-value="true"></umb-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-if="styles">
|
||||
<h4>Style</h4>
|
||||
<umb-property
|
||||
property="styleValue"
|
||||
ng-repeat="styleValue in styles">
|
||||
<umb-editor model="styleValue" is-pre-value="true"></umb-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
|
||||
</umb-pane>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-panel-footer">
|
||||
<div class="umb-el-wrap umb-panel-buttons">
|
||||
<div class="btn-toolbar umb-btn-toolbar pull-right">
|
||||
<a href ng-click="saveAndClose()" class="btn btn-primary">
|
||||
<localize key="buttons_save">Save</localize>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridPrevalueEditorController.Dialogs.EditConfig",
|
||||
function ($scope, $http) {
|
||||
|
||||
$scope.renderModel = {};
|
||||
$scope.renderModel.name = $scope.dialogOptions.name;
|
||||
$scope.renderModel.config = $scope.dialogOptions.config;
|
||||
|
||||
$scope.saveAndClose = function(isValid){
|
||||
if(isValid){
|
||||
$scope.submit($scope.renderModel.config);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
<form name="gridConfigEditor">
|
||||
<div class="umb-panel" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditorController.Dialogs.EditConfig">
|
||||
|
||||
<div class="umb-panel-body no-header with-footer compact">
|
||||
|
||||
<umb-pane>
|
||||
<h4>{{renderModel.name}}</h4>
|
||||
<p>Settings will only save if the entered json configuration is valid</p>
|
||||
<textarea name="configSource"
|
||||
validate-on="'blur'"
|
||||
rows="20" class="umb-editor umb-textarea"
|
||||
umb-raw-model="renderModel.config"></textarea>
|
||||
|
||||
<div class="alert alert-error" ng-show="gridConfigEditor.$invalid === true">
|
||||
This configuration is not valid json, and will not be saved.
|
||||
</div>
|
||||
</umb-pane>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-panel-footer">
|
||||
<div class="umb-el-wrap umb-panel-buttons">
|
||||
<div class="btn-toolbar umb-btn-toolbar pull-right">
|
||||
<a href ng-click="saveAndClose(gridConfigEditor.$valid)" class="btn btn-primary">
|
||||
<localize key="buttons_save">Save</localize>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
+5
-1
@@ -3,8 +3,12 @@ angular.module("umbraco")
|
||||
function ($scope, $rootScope, $timeout, dialogService, macroResource, macroService, $routeParams) {
|
||||
|
||||
$scope.title = "Click to insert macro";
|
||||
|
||||
$scope.setMacro = function(){
|
||||
dialogService.macroPicker({
|
||||
dialogService.macroPicker({
|
||||
dialogData: {
|
||||
macroData: $scope.control.value
|
||||
},
|
||||
callback: function (data) {
|
||||
|
||||
$scope.control.value = {
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@ angular.module("umbraco")
|
||||
function ($scope, $rootScope, $timeout, dialogService) {
|
||||
|
||||
$scope.setImage = function(){
|
||||
dialogService.mediaPicker({
|
||||
dialogService.mediaPicker({
|
||||
startNodeId: $scope.control.editor.config && $scope.control.editor.config.startNodeId ? $scope.control.editor.config.startNodeId : undefined,
|
||||
multiPicker: false,
|
||||
callback: function (data) {
|
||||
$scope.control.value = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.Grid.TextStringController">
|
||||
<textarea
|
||||
rows="1"
|
||||
class="textstring input-block-level" id="{{control.uniqueId}}_text"
|
||||
ng-keyup="adjustSize($event)" ng-model="control.value"
|
||||
ng-attr-style="{{control.editor.config.style}}" placeholder="Write here..."></textarea>
|
||||
|
||||
@@ -8,7 +8,7 @@ angular.module("umbraco")
|
||||
$scope.currentToolsControl = null;
|
||||
$scope.currentControl = null;
|
||||
$scope.openRTEToolbarId = null;
|
||||
|
||||
$scope.hasSettings = false;
|
||||
|
||||
// *********************************************
|
||||
// Sortable options
|
||||
@@ -99,8 +99,8 @@ angular.module("umbraco")
|
||||
|
||||
start: function (e, ui) {
|
||||
ui.item.find('.mceNoEditor').each(function () {
|
||||
notIncludedRte = []
|
||||
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'))
|
||||
notIncludedRte = [];
|
||||
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -119,7 +119,7 @@ angular.module("umbraco")
|
||||
}, 500, false);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// *********************************************
|
||||
// Add items overlay menu
|
||||
@@ -184,9 +184,15 @@ angular.module("umbraco")
|
||||
$scope.currentRow = null;
|
||||
};
|
||||
|
||||
$scope.setCurrentRemoveRow = function (Row) {
|
||||
$scope.currentRemoveRow = Row;
|
||||
};
|
||||
|
||||
$scope.disableCurrentRemoveRow = function (Row) {
|
||||
$scope.currentRemoveRow = null;
|
||||
};
|
||||
|
||||
$scope.setCurrentMovedRow = function (Row) {
|
||||
$scope.currentRow = null;
|
||||
$scope.currentRemoveControl = null;
|
||||
$scope.currentMovedRow = Row;
|
||||
};
|
||||
|
||||
@@ -218,18 +224,32 @@ angular.module("umbraco")
|
||||
if(row){
|
||||
section.rows.push(row);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.removeRow = function (section, $index) {
|
||||
if (section.rows.length > 0) {
|
||||
section.rows.splice($index, 1);
|
||||
$scope.openRTEToolbarId = null;
|
||||
|
||||
$scope.initContent();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.editGridItemSettings = function (gridItem) {
|
||||
|
||||
dialogService.open(
|
||||
{
|
||||
template: "views/propertyeditors/grid/dialogs/config.html",
|
||||
gridItem: gridItem,
|
||||
config: $scope.model.config,
|
||||
callback: function(data){
|
||||
|
||||
gridItem.styles = data.styles;
|
||||
gridItem.config = data.config;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// *********************************************
|
||||
// Cell management functions
|
||||
@@ -365,6 +385,11 @@ angular.module("umbraco")
|
||||
$scope.initContent = function() {
|
||||
var clear = true;
|
||||
|
||||
//settings indicator shortcut
|
||||
if($scope.model.config.items.config || $scope.model.config.items.styles){
|
||||
$scope.hasSettings = true;
|
||||
}
|
||||
|
||||
if ($scope.model.value && $scope.model.value.sections && $scope.model.value.sections.length > 0) {
|
||||
_.forEach($scope.model.value.sections, function(section){
|
||||
|
||||
@@ -401,6 +426,7 @@ angular.module("umbraco")
|
||||
_.forEach(section.rows, function(row, index){
|
||||
if(!row.$initialized){
|
||||
var initd = $scope.initRow(row);
|
||||
|
||||
//if init fails, remove
|
||||
if(!initd){
|
||||
section.rows.splic(index, 1);
|
||||
@@ -420,18 +446,26 @@ angular.module("umbraco")
|
||||
|
||||
//merge the layout data with the original config data
|
||||
//if there are no config info on this, splice it out
|
||||
var original = _.find($scope.model.config.items.layouts, function(o){ return o.name === row.name; });
|
||||
var original = _.find($scope.model.config.items.layouts, function (o) { return o.name === row.name; });
|
||||
|
||||
if(!original){
|
||||
return null;
|
||||
}else{
|
||||
//make a copy to not touch the original config
|
||||
original = angular.copy(original);
|
||||
original.styles = row.styles;
|
||||
original.config = row.config;
|
||||
|
||||
//sync area configuration
|
||||
_.each(original.areas, function(area, areaIndex){
|
||||
|
||||
var currentArea = row.areas[areaIndex];
|
||||
area.config = currentArea.config;
|
||||
area.styles = currentArea.styles;
|
||||
|
||||
//copy over existing controls into the new areas
|
||||
if(row.areas.length > areaIndex && row.areas[areaIndex].controls){
|
||||
area.controls = row.areas[areaIndex].controls;
|
||||
area.controls = currentArea.controls;
|
||||
|
||||
_.forEach(area.controls, function(control, controlIndex){
|
||||
$scope.initControl(control, controlIndex);
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.GridController" class="usky-grid">
|
||||
|
||||
<div ng-if="contentReady">
|
||||
|
||||
<!-- 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 model.config.items.templates" style="">
|
||||
<div class="tb" ng-click="addTemplate(template)">
|
||||
<div class="tr">
|
||||
<div class="td uSky-templates-column"
|
||||
|
||||
<div class="templates-preview"
|
||||
ng-show="!model.value || model.value == ''">
|
||||
|
||||
<div class="preview-rows layout"
|
||||
ng-repeat="template in model.config.items.templates"
|
||||
ng-click="addTemplate(template)">
|
||||
|
||||
<div class="preview-row">
|
||||
|
||||
<div class="preview-col"
|
||||
ng-class="{last:$last}"
|
||||
ng-repeat="section in template.sections"
|
||||
style="width:{{ percentage(section.grid) }}%">
|
||||
</div>
|
||||
</div>
|
||||
ng-style="{width: percentage(section.grid) + '%'}">
|
||||
|
||||
<div class="preview-cell">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<div class="help-text">To start, select a layout for your grid</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-overlay">
|
||||
</div>
|
||||
|
||||
<small>{{layout.name}}</small>
|
||||
|
||||
</div> <!-- .templates-preview-rows -->
|
||||
|
||||
<p><span class="help-text">Add rows to your layout</span></p>
|
||||
|
||||
|
||||
</div> <!-- .templates-preview -->
|
||||
|
||||
<!-- template picker end -->
|
||||
|
||||
<!-- Grids -->
|
||||
@@ -34,16 +48,15 @@
|
||||
ng-class="{last:$last}"
|
||||
ng-repeat="section in model.value.sections"
|
||||
ng-init="initSection(section)"
|
||||
style="width:{{section.$percentage}}%">
|
||||
ng-style="{width: section.$percentage + '%'}">
|
||||
|
||||
<div ui-sortable="sortableOptions" ng-model="section.rows">
|
||||
|
||||
<!-- for each row in template section -->
|
||||
<div ng-repeat="row in section.rows"
|
||||
class="usky-row"
|
||||
ng-mouseover="setCurrentRow(row)"
|
||||
ng-mouseleave="disableCurrentRow()"
|
||||
ng-class="{'selectedControl':currentRow == row && currentControl === null}">
|
||||
ng-mouseenter="setCurrentRow(row)"
|
||||
ng-mouseleave="disableCurrentRow()">
|
||||
|
||||
<!-- Row tool -->
|
||||
<div class="row-tools" ng-animate="'fade'" ng-if="currentRow == row && currentControl === null">
|
||||
@@ -52,8 +65,8 @@
|
||||
<div class="cell-tools-remove">
|
||||
<div class="iconBox"
|
||||
ng-click="deletePrompt = true"
|
||||
ng-mouseover="setCurrentRemoveControl(row)"
|
||||
ng-mouseover="disableCurrentRemoveControl(row)">
|
||||
ng-mouseenter="setCurrentRemoveControl(row)"
|
||||
ng-mouseleave="disableCurrentRemoveControl(row)">
|
||||
|
||||
<span ng-if="deletePrompt">
|
||||
Are you sure?
|
||||
@@ -65,73 +78,34 @@
|
||||
</div>
|
||||
|
||||
<div class="cell-tools-move">
|
||||
<div class="iconBox"
|
||||
ng-mouseover="setCurrentMovedRow(row)"
|
||||
ng-mouseleave="disableCurrentMovedRow(row)">
|
||||
<a class="iconBox"
|
||||
href>
|
||||
<i class="icon icon-navigation"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="cell-tools-edit" ng-if="hasSettings">
|
||||
<a href class="iconBox" ng-click="editGridItemSettings(row)">
|
||||
<i class="icon icon-settings"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- row container -->
|
||||
<div class="{{row.cssClass}} mainContainer usky-row-inner"
|
||||
ng-class="{last:$last,first:$first,warnhighlight:currentRemoveControl == row, infohighlight:currentMovedRow == row}">
|
||||
ng-class="{last:$last,first:$first,warnhighlight:currentRemoveRow == row, infohighlight:currentMovedRow == row}">
|
||||
|
||||
<div class="mainTb">
|
||||
<div class="tb">
|
||||
<div class="tr">
|
||||
|
||||
<!-- cells in row -->
|
||||
<div style="width:{{ area.$percentage }}%"
|
||||
<div ng-style="{width: area.$percentage + '%'}"
|
||||
ng-class="{last:$last,first:$first}"
|
||||
class="td mainTd usky-cell"
|
||||
ng-repeat="area in row.areas" ui-sortable="sortableOptionsCell" ng-model="area.controls">
|
||||
|
||||
<!-- if area is empty tools -->
|
||||
<div class="usky-control usky-control-placeholder"
|
||||
ng-if="area.controls.length == 0">
|
||||
|
||||
<div ng-if="area.allowed && area.allowed.length === 1"
|
||||
ng-init="singleEditor = area.$allowedEditors[0]"
|
||||
class="cell-tools-add-single single-editor-{{singleEditor.alias}}">
|
||||
|
||||
<div class="help-text" style="margin-bottom: 15px">
|
||||
To start, click the <i class=" icon {{singleEditor.icon}} blue">
|
||||
</i> below and add your first {{singleEditor.name}}
|
||||
</div><br/>
|
||||
|
||||
<div class="iconBox">
|
||||
<a href ng-click="addControl(singleEditor, area)">
|
||||
<i class="icon {{singleEditor.icon}}"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-if="!area.allowed || area.allowed.length > 1">
|
||||
|
||||
<div class="help-text" style="margin-bottom: 15px">
|
||||
To start, click the <i class=" icon icon-add blue">
|
||||
</i> below and add your first element
|
||||
</div><br/>
|
||||
|
||||
|
||||
<div class="cell-tools-add"
|
||||
ng-if="!currentToolsControl"
|
||||
ng-animate="'fade'">
|
||||
|
||||
<div class="iconBox">
|
||||
<a href ng-click="addItemOverlay($event, area, 0, area.$uniqueId);">
|
||||
<i class=" icon icon-add"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div ng-if="overlayMenu.show && overlayMenu.key == area.$uniqueId" ng-include="'views/propertyeditors/grid/dialogs/additem.html'"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Controls in cell -->
|
||||
<div ng-repeat="control in area.controls"
|
||||
ng-mouseover="setCurrentControl(control)"
|
||||
@@ -151,12 +125,12 @@
|
||||
ng-mouseover="setCurrentRemoveControl(control)"
|
||||
ng-mouseleave="disableCurrentRemoveControl(control)">
|
||||
|
||||
<span ng-show="deletePrompt">
|
||||
Are you sure?
|
||||
<a href style="text-decoration: underline" ng-click="removeControl(area, $index)">Yes</a>
|
||||
</span>
|
||||
<span ng-show="deletePrompt">
|
||||
Are you sure?
|
||||
<a href style="text-decoration: underline" ng-click="removeControl(area, $index)">Yes</a>
|
||||
</span>
|
||||
|
||||
<i ng-show="!deletePrompt" class="icon icon-trash"></i>
|
||||
<i ng-show="!deletePrompt" class="icon icon-trash"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -169,6 +143,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell-tools-edit" ng-if="hasSettings && $first">
|
||||
<a href class="iconBox" ng-click="editGridItemSettings(area)">
|
||||
<i class="icon icon-settings"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="usky-control-inner" ng-class="{last:$last,
|
||||
@@ -181,24 +160,31 @@
|
||||
class="usky-cell usky-cell-{{control.editor.view}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- add stuff -->
|
||||
<div class="cell-tools-add"
|
||||
ng-show="!currentToolsControl && control===currentControl && (area.max === undefined || area.max < area.controls.length)"
|
||||
ng-animate="'fade'">
|
||||
|
||||
<div class="iconBox">
|
||||
<a href ng-click="addItemOverlay($event, area, control.$index, control.$uniqueId)">
|
||||
<i class=" icon icon-add"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div ng-show="overlayMenu.show && overlayMenu.key == control.$uniqueId" ng-include="'views/propertyeditors/grid/dialogs/additem.html'"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Controls repeat end -->
|
||||
|
||||
<!-- if area is empty tools -->
|
||||
<div class="usky-control usky-control-placeholder"
|
||||
ng-if="area.controls.length == 0">
|
||||
<div class="help-text" style="margin-bottom: 15px">
|
||||
To start, click the <i class=" icon icon-add blue">
|
||||
</i> below and add your first element
|
||||
</div><br />
|
||||
</div>
|
||||
|
||||
<div class="cell-tools-add"
|
||||
ng-if="!currentToolsControl"
|
||||
ng-animate="'fade'">
|
||||
|
||||
<div class="iconBox">
|
||||
<a href ng-click="addItemOverlay($event, area, 0, area.$uniqueId);">
|
||||
<i class=" icon icon-add"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div ng-if="overlayMenu.show && overlayMenu.key == area.$uniqueId" ng-include="'views/propertyeditors/grid/dialogs/additem.html'"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- cells repeat end -->
|
||||
</div>
|
||||
@@ -212,35 +198,43 @@
|
||||
|
||||
</div>
|
||||
<!-- row sortable end -->
|
||||
|
||||
|
||||
<!-- column tools -->
|
||||
<div class="usky-templates-columns tb">
|
||||
|
||||
<div class="tr">
|
||||
<div class="td middle">
|
||||
<ul>
|
||||
<li ng-repeat="layout in section.$allowedLayouts" ng-show="layout.areas.length > 0">
|
||||
<div class="tb mainTbpt" ng-click="addRow(section, layout)">
|
||||
<div class="tr">
|
||||
<div style="width:{{ percentage(area.grid); }}%"
|
||||
class="middle mainTdpt td"
|
||||
ng-repeat="area in layout.areas">
|
||||
<i class="icon {{cellPreview(area)}}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<small>{{layout.name}}</small>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="templates-preview">
|
||||
|
||||
<div class="preview-rows columns"
|
||||
ng-repeat="layout in section.$allowedLayouts"
|
||||
ng-show="layout.areas.length > 0"
|
||||
ng-click="addRow(section, layout)">
|
||||
|
||||
<div class="preview-row">
|
||||
|
||||
<div class="preview-col" ng-style="{width: percentage(area.grid) + '%'}" ng-repeat="area in layout.areas">
|
||||
|
||||
<div class="preview-cell">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="td middle">
|
||||
<br />
|
||||
<span class="help-text">Add rows to your layout</span>
|
||||
|
||||
<div class="preview-overlay">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<small>{{layout.name}}</small>
|
||||
|
||||
</div> <!-- .templates-preview-rows -->
|
||||
|
||||
|
||||
<p>
|
||||
<span class="help-text">Add rows to your layout</span>
|
||||
</p>
|
||||
|
||||
|
||||
</div> <!-- .templates-preview -->
|
||||
|
||||
<!-- column tools end -->
|
||||
|
||||
</div>
|
||||
@@ -249,7 +243,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
+75
-4
@@ -3,6 +3,25 @@ angular.module("umbraco")
|
||||
function ($scope, $http, assetsService, $rootScope, dialogService, mediaResource, gridService, imageHelper, $timeout) {
|
||||
|
||||
var emptyModel = {
|
||||
styles:[
|
||||
{
|
||||
label: "Set a background image",
|
||||
description: "Set a row background",
|
||||
key: "background-image",
|
||||
view: "imagepicker",
|
||||
modifier: "url({0})"
|
||||
}
|
||||
],
|
||||
|
||||
config:[
|
||||
{
|
||||
label: "Class",
|
||||
description: "Set a css class",
|
||||
key: "class",
|
||||
view: "textstring"
|
||||
}
|
||||
],
|
||||
|
||||
columns: 12,
|
||||
templates:[
|
||||
{
|
||||
@@ -160,10 +179,17 @@ angular.module("umbraco")
|
||||
delete $scope.currentArea;
|
||||
}else{
|
||||
if(area === undefined){
|
||||
var space = ($scope.availableLayoutSpace > 4) ? 4 : $scope.availableLayoutSpace;
|
||||
var available = $scope.availableLayoutSpace;
|
||||
var space = 4;
|
||||
|
||||
if(available < 4 && available > 0){
|
||||
space = available;
|
||||
}
|
||||
|
||||
area = {
|
||||
grid: space
|
||||
};
|
||||
|
||||
layout.areas.push(area);
|
||||
}
|
||||
$scope.currentArea = area;
|
||||
@@ -180,8 +206,12 @@ angular.module("umbraco")
|
||||
/****************
|
||||
utillities
|
||||
*****************/
|
||||
$scope.scaleUp = function(section, max){
|
||||
var add = (max > 1) ? 1 : max;
|
||||
$scope.scaleUp = function(section, max, overflow){
|
||||
var add = 1;
|
||||
if(overflow !== true){
|
||||
add = (max > 1) ? 1 : max;
|
||||
}
|
||||
//var add = (max > 1) ? 1 : max;
|
||||
section.grid = section.grid+add;
|
||||
};
|
||||
$scope.scaleDown = function(section){
|
||||
@@ -195,11 +225,42 @@ angular.module("umbraco")
|
||||
delete collection;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.percentage = function(spans){
|
||||
return ((spans / $scope.model.value.columns) * 100).toFixed(1);
|
||||
};
|
||||
|
||||
|
||||
$scope.removeConfigValue = function(collection, index){
|
||||
collection.splice(index, 1);
|
||||
};
|
||||
|
||||
|
||||
var editConfigCollection = function(configValues, title, callbackOnSave){
|
||||
dialogService.open(
|
||||
{
|
||||
template: "views/propertyeditors/grid/dialogs/editconfig.html",
|
||||
config: configValues,
|
||||
name: title,
|
||||
callback: function(data){
|
||||
callbackOnSave(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editConfig = function(){
|
||||
editConfigCollection($scope.model.value.config, "Settings", function(data){
|
||||
$scope.model.value.config = data;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editStyles = function(){
|
||||
editConfigCollection($scope.model.value.styles, "Styling", function(data){
|
||||
$scope.model.value.styles = data;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/****************
|
||||
watchers
|
||||
*****************/
|
||||
@@ -236,9 +297,19 @@ angular.module("umbraco")
|
||||
if (!$scope.model.value || $scope.model.value === "" || !$scope.model.value.templates) {
|
||||
$scope.model.value = emptyModel;
|
||||
} else {
|
||||
|
||||
if (!$scope.model.value.columns) {
|
||||
$scope.model.value.columns = emptyModel.columns;
|
||||
}
|
||||
|
||||
|
||||
if (!$scope.model.value.config) {
|
||||
$scope.model.value.config = [];
|
||||
}
|
||||
|
||||
if (!$scope.model.value.styles) {
|
||||
$scope.model.value.styles = [];
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.GridPrevalueEditorController" class="usky-grid usky-grid-configuration">
|
||||
|
||||
<div style="width: 600px">
|
||||
|
||||
<div class="control-group uSky-templates" ng-if="!currentTemplate">
|
||||
|
||||
<umb-control-group label="Grid layouts" description="Layouts are the overall work area for the grid editor, usually you only need one or two differnt layouts" hide-label="false">
|
||||
@@ -12,22 +11,22 @@
|
||||
|
||||
<li ng-repeat="template in model.value.templates">
|
||||
|
||||
<div class="uSky-templates-template" style="float: left">
|
||||
<a href class="tb" ng-click="configureTemplate(template)">
|
||||
<div class="tr">
|
||||
<div class="td uSky-templates-column"
|
||||
ng-class="{last:$last}"
|
||||
ng-repeat="section in template.sections"
|
||||
style="width:{{ percentage(section.grid) }}%">
|
||||
</div>
|
||||
<a class="uSky-templates-template tb mainTbpt" style="float: left"
|
||||
ng-click="configureTemplate(template)">
|
||||
<div class="tr">
|
||||
<div
|
||||
ng-style="{width: percentage(section.grid) + '%'}"
|
||||
class="mainTdpt td"
|
||||
ng-class="{last:$last}"
|
||||
ng-repeat="section in template.sections">
|
||||
<span style="height: 50px"></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<a ng-click="configureTemplate(template)" href>{{template.name}}</a><br />
|
||||
<small>{{template.sections.length}} layout areas</small><br />
|
||||
<small>{{template.sections.length}} sections</small><br />
|
||||
|
||||
<a class="btn btn-small btn-link" href ng-click="deleteTemplate($index)"><i class="icon-delete red"></i> Delete layout </a>
|
||||
</div>
|
||||
@@ -39,20 +38,21 @@
|
||||
<button class="btn btn-small"
|
||||
prevent-default
|
||||
ng-click="configureTemplate()">
|
||||
<i class="icon-add"></i>Add layout
|
||||
<i class="icon-add"></i>Add new layout
|
||||
</button>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-if="currentTemplate">
|
||||
<h5>Layout</h5>
|
||||
<umb-control-group label="Name" hide-label="false">
|
||||
<input type="text" class="" ng-model="currentTemplate.name" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="Sections" description="Choose an area in the layout to edit" hide-label="false">
|
||||
<umb-control-group label="Sections" description="Choose a section in the layout to edit" hide-label="false">
|
||||
<div class="uSky-templates-template"
|
||||
style="margin: 0; width: 350px; position: relative;">
|
||||
<div class="tb" style="height: 70px; border-width: 2px; padding: 2px">
|
||||
@@ -74,8 +74,7 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="currentSection" style="padding-bottom: 50px;">
|
||||
<h5>Modify layout area</h5>
|
||||
<umb-control-group label="Size" hide-label="false">
|
||||
<umb-control-group label="Width" hide-label="false">
|
||||
<div class="grid-size-scaler">
|
||||
<a href ng-click="scaleDown(currentSection)">
|
||||
<i class="icon icon-remove"></i>
|
||||
@@ -128,7 +127,7 @@
|
||||
|
||||
<div>
|
||||
{{layout.name}}<br />
|
||||
<small>{{layout.areas.length}} configurable columns</small><br />
|
||||
<small>{{layout.areas.length}} configurable sections</small><br />
|
||||
</div>
|
||||
|
||||
<br style="clear: both" />
|
||||
@@ -138,11 +137,11 @@
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
<button prevent-default ng-click="closeSection()" class="btn btn-small">Finish editing area</button>
|
||||
<button prevent-default ng-click="closeSection()" class="btn btn-small">Finish editing section</button>
|
||||
|
||||
<a class="btn btn-small btn-link"
|
||||
href
|
||||
ng-click="deleteSection($index)"><i class="icon-delete red"></i>Delete area</a>
|
||||
ng-click="deleteSection($index)"><i class="icon-delete red"></i>Delete section</a>
|
||||
</div>
|
||||
|
||||
</umb-control-group>
|
||||
@@ -163,10 +162,10 @@
|
||||
|
||||
<div style="max-width: 600px">
|
||||
|
||||
<div class="control-group uSky-templates" ng-if="!currentLayout">
|
||||
<div class="control-group uSky-templates" ng-if="!currentTemplate">
|
||||
<umb-control-group
|
||||
label="Row configurations"
|
||||
description="Rows are predefined columns of editors arranged horizontally"
|
||||
description="Rows are predefined cells arranged horizontally"
|
||||
hide-label="false">
|
||||
<div class="control-group uSky-templates-rows">
|
||||
|
||||
@@ -176,19 +175,24 @@
|
||||
|
||||
<li ng-repeat="layout in model.value.layouts">
|
||||
|
||||
<div class="uSky-templates-row" style="float: left">
|
||||
<a href class="tb mainTbpt" ng-click="configureLayout(layout)">
|
||||
<div class="tr">
|
||||
<div style="width:{{ percentage(area.grid); }}%" class="middle mainTdpt td" ng-repeat="area in layout.areas">
|
||||
<i class="icon {{areaPreview(area)}}"></i>
|
||||
</div>
|
||||
<a class="uSky-templates-template tb mainTbpt" style="float: left"
|
||||
ng-click="configureLayout(layout)">
|
||||
<div class="tr">
|
||||
<div
|
||||
ng-style="{width: percentage(area.grid) + '%'}"
|
||||
class="mainTdpt td"
|
||||
ng-class="{last:$last}"
|
||||
ng-repeat="area in layout.areas">
|
||||
<span style="height: 20px"></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<a ng-click="configureLayout(layout)" href>{{layout.name}}</a><br />
|
||||
<small>{{layout.areas.length}} columns</small><br />
|
||||
<small>{{layout.areas.length}} cells</small><br />
|
||||
<a class="btn btn-small btn-link" href ng-click="deleteLayout($index)"><i class="icon-delete red"></i> Delete row </a>
|
||||
</div>
|
||||
|
||||
@@ -214,11 +218,14 @@
|
||||
<input type="text" class="" ng-model="currentLayout.name" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="Layout areas" hide-label="false" description="Choose column from the row to edit">
|
||||
<umb-control-group label="Layout areas" hide-label="false" description="Choose a cell from the row to edit">
|
||||
|
||||
<div class="uSky-templates-template"
|
||||
style="margin: 0; width: 350px; position: relative;">
|
||||
<div class="tb" style="height: 70px; border-width: 2px; padding: 2px">
|
||||
|
||||
<div class="tb" style="height: auto; border: none !important; background: none">
|
||||
<div class="tr">
|
||||
|
||||
<a class="td uSky-templates-column"
|
||||
ng-class="{last:$last, selected:area==currentArea}"
|
||||
ng-repeat="area in currentLayout.areas"
|
||||
@@ -226,7 +233,7 @@
|
||||
style="width:{{ percentage(area.grid) }}%">
|
||||
</a>
|
||||
|
||||
<a class="td uSky-templates-column add" ng-if="availableLayoutSpace > 0"
|
||||
<a class="td uSky-templates-column add"
|
||||
ng-click="configureArea(undefined, currentLayout)"
|
||||
style="width:{{ percentage(availableLayoutSpace) }}%">
|
||||
<i class="icon icon-add"></i>
|
||||
@@ -236,23 +243,19 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="currentArea" style="padding-bottom: 50px;">
|
||||
<h5>Modify column</h5>
|
||||
<umb-control-group label="Size" hide-label="false">
|
||||
<umb-control-group label="Width" hide-label="false">
|
||||
<div class="grid-size-scaler">
|
||||
<a href ng-click="scaleDown(currentArea)">
|
||||
<i class="icon icon-remove"></i>
|
||||
</a>
|
||||
|
||||
{{currentArea.grid}}
|
||||
|
||||
<a href ng-click="scaleUp(currentArea, availableLayoutSpace)">
|
||||
<a href ng-click="scaleUp(currentArea, availableLayoutSpace, true)">
|
||||
<i class="icon icon-add"></i>
|
||||
</a>
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group hide-label="true">
|
||||
|
||||
<ul class="unstyled">
|
||||
<li>
|
||||
<label>
|
||||
@@ -280,25 +283,80 @@
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
<button prevent-default ng-click="closeArea()" class="btn btn-small">Finish editing column</button>
|
||||
<button prevent-default ng-click="closeArea()" class="btn btn-small">Finish editing cell</button>
|
||||
|
||||
<a class="btn btn-small btn-link"
|
||||
href
|
||||
ng-click="deleteArea($index)"><i class="icon-delete red"></i> Delete column </a>
|
||||
ng-click="deleteArea($index)"><i class="icon-delete red"></i> Delete cell </a>
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
|
||||
<umb-control-group hide-label="false" ng-if="!currentArea">
|
||||
<button prevent-default ng-click="closeLayout()" class="btn btn-small">Finish editing row</button>
|
||||
</umb-control-group>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="max-width: 600px">
|
||||
<div style="max-width: 600px" ng-if="!currentTemplate && !currentLayout">
|
||||
|
||||
<umb-control-group label="Columns" hide-label="false" description="Total combined number of columns in the grid layout">
|
||||
<input type="text" class="" ng-model="model.value.columns" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="Settings" hide-label="false" description="Configure what settings editors can change">
|
||||
<ul class="unstyled list-icons umb-contentpicker"
|
||||
ui-sortable
|
||||
ng-model="model.config">
|
||||
|
||||
<li ng-repeat="configValue in model.value.config">
|
||||
<i class="icon icon-navigation handle"></i>
|
||||
|
||||
<a href="#" prevent-default ng-click="removeConfigValue(model.value.config, $index)">
|
||||
<i class="icon icon-delete red hover-show"></i>
|
||||
<i class="icon-settings-alt-2 hover-hide"></i>
|
||||
{{configValue.label}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="unstyled list-icons">
|
||||
<li>
|
||||
<i class="icon icon-add blue"></i>
|
||||
<a href="#" ng-click="editConfig()" prevent-default>
|
||||
Edit settings
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
|
||||
<umb-control-group label="Styles" hide-label="false" description="Configure what styling editors can change">
|
||||
<ul class="unstyled list-icons umb-contentpicker"
|
||||
ui-sortable
|
||||
ng-model="model.value.styles">
|
||||
|
||||
<li ng-repeat="style in model.value.styles">
|
||||
<i class="icon icon-navigation handle"></i>
|
||||
|
||||
<a href="#" prevent-default ng-click="removeConfigValue(model.value.styles, $index)">
|
||||
<i class="icon icon-delete red hover-show"></i>
|
||||
<i class="icon-brush hover-hide"></i>
|
||||
{{style.label}}
|
||||
</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="unstyled list-icons">
|
||||
<li>
|
||||
<i class="icon icon-add blue"></i>
|
||||
<a href="#" ng-click="editStyles()" prevent-default>
|
||||
Edit style configuration
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</umb-control-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48,7 +48,7 @@ describe('edit content controller tests', function () {
|
||||
});
|
||||
|
||||
it('it should have a tabs collection', function () {
|
||||
expect(scope.content.tabs.length).toBe(9);
|
||||
expect(scope.content.tabs.length).toBe(7);
|
||||
});
|
||||
|
||||
it('it should have a properties collection on each tab', function () {
|
||||
|
||||
@@ -229,7 +229,7 @@ describe('contentEditingHelper tests', function () {
|
||||
|
||||
//assert
|
||||
expect(changed.length).toBe(2);
|
||||
expect(changed[0].alias).toBe("list");
|
||||
expect(changed[0].alias).toBe("grid");
|
||||
expect(changed[1].alias).toBe("bodyText");
|
||||
});
|
||||
|
||||
|
||||
@@ -1,47 +1,78 @@
|
||||
@inherits UmbracoViewPage<dynamic>
|
||||
@using Umbraco.Web.Templates
|
||||
@using Newtonsoft.Json.Linq;
|
||||
@using Newtonsoft.Json.Linq
|
||||
|
||||
@functions {
|
||||
public static MvcHtmlString RenderElementAttributes(dynamic contentItem)
|
||||
{
|
||||
var attrs = new List<string>();
|
||||
JObject cfg = contentItem.config;
|
||||
|
||||
if(cfg != null)
|
||||
foreach (JProperty property in cfg.Properties())
|
||||
attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
|
||||
|
||||
JObject style = contentItem.styles;
|
||||
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
|
||||
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
|
||||
}
|
||||
|
||||
return new MvcHtmlString(string.Join(" ", attrs));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@if (Model != null && !string.IsNullOrEmpty(Model.ToString()))
|
||||
{
|
||||
var onlyOneColumn = Model.sections != null ? ((System.Collections.ICollection)Model.sections).Count : 0;
|
||||
|
||||
<div class="uSky-grid @(onlyOneColumn > 1 ? "container-fluid" : "")">
|
||||
<div class="row-fluid clearfix">
|
||||
@foreach (var s in Model.sections)
|
||||
{
|
||||
<div class="@("span" + s.grid)">
|
||||
@foreach (var row in s.rows)
|
||||
{
|
||||
<div class="gridrow_@row.uniqueId" >
|
||||
<div>
|
||||
<div class="row-fluid clearfix">
|
||||
<div class="uSky-grid @(onlyOneColumn > 1 ? "container-fluid" : "")">
|
||||
<div class="row-fluid clearfix">
|
||||
|
||||
@foreach (var area in row.areas)
|
||||
{
|
||||
<div class="@("span" + area.grid)">
|
||||
@foreach (var s in Model.sections){
|
||||
<div class="@("span" + s.grid) column"> <!-- section -->
|
||||
<div class="grid-section">
|
||||
<div @RenderElementAttributes(s)>
|
||||
<div class="@(onlyOneColumn == 1 ? "container-fluid" : "")"><!-- remove container class -->
|
||||
|
||||
<!-- foreach row in section -->
|
||||
@foreach (var row in s.rows){
|
||||
<div class="row-fluid clearfix">
|
||||
<div class="grid-row grid-row-@row.uniqueId">
|
||||
<div @RenderElementAttributes(row)>
|
||||
@foreach (var area in row.areas){
|
||||
<div class="@("span" + area.grid) column">
|
||||
<div class="grid-cell">
|
||||
<div @RenderElementAttributes(area)>
|
||||
|
||||
@foreach (var control in area.controls)
|
||||
{
|
||||
if (control != null && control.editor != null && control.editor.view != null)
|
||||
{
|
||||
|
||||
string editor = "grid/editors/" + control.editor.view.ToString();
|
||||
<text>
|
||||
@Html.Partial(editor, (object)control)
|
||||
</text>
|
||||
@foreach (var control in area.controls){
|
||||
if (control != null && control.editor != null && control.editor.view != null){
|
||||
string editor = "grid/editors/" + control.editor.view.ToString();
|
||||
<text>@Html.Partial(editor, (object)control)</text>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -1,45 +1,78 @@
|
||||
@inherits UmbracoViewPage<dynamic>
|
||||
@using Umbraco.Web.Templates
|
||||
@using Newtonsoft.Json.Linq
|
||||
|
||||
@functions {
|
||||
public static MvcHtmlString RenderElementAttributes(dynamic contentItem)
|
||||
{
|
||||
var attrs = new List<string>();
|
||||
JObject cfg = contentItem.config;
|
||||
|
||||
if(cfg != null)
|
||||
foreach (JProperty property in cfg.Properties())
|
||||
attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
|
||||
|
||||
JObject style = contentItem.styles;
|
||||
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
|
||||
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
|
||||
}
|
||||
|
||||
return new MvcHtmlString(string.Join(" ", attrs));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@if (Model != null && !string.IsNullOrEmpty(Model.ToString()))
|
||||
{
|
||||
var onlyOneColumn = Model.sections != null ? ((System.Collections.ICollection)Model.sections).Count : 0;
|
||||
|
||||
<div class="uSky-grid @(onlyOneColumn > 1 ? "container" : "")">
|
||||
<div class="row clearfix">
|
||||
@foreach (var s in Model.sections)
|
||||
{
|
||||
<div class="col-md-@s.grid column">
|
||||
@foreach (var row in s.rows)
|
||||
{
|
||||
<div class="gridrow_@row.uniqueId" >
|
||||
<div class="container">
|
||||
<div class="row clearfix">
|
||||
<div class="uSky-grid @(onlyOneColumn > 1 ? "container" : "")">
|
||||
<div class="row clearfix">
|
||||
|
||||
@foreach (var area in row.areas)
|
||||
{
|
||||
<div class="col-md-@area.grid column">
|
||||
@foreach (var s in Model.sections){
|
||||
<div class="col-md-@s.grid column"> <!-- section -->
|
||||
<div class="grid-section">
|
||||
<div @RenderElementAttributes(s)>
|
||||
<div class="@(onlyOneColumn == 1 ? "container" : "")"><!-- remove container class -->
|
||||
|
||||
<!-- foreach row in section -->
|
||||
@foreach (var row in s.rows){
|
||||
<div class="row clearfix">
|
||||
<div class="grid-row grid-row-@row.uniqueId">
|
||||
<div @RenderElementAttributes(row)>
|
||||
@foreach (var area in row.areas){
|
||||
<div class="col-md-@area.grid column">
|
||||
<div class="grid-cell">
|
||||
<div @RenderElementAttributes(area)>
|
||||
|
||||
@foreach (var control in area.controls)
|
||||
{
|
||||
if (control != null && control.editor != null && control.editor.view != null)
|
||||
{
|
||||
|
||||
string editor = "grid/editors/" + control.editor.view.ToString();
|
||||
<text>
|
||||
@Html.Partial(editor, (object)control)
|
||||
</text>
|
||||
@foreach (var control in area.controls){
|
||||
if (control != null && control.editor != null && control.editor.view != null){
|
||||
string editor = "grid/editors/" + control.editor.view.ToString();
|
||||
<text>@Html.Partial(editor, (object)control)</text>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -4,12 +4,12 @@ using System.Web.Mvc;
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Redirects to the current URL rendering an Umbraco page
|
||||
/// Redirects to the current URL rendering an Umbraco page including it's query strings
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// this is useful if you need to redirect
|
||||
/// This is useful if you need to redirect
|
||||
/// to the current page but the current page is actually a rewritten URL normally done with something like
|
||||
/// Server.Transfer.
|
||||
/// Server.Transfer. It is also handy if you want to persist the query strings.
|
||||
/// </remarks>
|
||||
public class RedirectToUmbracoUrlResult : ActionResult
|
||||
{
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
/// <param name="requestContext"></param>
|
||||
/// <returns></returns>
|
||||
private static PostedDataProxyInfo GetFormInfo(RequestContext requestContext)
|
||||
internal static PostedDataProxyInfo GetFormInfo(RequestContext requestContext)
|
||||
{
|
||||
if (requestContext == null) throw new ArgumentNullException("requestContext");
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
/// <param name="requestContext"></param>
|
||||
/// <param name="postedInfo"></param>
|
||||
private IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo)
|
||||
internal static IHttpHandler HandlePostedValues(RequestContext requestContext, PostedDataProxyInfo postedInfo)
|
||||
{
|
||||
if (requestContext == null) throw new ArgumentNullException("requestContext");
|
||||
if (postedInfo == null) throw new ArgumentNullException("postedInfo");
|
||||
|
||||
@@ -34,6 +34,25 @@ namespace Umbraco.Web.Mvc
|
||||
requestContext.RouteData.DataTokens.Add("umbraco", renderModel);
|
||||
requestContext.RouteData.DataTokens.Add("umbraco-doc-request", umbracoContext.PublishedContentRequest);
|
||||
requestContext.RouteData.DataTokens.Add("umbraco-context", umbracoContext);
|
||||
//this is used just for a flag that this is an umbraco custom route
|
||||
requestContext.RouteData.DataTokens.Add("umbraco-custom-route", true);
|
||||
|
||||
//Here we need to detect if a SurfaceController has posted
|
||||
var formInfo = RenderRouteHandler.GetFormInfo(requestContext);
|
||||
if (formInfo != null)
|
||||
{
|
||||
var def = new RouteDefinition
|
||||
{
|
||||
ActionName = requestContext.RouteData.GetRequiredString("action"),
|
||||
ControllerName = requestContext.RouteData.GetRequiredString("controller"),
|
||||
PublishedContentRequest = umbracoContext.PublishedContentRequest
|
||||
};
|
||||
|
||||
//set the special data token to the current route definition
|
||||
requestContext.RouteData.DataTokens["umbraco-route-def"] = def;
|
||||
|
||||
return RenderRouteHandler.HandlePostedValues(requestContext, formInfo);
|
||||
}
|
||||
|
||||
return new MvcHandler(requestContext);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// This url provider is used purely to deal with umbraco custom routes that utilize UmbracoVirtualNodeRouteHandler and will return
|
||||
/// the URL returned from the current PublishedContentRequest.PublishedContent (virtual node) if the request is in fact a virtual route and
|
||||
/// the id that is being requested matches the id of the current PublishedContentRequest.PublishedContent.
|
||||
/// </summary>
|
||||
internal class CustomRouteUrlProvider : IUrlProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// This will simply return the URL that is returned by the assigned IPublishedContent if this is a custom route
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="current"></param>
|
||||
/// <param name="mode"></param>
|
||||
/// <returns></returns>
|
||||
public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode)
|
||||
{
|
||||
if (umbracoContext == null) return null;
|
||||
if (umbracoContext.PublishedContentRequest == null) return null;
|
||||
if (umbracoContext.PublishedContentRequest.PublishedContent == null) return null;
|
||||
if (umbracoContext.HttpContext == null) return null;
|
||||
if (umbracoContext.HttpContext.Request == null) return null;
|
||||
if (umbracoContext.HttpContext.Request.RequestContext == null) return null;
|
||||
if (umbracoContext.HttpContext.Request.RequestContext.RouteData == null) return null;
|
||||
if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens == null) return null;
|
||||
if (umbracoContext.HttpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey("umbraco-custom-route") == false) return null;
|
||||
//ok so it's a custom route with published content assigned, check if the id being requested for is the same id as the assigned published content
|
||||
return id == umbracoContext.PublishedContentRequest.PublishedContent.Id
|
||||
? umbracoContext.PublishedContentRequest.PublishedContent.Url
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This always returns null because this url provider is used purely to deal with Umbraco custom routes with
|
||||
/// UmbracoVirtualNodeRouteHandler, we really only care about the normal URL so that RedirectToCurrentUmbracoPage() works
|
||||
/// with SurfaceControllers
|
||||
/// </summary>
|
||||
/// <param name="umbracoContext"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="current"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
if (mode == UrlProviderMode.Auto)
|
||||
{
|
||||
if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority))
|
||||
if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority))
|
||||
mode = UrlProviderMode.Relative;
|
||||
else
|
||||
mode = UrlProviderMode.Absolute;
|
||||
|
||||
@@ -14,18 +14,25 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl();
|
||||
|
||||
var url = string.Format("{0}/ping.aspx", umbracoBaseUrl);
|
||||
|
||||
try
|
||||
if (string.IsNullOrWhiteSpace(umbracoBaseUrl))
|
||||
{
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
wc.DownloadString(url);
|
||||
}
|
||||
LogHelper.Warn<KeepAlive>("No url for service (yet), skip.");
|
||||
}
|
||||
catch (Exception ee)
|
||||
else
|
||||
{
|
||||
LogHelper.Error<KeepAlive>("Error in ping", ee);
|
||||
var url = string.Format("{0}/ping.aspx", umbracoBaseUrl);
|
||||
|
||||
try
|
||||
{
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
wc.DownloadString(url);
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
LogHelper.Error<KeepAlive>("Error in ping", ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,21 @@ namespace Umbraco.Web.Scheduling
|
||||
try
|
||||
{
|
||||
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl();
|
||||
var url = string.Format("{0}/RestServices/ScheduledPublish/Index", umbracoBaseUrl);
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
//pass custom the authorization header
|
||||
wc.Headers.Set("Authorization", AdminTokenAuthorizeAttribute.GetAuthHeaderTokenVal(appContext));
|
||||
|
||||
var result = wc.UploadString(url, "");
|
||||
if (string.IsNullOrWhiteSpace(umbracoBaseUrl))
|
||||
{
|
||||
LogHelper.Warn<ScheduledPublishing>("No url for service (yet), skip.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var url = string.Format("{0}/RestServices/ScheduledPublish/Index", umbracoBaseUrl);
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
//pass custom the authorization header
|
||||
wc.Headers.Set("Authorization", AdminTokenAuthorizeAttribute.GetAuthHeaderTokenVal(appContext));
|
||||
|
||||
var result = wc.UploadString(url, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
|
||||
@@ -172,11 +172,14 @@ namespace Umbraco.Web.Security
|
||||
if (status != MembershipCreateStatus.Success) return null;
|
||||
}
|
||||
|
||||
//Set member online
|
||||
provider.GetUser(model.Username, true);
|
||||
|
||||
//Log them in
|
||||
FormsAuthentication.SetAuthCookie(membershipUser.UserName, model.CreatePersistentLoginCookie);
|
||||
if (logMemberIn)
|
||||
{
|
||||
//Set member online
|
||||
provider.GetUser(model.Username, true);
|
||||
|
||||
//Log them in
|
||||
FormsAuthentication.SetAuthCookie(membershipUser.UserName, model.CreatePersistentLoginCookie);
|
||||
}
|
||||
|
||||
return membershipUser;
|
||||
}
|
||||
|
||||
@@ -492,6 +492,7 @@
|
||||
<Compile Include="PublishedContentQuery.cs" />
|
||||
<Compile Include="ImageCropperTemplateExtensions.cs" />
|
||||
<Compile Include="Mvc\UmbracoVirtualNodeRouteHandler.cs" />
|
||||
<Compile Include="Routing\CustomRouteUrlProvider.cs" />
|
||||
<Compile Include="Routing\UrlProviderExtensions.cs" />
|
||||
<Compile Include="Strategies\Migrations\ClearCsrfCookiesAfterUpgrade.cs" />
|
||||
<Compile Include="Strategies\Migrations\ClearMediaXmlCacheForDeletedItemsAfterUpgrade.cs" />
|
||||
|
||||
@@ -352,8 +352,9 @@ namespace Umbraco.Web
|
||||
});
|
||||
|
||||
UrlProviderResolver.Current = new UrlProviderResolver(
|
||||
//typeof(AliasUrlProvider), // not enabled by default
|
||||
typeof(DefaultUrlProvider)
|
||||
//typeof(AliasUrlProvider), // not enabled by default
|
||||
typeof(DefaultUrlProvider),
|
||||
typeof(CustomRouteUrlProvider)
|
||||
);
|
||||
|
||||
ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver(
|
||||
|
||||
Reference in New Issue
Block a user