Compare commits

..

1 Commits

Author SHA1 Message Date
Anders Bjerner e8b320d7b4 Introduced properties overlay 2018-12-23 02:13:57 +01:00
139 changed files with 892 additions and 2468 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/dev-v8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
# Contributing to Umbraco CMS
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
@@ -16,7 +16,7 @@ This document gives you a quick overview on how to get started, we will link to
## Guidelines for contributions we welcome
Not all changes are wanted, so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valuable time.
Not all changes are wanted, so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valueable time.
We have [documented what we consider small and large changes](CONTRIBUTION_GUIDELINES.md). Make sure to talk to us before making large changes.
-1
View File
@@ -1,5 +1,4 @@
[![Build status](https://ci.appveyor.com/api/projects/status/6by6harxtxt0ocdx/branch/dev-v7?svg=true)](https://ci.appveyor.com/project/Umbraco/umbraco-cms-b2cri/branch/dev-v7)
[![pullreminders](https://pullreminders.com/badge.svg)](https://pullreminders.com?ref=badge)
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/tree/temp8) to go to the v8 branch_
+20 -20
View File
@@ -3,57 +3,57 @@
[string]$Directory
)
$workingDirectory = $Directory
CD "$($workingDirectory)"
CD $workingDirectory
# Clone repo
$fullGitUrl = "https://$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
git clone $($fullGitUrl) $($env:GIT_REPOSITORYNAME) 2>&1 | % { $_.ToString() }
$fullGitUrl = "https://$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
git clone $fullGitUrl 2>&1 | % { $_.ToString() }
# Remove everything so that unzipping the release later will update everything
# Don't remove the readme file nor the git directory
Write-Host "Cleaning up git directory before adding new version"
Remove-Item -Recurse "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)\*" -Exclude README.md,.git
Remove-Item -Recurse $workingDirectory\$env:GIT_REPOSITORYNAME\* -Exclude README.md,.git
# Find release zip
$zipsDir = "$($workingDirectory)\$($env:BUILD_DEFINITIONNAME)\zips"
$zipsDir = "$workingDirectory\$env:BUILD_DEFINITIONNAME\zips"
$pattern = "UmbracoCms.([0-9]{1,2}.[0-9]{1,3}.[0-9]{1,3}).zip"
Write-Host "Searching for Umbraco release files in $($zipsDir) for a file with pattern $($pattern)"
$file = (Get-ChildItem "$($zipsDir)" | Where-Object { $_.Name -match "$($pattern)" })
Write-Host "Searching for Umbraco release files in $workingDirectory\$zipsDir for a file with pattern $pattern"
$file = (Get-ChildItem $zipsDir | Where-Object { $_.Name -match "$pattern" })
if($file)
{
# Get release name
$version = [regex]::Match($($file.Name), $($pattern)).captures.groups[1].value
$releaseName = "Umbraco $($version)"
Write-Host "Found $($releaseName)"
$version = [regex]::Match($file.Name, $pattern).captures.groups[1].value
$releaseName = "Umbraco $version"
Write-Host "Found $releaseName"
# Unzip into repository to update release
Add-Type -AssemblyName System.IO.Compression.FileSystem
Write-Host "Unzipping $($file.FullName) to $($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
[System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)")
Write-Host "Unzipping $($file.FullName) to $workingDirectory\$env:GIT_REPOSITORYNAME"
[System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$workingDirectory\$env:GIT_REPOSITORYNAME")
# Telling git who we are
git config --global user.email "coffee@umbraco.com" 2>&1 | % { $_.ToString() }
git config --global user.name "Umbraco HQ" 2>&1 | % { $_.ToString() }
# Commit
CD "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
Write-Host "Committing Umbraco $($version) Release from Build Output"
CD $env:GIT_REPOSITORYNAME
Write-Host "Committing Umbraco $version Release from Build Output"
git add . 2>&1 | % { $_.ToString() }
git commit -m " Release $($releaseName) from Build Output" 2>&1 | % { $_.ToString() }
git commit -m " Release $releaseName from Build Output" 2>&1 | % { $_.ToString() }
# Tag the release
git tag -a "v$($version)" -m "v$($version)"
git tag -a "v$version" -m "v$version"
# Push release to master
$fullGitAuthUrl = "https://$($env:GIT_USERNAME):$($GitHubPersonalAccessToken)@$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
git push $($fullGitAuthUrl) 2>&1 | % { $_.ToString() }
$fullGitAuthUrl = "https://$($env:GIT_USERNAME):$GitHubPersonalAccessToken@$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
git push $fullGitAuthUrl 2>&1 | % { $_.ToString() }
#Push tag to master
git push $($fullGitAuthUrl) --tags 2>&1 | % { $_.ToString() }
git push $fullGitAuthUrl --tags 2>&1 | % { $_.ToString() }
}
else
{
Write-Error "Umbraco release file not found, searched in $($workingDirectory)\$($zipsDir) for a file with pattern $($pattern) - canceling"
Write-Error "Umbraco release file not found, searched in $workingDirectory\$zipsDir for a file with pattern $pattern - cancelling"
}
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.14.0")]
[assembly: AssemblyInformationalVersion("7.14.0")]
[assembly: AssemblyFileVersion("7.13.0")]
[assembly: AssemblyInformationalVersion("7.13.0")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.14.0");
private static readonly Version Version = new Version("7.13.0");
/// <summary>
/// Gets the current version of Umbraco.
@@ -447,11 +447,6 @@ namespace Umbraco.Core
/// </summary>
public const string NestedContentAlias = "Umbraco.NestedContent";
/// <summary>
/// Alias for the multi url picker editor.
/// </summary>
public const string MultiUrlPickerAlias = "Umbraco.MultiUrlPicker";
public static class PreValueKeys
{
/// <summary>
+2 -11
View File
@@ -1,6 +1,4 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
@@ -295,12 +293,6 @@ namespace Umbraco.Core.IO
{
var property = GetProperty(content, propertyTypeAlias);
var svalue = property.Value as string;
if (svalue != null && svalue.DetectIsJson())
{
// the property value is a JSON serialized image crop data set - grab the "src" property as the file source
var jObject = JsonConvert.DeserializeObject<JObject>(svalue);
svalue = jObject != null ? jObject.GetValueAsString("src") : svalue;
}
var oldpath = svalue == null ? null : GetRelativePath(svalue);
var filepath = StoreFile(content, property.PropertyType, filename, filestream, oldpath);
property.Value = GetUrl(filepath);
@@ -365,8 +357,7 @@ namespace Umbraco.Core.IO
{
var jpgInfo = ImageFile.FromStream(stream);
if (jpgInfo != null
&& jpgInfo.Format != ImageFileFormat.Unknown
if (jpgInfo.Format != ImageFileFormat.Unknown
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelYDimension)
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelXDimension))
{
+4 -5
View File
@@ -118,9 +118,9 @@ namespace Umbraco.Core.Media.Exif
/// <param name="encoding">The encoding to be used for text metadata when the source encoding is unknown.</param>
/// <returns>The <see cref="ImageFile"/> created from the file.</returns>
public static ImageFile FromStream(Stream stream, Encoding encoding)
{
{
// JPEG
if (JPEGDetector.IsOfType(stream))
if(JPEGDetector.IsOfType(stream))
{
return new JPEGFile(stream, encoding);
}
@@ -137,9 +137,8 @@ namespace Umbraco.Core.Media.Exif
return new SVGFile(stream);
}
// We don't know
return null;
}
throw new NotValidImageFileException ();
}
#endregion
}
}
@@ -7,7 +7,8 @@ namespace Umbraco.Core.Media.TypeDetector
public static bool IsOfType(Stream fileStream)
{
var header = GetFileHeader(fileStream);
return header != null && header[0] == 0xff && header[1] == 0xD8;
return header[0] == 0xff && header[1] == 0xD8;
}
}
}
@@ -7,13 +7,9 @@ namespace Umbraco.Core.Media.TypeDetector
public static byte[] GetFileHeader(Stream fileStream)
{
fileStream.Seek(0, SeekOrigin.Begin);
var header = new byte[8];
byte[] header = new byte[8];
fileStream.Seek(0, SeekOrigin.Begin);
// Invalid header
if (fileStream.Read(header, 0, header.Length) != header.Length)
return null;
return header;
}
}
@@ -7,17 +7,17 @@ namespace Umbraco.Core.Media.TypeDetector
{
public static bool IsOfType(Stream fileStream)
{
var tiffHeader = GetFileHeader(fileStream);
return tiffHeader != null && tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
string tiffHeader = GetFileHeader(fileStream);
return tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
}
public static string GetFileHeader(Stream fileStream)
{
var header = RasterizedTypeDetector.GetFileHeader(fileStream);
if (header == null)
return null;
var tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
string tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
return tiffHeader;
}
}
@@ -25,8 +25,6 @@ namespace Umbraco.Core.Models.PublishedContent
{
Id = contentType.Id;
Alias = contentType.Alias;
Name = contentType.Name;
Description = contentType.Description;
_compositionAliases = new HashSet<string>(contentType.CompositionAliases(), StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = contentType.CompositionPropertyTypes
.Select(x => new PublishedPropertyType(this, x))
@@ -35,12 +33,10 @@ namespace Umbraco.Core.Models.PublishedContent
}
// internal so it can be used for unit tests
internal PublishedContentType(int id, string alias, string name, string description, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
internal PublishedContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
{
Id = id;
Alias = alias;
Name = name;
Description = description;
_compositionAliases = new HashSet<string>(compositionAliases, StringComparer.InvariantCultureIgnoreCase);
_propertyTypes = propertyTypes.ToArray();
foreach (var propertyType in _propertyTypes)
@@ -50,7 +46,7 @@ namespace Umbraco.Core.Models.PublishedContent
// create detached content type - ie does not match anything in the DB
internal PublishedContentType(string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: this(0, alias, string.Empty, string.Empty, compositionAliases, propertyTypes)
: this(0, alias, compositionAliases, propertyTypes)
{ }
private void InitializeIndexes()
@@ -67,8 +63,6 @@ namespace Umbraco.Core.Models.PublishedContent
public int Id { get; private set; }
public string Alias { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public HashSet<string> CompositionAliases { get { return _compositionAliases; } }
#endregion
@@ -1,36 +0,0 @@
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourteenZero
{
/// <summary>
/// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268.
/// </summary>
[Migration("7.14.0", 1, Constants.System.UmbracoMigrationName)]
public class UpdateMemberGroupPickerData : MigrationBase
{
public UpdateMemberGroupPickerData(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
{
}
public override void Up()
{
// move the data for all member group properties from the NVarchar to the NText column and clear the NVarchar column
Execute.Sql($@"UPDATE cmsPropertyData SET dataNtext = dataNvarchar, dataNvarchar = NULL
WHERE dataNtext IS NULL AND id IN (
SELECT id FROM cmsPropertyData WHERE propertyTypeId in (
SELECT id from cmsPropertyType where dataTypeID IN (
SELECT nodeId FROM cmsDataType WHERE propertyEditorAlias = '{Constants.PropertyEditors.MemberGroupPickerAlias}'
)
)
)");
// ensure that all exising member group properties are defined as NText
Execute.Sql($"UPDATE cmsDataType SET dbType = 'Ntext' WHERE propertyEditorAlias = '{Constants.PropertyEditors.MemberGroupPickerAlias}'");
}
public override void Down()
{
}
}
}
@@ -53,12 +53,6 @@ namespace Umbraco.Core.PropertyEditors
nestedContentEditorFromPackage.Name = "(Obsolete) " + nestedContentEditorFromPackage.Name;
nestedContentEditorFromPackage.IsDeprecated = true;
}
var multiUrlPickerEditorFromPackage = editors.FirstOrDefault(x => x.Alias == "RJP.MultiUrlPicker");
if (multiUrlPickerEditorFromPackage != null)
{
multiUrlPickerEditorFromPackage.Name = "(Obsolete) " + multiUrlPickerEditorFromPackage.Name;
multiUrlPickerEditorFromPackage.IsDeprecated = true;
}
return editors;
}
@@ -42,22 +42,16 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var sourceAsString = source?.ToString();
if(sourceAsString.IsNullOrWhiteSpace())
{
return new string[0];
}
// if Json storage type deserialzie and return as string array
if (JsonStorageType(propertyType.DataTypeId))
{
var jArray = JsonConvert.DeserializeObject<JArray>(sourceAsString);
var jArray = JsonConvert.DeserializeObject<JArray>(source.ToString());
return jArray.ToObject<string[]>();
}
// Otherwise assume CSV storage type and return as string array
var csvTags =
sourceAsString
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
@@ -107,11 +107,6 @@ namespace Umbraco.Core.Security
await EnsureValidSessionId(context);
if (context?.Identity == null)
{
context?.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
return;
}
await base.ValidateIdentity(context);
}
+1 -1
View File
@@ -509,7 +509,7 @@ namespace Umbraco.Core.Services
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter, null);
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter, null);
}
/// <summary>
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
@@ -70,11 +69,6 @@ namespace Umbraco.Core.Services
public void Save(IMemberGroup memberGroup, bool raiseEvents = true)
{
if (string.IsNullOrWhiteSpace(memberGroup.Name))
{
throw new InvalidOperationException("The name of a MemberGroup can not be empty");
}
using (var uow = UowProvider.GetUnitOfWork())
{
var saveEventArgs = new SaveEventArgs<IMemberGroup>(memberGroup);
@@ -139,4 +133,4 @@ namespace Umbraco.Core.Services
/// </remarks>
public static event TypedEventHandler<IMemberGroupService, SaveEventArgs<IMemberGroup>> Saved;
}
}
}
+2 -3
View File
@@ -189,6 +189,7 @@ namespace Umbraco.Core
outputArray[i] = char.IsLetterOrDigit(inputArray[i]) ? inputArray[i] : replacement;
return new string(outputArray);
}
private static readonly char[] CleanForXssChars = "*?(){}[];:%<>/\\|&'\"".ToCharArray();
/// <summary>
@@ -541,7 +542,7 @@ namespace Umbraco.Core
public static string StripHtml(this string text)
{
const string pattern = @"<(.|\n)*?>";
return Regex.Replace(text, pattern, string.Empty);
return Regex.Replace(text, pattern, String.Empty);
}
/// <summary>
@@ -731,7 +732,6 @@ namespace Umbraco.Core
/// </summary>
/// <param name="stringToConvert">Referrs to itself</param>
/// <returns>The MD5 hashed string</returns>
[Obsolete("Please use the GenerateHash method instead. This may be removed in future versions")]
public static string ToMd5(this string stringToConvert)
{
return stringToConvert.GenerateHash("MD5");
@@ -742,7 +742,6 @@ namespace Umbraco.Core
/// </summary>
/// <param name="stringToConvert">referrs to itself</param>
/// <returns>The SHA1 hashed string</returns>
[Obsolete("Please use the GenerateHash method instead. This may be removed in future versions")]
public static string ToSHA1(this string stringToConvert)
{
return stringToConvert.GenerateHash("SHA1");
-1
View File
@@ -572,7 +572,6 @@
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddInstructionCountColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddCmsMediaTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddUserLoginTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFourteenZero\UpdateMemberGroupPickerData.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwelveZero\RenameTrueFalseField.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenTwelveZero\SetDefaultTagsStorageType.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenNineZero\AddUmbracoAuditTable.cs" />
@@ -83,7 +83,7 @@ namespace Umbraco.Tests.CodeFirst
new PublishedPropertyType("articleDate", 0, "?"),
new PublishedPropertyType("pageTitle", 0, "?"),
};
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", propertyTypes);
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
Debug.Print("INIT STRONG {0}",
PublishedContentType.Get(PublishedItemType.Content, "anything")
@@ -148,4 +148,4 @@ namespace Umbraco.Tests.CodeFirst
}
#endregion
}
}
}
+1 -1
View File
@@ -43,7 +43,7 @@ namespace Umbraco.Tests
// AutoPublishedContentType will auto-generate other properties
new PublishedPropertyType("content", 0, "?"),
};
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", propertyTypes);
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
Debug.Print("INIT LIB {0}",
PublishedContentType.Get(PublishedItemType.Content, "anything")
@@ -41,7 +41,7 @@ namespace Umbraco.Tests.Membership
new PublishedPropertyType("bodyText", 0, "?"),
new PublishedPropertyType("author", 0, "?")
};
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", propertyTypes);
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
}
@@ -50,7 +50,7 @@ namespace Umbraco.Tests.PublishedContent
new PublishedPropertyType("creatorName", 0, "?"),
new PublishedPropertyType("blah", 0, "?"), // ugly error when that one is missing...
};
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", propertyTypes);
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
}
@@ -729,4 +729,4 @@ namespace Umbraco.Tests.PublishedContent
return s.Contains(val.ToString());
}
}
}
}
@@ -24,7 +24,7 @@ namespace Umbraco.Tests.PublishedContent
// need to specify a custom callback for unit tests
// AutoPublishedContentTypes generates properties automatically
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", new PublishedPropertyType[] {});
var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] {});
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
// need to specify a different callback for testing
@@ -251,4 +251,4 @@ namespace Umbraco.Tests.PublishedContent
}
}
}
}
}
@@ -234,9 +234,9 @@ namespace Umbraco.Tests.PublishedContent
new PublishedPropertyType("prop1", 1, "?"),
};
var contentType1 = new PublishedContentType(1, "ContentType1", "ContentType1", "ContentType1", Enumerable.Empty<string>(), props);
var contentType2 = new PublishedContentType(2, "ContentType2", "ContentType2", "ContentType2", Enumerable.Empty<string>(), props);
var contentType2s = new PublishedContentType(3, "ContentType2Sub", "ContentType2Sub", "ContentType2Sub", Enumerable.Empty<string>(), props);
var contentType1 = new PublishedContentType(1, "ContentType1", Enumerable.Empty<string>(), props);
var contentType2 = new PublishedContentType(2, "ContentType2", Enumerable.Empty<string>(), props);
var contentType2s = new PublishedContentType(3, "ContentType2Sub", Enumerable.Empty<string>(), props);
cache.Add(new SolidPublishedContent(contentType1)
{
@@ -29,7 +29,7 @@ namespace Umbraco.Tests.PublishedContent
// AutoPublishedContentType will auto-generate other properties
new PublishedPropertyType("content", 0, Constants.PropertyEditors.TinyMCEAlias),
};
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", propertyTypes);
var type = new AutoPublishedContentType(0, "anything", propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
var rCtx = GetRoutingContext("/test", 1234);
@@ -65,4 +65,4 @@ namespace Umbraco.Tests.PublishedContent
UmbracoContext.Current = null;
}
}
}
}
@@ -354,12 +354,12 @@ namespace Umbraco.Tests.PublishedContent
{
private static readonly PublishedPropertyType Default = new PublishedPropertyType("*", 0, "?");
public AutoPublishedContentType(int id, string alias, string name, string description, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, name, description, Enumerable.Empty<string>(), propertyTypes)
public AutoPublishedContentType(int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, Enumerable.Empty<string>(), propertyTypes)
{ }
public AutoPublishedContentType(int id, string alias, string name, string description, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, name, description, compositionAliases, propertyTypes)
public AutoPublishedContentType(int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
: base(id, alias, compositionAliases, propertyTypes)
{ }
public override PublishedPropertyType GetPropertyType(string alias)
@@ -49,7 +49,7 @@ namespace Umbraco.Tests.PublishedContent
new PublishedPropertyType("testRecursive", 0, "?"),
};
var compositionAliases = new[] { "MyCompositionAlias" };
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", compositionAliases, propertyTypes);
var type = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes);
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
}
@@ -1,39 +0,0 @@
using System;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
namespace Umbraco.Tests.Services
{
[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)]
[TestFixture, RequiresSTA]
public class MemberGroupServiceTests : BaseServiceTest
{
[SetUp]
public override void Initialize()
{
base.Initialize();
}
[TearDown]
public override void TearDown()
{
base.TearDown();
}
[Test]
[ExpectedException("System.InvalidOperationException")]
public void New_MemberGroup_Is_Not_Allowed_With_Empty_Name()
{
var service = ServiceContext.MemberGroupService;
service.Save(new MemberGroup {Name = ""});
Assert.Fail("An exception should have been thrown");
}
}
}
@@ -61,17 +61,6 @@ namespace Umbraco.Tests.Strings
Assert.AreEqual(stripped, result);
}
[TestCase("'+alert(1234)+'", "+alert1234+")]
[TestCase("'+alert(56+78)+'", "+alert56+78+")]
[TestCase("{{file}}", "file")]
[TestCase("'+alert('hello')+'", "+alerthello+")]
[TestCase("Test", "Test")]
public void Clean_From_XSS(string input, string result)
{
var cleaned = input.CleanForXss();
Assert.AreEqual(cleaned, result);
}
[TestCase("This is a string to encrypt")]
[TestCase("This is a string to encrypt\nThis is a second line")]
[TestCase(" White space is preserved ")]
+1 -1
View File
@@ -15,7 +15,7 @@ namespace Umbraco.Tests.TestHelpers
// need to specify a custom callback for unit tests
// AutoPublishedContentTypes generates properties automatically
var type = new AutoPublishedContentType(0, "anything", "anything", "anything", new PublishedPropertyType[] {});
var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] {});
PublishedContentType.GetPublishedContentTypeCallback = (alias) => type;
}
-1
View File
@@ -193,7 +193,6 @@
<Compile Include="PublishedContent\StronglyTypedModels\Home.cs" />
<Compile Include="Services\AuditServiceTests.cs" />
<Compile Include="Services\ConsentServiceTests.cs" />
<Compile Include="Services\MemberGroupServiceTests.cs" />
<Compile Include="TestHelpers\ControllerTesting\AuthenticateEverythingExtensions.cs" />
<Compile Include="TestHelpers\ControllerTesting\AuthenticateEverythingMiddleware.cs" />
<Compile Include="TestHelpers\ControllerTesting\SpecificAssemblyResolver.cs" />
@@ -29,30 +29,5 @@ namespace Umbraco.Tests.Web.Mvc
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
Assert.AreEqual("<div style=\"color:red;\" onclick=\"void();\">hello world</div>", output.ToHtmlString());
}
[Test]
public void GetRelatedLinkHtml_Simple()
{
var relatedLink = new Umbraco.Web.Models.RelatedLink {
Caption = "Link Caption",
NewWindow = true,
Link = "https://www.google.com/"
};
var output = _htmlHelper.GetRelatedLinkHtml(relatedLink);
Assert.AreEqual("<a href=\"https://www.google.com/\" target=\"_blank\">Link Caption</a>", output.ToHtmlString());
}
[Test]
public void GetRelatedLinkHtml_HtmlAttributes()
{
var relatedLink = new Umbraco.Web.Models.RelatedLink
{
Caption = "Link Caption",
NewWindow = true,
Link = "https://www.google.com/"
};
var output = _htmlHelper.GetRelatedLinkHtml(relatedLink, new { @class = "test-class"});
Assert.AreEqual("<a class=\"test-class\" href=\"https://www.google.com/\" target=\"_blank\">Link Caption</a>", output.ToHtmlString());
}
}
}
}
}
@@ -11,7 +11,8 @@ LazyLoad.js([
'../js/umbraco.security.js',
'../ServerVariables',
'../lib/spectrum/spectrum.js',
'../js/umbraco.canvasdesigner.js'
'../js/umbraco.canvasdesigner.js',
'../js/canvasdesigner.panel.js'
], function () {
jQuery(document).ready(function () {
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
@@ -18,7 +18,6 @@
<umb-toggle
checked="vm.checked"
disabled="vm.disabled"
on-click="vm.toggle()"
show-labels="true"
label-on="Start"
@@ -39,7 +38,6 @@
var vm = this;
vm.checked = false;
vm.disabled = false;
vm.toggle = toggle;
@@ -54,7 +52,6 @@
</pre>
@param {boolean} checked Set to <code>true</code> or <code>false</code> to toggle the switch.
@param {boolean} disabled Set to <code>true</code> or <code>false</code> to disable/enable the switch.
@param {callback} onClick The function which should be called when the toggle is clicked.
@param {string=} showLabels Set to <code>true</code> or <code>false</code> to show a "On" or "Off" label next to the switch.
@param {string=} labelOn Set a custom label for when the switched is turned on. It will default to "On".
@@ -118,7 +115,6 @@
templateUrl: 'views/components/buttons/umb-toggle.html',
scope: {
checked: "=",
disabled: "=",
onClick: "&",
labelOn: "@?",
labelOff: "@?",
@@ -53,9 +53,6 @@
if (scope.documentType !== null) {
scope.previewOpenUrl = '#/settings/documenttypes/edit/' + scope.documentType.id;
}
// only allow configuring scheduled publishing if the user has publish ("U") and unpublish ("Z") permissions on this node
scope.allowScheduledPublishing = _.contains(scope.node.allowedActions, "U") && _.contains(scope.node.allowedActions, "Z");
}
scope.auditTrailPageChange = function (pageNumber) {
@@ -1,55 +0,0 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbCheckbox
@restrict E
@scope
@description
<b>Added in Umbraco version 7.14.0</b> Use this directive to render an umbraco checkbox.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-checkbox
name="checkboxlist"
value="{{key}}"
model="true"
text="{{text}}">
</umb-checkbox>
</div>
</pre>
@param {boolean} model Set to <code>true</code> or <code>false</code> to set the checkbox to checked or unchecked.
@param {string} value Set the value of the checkbox.
@param {string} name Set the name of the checkbox.
@param {string} text Set the text for the checkbox label.
**/
(function () {
'use strict';
function CheckboxDirective() {
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/forms/umb-checkbox.html',
scope: {
model: "=",
value: "@",
name: "@",
text: "@",
required: "="
}
};
return directive;
}
angular.module('umbraco.directives').directive('umbCheckbox', CheckboxDirective);
})();
@@ -1,54 +0,0 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbRadiobutton
@restrict E
@scope
@description
<b>Added in Umbraco version 7.14.0</b> Use this directive to render an umbraco radio button.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-radiobutton
name="checkboxlist"
value="{{key}}"
model="true"
text="{{text}}">
</umb-radiobutton>
</div>
</pre>
@param {boolean} model Set to <code>true</code> or <code>false</code> to set the radiobutton to checked or unchecked.
@param {string} value Set the value of the radiobutton.
@param {string} name Set the name of the radiobutton.
@param {string} text Set the text for the radiobutton label.
**/
(function () {
'use strict';
function RadiobuttonDirective() {
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/forms/umb-radiobutton.html',
scope: {
model: "=",
value: "@",
name: "@",
text: "@"
}
};
return directive;
}
angular.module('umbraco.directives').directive('umbRadiobutton', RadiobuttonDirective);
})();
@@ -103,6 +103,34 @@ angular.module("umbraco.directives")
scope.dimensions.cropper.height = _viewPortH; // scope.dimensions.viewport.height - 2 * scope.dimensions.margin;
};
//when loading an image without any crop info, we center and fit it
var resizeImageToEditor = function(){
//returns size fitting the cropper
var size = cropperHelper.calculateAspectRatioFit(
scope.dimensions.image.width,
scope.dimensions.image.height,
scope.dimensions.cropper.width,
scope.dimensions.cropper.height,
true);
//sets the image size and updates the scope
scope.dimensions.image.width = size.width;
scope.dimensions.image.height = size.height;
//calculate the best suited ratios
scope.dimensions.scale.min = size.ratio;
scope.dimensions.scale.max = 2;
scope.dimensions.scale.current = size.ratio;
//center the image
var position = cropperHelper.centerInsideViewPort(scope.dimensions.image, scope.dimensions.cropper);
scope.dimensions.top = position.top;
scope.dimensions.left = position.left;
setConstraints();
};
//resize to a given ratio
var resizeImageToScale = function(ratio){
//do stuff
@@ -199,19 +227,12 @@ angular.module("umbraco.directives")
//set dimensions on image, viewport, cropper etc
setDimensions(image);
//create a default crop if we haven't got one already
var createDefaultCrop = !scope.crop;
if (createDefaultCrop) {
calculateCropBox();
}
resizeImageToCrop();
//if we're creating a new crop, make sure to zoom out fully
if (createDefaultCrop) {
scope.dimensions.scale.current = scope.dimensions.scale.min;
resizeImageToScale(scope.dimensions.scale.min);
}
//if we have a crop already position the image
if(scope.crop){
resizeImageToCrop();
}else{
resizeImageToEditor();
}
//sets constaints for the cropper
setConstraints();
@@ -232,7 +253,7 @@ angular.module("umbraco.directives")
var throttledResizing = _.throttle(function(){
resizeImageToScale(scope.dimensions.scale.current);
calculateCropBox();
}, 16);
}, 100);
//happens when we change the scale
@@ -14,8 +14,7 @@ angular.module("umbraco.directives")
scope: {
src: '=',
center: "=",
onImageLoaded: "&",
onGravityChanged: "&"
onImageLoaded: "&"
},
link: function(scope, element, attrs) {
@@ -35,7 +34,7 @@ angular.module("umbraco.directives")
var $overlay = element.find(".overlay");
scope.style = function () {
if (scope.dimensions.width <= 0 || scope.dimensions.height <= 0) {
if (scope.dimensions.width <= 0) {
setDimensions();
}
@@ -53,7 +52,7 @@ angular.module("umbraco.directives")
calculateGravity(offsetX, offsetY);
gravityChanged();
lazyEndEvent();
};
var setDimensions = function () {
@@ -78,11 +77,12 @@ angular.module("umbraco.directives")
scope.center.top = (scope.dimensions.top+10) / scope.dimensions.height;
};
var gravityChanged = function () {
if (angular.isFunction(scope.onGravityChanged)) {
scope.onGravityChanged();
}
};
var lazyEndEvent = _.debounce(function(){
scope.$apply(function(){
scope.$emit("imageFocalPointStop");
});
}, 2000);
//Drag and drop positioning, using jquery ui draggable
//TODO ensure that the point doesnt go outside the box
@@ -100,7 +100,7 @@ angular.module("umbraco.directives")
calculateGravity(offsetX, offsetY);
});
gravityChanged();
lazyEndEvent();
}
});
@@ -86,21 +86,20 @@ angular.module("umbraco.directives")
function generateAlias(value) {
if (generateAliasTimeout) {
$timeout.cancel(generateAliasTimeout);
$timeout.cancel(generateAliasTimeout);
}
if (value !== undefined && value !== "" && value !== null) {
if( value !== undefined && value !== "" && value !== null) {
scope.alias = "";
scope.alias = "";
scope.placeholderText = scope.labels.busy;
generateAliasTimeout = $timeout(function () {
updateAlias = true;
entityResource.getSafeAlias(encodeURIComponent(value), true).then(function (safeAlias) {
if (updateAlias) {
scope.alias = safeAlias.alias;
}
scope.placeholderText = scope.labels.idle;
scope.alias = safeAlias.alias;
}
});
}, 500);
@@ -109,6 +108,7 @@ angular.module("umbraco.directives")
scope.alias = "";
scope.placeholderText = scope.labels.idle;
}
}
// if alias gets unlocked - stop watching alias
@@ -119,17 +119,17 @@ angular.module("umbraco.directives")
}));
// validate custom entered alias
eventBindings.push(scope.$watch('alias', function (newValue, oldValue) {
if (scope.alias === "" || scope.alias === null || scope.alias === undefined) {
if (bindWatcher === true) {
// add watcher
eventBindings.push(scope.$watch('aliasFrom', function (newValue, oldValue) {
if (bindWatcher) {
generateAlias(newValue);
}
}));
}
}
eventBindings.push(scope.$watch('alias', function(newValue, oldValue){
if(scope.alias === "" && bindWatcher === true || scope.alias === null && bindWatcher === true) {
// add watcher
eventBindings.push(scope.$watch('aliasFrom', function(newValue, oldValue) {
if(bindWatcher) {
generateAlias(newValue);
}
}));
}
}));
// clean up
@@ -38,7 +38,7 @@ Use this directive to generate color swatches to pick from.
scope.selectedColor = color;
if (scope.onSelect) {
scope.onSelect({color: color });
scope.onSelect(color);
}
};
}
@@ -3,7 +3,7 @@
* @name umbraco.resources.codefileResource
* @description Loads in data for files that contain code such as js scripts, partial views and partial view macros
**/
function codefileResource($q, $http, umbDataFormatter, umbRequestHelper, localizationService) {
function codefileResource($q, $http, umbDataFormatter, umbRequestHelper) {
return {
@@ -106,16 +106,13 @@ function codefileResource($q, $http, umbDataFormatter, umbRequestHelper, localiz
*
*/
deleteByPath: function (type, virtualpath) {
var promise = localizationService.localize("codefile_deleteItemFailed", [virtualpath]);
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"codeFileApiBaseUrl",
"Delete",
[{ type: type }, { virtualPath: virtualpath}])),
promise);
"Failed to delete item: " + virtualpath);
},
/**
@@ -239,19 +236,13 @@ function codefileResource($q, $http, umbDataFormatter, umbRequestHelper, localiz
*
*/
createContainer: function (type, parentId, name) {
// Is the parent ID numeric?
var key = "codefile_createFolderFailedBy" + (isNaN(parseInt(parentId)) ? "Name" : "Id");
var promise = localizationService.localize(key, [parentId]);
createContainer: function(type, parentId, name) {
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl(
"codeFileApiBaseUrl",
"PostCreateContainer",
{ type: type, parentId: parentId, name: encodeURIComponent(name) })),
promise);
'Failed to create a folder under parent id ' + parentId);
}
};
@@ -26,7 +26,7 @@ function relationResource($q, $http, umbRequestHelper) {
umbRequestHelper.getApiUrl(
"relationApiBaseUrl",
"GetByChildId",
{ childId: id, relationTypeAlias: alias })),
[{ childId: id, relationTypeAlias: alias }])),
"Failed to get relation by child ID " + id + " and type of " + alias);
},
@@ -62,4 +62,4 @@ function relationResource($q, $http, umbRequestHelper) {
};
}
angular.module('umbraco.resources').factory('relationResource', relationResource);
angular.module('umbraco.resources').factory('relationResource', relationResource);
@@ -3,7 +3,7 @@
* @name umbraco.resources.templateResource
* @description Loads in data for templates
**/
function templateResource($q, $http, umbDataFormatter, umbRequestHelper, localizationService) {
function templateResource($q, $http, umbDataFormatter, umbRequestHelper) {
return {
@@ -152,16 +152,13 @@ function templateResource($q, $http, umbDataFormatter, umbRequestHelper, localiz
*
*/
deleteById: function(id) {
var promise = localizationService.localize("template_deleteByIdFailed", [id]);
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"templateApiBaseUrl",
"DeleteById",
[{ id: id }])),
promise);
"Failed to delete item " + id);
},
/**
@@ -123,6 +123,13 @@ function cropperHelper(umbRequestHelper, $http) {
return crop;
},
centerInsideViewPort : function(img, viewport){
var left = viewport.width/ 2 - img.width / 2,
top = viewport.height / 2 - img.height / 2;
return {left: left, top: top};
},
alignToCoordinates : function(image, center, viewport){
var min_left = (image.width) - (viewport.width);
@@ -16,17 +16,17 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
};
//add to umbraco installer facts here
var facts = ["Umbraco helped millions of people watch a man jump from the edge of space",
"Over 500 000 websites are currently powered by Umbraco",
var facts = ['Umbraco helped millions of people watch a man jump from the edge of space',
'Over 440 000 websites are currently powered by Umbraco',
"At least 2 people have named their cat 'Umbraco'",
"On an average day more than 1000 people download Umbraco",
"<a target='_blank' href='https://umbraco.tv/'>umbraco.tv</a> is the premier source of Umbraco video tutorials to get you started",
"You can find the world's friendliest CMS community at <a target='_blank' href='https://our.umbraco.com/'>our.umbraco.com</a>",
"You can become a certified Umbraco developer by attending one of the official courses",
"Umbraco works really well on tablets",
"You have 100% control over your markup and design when crafting a website in Umbraco",
"Umbraco is the best of both worlds: 100% free and open source, and backed by a professional and profitable company",
"There's a pretty big chance you've visited a website powered by Umbraco today",
'On an average day, more than 1000 people download Umbraco',
'<a target="_blank" href="https://umbraco.tv">umbraco.tv</a> is the premier source of Umbraco video tutorials to get you started',
'You can find the world\'s friendliest CMS community at <a target="_blank" href="https://our.umbraco.com">our.umbraco.com</a>',
'You can become a certified Umbraco developer by attending one of the official courses',
'Umbraco works really well on tablets',
'You have 100% control over your markup and design when crafting a website in Umbraco',
'Umbraco is the best of both worlds: 100% free and open source, and backed by a professional and profitable company',
"There's a pretty big chance, you've visited a website powered by Umbraco today",
"'Umbraco-spotting' is the game of spotting big brands running Umbraco",
"At least 4 people have the Umbraco logo tattooed on them",
"'Umbraco' is the Danish name for an allen key",
@@ -101,7 +101,6 @@
@import "components/umb-confirm-action.less";
@import "components/umb-keyboard-shortcuts-overview.less";
@import "components/umb-checkbox-list.less";
@import "components/umb-form-check.less";
@import "components/umb-locked-field.less";
@import "components/umb-tabs.less";
@import "components/umb-load-indicator.less";
@@ -28,8 +28,7 @@
.umb-toggle__toggle {
cursor: pointer;
align-items: center;
display: flex;
display: inline-block;
width: 48px;
height: 24px;
background: @gray-8;
@@ -42,11 +41,6 @@
background-color: @green;
}
.umb-toggle--disabled .umb-toggle__toggle {
cursor: not-allowed;
opacity: 0.8;
}
.umb-toggle--checked .umb-toggle__handler {
transform: translate3d(24px, 0, 0) rotate(0);
}
@@ -69,7 +63,7 @@
.umb-toggle__icon {
position: absolute;
line-height: 1em;
top: 3px;
text-decoration: none;
transition: all 0.2s ease;
}
@@ -1,6 +1,3 @@
@checkboxWidth: 15px;
@checkboxHeight: 15px;
.umb-checkbox-list {
list-style: none;
margin-left: 0;
@@ -1,125 +0,0 @@
@checkboxWidth: 15px;
@checkboxHeight: 15px;
.umb-form-check {
display: flex;
flex-wrap: wrap;
align-items: center;
position: relative;
padding: 0;
margin: 0;
&__text{
margin: 0 0 0 26px;
position: relative;
top: 2px;
}
&__input{
position: absolute;
top: 0;
left: 0;
opacity: 0;
&:checked ~ .umb-form-check__state .umb-form-check__check{
border-color: @green;
}
&:focus:checked ~ .umb-form-check .umb-form-check__check,
&:focus ~ .umb-form-check__state .umb-form-check__check{
border-color: @gray-5;
}
&:checked ~ .umb-form-check__state{
.umb-form-check__check{
// This only happens if the state has a radiobutton modifier
.umb-form-check--radiobutton &{
&:before{
opacity: 1;
transform: scale(1);
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
&:before{
width: @checkboxWidth;
height: @checkboxHeight;
}
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
.umb-form-check__icon{
opacity: 1;
}
}
}
}
&__state{
height: 17px;
position: absolute;
top: 2px;
left: 0;
}
&__check{
position: relative;
border: 1px solid @gray-7;
width: @checkboxWidth;
height: @checkboxHeight;
&:before{
content: "";
background: @green;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
// This only happens if state has the radiobutton modifier
.umb-form-check--radiobutton &{
border-radius: 100%;
&:before{
width: 9px;
height: 9px;
border-radius: 100%;
opacity: 0;
transform: scale(0);
transition: .15s ease-out;
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
&:before{
width: 0;
height: 0;
transition: .05s ease-out;
}
}
}
&__icon{
color: @white;
text-align: center;
font-size: 10px;
opacity: 0;
transition: .2s ease-out;
&:before{
position: absolute;
top: -2px;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
}
}
@@ -165,7 +165,7 @@ input.umb-table__input {
}
.-content .-unpublished:not(.with-unpublished-version) {
.-content :not(.with-unpublished-version).-unpublished {
.umb-table__name > * {
opacity: .4;
}
@@ -21,12 +21,6 @@
cursor: pointer;
}
.umb-permission--disabled .umb-permission__toggle,
.umb-permission--disabled .umb-permission__content {
cursor: not-allowed;
opacity: 0.8;
}
.umb-permission__description {
font-size: 13px;
color: @gray-5;
@@ -17,14 +17,12 @@
-webkit-font-smoothing: antialiased;
*margin-right: .3em;
}
[class^="icon-"]:before,
[class*=" icon-"]:before {
text-decoration: inherit;
display: inline-block;
speak: none;
}
/*
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: 'icomoon';
@@ -40,6 +38,7 @@
i.large{
font-size: 32px;
}
i.medium{
font-size: 24px;
}
@@ -188,6 +187,8 @@ i.small{
.icon-umb-translation:before, .traytranslation:before {
content: "\e1fd";
}
.icon-tv:before {
content: "\e02e";
}
@@ -212,8 +213,7 @@ i.small{
.icon-train:before {
content: "\e035";
}
.icon-trafic:before,
.icon-traffic:before {
.icon-trafic:before {
content: "\e036";
}
.icon-traffic-alt:before {
@@ -255,7 +255,6 @@ i.small{
.icon-target:before {
content: "\e043";
}
.icon-temperature-alt:before,
.icon-temperatrure-alt:before {
content: "\e044";
}
@@ -268,7 +267,6 @@ i.small{
.icon-theater:before {
content: "\e047";
}
.icon-thief:before,
.icon-theif:before {
content: "\e048";
}
@@ -377,7 +375,6 @@ i.small{
.icon-shuffle:before {
content: "\e06b";
}
.icon-science:before,
.icon-sience:before {
content: "\e06c";
}
@@ -750,7 +747,6 @@ i.small{
.icon-pictures-alt-2:before {
content: "\e0e7";
}
.icon-panel-close:before,
.icon-pannel-close:before {
content: "\e0e8";
}
@@ -1631,7 +1627,6 @@ i.small{
.icon-alarm-clock:before {
content: "\e20c";
}
.icon-addressbook:before,
.icon-adressbook:before {
content: "\e20d";
}
@@ -1,5 +1,3 @@
@checkered-background: url(../img/checkered-background.png);
//
// Container styles
// --------------------------------------------------
@@ -13,16 +11,7 @@
&-push {
float:right;
}
&--list{
float: left;
}
&__item{
line-height: 1;
margin: 0 0 5px;
}
}
}
.umb-editor-tiny {
@@ -255,7 +244,7 @@ div.umb-codeeditor .umb-btn-toolbar {
margin: 24px 0 0;
display: flex;
}
&__input {
width: 100%;
&-wrap{
@@ -397,7 +386,7 @@ div.umb-codeeditor .umb-btn-toolbar {
max-height:100%;
margin:auto;
display:block;
background-image: @checkered-background;
background-image: url(../img/checkered-background.png);
}
.umb-sortable-thumbnails li .trashed {
@@ -610,18 +599,12 @@ div.umb-codeeditor .umb-btn-toolbar {
vertical-align: top;
}
.gravity-container {
border: 1px solid @gray-8;
line-height: 0;
.gravity-container .viewport {
max-width: 600px;
}
.viewport {
max-width: 600px;
background: @checkered-background;
&:hover {
cursor: pointer;
}
}
.gravity-container .viewport:hover {
cursor: pointer;
}
.imagecropper {
@@ -634,10 +617,6 @@ div.umb-codeeditor .umb-btn-toolbar {
float: left;
max-width: 100%;
}
.viewport img {
background: @checkered-background;
}
}
.imagecropper .umb-cropper__container {
@@ -905,10 +884,6 @@ div.umb-codeeditor .umb-btn-toolbar {
list-style: none;
vertical-align: middle;
margin-bottom: 0;
img {
background: @checkered-background;
}
}
.umb-fileupload label {
@@ -25,31 +25,30 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController",
$scope.showTarget = $scope.model.hideTarget !== true;
if (dialogOptions.currentTarget) {
// clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
$scope.model.target = angular.copy(dialogOptions.currentTarget);
$scope.model.target = dialogOptions.currentTarget;
//if we have a node ID, we fetch the current node to build the form data
if ($scope.model.target.id || $scope.model.target.udi) {
//will be either a udi or an int
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
// is it a content link?
if (!$scope.model.target.isMedia) {
// get the content path
entityResource.getPath(id, "Document").then(function(path) {
//now sync the tree to this path
$scope.dialogTreeEventHandler.syncTree({
path: path,
tree: "content"
});
});
if (!$scope.model.target.path) {
// get the content properties to build the anchor name list
contentResource.getById(id).then(function (resp) {
$scope.model.target.url = resp.urls[0];
$scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties));
});
}
entityResource.getPath(id, "Document").then(function (path) {
$scope.model.target.path = path;
//now sync the tree to this path
$scope.dialogTreeEventHandler.syncTree({
path: $scope.model.target.path,
tree: "content"
});
});
}
// if a link exists, get the properties to build the anchor name list
contentResource.getById(id).then(function (resp) {
$scope.model.target.url = resp.urls[0];
$scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties));
});
} else if ($scope.model.target.url.length) {
// a url but no id/udi indicates an external link - trim the url to remove the anchor/qs
// only do the substring if there's a # or a ?
@@ -123,12 +122,6 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController",
$scope.mediaPickerOverlay.show = false;
$scope.mediaPickerOverlay = null;
// make sure the content tree has nothing highlighted
$scope.dialogTreeEventHandler.syncTree({
path: "-1",
tree: "content"
});
}
};
});
@@ -0,0 +1,7 @@
<div>
<form ng-submit="model.submit(model)">
<umb-property property="property" ng-repeat="property in model.properties">
<umb-property-editor model="property"></umb-property-editor>
</umb-property>
</form>
</div>
@@ -1,4 +1,5 @@
<div ng-controller="Umbraco.Overlays.UserController">
<div class="umb-control-group" ng-if="!showPasswordFields">
<h5><localize key="user_yourProfile" /></h5>
@@ -77,7 +78,7 @@
</div>
<div class="umb-control-group" ng-if="!showPasswordFields && history.length">
<div class="umb-control-group" ng-if="!showPasswordFields">
<h5><localize key="user_yourHistory" /></h5>
<ul class="umb-tree">
<li ng-repeat="item in history | orderBy:'time':true">
@@ -125,7 +126,7 @@
</div>
<div class="umb-control-group" ng-if="tab.length">
<div class="umb-control-group">
<div ng-repeat="tab in dashboard">
<div ng-repeat="property in tab.properties">
<div>
@@ -1,4 +1,4 @@
<button ng-click="click()" type="button" class="umb-toggle" ng-disabled="disabled" ng-class="{'umb-toggle--checked': checked, 'umb-toggle--disabled': disabled}">
<button ng-click="click()" type="button" class="umb-toggle" ng-class="{'umb-toggle--checked': checked}">
<span ng-if="!labelPosition && showLabels === 'true' || labelPosition === 'left' && showLabels === 'true'">
<span ng-if="!checked" class="umb-toggle__label umb-toggle__label--left">{{ displayLabelOff }}</span>
@@ -107,7 +107,7 @@
</div>
<div class="umb-package-details__sidebar">
<umb-box data-element="node-info-scheduled-publishing" ng-if="allowScheduledPublishing">
<umb-box data-element="node-info-scheduled-publishing">
<umb-box-header title-key="general_scheduledPublishing"></umb-box-header>
<umb-box-content class="block-form">
@@ -1,14 +0,0 @@
<label class="checkbox umb-form-check umb-form-check--checkbox">
<input type="checkbox" name="{{name}}"
value="{{value}}"
ng-model="model"
class="umb-form-check__input"
ng-required="required" />
<div class="umb-form-check__state umb-form-check__state" aria-hidden="true">
<div class="umb-form-check__check">
<i class="umb-form-check__icon icon-check"></i>
</div>
</div>
<span class="umb-form-check__text">{{text}}</span>
</label>
@@ -1,11 +0,0 @@
<label class="radio umb-form-check umb-form-check--radiobutton">
<input type="radio" name="radiobuttons-{{name}}"
value="{{value}}"
ng-model="model"
class="umb-form-check__input" />
<div class="umb-form-check__state umb-form-check__state" aria-hidden="true">
<div class="umb-form-check__check"></div>
</div>
<span class="umb-form-check__text">{{text}}</span>
</label>
@@ -6,7 +6,7 @@
</div>
</div>
<div class="crop-slider" ng-if="loaded">
<div class="crop-slider">
<i class="icon-picture"></i>
<input
type="range"
@@ -16,4 +16,4 @@
ng-model="dimensions.scale.current" />
<i class="icon-picture" style="font-size: 22px"></i>
</div>
</div>
</div>
@@ -23,7 +23,7 @@
<!-- Icon for files -->
<span class="umb-media-grid__item-file-icon" ng-if="!item.thumbnail && item.extension != 'svg'">
<i class="umb-media-grid__item-icon {{item.icon}}"></i>
<span ng-if="item.extension">.{{item.extension}}</span>
<span>.{{item.extension}}</span>
</span>
</div>
</div>
@@ -3,8 +3,7 @@
$scope,
contentResource,
navigationService,
angularHelper,
localizationService) {
angularHelper) {
var vm = this;
var currentForm;
vm.notifyOptions = [];
@@ -12,8 +11,7 @@
vm.cancel = cancel;
vm.message = {
name: $scope.currentNode.name
};
vm.labels = {};
};;
function onInit() {
vm.loading = true;
contentResource.getNotifySettingsById($scope.currentNode.id).then(function (options) {
@@ -21,9 +19,6 @@
vm.loading = false;
vm.notifyOptions = options;
});
localizationService.localize("notifications_editNotifications", [$scope.currentNode.name]).then(function(value) {
vm.labels.headline = value;
});
}
function cancel() {
navigationService.hideMenu();
@@ -1,5 +1,5 @@
angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController",
function ($scope, relationResource, contentResource, navigationService, appState, treeService, userService, localizationService) {
function ($scope, relationResource, contentResource, navigationService, appState, treeService, userService) {
var dialogOptions = $scope.dialogOptions;
$scope.source = _.clone(dialogOptions.currentNode);
@@ -21,10 +21,6 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
userService.getCurrentUser().then(function (userData) {
$scope.treeModel.hideHeader = userData.startContentIds.length > 0 && userData.startContentIds.indexOf(-1) == -1;
});
$scope.labels = {};
localizationService.localizeMany(["treeHeaders_content"]).then(function (data) {
$scope.labels.treeRoot = data[0];
});
function nodeSelectHandler(ev, args) {
@@ -100,7 +96,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
$scope.relation = data[0];
if ($scope.relation.parentId == -1) {
$scope.target = { id: -1, name: $scope.labels.treeRoot };
$scope.target = { id: -1, name: "Root" };
} else {
$scope.loading = true;
@@ -11,17 +11,14 @@
<div ng-show="success">
<div class="alert alert-success">
<strong>{{currentNode.name}}</strong>
<localize key="actions_wasCopiedTo">was copied to</localize>
<strong>{{currentNode.name}}</strong> was copied to
<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="nav.hideDialog()">Ok</button>
</div>
<p class="abstract" ng-hide="success">
<localize key="actions_chooseWhereToCopy">Choose where to copy</localize>
<strong>{{currentNode.name}}</strong>
<localize key="actions_toInTheTreeStructureBelow">to in the tree structure below</localize>
Choose where to copy <strong>{{currentNode.name}}</strong> to in the tree structure below
</p>
<div class="umb-loader-wrapper" ng-show="busy">
@@ -11,9 +11,7 @@
<div ng-show="success">
<div class="alert alert-success">
<strong>{{currentNode.name}}</strong>
<localize key="actions_wasMovedTo">was moved to</localize>
<strong>{{target.name}}</strong>
<strong>{{currentNode.name}}</strong> was moved underneath&nbsp;<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="nav.hideDialog()">Ok</button>
</div>
@@ -13,13 +13,13 @@
</div>
<div ng-show="vm.saveSuccces" ng-cloak>
<div class="alert alert-success">
<localize key="notifications_notificationsSavedFor"></localize> <strong>{{currentNode.name}}</strong>
<localize key="notify_notificationsSavedFor"></localize><strong> {{currentNode.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="vm.cancel()"><localize key="general_ok">Ok</localize></button>
</div>
<div ng-hide="vm.saveSuccces || vm.saveError" ng-cloak>
<div class="block-form" ng-show="!vm.loading">
<span ng-bind-html="vm.labels.headline"></span>
<localize key="notify_notifySet">Set your notification for</localize> <strong>{{ currentNode.name }}</strong>
<umb-control-group>
<umb-permission ng-repeat="option in vm.notifyOptions"
name="option.name"
@@ -1,138 +1,63 @@
angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController",
function ($scope, relationResource, mediaResource, navigationService, appState, treeService, userService, localizationService) {
function ($scope, relationResource, mediaResource, navigationService, appState, treeService, localizationService) {
var dialogOptions = $scope.dialogOptions;
$scope.source = _.clone(dialogOptions.currentNode);
var node = dialogOptions.currentNode;
$scope.error = null;
$scope.loading = true;
$scope.moving = false;
$scope.success = false;
$scope.error = null;
$scope.success = false;
$scope.dialogTreeEventHandler = $({});
$scope.searchInfo = {
showSearch: false,
results: [],
selectedSearchResults: []
}
$scope.treeModel = {
hideHeader: false
}
userService.getCurrentUser().then(function (userData) {
$scope.treeModel.hideHeader = userData.startContentIds.length > 0 && userData.startContentIds.indexOf(-1) == -1;
});
$scope.labels = {};
localizationService.localizeMany(["treeHeaders_media"]).then(function (data) {
$scope.labels.treeRoot = data[0];
});
relationResource.getByChildId(node.id, "relateParentDocumentOnDelete").then(function (data) {
function nodeSelectHandler(ev, args) {
if (args && args.event) {
args.event.preventDefault();
args.event.stopPropagation();
if (data.length == 0) {
$scope.success = false;
$scope.error = {
errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'),
data: {
Message: localizationService.localize('recycleBin_noRestoreRelation')
}
}
return;
}
if ($scope.target) {
//un-select if there's a current one selected
$scope.target.selected = false;
}
$scope.target = args.node;
$scope.target.selected = true;
}
function nodeExpandedHandler(ev, args) {
// open mini list view for list views
if (args.node.metaData.isContainer) {
openMiniListView(args.node);
}
}
$scope.hideSearch = function () {
$scope.searchInfo.showSearch = false;
$scope.searchInfo.results = [];
}
// method to select a search result
$scope.selectResult = function (evt, result) {
result.selected = result.selected === true ? false : true;
nodeSelectHandler(evt, { event: evt, node: result });
};
//callback when there are search results
$scope.onSearchResults = function (results) {
$scope.searchInfo.results = results;
$scope.searchInfo.showSearch = true;
};
$scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler);
$scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler);
$scope.$on('$destroy', function () {
$scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler);
$scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler);
});
// Mini list view
$scope.selectListViewNode = function (node) {
node.selected = node.selected === true ? false : true;
nodeSelectHandler({}, { node: node });
};
$scope.closeMiniListView = function () {
$scope.miniListView = undefined;
};
function openMiniListView(node) {
$scope.miniListView = node;
}
relationResource.getByChildId($scope.source.id, "relateParentMediaFolderOnDelete").then(function (data) {
$scope.loading = false;
if (!data.length) {
$scope.moving = true;
return;
}
$scope.relation = data[0];
if ($scope.relation.parentId == -1) {
$scope.target = { id: -1, name: $scope.labels.treeRoot };
$scope.target = { id: -1, name: "Root" };
} else {
$scope.loading = true;
mediaResource.getById($scope.relation.parentId).then(function (data) {
$scope.loading = false;
$scope.target = data;
// make sure the target item isn't in the recycle bin
if ($scope.target.path.indexOf("-21") !== -1) {
$scope.moving = true;
$scope.target = null;
// make sure the target item isn't in the recycle bin
if ($scope.target.path.indexOf("-20") !== -1) {
$scope.error = {
errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'),
data: {
Message: localizationService.localize('recycleBin_restoreUnderRecycled').then(function (value) {
value.replace('%0%', $scope.target.name);
})
}
};
$scope.success = false;
}
}, function (err) {
$scope.loading = false;
$scope.success = false;
$scope.error = err;
});
}
}, function (err) {
$scope.loading = false;
$scope.error = err;
$scope.success = false;
$scope.error = err;
});
$scope.restore = function () {
$scope.loading = true;
$scope.restore = function () {
// this code was copied from `content.move.controller.js`
mediaResource.move({ parentId: $scope.target.id, id: $scope.source.id })
mediaResource.move({ parentId: $scope.target.id, id: node.id })
.then(function (path) {
$scope.loading = false;
$scope.success = true;
//first we need to remove the node that launched the dialog
@@ -153,7 +78,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController",
});
}, function (err) {
$scope.loading = false;
$scope.success = false;
$scope.error = err;
});
};
@@ -11,9 +11,7 @@
<div ng-show="success">
<div class="alert alert-success">
<strong>{{currentNode.name}}</strong>
<localize key="actions_wasMovedTo">was moved to</localize>
<strong>{{target.name}}</strong>
<strong>{{currentNode.name}}</strong> was moved underneath <strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="nav.hideDialog()">Ok</button>
</div>
@@ -1,96 +1,25 @@
<div ng-controller="Umbraco.Editors.Media.RestoreController">
<div class="umb-dialog-body" ng-cloak>
<div class="umb-dialog-body">
<umb-pane>
<umb-load-indicator
ng-if="loading">
</umb-load-indicator>
<div ng-show="error">
<div class="alert alert-error">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.Message}}</div>
</div>
</div>
<p class="abstract" ng-hide="error != null || success == true">
<localize key="actions_restore">Restore</localize> <strong>{{currentNode.name}}</strong> <localize key="general_under">under</localize> <strong>{{target.name}}</strong>?
</p>
<div ng-show="success">
<div class="alert alert-success">
<strong>{{source.name}}</strong>
<span ng-hide="moving"><localize key="recycleBin_wasRestored">was restored under</localize></span>
<span ng-show="moving"><localize key="editdatatype_wasMoved">was moved underneath</localize></span>
<strong>{{target.name}}</strong>
</div>
<button class="btn btn-primary" ng-click="nav.hideDialog()">Ok</button>
</div>
<div class="alert alert-error" ng-show="error != null">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.Message}}</div>
</div>
<div ng-hide="moving || loading || success">
<p class="abstract" ng-hide="error || success">
<localize key="actions_restore">Restore</localize> <strong>{{source.name}}</strong> <localize key="general_under">under</localize> <strong>{{target.name}}</strong>?
</p>
</div>
<div ng-hide="!moving || loading || success">
<div>
<div class="alert alert-info">
<div><strong><localize key="recycleBin_itemCannotBeRestored">Cannot automatically restore this item</localize></strong></div>
<div><localize key="recycleBin_itemCannotBeRestoredHelpText">There is no location where this item can be automatically restored. You can move the item manually using the tree below.</localize></div>
</div>
</div>
<div ng-hide="miniListView">
<umb-tree-search-box
hide-search-callback="hideSearch"
search-callback="onSearchResults"
show-search="{{searchInfo.showSearch}}"
section="media">
</umb-tree-search-box>
<br />
<umb-tree-search-results
ng-if="searchInfo.showSearch"
results="searchInfo.results"
select-result-callback="selectResult">
</umb-tree-search-results>
<div ng-hide="searchInfo.showSearch">
<umb-tree
section="media"
hideheader="{{treeModel.hideHeader}}"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler"
enablelistviewexpand="true"
enablecheckboxes="true">
</umb-tree>
</div>
</div>
<umb-mini-list-view
ng-if="miniListView"
node="miniListView"
entity-type="Document"
on-select="selectListViewNode(node)"
on-close="closeMiniListView()">
</umb-mini-list-view>
</div>
<div class="alert alert-success" ng-show="success == true">
<p><strong>{{currentNode.name}}</strong> <localize key="editdatatype_wasMoved">was moved underneath</localize> <strong>{{target.name}}</strong></p>
<button class="btn btn-primary" ng-click="nav.hideDialog()"><localize key="general_ok">OK</localize></button>
</div>
</umb-pane>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="loading || moving || success">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="restore()" ng-show="error == null"><localize key="actions_restore">Restore</localize></button>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="loading || !moving || success">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="restore()" ng-show="error == null" ng-disabled="!target"><localize key="actions_move">Move</localize></button>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success == true">
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success == true">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="restore()" ng-show="error == null"><localize key="actions_restore">Restore</localize></button>
</div>
@@ -57,7 +57,7 @@
</div>
</div>
<umb-control-group label="@create_enterFolderName" localize="label" hide-label="false">
<umb-control-group label="Enter a folder name" hide-label="false">
<input type="text" name="folderName" ng-model="vm.folderName" class="umb-textstring textstring input-block-level" umb-auto-focus required />
</umb-control-group>
@@ -12,9 +12,6 @@ function PartialViewsDeleteController($scope, codefileResource, treeService, nav
//mark it for deletion (used in the UI)
$scope.currentNode.loading = true;
// Reset the error message
$scope.error = null;
codefileResource.deleteByPath('partialViews', $scope.currentNode.id)
.then(function() {
@@ -24,9 +21,6 @@ function PartialViewsDeleteController($scope, codefileResource, treeService, nav
//TODO: Need to sync tree, etc...
treeService.removeNode($scope.currentNode);
navigationService.hideMenu();
}, function (err) {
$scope.currentNode.loading = false;
$scope.error = err;
});
};
@@ -1,13 +1,6 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.PartialViews.DeleteController">
<div class="umb-dialog-body">
<div ng-show="error">
<div class="alert alert-error">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.message}}</div>
</div>
</div>
<p class="umb-abstract">
<localize key="defaultdialogs_confirmdelete">Are you sure you want to delete</localize> <strong>{{currentNode.name}}</strong> ?
</p>
@@ -1,4 +1,4 @@
function booleanEditorController($scope, angularHelper) {
function booleanEditorController($scope) {
function setupViewModel() {
$scope.renderModel = {
@@ -28,8 +28,7 @@ function booleanEditorController($scope, angularHelper) {
};
// Update the value when the toggle is clicked
$scope.toggle = function () {
angularHelper.getCurrentForm($scope).$setDirty();
$scope.toggle = function(){
if($scope.renderModel.value){
$scope.model.value = "0";
setupViewModel();
@@ -1,8 +1,14 @@
<div class="umb-editor umb-editor--list" ng-controller="Umbraco.PropertyEditors.CheckboxListController">
<div class="umb-editor umb-checkboxlist" ng-controller="Umbraco.PropertyEditors.CheckboxListController">
<ul class="unstyled">
<li ng-repeat="item in selectedItems" class="umb-editor__item">
<umb-checkbox name="checkboxlist" value="{{item.key}}" model="item.checked" text="{{item.val}}" required="model.validation.mandatory && !model.value.length"></umb-checkbox>
<li ng-repeat="item in selectedItems">
<label class="checkbox">
<input type="checkbox" name="checkboxlist"
value="{{item.key}}"
ng-model="item.checked"
ng-required="model.validation.mandatory && !model.value.length" />
{{item.val}}
</label>
</li>
</ul>
@@ -1,4 +1,4 @@
function ColorPickerController($scope, angularHelper) {
function ColorPickerController($scope) {
//setup the default config
var config = {
@@ -12,12 +12,31 @@ function ColorPickerController($scope, angularHelper) {
//map back to the model
$scope.model.config = config;
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
function convertArrayToDictionaryArray(model) {
//now we need to format the items in the dictionary because we always want to have an array
var newItems = [];
for (var i = 0; i < model.length; i++) {
newItems.push({ id: model[i], sortOrder: 0, value: model[i] });
}
$scope.model.activeColor = {
value: "",
label: ""
};
return newItems;
}
function convertObjectToDictionaryArray(model) {
//now we need to format the items in the dictionary because we always want to have an array
var newItems = [];
var vals = _.values($scope.model.config.items);
var keys = _.keys($scope.model.config.items);
for (var i = 0; i < vals.length; i++) {
var label = vals[i].value ? vals[i].value : vals[i];
newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label });
}
return newItems;
}
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
if ($scope.isConfigured) {
@@ -58,7 +77,29 @@ function ColorPickerController($scope, angularHelper) {
//now make the editor model the array
$scope.model.config.items = items;
}
$scope.toggleItem = function (color) {
var currentColor = ($scope.model.value && $scope.model.value.hasOwnProperty("value"))
? $scope.model.value.value
: $scope.model.value;
var newColor;
if (currentColor === color.value) {
// deselect
$scope.model.value = $scope.model.useLabel ? { value: "", label: "" } : "";
newColor = "";
}
else {
// select
$scope.model.value = $scope.model.useLabel ? { value: color.value, label: color.label } : color.value;
newColor = color.value;
}
// this is required to re-validate
$scope.propertyForm.modelValue.$setViewValue(newColor);
};
// Method required by the valPropertyValidator directive (returns true if the property editor has at least one color selected)
$scope.validateMandatory = function () {
var isValid = !$scope.model.validation.mandatory || (
@@ -74,48 +115,33 @@ function ColorPickerController($scope, angularHelper) {
}
$scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0;
$scope.onSelect = function (color) {
// did the value change?
if ($scope.model.value != null && $scope.model.value.value === color) {
// User clicked the currently selected color
// to remove the selection, they don't want
// to select any color after all.
// Unselect the color and mark as dirty
$scope.model.activeColor = null;
$scope.model.value = null;
angularHelper.getCurrentForm($scope).$setDirty();
// A color is active if it matches the value and label of the model.
// If the model doesn't store the label, ignore the label during the comparison.
$scope.isActiveColor = function (color) {
return;
}
// no value
if (!$scope.model.value)
return false;
// yes, update the model (label + value) according to the new color
var selectedItem = _.find($scope.model.config.items, function (item) {
return item.value === color;
});
if (!selectedItem) {
return;
}
$scope.model.value = {
label: selectedItem.label,
value: selectedItem.value
};
// make sure to set dirty
angularHelper.getCurrentForm($scope).$setDirty();
}
// Complex color (value and label)?
if (!$scope.model.value.hasOwnProperty("value"))
return $scope.model.value === color.value;
return $scope.model.value.value === color.value && $scope.model.value.label === color.label;
};
// Finds the color best matching the model's color,
// and sets the model color to that one. This is useful when
// either the value or label was changed on the data type.
function initActiveColor() {
// no value - initialize default value
// no value
if (!$scope.model.value)
return;
// Backwards compatibility, the color used to be stored as a hex value only
if (typeof $scope.model.value === "string") {
$scope.model.value = { value: $scope.model.value, label: $scope.model.value };
}
// Complex color (value and label)?
if (!$scope.model.value.hasOwnProperty("value"))
return;
var modelColor = $scope.model.value.value;
var modelLabel = $scope.model.value.label;
@@ -156,8 +182,8 @@ function ColorPickerController($scope, angularHelper) {
// If a match was found, set it as the active color.
if (foundItem) {
$scope.model.activeColor.value = foundItem.value;
$scope.model.activeColor.label = foundItem.label;
$scope.model.value.value = foundItem.value;
$scope.model.value.label = foundItem.label;
}
}
@@ -6,10 +6,9 @@
</div>
<umb-color-swatches colors="model.config.items"
selected-color="model.activeColor.value"
selected-color="model.value.value"
size="m"
use-label="model.useLabel"
on-select="onSelect(color)">
use-label="model.useLabel">
</umb-color-swatches>
<input type="hidden" name="modelValue" ng-model="model.value" val-property-validator="validateMandatory" />
@@ -35,6 +35,7 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
return $scope.model.config.idType === "udi" ? i.udi : i.id;
});
$scope.model.value = trim(currIds.join(), ",");
angularHelper.getCurrentForm($scope).$setDirty();
//Validate!
if ($scope.model.config && $scope.model.config.minNumber && parseInt($scope.model.config.minNumber) > $scope.renderModel.length) {
@@ -83,10 +84,7 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
opacity: 0.7,
tolerance: "pointer",
scroll: true,
zIndex: 6000,
update: function (e, ui) {
angularHelper.getCurrentForm($scope).$setDirty();
}
zIndex: 6000
};
if ($scope.model.config) {
@@ -145,9 +145,9 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
var element = $element.find("div:first");
// Open the datepicker and add a changeDate eventlistener
// Open the datepicker and add a changeDate eventlistener
element
.datetimepicker(angular.extend({ useCurrent: $scope.model.config.defaultEmpty !== "1" }, $scope.model.config))
.datetimepicker(angular.extend({ useCurrent: true }, $scope.model.config))
.on("dp.change", applyDate)
.on("dp.error", function(a, b, c) {
$scope.hasDatetimePickerValue = false;
@@ -52,7 +52,6 @@ angular.module('umbraco')
});
editedCrop.coordinates = $scope.currentCrop.coordinates;
$scope.close();
angularHelper.getCurrentForm($scope).$setDirty();
};
//reset the current crop
@@ -99,10 +98,6 @@ angular.module('umbraco')
$scope.hasDimensions = hasDimensions;
};
$scope.focalPointChanged = function () {
angularHelper.getCurrentForm($scope).$setDirty();
}
//on image selected, update the cropper
$scope.$on("filesSelected", function (ev, args) {
$scope.model.value = config;
@@ -40,8 +40,7 @@
<umb-image-gravity
src="imageSrc"
center="model.value.focalPoint"
on-image-loaded="imageLoaded(isCroppable, hasDimensions)"
on-gravity-changed="focalPointChanged()">
on-image-loaded="imageLoaded(isCroppable, hasDimensions)">
</umb-image-gravity>
<a href class="btn btn-link btn-crop-delete" ng-click="clear()"><i class="icon-delete red"></i> <localize key="content_uploadClear">Remove file</localize></a>
</div>
@@ -1,4 +1,4 @@
function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService, navigationService, treeService, mediaHelper) {
function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService, navigationService, treeService) {
//this is a quick check to see if we're in create mode, if so just exit - we cannot show children for content
// that isn't created yet, if we continue this will use the parent id in the route params which isn't what
@@ -269,12 +269,10 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
$scope.listViewResultSet = data;
//update all values for display
var section = appState.getSectionState("currentSection");
if ($scope.listViewResultSet.items) {
_.each($scope.listViewResultSet.items, function (e, index) {
setPropertyValues(e);
// create the folders collection (only for media list views)
if (section === "media" && !mediaHelper.hasFilePropertyType(e)) {
if (e.contentTypeAlias === 'Folder') {
$scope.folders.push(e);
}
});
@@ -1,133 +0,0 @@
function multiUrlPickerController($scope, angularHelper, localizationService, entityResource, iconHelper) {
$scope.renderModel = [];
if ($scope.preview) {
return;
}
if (!Array.isArray($scope.model.value)) {
$scope.model.value = [];
}
var currentForm = angularHelper.getCurrentForm($scope);
$scope.sortableOptions = {
distance: 10,
tolerance: "pointer",
scroll: true,
zIndex: 6000,
update: function () {
currentForm.$setDirty();
}
};
$scope.model.value.forEach(function (link) {
link.icon = iconHelper.convertFromLegacyIcon(link.icon);
$scope.renderModel.push(link);
});
$scope.$on("formSubmitting", function () {
$scope.model.value = $scope.renderModel;
});
$scope.$watch(
function () {
return $scope.renderModel.length;
},
function () {
if ($scope.model.config && $scope.model.config.minNumber) {
$scope.multiUrlPickerForm.minCount.$setValidity(
"minCount",
+$scope.model.config.minNumber <= $scope.renderModel.length
);
}
if ($scope.model.config && $scope.model.config.maxNumber) {
$scope.multiUrlPickerForm.maxCount.$setValidity(
"maxCount",
+$scope.model.config.maxNumber >= $scope.renderModel.length
);
}
$scope.sortableOptions.disabled = $scope.renderModel.length === 1;
}
);
$scope.remove = function ($index) {
$scope.renderModel.splice($index, 1);
currentForm.$setDirty();
};
$scope.openLinkPicker = function (link, $index) {
var target = link ? {
name: link.name,
anchor: link.queryString,
// the linkPicker breaks if it get an udi for media
udi: link.isMedia ? null : link.udi,
url: link.url,
target: link.target
} : null;
$scope.linkPickerOverlay = {
view: "linkpicker",
currentTarget: target,
show: true,
submit: function (model) {
if (model.target.url || model.target.anchor) {
// if an anchor exists, check that it is appropriately prefixed
if (model.target.anchor && model.target.anchor[0] !== '?' && model.target.anchor[0] !== '#') {
model.target.anchor = (model.target.anchor.indexOf('=') === -1 ? '#' : '?') + model.target.anchor;
}
if (link) {
if (link.isMedia && link.url === model.target.url) {
// we can assume the existing media item is changed and no new file has been selected
// so we don't need to update the udi and isMedia fields
} else {
link.udi = model.target.udi;
link.isMedia = model.target.isMedia;
}
link.name = model.target.name || model.target.url || model.target.anchor;
link.queryString = model.target.anchor;
link.target = model.target.target;
link.url = model.target.url;
} else {
link = {
isMedia: model.target.isMedia,
name: model.target.name || model.target.url || model.target.anchor,
queryString: model.target.anchor,
target: model.target.target,
udi: model.target.udi,
url: model.target.url
};
$scope.renderModel.push(link);
}
if (link.udi) {
var entityType = link.isMedia ? "media" : "document";
entityResource.getById(link.udi, entityType).then(function (data) {
link.icon = iconHelper.convertFromLegacyIcon(data.icon);
link.published = (data.metaData && data.metaData.IsPublished === false && entityType === "Document") ? false : true;
link.trashed = data.trashed;
if (link.trashed) {
item.url = localizationService.dictionary.general_recycleBin;
}
});
} else {
link.icon = "icon-link";
link.published = true;
}
currentForm.$setDirty();
}
$scope.linkPickerOverlay.show = false;
$scope.linkPickerOverlay = null;
}
};
};
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.MultiUrlPickerController", multiUrlPickerController);
@@ -1,79 +0,0 @@
<div ng-controller="Umbraco.PropertyEditors.MultiUrlPickerController" class="umb-editor umb-contentpicker">
<p ng-if="(renderModel|filter:{trashed:true}).length == 1"><localize key="contentPicker_pickedTrashedItem"></localize></p>
<p ng-if="(renderModel|filter:{trashed:true}).length > 1"><localize key="contentPicker_pickedTrashedItems"></localize></p>
<ng-form name="multiUrlPickerForm">
<div ui-sortable="sortableOptions" ng-model="renderModel">
<umb-node-preview
ng-repeat="link in renderModel"
icon="link.icon"
name="link.name"
published="link.published"
description="link.url + (link.queryString ? link.queryString : '')"
sortable="!sortableOptions.disabled"
allow-remove="true"
allow-edit="true"
on-remove="remove($index)"
on-edit="openLinkPicker(link, $index)">
</umb-node-preview>
</div>
<a ng-show="!model.config.maxNumber || renderModel.length < model.config.maxNumber"
class="umb-node-preview-add"
href
ng-click="openLinkPicker()"
prevent-default>
<localize key="general_add">Add</localize>
</a>
<div class="umb-contentpicker__min-max-help">
<!-- Both min and max items -->
<span ng-if="model.config.minNumber && model.config.maxNumber && model.config.minNumber !== model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add between {{model.config.minNumber}} and {{model.config.maxNumber}} items</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected"> items selected</localize>
</span>
</span>
<!-- Equal min and max -->
<span ng-if="model.config.minNumber && model.config.maxNumber && model.config.minNumber === model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add {{model.config.minNumber - renderModel.length}} item(s)</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected"> items selected</localize>
</span>
</span>
<!-- Only max -->
<span ng-if="!model.config.minNumber && model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add up to {{model.config.maxNumber}} items</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected">items selected</localize>
</span>
</span>
<!-- Only min -->
<span ng-if="model.config.minNumber && !model.config.maxNumber && renderModel.length < model.config.minNumber">
Add at least {{model.config.minNumber}} item(s)
</span>
</div>
<!--These are here because we need ng-form fields to validate against-->
<input type="hidden" name="minCount" ng-model="renderModel" />
<input type="hidden" name="maxCount" ng-model="renderModel" />
<div class="help-inline" val-msg-for="minCount" val-toggle-msg="minCount">
<localize key="validation_minCount">You need to add at least</localize> {{model.config.minNumber}} <localize key="validation_items">items</localize>
</div>
<div class="help-inline" val-msg-for="maxCount" val-toggle-msg="maxCount">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected">items selected</localize>
</div>
</ng-form>
<umb-overlay ng-if="linkPickerOverlay.show"
model="linkPickerOverlay"
view="linkPickerOverlay.view"
position="right">
</umb-overlay>
</div>
@@ -1,8 +1,12 @@
<div class="umb-editor umb-edtitor--list" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<div class="umb-editor umb-radiobuttons" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<ul class="unstyled">
<li ng-repeat="item in model.config.items" class="umb-editor__item">
<umb-radiobutton name="{{model.alias}}" value="{{item.id}}" model="model.value" text="{{item.value}}"></umb-radiobutton>
<li ng-repeat="item in model.config.items">
<label class="radio">
<input type="radio" name="radiobuttons-{{model.alias}}"
value="{{item.id}}"
ng-model="model.value" />
{{item.value}}
</label>
</li>
</ul>
</div>
</div>
@@ -278,7 +278,7 @@ angular.module("umbraco")
$scope.linkPickerOverlay = {
view: "linkpicker",
currentTarget: currentTarget,
anchors: editorState.current ? tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)) : [],
anchors: tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)),
show: true,
submit: function(model) {
tinyMceService.insertLinkInEditor(editor, model.target, anchorElement);
@@ -12,10 +12,6 @@ function TemplatesDeleteController($scope, templateResource , treeService, navig
//mark it for deletion (used in the UI)
$scope.currentNode.loading = true;
// Reset the error message
$scope.error = null;
templateResource.deleteById($scope.currentNode.id).then(function () {
$scope.currentNode.loading = false;
@@ -25,9 +21,6 @@ function TemplatesDeleteController($scope, templateResource , treeService, navig
//TODO: Need to sync tree, etc...
treeService.removeNode($scope.currentNode);
navigationService.hideMenu();
}, function (err) {
$scope.currentNode.loading = false;
$scope.error = err;
});
};
@@ -1,18 +1,11 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.Templates.DeleteController">
<div class="umb-dialog-body">
<div ng-show="error">
<div class="alert alert-error">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.message}}</div>
</div>
</div>
<p class="umb-abstract">
<localize key="defaultdialogs_confirmdelete">Are you sure you want to delete</localize>&nbsp;<strong>{{currentNode.name}}</strong> ?
</p>
<umb-confirm on-confirm="performDelete" on-cancel="cancel">
<umb-confirm on-confirm="performDelete" on-cancel="cancel">
</umb-confirm>
</div>
+3
View File
@@ -0,0 +1,3 @@
/Umbraco/**
/Umbraco_Client/**
+3 -2
View File
@@ -520,6 +520,7 @@
</Content>
<Content Include="Umbraco\Install\Views\Web.config" />
<Content Include="App_Plugins\ModelsBuilder\package.manifest" />
<Content Include=".eslintignore" />
<None Include="Config\404handlers.Release.config">
<DependentUpon>404handlers.config</DependentUpon>
</None>
@@ -1038,9 +1039,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7140</DevelopmentServerPort>
<DevelopmentServerPort>7130</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7140</IISUrl>
<IISUrl>http://localhost:7130</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -1350,4 +1350,4 @@
<key alias="enabledConfirm">轉址追蹤器已開啟。</key>
<key alias="enableError">啟動轉址追蹤器錯誤,更多資訊請參閱您的紀錄檔。</key>
</area>
</language>
</language>
+15 -15
View File
@@ -8,19 +8,19 @@ For details on the format of this configuration file see:
https://our.umbraco.com/documentation/reference/config/healthchecks
-->
<HealthChecks>
<disabledChecks>
<!--<check id="1B5D221B-CE99-4193-97CB-5F3261EC73DF" disabledOn="" disabledBy="0" />-->
</disabledChecks>
<notificationSettings enabled="true" firstRunTime="" periodInHours="24">
<notificationMethods>
<notificationMethod alias="email" enabled="true" verbosity="Summary">
<settings>
<add key="recipientEmail" value="" />
</settings>
</notificationMethod>
</notificationMethods>
<disabledChecks>
<!--<check id="1B5D221B-CE99-4193-97CB-5F3261EC73DF" disabledOn="" disabledBy="0" />-->
</disabledChecks>
<notificationSettings enabled="true" firstRunTime="" periodInHours="24">
<notificationMethods>
<notificationMethod alias="email" enabled="true" verbosity="Summary">
<settings>
<add key="recipientEmail" value="" />
</settings>
</notificationMethod>
</notificationMethods>
<disabledChecks>
<!--<check id="EB66BB3B-1BCD-4314-9531-9DA2C1D6D9A7" disabledOn="" disabledBy="0" />-->
</disabledChecks>
</notificationSettings>
</HealthChecks>
<!--<check id="EB66BB3B-1BCD-4314-9531-9DA2C1D6D9A7" disabledOn="" disabledBy="0" />-->
</disabledChecks>
</notificationSettings>
</HealthChecks>
@@ -6,11 +6,11 @@
https://our.umbraco.com/documentation/using-umbraco/config-files/umbracoSettings/
Many of the optional settings are not explicitly listed here
but can be found in the online documentation.
-->
-->
<backOffice>
<tours enable="true"></tours>
</backOffice>
</backOffice>
<content>
@@ -32,7 +32,7 @@
<notifications>
<!-- the email that should be used as from mail when umbraco sends a notification -->
<!-- you can add a display name to the email like this: <email>Your display name here &lt;your@email.here&gt;</email> -->
<!-- you can add a display name to the email like thist: <email>Your display name here &lt;your@email.here&gt;</email> -->
<email>your@email.here</email>
</notifications>
@@ -61,14 +61,14 @@
<EnablePropertyValueConverters>true</EnablePropertyValueConverters>
<!-- You can specify your own background image for the login screen here. The image will automatically get an overlay to match back office colors - this path is relative to the ~/umbraco path. The default location is: /umbraco/assets/img/installer.jpg -->
<loginBackgroundImage>assets/img/installer.jpg</loginBackgroundImage>
<loginBackgroundImage>assets/img/installer.jpg</loginBackgroundImage>
</content>
<security>
<!-- set to true to auto update login interval (and there by disabling the lock screen -->
<keepUserLoggedIn>false</keepUserLoggedIn>
<!-- by default this is true and if not specified in config will be true. set to false to always show a separate username field in the back office user editor -->
<!-- by default this is true and if not specified in config will be true. set to false to always show a separate username field in the back office user editor -->
<usernameIsEmail>true</usernameIsEmail>
<!-- change in 4.8: Disabled users are now showed dimmed and last in the tree. If you prefer not to display them set this to true -->
<hideDisabledUsersInBackoffice>false</hideDisabledUsersInBackoffice>
+4 -16
View File
@@ -32,11 +32,8 @@
<key alias="rename" version="7.3.0">Omdøb</key>
<key alias="restore" version="7.3.0">Gendan</key>
<key alias="SetPermissionsForThePage">Sæt rettigheder for siden %0%</key>
<key alias="chooseWhereToCopy">Vælg hvor du vil kopiere</key>
<key alias="chooseWhereToMove">Vælg hvortil du vil flytte</key>
<key alias="toInTheTreeStructureBelow">til i træstrukturen nedenfor</key>
<key alias="wasMovedTo">blev flyttet til</key>
<key alias="wasCopiedTo">blev kopieret til</key>
<key alias="toInTheTreeStructureBelow">I træstrukturen nedenfor</key>
<key alias="rights">Rettigheder</key>
<key alias="rollback">Fortryd ændringer</key>
<key alias="sendtopublish">Send til udgivelse</key>
@@ -182,11 +179,6 @@
<key alias="validationErrorPropertyWithMoreThanOneMapping">Overførsel af egenskaber kunne ikke fuldføres, da en eller flere egenskaber er indstillet til at blive overført mere end én gang.</key>
<key alias="validDocTypesNote">Kun andre dokumenttyper, der er gyldige på denne placering, vises.</key>
</area>
<area alias="codefile">
<key alias="createFolderFailedById">Oprettelse af mappen under parent med ID %0% fejlede</key>
<key alias="createFolderFailedByName">Oprettelse af mappen under parent med navnet %0% fejlede</key>
<key alias="deleteItemFailed">Sletning af filen/mappen fejlede: %0%</key>
</area>
<area alias="content">
<key alias="isPublished" version="7.2">Udgivet</key>
<key alias="about">Om siden</key>
@@ -287,7 +279,6 @@
<key alias="chooseNode">Hvor ønsker du at oprette den nye %0%</key>
<key alias="createUnder">Opret under</key>
<key alias="createContentBlueprint">Vælg den dokumenttype, du vil oprette en indholdsskabelon til</key>
<key alias="enterFolderName">Angiv et navn for mappen</key>
<key alias="updateData">Vælg en type og skriv en titel</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[Der kunne ikke findes nogen tilladte dokument typer. Du skal tillade disse i indstillinger under <strong>"dokument typer"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[Der kunne ikke findes nogen tilladte media typer. Du skal tillade disse i indstillinger under <strong>"media typer"</strong>.]]></key>
@@ -839,8 +830,7 @@
<key alias="relateToOriginal">Relater det kopierede element til originalen</key>
</area>
<area alias="notifications">
<key alias="editNotifications"><![CDATA[Vælg dine notificeringer for <strong>%0%</strong>]]></key>
<key alias="notificationsSavedFor">Notificeringer er gemt for</key>
<key alias="editNotifications">Rediger dine notificeringer for %0%</key>
<key alias="mailBody">
<![CDATA[
Hej %0%
@@ -1014,7 +1004,6 @@ Mange hilsner fra Umbraco robotten
<area alias="rollback">
<key alias="headline">Vælg en version at sammenligne med den nuværende version</key>
<key alias="currentVersion">Nuværende version</key>
<key alias="diffHelp"><![CDATA[Her vises forskellene mellem den nuværende version og den valgte version<br /><del>Rød</del> tekst vil ikke blive vist i den valgte version. <ins>Grøn betyder tilføjet</ins>]]></key>
<key alias="documentRolledBack">Dokument tilbagerullet</key>
@@ -1164,7 +1153,6 @@ Mange hilsner fra Umbraco robotten
</area>
<area alias="template">
<key alias="deleteByIdFailed">Sletning af skabelonen med ID %0% fejlede</key>
<key alias="edittemplate">Rediger skabelon</key>
<key alias="insertSections">Sektioner</key>
@@ -1458,9 +1446,9 @@ Mange hilsner fra Umbraco robotten
<key alias="macros">Makroer</key>
<key alias="mediaTypes">Medietyper</key>
<key alias="member">Medlemmer</key>
<key alias="memberGroups">Medlemsgrupper</key>
<key alias="memberGroups">Medlemsgruppe</key>
<key alias="memberRoles">Roller</key>
<key alias="memberTypes">Medlemstyper</key>
<key alias="memberTypes">Medlemstype</key>
<key alias="documentTypes">Dokumenttyper</key>
<key alias="relationTypes">Relationstyper</key>
<key alias="packager">Pakker</key>
+2 -17
View File
@@ -33,11 +33,8 @@
<key alias="rename" version="7.3.0">Rename</key>
<key alias="restore" version="7.3.0">Restore</key>
<key alias="SetPermissionsForThePage">Set permissions for the page %0%</key>
<key alias="chooseWhereToCopy">Choose where to copy</key>
<key alias="chooseWhereToMove">Choose where to move</key>
<key alias="toInTheTreeStructureBelow">to in the tree structure below</key>
<key alias="wasMovedTo">was moved to</key>
<key alias="wasCopiedTo">was copied to</key>
<key alias="toInTheTreeStructureBelow">In the tree structure below</key>
<key alias="rights">Permissions</key>
<key alias="rollback">Rollback</key>
<key alias="sendtopublish">Send To Publish</key>
@@ -188,11 +185,6 @@
<key alias="validationErrorPropertyWithMoreThanOneMapping">Could not complete property mapping as one or more properties have more than one mapping defined.</key>
<key alias="validDocTypesNote">Only alternate types valid for the current location are displayed.</key>
</area>
<area alias="codefile">
<key alias="createFolderFailedById">Failed to create a folder under parent with ID %0%</key>
<key alias="createFolderFailedByName">Failed to create a folder under parent with name %0%</key>
<key alias="deleteItemFailed">Failed to delete item: %0%</key>
</area>
<area alias="content">
<key alias="isPublished" version="7.2">Is Published</key>
<key alias="about">About this page</key>
@@ -295,7 +287,6 @@
<key alias="chooseNode">Where do you want to create the new %0%</key>
<key alias="createUnder">Create an item under</key>
<key alias="createContentBlueprint">Select the document type you want to make a content template for</key>
<key alias="enterFolderName">Enter a folder name</key>
<key alias="updateData">Choose a type and a title</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[There are no allowed document types available. You must enable these in the settings section under <strong>"document types"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[There are no allowed media types available. You must enable these in the settings section under <strong>"media types"</strong>.]]></key>
@@ -1047,8 +1038,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="relateToOriginal">Relate copied items to original</key>
</area>
<area alias="notifications">
<key alias="editNotifications"><![CDATA[Select your notification for <strong>%0%</strong>]]></key>
<key alias="notificationsSavedFor">Notification settings saved for</key>
<key alias="editNotifications">Edit your notification for %0%</key>
<key alias="mailBody">
<![CDATA[
Hi %0%
@@ -1320,7 +1310,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="undoEditCrop">Undo edits</key>
</area>
<area alias="rollback">
<key alias="headline">Select a version to compare with the current version</key>
<key alias="currentVersion">Current version</key>
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
<key alias="documentRolledBack">Document has been rolled back</key>
@@ -1489,7 +1478,6 @@ To manage your website, simply open the Umbraco back office and start adding con
</area>
<area alias="template">
<key alias="deleteByIdFailed">Failed to delete template with ID %0%</key>
<key alias="edittemplate">Edit template</key>
<key alias="insertSections">Sections</key>
@@ -2206,9 +2194,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[Notification email is still set to the default value of <strong>%0%</strong>.]]></key>
<key alias="scheduledHealthCheckEmailBody"><![CDATA[<html><body><p>Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:</p>%2%</body></html>]]></key>
<key alias="scheduledHealthCheckEmailSubject">Umbraco Health Check Status: %0%</key>
<key alias="tls12HealthCheckSuccess">Your site can use the TLS 1.2 security protocol when making outbound connections to HTTPS endpoints.</key>
<key alias="tls12HealthCheckWarn">Your site isn't configured to allow the TLS 1.2 security protocol when making outbound connections: some HTTPS endpoints might not be reachable using a less secure protocol.</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Disable URL tracker</key>
@@ -33,11 +33,8 @@
<key alias="rename" version="7.3.0">Rename</key>
<key alias="restore" version="7.3.0">Restore</key>
<key alias="SetPermissionsForThePage">Set permissions for the page %0%</key>
<key alias="chooseWhereToCopy">Choose where to copy</key>
<key alias="chooseWhereToMove">Choose where to move</key>
<key alias="toInTheTreeStructureBelow">to in the tree structure below</key>
<key alias="wasMovedTo">was moved to</key>
<key alias="wasCopiedTo">was copied to</key>
<key alias="toInTheTreeStructureBelow">In the tree structure below</key>
<key alias="rights">Permissions</key>
<key alias="rollback">Rollback</key>
<key alias="sendtopublish">Send To Publish</key>
@@ -189,11 +186,6 @@
<key alias="validationErrorPropertyWithMoreThanOneMapping">Could not complete property mapping as one or more properties have more than one mapping defined.</key>
<key alias="validDocTypesNote">Only alternate types valid for the current location are displayed.</key>
</area>
<area alias="codefile">
<key alias="createFolderFailedById">Failed to create a folder under parent with ID %0%</key>
<key alias="createFolderFailedByName">Failed to create a folder under parent with name %0%</key>
<key alias="deleteItemFailed">Failed to delete item: %0%</key>
</area>
<area alias="content">
<key alias="isPublished" version="7.2">Is Published</key>
<key alias="about">About this page</key>
@@ -297,7 +289,6 @@
<key alias="chooseNode">Where do you want to create the new %0%</key>
<key alias="createUnder">Create an item under</key>
<key alias="createContentBlueprint">Select the document type you want to make a content template for</key>
<key alias="enterFolderName">Enter a folder name</key>
<key alias="updateData">Choose a type and a title</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[There are no allowed document types available. You must enable these in the settings section under <strong>"document types"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[There are no allowed media types available. You must enable these in the settings section under <strong>"media types"</strong>.]]></key>
@@ -1046,8 +1037,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="relateToOriginal">Relate copied items to original</key>
</area>
<area alias="notifications">
<key alias="editNotifications"><![CDATA[Select your notification for <strong>%0%</strong>]]></key>
<key alias="notificationsSavedFor">Notification settings saved for</key>
<key alias="editNotifications">Edit your notification for %0%</key>
<key alias="mailBody">
<![CDATA[
Hi %0%
@@ -1319,7 +1309,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="undoEditCrop">Undo edits</key>
</area>
<area alias="rollback">
<key alias="headline">Select a version to compare with the current version</key>
<key alias="currentVersion">Current version</key>
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
<key alias="documentRolledBack">Document has been rolled back</key>
@@ -1487,7 +1476,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="styles">Styles</key>
</area>
<area alias="template">
<key alias="deleteByIdFailed">Failed to delete template with ID %0%</key>
<key alias="edittemplate">Edit template</key>
<key alias="insertSections">Sections</key>
@@ -2199,9 +2187,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[Notification email is still set to the default value of <strong>%0%</strong>.]]></key>
<key alias="scheduledHealthCheckEmailBody"><![CDATA[<html><body><p>Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:</p>%2%</body></html>]]></key>
<key alias="scheduledHealthCheckEmailSubject">Umbraco Health Check Status: %0%</key>
<key alias="tls12HealthCheckSuccess">Your site can use the TLS 1.2 security protocol when making outbound connections to HTTPS endpoints.</key>
<key alias="tls12HealthCheckWarn">Your site isn't configured to allow the TLS 1.2 security protocol when making outbound connections: some HTTPS endpoints might not be reachable using a less secure protocol.</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Disable URL tracker</key>
@@ -2235,4 +2220,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="itemCannotBeRestoredHelpText">There is no location where this item can be automatically restored. You can move the item manually using the tree below.</key>
<key alias="wasRestored">was restored under</key>
</area>
<area alias="notify">
<key alias="notifySet">Select your notifications for</key>
<key alias="notificationsSavedFor">Notification settings saved for </key>
</area>
</language>
@@ -1856,9 +1856,6 @@
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[El email de notificación está todavía configurado en tuvalor por defecto: <strong>%0%</strong>.]]></key>
<key alias="scheduledHealthCheckEmailBody"><![CDATA[<html><body><p>Los resultados de los Chequeos de Salud de Umbraco programados para ejecutarse el %0% a las %1% son:</p>%2%</body></html>]]></key>
<key alias="scheduledHealthCheckEmailSubject">Status de los Chequeos de Salud de Umbraco: %0%</key>
<key alias="tlsHealthCheckSuccess">Su sitio web está configurado para usar TLS 1.2 o superior para las conexiones salientes.</key>
<key alias="tlsHealthCheckWarn">Las conexiones salientes de su sitio web están siendo servidas a través de un protocolo antiguo. Deberías considerar actualizarlo para usar TLS 1.2 o superior.</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Desactivar URL tracker</key>

Some files were not shown because too many files have changed in this diff Show More