Merge branch 'temp8' into temp8-3675-variant-tags

This commit is contained in:
Stephan
2018-12-07 08:49:25 +01:00
123 changed files with 7561 additions and 11449 deletions
+10 -4
View File
@@ -19,7 +19,7 @@ When contributing code to Umbraco there's plenty of things you'll want to know,
* [What branch should I target for my contributions?](#what-branch-should-i-target-for-my-contributions)
* [Building Umbraco from source code](#building-umbraco-from-source-code)
* [Keeping your Umbraco fork in sync with the main repository](#keeping-your-umbraco-fork-in-sync-with-the-main-repository)
## How Can I Contribute?
### Reporting Bugs
@@ -52,7 +52,7 @@ Provide more context by answering these questions:
Include details about your configuration and environment:
* **Which version of Umbraco are you using?**
* **Which version of Umbraco are you using?**
* **What is the environment you're using Umbraco in?** Is this a problem on your local machine or on a server. Tell us about your configuration: Windows version, IIS/IISExpress, database type, etc.
* **Which packages do you have installed?**
@@ -80,7 +80,7 @@ The most successful pull requests usually look a like this:
* Unit tests, while optional are awesome, thank you!
* New code is commented with documentation from which [the reference documentation](https://our.umbraco.com/documentation/Reference/) is generated
Again, these are guidelines, not strict requirements.
Again, these are guidelines, not strict requirements.
## Making changes after the PR was opened
@@ -90,7 +90,7 @@ If you make the corrections we ask for in the same branch and push them to your
To be honest, we don't like rules very much. We trust you have the best of intentions and we encourage you to create working code. If it doesn't look perfect then we'll happily help clean it up.
That said, the Umbraco development team likes to follow the hints that ReSharper gives us (no problem if you don't have this installed) and we've added a `.editorconfig` file so that Visual Studio knows what to do with whitespace, line endings, etc.
That said, the Umbraco development team likes to follow the hints that ReSharper gives us (no problem if you don't have this installed) and we've added a `.editorconfig` file so that Visual Studio knows what to do with whitespace, line endings, etc.
## What should I know before I get started?
@@ -125,6 +125,12 @@ We like to use [Gitflow as much as possible](https://jeffkreeftmeijer.com/git-fl
### Building Umbraco from source code
In order to build the Umbraco source code locally, first make sure you have the following installed.
* Visual Studio 2017 v15.3+
* Node v10+ (Installed via `build.bat` script. If you already have it installed, make sure you're running at least v10)
* npm v6.4.1+ (Installed via `build.bat` script. If you already have it installed, make sure you're running at least v6.4.1)
The easiest way to get started is to run `build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `gulp dev` in `src\Umbraco.Web.UI.Client`. See [this page](BUILD.md) for more details.
Alternatively, you can open `src\umbraco.sln` in Visual Studio 2017 (version 15.3 or higher, [the community edition is free](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15) for you to use to contribute to Open Source projects). In Visual Studio, find the Task Runner Explorer (in the View menu under Other Windows) and run the build task under the gulpfile.
@@ -3,7 +3,7 @@
<section alias="StartupSettingsDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Welcome" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing">
<control showOnce="true" addPanel="true" panelCaption="" xdt:Transform="InsertIfMissing">
<control panelCaption="" xdt:Transform="InsertIfMissing">
views/dashboard/settings/settingsdashboardintro.html
</control>
</tab>
@@ -14,7 +14,7 @@
<area>forms</area>
</areas>
<tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/forms/formsdashboardintro.html
</control>
</tab>
@@ -28,7 +28,7 @@
<section alias="StartupDeveloperDashboardSection">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/developer/developerdashboardvideos.html
</control>
</tab>
@@ -47,7 +47,7 @@
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="InsertIfMissing" />
<tab caption="Content" xdt:Locator="Match(caption)" xdt:Transform="Replace">
<control showOnce="false" addPanel="false" panelCaption="">
<control panelCaption="">
views/dashboard/media/mediafolderbrowser.html
</control>
</tab>
@@ -56,7 +56,7 @@
<section alias="StartupMemberDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
<tab caption="Get Started" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
<tab caption="Get Started" xdt:Transform="Insert">
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/members/membersdashboardvideos.html
</control>
</tab>
@@ -92,4 +92,4 @@
</control>
</tab>
</section>
</dashBoard>
</dashBoard>
@@ -16,6 +16,7 @@ namespace Umbraco.Core.Composing.CompositionRoots
container.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().Templates);
container.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().RequestHandler);
container.Register(factory => UmbracoConfig.For.GlobalSettings());
container.Register(factory => UmbracoConfig.For.DashboardSettings());
// fixme - other sections we need to add?
}
@@ -7,26 +7,22 @@ namespace Umbraco.Core.Configuration.Dashboard
internal class AccessElement : RawXmlConfigurationElement, IAccess
{
public AccessElement()
{
}
{ }
public AccessElement(XElement rawXml)
:base(rawXml)
{
}
: base(rawXml)
{ }
public IEnumerable<IAccessItem> Rules
public IEnumerable<IAccessRule> Rules
{
get
{
var result = new List<AccessItem>();
if (RawXml != null)
{
result.AddRange(RawXml.Elements("deny").Select(x => new AccessItem {Action = AccessType.Deny, Value = x.Value }));
result.AddRange(RawXml.Elements("grant").Select(x => new AccessItem { Action = AccessType.Grant, Value = x.Value }));
result.AddRange(RawXml.Elements("grantBySection").Select(x => new AccessItem { Action = AccessType.GrantBySection, Value = x.Value }));
}
var result = new List<AccessRule>();
if (RawXml == null) return result;
result.AddRange(RawXml.Elements("deny").Select(x => new AccessRule {Type = AccessRuleType.Deny, Value = x.Value }));
result.AddRange(RawXml.Elements("grant").Select(x => new AccessRule { Type = AccessRuleType.Grant, Value = x.Value }));
result.AddRange(RawXml.Elements("grantBySection").Select(x => new AccessRule { Type = AccessRuleType.GrantBySection, Value = x.Value }));
return result;
}
}
@@ -1,15 +0,0 @@
namespace Umbraco.Core.Configuration.Dashboard
{
internal class AccessItem : IAccessItem
{
/// <summary>
/// This can be grant, deny or grantBySection
/// </summary>
public AccessType Action { get; set; }
/// <summary>
/// The value of the action
/// </summary>
public string Value { get; set; }
}
}
@@ -0,0 +1,14 @@
namespace Umbraco.Core.Configuration.Dashboard
{
/// <summary>
/// Implements <see cref="IAccessRule"/>.
/// </summary>
internal class AccessRule : IAccessRule
{
/// <inheritdoc />
public AccessRuleType Type { get; set; }
/// <inheritdoc />
public string Value { get; set; }
}
}
@@ -0,0 +1,28 @@
namespace Umbraco.Core.Configuration.Dashboard
{
/// <summary>
/// Defines dashboard access rules type.
/// </summary>
public enum AccessRuleType
{
/// <summary>
/// Unknown (default value).
/// </summary>
Unknown = 0,
/// <summary>
/// Grant access to the dashboard if user belongs to the specified user group.
/// </summary>
Grant,
/// <summary>
/// Deny access to the dashboard if user belongs to the specified user group.
/// </summary>
Deny,
/// <summary>
/// Grant access to the dashboard if user has access to the specified section.
/// </summary>
GrantBySection
}
}
@@ -1,9 +0,0 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public enum AccessType
{
Grant,
Deny,
GrantBySection
}
}
@@ -1,5 +1,4 @@
using System;
using System.Configuration;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
@@ -8,33 +7,12 @@ namespace Umbraco.Core.Configuration.Dashboard
internal class ControlElement : RawXmlConfigurationElement, IDashboardControl
{
public bool ShowOnce
{
get
{
return RawXml.Attribute("showOnce") == null
? false
: bool.Parse(RawXml.Attribute("showOnce").Value);
}
}
public bool AddPanel
{
get
{
return RawXml.Attribute("addPanel") == null
? true
: bool.Parse(RawXml.Attribute("addPanel").Value);
}
}
public string PanelCaption
{
get
{
return RawXml.Attribute("panelCaption") == null
? ""
: RawXml.Attribute("panelCaption").Value;
var panelCaption = RawXml.Attribute("panelCaption");
return panelCaption == null ? "" : panelCaption.Value;
}
}
@@ -43,11 +21,7 @@ namespace Umbraco.Core.Configuration.Dashboard
get
{
var access = RawXml.Element("access");
if (access == null)
{
return new AccessElement();
}
return new AccessElement(access);
return access == null ? new AccessElement() : new AccessElement(access);
}
}
@@ -65,10 +39,6 @@ namespace Umbraco.Core.Configuration.Dashboard
}
}
IAccess IDashboardControl.AccessRights
{
get { return Access; }
}
IAccess IDashboardControl.AccessRights => Access;
}
}
@@ -4,6 +4,6 @@ namespace Umbraco.Core.Configuration.Dashboard
{
public interface IAccess
{
IEnumerable<IAccessItem> Rules { get; }
IEnumerable<IAccessRule> Rules { get; }
}
}
@@ -1,15 +0,0 @@
namespace Umbraco.Core.Configuration.Dashboard
{
public interface IAccessItem
{
/// <summary>
/// This can be grant, deny or grantBySection
/// </summary>
AccessType Action { get; set; }
/// <summary>
/// The value of the action
/// </summary>
string Value { get; set; }
}
}
@@ -0,0 +1,18 @@
namespace Umbraco.Core.Configuration.Dashboard
{
/// <summary>
/// Represents an access rule.
/// </summary>
public interface IAccessRule
{
/// <summary>
/// Gets or sets the rule type.
/// </summary>
AccessRuleType Type { get; set; }
/// <summary>
/// Gets or sets the value for the rule.
/// </summary>
string Value { get; set; }
}
}
@@ -2,10 +2,6 @@
{
public interface IDashboardControl
{
bool ShowOnce { get; }
bool AddPanel { get; }
string PanelCaption { get; }
string ControlPath { get; }
@@ -0,0 +1,45 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Serialization;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Implements a json read converter for <see cref="IAccessRule"/>.
/// </summary>
internal class DashboardAccessRuleConverter : JsonReadConverter<IAccessRule>
{
/// <inheritdoc />
protected override IAccessRule Create(Type objectType, string path, JObject jObject)
{
return new AccessRule();
}
/// <inheritdoc />
protected override void Deserialize(JObject jobject, IAccessRule target, JsonSerializer serializer)
{
// see Create above, target is either DataEditor (parameter) or ConfiguredDataEditor (property)
if (!(target is AccessRule accessRule))
throw new Exception("panic.");
GetRule(accessRule, jobject, "grant", AccessRuleType.Grant);
GetRule(accessRule, jobject, "deny", AccessRuleType.Deny);
GetRule(accessRule, jobject, "grantBySection", AccessRuleType.GrantBySection);
if (accessRule.Type == AccessRuleType.Unknown) throw new InvalidOperationException("Rule is not defined.");
}
private void GetRule(AccessRule rule, JObject jobject, string name, AccessRuleType type)
{
var token = jobject[name];
if (token == null) return;
if (rule.Type != AccessRuleType.Unknown) throw new InvalidOperationException("Multiple definition of a rule.");
if (token.Type != JTokenType.String) throw new InvalidOperationException("Rule value is not a string.");
rule.Type = type;
rule.Value = token.Value<string>();
}
}
}
@@ -0,0 +1,36 @@
using System;
using System.ComponentModel;
using Newtonsoft.Json;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.IO;
namespace Umbraco.Core.Manifest
{
public class ManifestDashboardDefinition
{
private string _view;
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonProperty("alias", Required = Required.Always)]
public string Alias { get; set; }
[JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
[DefaultValue(100)]
public int Weight { get; set; }
[JsonProperty("view", Required = Required.Always)]
public string View
{
get => _view;
set => _view = IOHelper.ResolveVirtualUrl(value);
}
[JsonProperty("sections")]
public string[] Sections { get; set; } = Array.Empty<string>();
[JsonProperty("access")]
public IAccessRule[] AccessRules { get; set; } = Array.Empty<IAccessRule>();
}
}
+180 -177
View File
@@ -1,177 +1,180 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Umbraco.Core.Cache;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Parses the Main.js file and replaces all tokens accordingly.
/// </summary>
public class ManifestParser
{
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
private readonly IRuntimeCacheProvider _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
private string _path;
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
public ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, ILogger logger)
: this(cache, validators, "~/App_Plugins", logger)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
private ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, string path, ILogger logger)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public string Path
{
get => _path;
set => _path = value.StartsWith("~/") ? IOHelper.MapPath(value) : value;
}
/// <summary>
/// Gets all manifests, merged into a single manifest object.
/// </summary>
/// <returns></returns>
public PackageManifest Manifest
=> _cache.GetCacheItem<PackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
{
var manifests = GetManifests();
return MergeManifests(manifests);
}, new TimeSpan(0, 4, 0));
/// <summary>
/// Gets all manifests.
/// </summary>
private IEnumerable<PackageManifest> GetManifests()
{
var manifests = new List<PackageManifest>();
foreach (var path in GetManifestFiles())
{
try
{
var text = File.ReadAllText(path);
text = TrimPreamble(text);
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
manifests.Add(manifest);
}
catch (Exception e)
{
_logger.Error<ManifestParser>(e, "Failed to parse manifest at '{Path}', ignoring.", path);
}
}
return manifests;
}
/// <summary>
/// Merges all manifests into one.
/// </summary>
private static PackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
{
var scripts = new HashSet<string>();
var stylesheets = new HashSet<string>();
var propertyEditors = new List<IDataEditor>();
var parameterEditors = new List<IDataEditor>();
var gridEditors = new List<GridEditor>();
var contentApps = new List<IContentAppDefinition>();
foreach (var manifest in manifests)
{
if (manifest.Scripts != null) foreach (var script in manifest.Scripts) scripts.Add(script);
if (manifest.Stylesheets != null) foreach (var stylesheet in manifest.Stylesheets) stylesheets.Add(stylesheet);
if (manifest.PropertyEditors != null) propertyEditors.AddRange(manifest.PropertyEditors);
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps);
}
return new PackageManifest
{
Scripts = scripts.ToArray(),
Stylesheets = stylesheets.ToArray(),
PropertyEditors = propertyEditors.ToArray(),
ParameterEditors = parameterEditors.ToArray(),
GridEditors = gridEditors.ToArray(),
ContentApps = contentApps.ToArray()
};
}
// gets all manifest files (recursively)
private IEnumerable<string> GetManifestFiles()
{
if (Directory.Exists(_path) == false)
return new string[0];
return Directory.GetFiles(_path, "package.manifest", SearchOption.AllDirectories);
}
private static string TrimPreamble(string text)
{
// strangely StartsWith(preamble) would always return true
if (text.Substring(0, 1) == Utf8Preamble)
text = text.Remove(0, Utf8Preamble.Length);
return text;
}
/// <summary>
/// Parses a manifest.
/// </summary>
internal PackageManifest ParseManifest(string text)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentNullOrEmptyException(nameof(text));
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger),
new ValueValidatorConverter(_validators),
new ContentAppDefinitionConverter());
// scripts and stylesheets are raw string, must process here
for (var i = 0; i < manifest.Scripts.Length; i++)
manifest.Scripts[i] = IOHelper.ResolveVirtualUrl(manifest.Scripts[i]);
for (var i = 0; i < manifest.Stylesheets.Length; i++)
manifest.Stylesheets[i] = IOHelper.ResolveVirtualUrl(manifest.Stylesheets[i]);
// add property editors that are also parameter editors, to the parameter editors list
// (the manifest format is kinda legacy)
var ppEditors = manifest.PropertyEditors.Where(x => (x.Type & EditorType.MacroParameter) > 0).ToList();
if (ppEditors.Count > 0)
manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray();
return manifest;
}
// purely for tests
internal IEnumerable<GridEditor> ParseGridEditors(string text)
{
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Umbraco.Core.Cache;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Parses the Main.js file and replaces all tokens accordingly.
/// </summary>
public class ManifestParser
{
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
private readonly IRuntimeCacheProvider _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
private string _path;
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
public ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, ILogger logger)
: this(cache, validators, "~/App_Plugins", logger)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
private ManifestParser(IRuntimeCacheProvider cache, ManifestValueValidatorCollection validators, string path, ILogger logger)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public string Path
{
get => _path;
set => _path = value.StartsWith("~/") ? IOHelper.MapPath(value) : value;
}
/// <summary>
/// Gets all manifests, merged into a single manifest object.
/// </summary>
/// <returns></returns>
public PackageManifest Manifest
=> _cache.GetCacheItem<PackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
{
var manifests = GetManifests();
return MergeManifests(manifests);
}, new TimeSpan(0, 4, 0));
/// <summary>
/// Gets all manifests.
/// </summary>
private IEnumerable<PackageManifest> GetManifests()
{
var manifests = new List<PackageManifest>();
foreach (var path in GetManifestFiles())
{
try
{
var text = File.ReadAllText(path);
text = TrimPreamble(text);
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
manifests.Add(manifest);
}
catch (Exception e)
{
_logger.Error<ManifestParser>(e, "Failed to parse manifest at '{Path}', ignoring.", path);
}
}
return manifests;
}
/// <summary>
/// Merges all manifests into one.
/// </summary>
private static PackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
{
var scripts = new HashSet<string>();
var stylesheets = new HashSet<string>();
var propertyEditors = new List<IDataEditor>();
var parameterEditors = new List<IDataEditor>();
var gridEditors = new List<GridEditor>();
var contentApps = new List<IContentAppDefinition>();
var dashboards = new List<ManifestDashboardDefinition>();
foreach (var manifest in manifests)
{
if (manifest.Scripts != null) foreach (var script in manifest.Scripts) scripts.Add(script);
if (manifest.Stylesheets != null) foreach (var stylesheet in manifest.Stylesheets) stylesheets.Add(stylesheet);
if (manifest.PropertyEditors != null) propertyEditors.AddRange(manifest.PropertyEditors);
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps);
if (manifest.Dashboards != null) dashboards.AddRange(manifest.Dashboards);
}
return new PackageManifest
{
Scripts = scripts.ToArray(),
Stylesheets = stylesheets.ToArray(),
PropertyEditors = propertyEditors.ToArray(),
ParameterEditors = parameterEditors.ToArray(),
GridEditors = gridEditors.ToArray(),
ContentApps = contentApps.ToArray(),
Dashboards = dashboards.ToArray()
};
}
// gets all manifest files (recursively)
private IEnumerable<string> GetManifestFiles()
{
if (Directory.Exists(_path) == false)
return new string[0];
return Directory.GetFiles(_path, "package.manifest", SearchOption.AllDirectories);
}
private static string TrimPreamble(string text)
{
// strangely StartsWith(preamble) would always return true
if (text.Substring(0, 1) == Utf8Preamble)
text = text.Remove(0, Utf8Preamble.Length);
return text;
}
/// <summary>
/// Parses a manifest.
/// </summary>
internal PackageManifest ParseManifest(string text)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentNullOrEmptyException(nameof(text));
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger),
new ValueValidatorConverter(_validators),
new ContentAppDefinitionConverter(),
new DashboardAccessRuleConverter());
// scripts and stylesheets are raw string, must process here
for (var i = 0; i < manifest.Scripts.Length; i++)
manifest.Scripts[i] = IOHelper.ResolveVirtualUrl(manifest.Scripts[i]);
for (var i = 0; i < manifest.Stylesheets.Length; i++)
manifest.Stylesheets[i] = IOHelper.ResolveVirtualUrl(manifest.Stylesheets[i]);
// add property editors that are also parameter editors, to the parameter editors list
// (the manifest format is kinda legacy)
var ppEditors = manifest.PropertyEditors.Where(x => (x.Type & EditorType.MacroParameter) > 0).ToList();
if (ppEditors.Count > 0)
manifest.ParameterEditors = manifest.ParameterEditors.Union(ppEditors).ToArray();
return manifest;
}
// purely for tests
internal IEnumerable<GridEditor> ParseGridEditors(string text)
{
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(text);
}
}
}
+34 -31
View File
@@ -1,31 +1,34 @@
using System;
using Newtonsoft.Json;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Represents the content of a package manifest.
/// </summary>
public class PackageManifest
{
[JsonProperty("javascript")]
public string[] Scripts { get; set; } = Array.Empty<string>();
[JsonProperty("css")]
public string[] Stylesheets { get; set; }= Array.Empty<string>();
[JsonProperty("propertyEditors")]
public IDataEditor[] PropertyEditors { get; set; } = Array.Empty<IDataEditor>();
[JsonProperty("parameterEditors")]
public IDataEditor[] ParameterEditors { get; set; } = Array.Empty<IDataEditor>();
[JsonProperty("gridEditors")]
public GridEditor[] GridEditors { get; set; } = Array.Empty<GridEditor>();
[JsonProperty("contentApps")]
public IContentAppDefinition[] ContentApps { get; set; } = Array.Empty<IContentAppDefinition>();
}
}
using System;
using Newtonsoft.Json;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Manifest
{
/// <summary>
/// Represents the content of a package manifest.
/// </summary>
public class PackageManifest
{
[JsonProperty("javascript")]
public string[] Scripts { get; set; } = Array.Empty<string>();
[JsonProperty("css")]
public string[] Stylesheets { get; set; }= Array.Empty<string>();
[JsonProperty("propertyEditors")]
public IDataEditor[] PropertyEditors { get; set; } = Array.Empty<IDataEditor>();
[JsonProperty("parameterEditors")]
public IDataEditor[] ParameterEditors { get; set; } = Array.Empty<IDataEditor>();
[JsonProperty("gridEditors")]
public GridEditor[] GridEditors { get; set; } = Array.Empty<GridEditor>();
[JsonProperty("contentApps")]
public IContentAppDefinition[] ContentApps { get; set; } = Array.Empty<IContentAppDefinition>();
[JsonProperty("dashboards")]
public ManifestDashboardDefinition[] Dashboards { get; set; } = Array.Empty<ManifestDashboardDefinition>();
}
}
@@ -3,6 +3,7 @@ using Umbraco.Core.Models.Membership;
namespace Umbraco.Core.Models.ContentEditing
{
/// <summary>
/// Represents a content app definition.
/// </summary>
@@ -169,6 +169,7 @@ namespace Umbraco.Core.Models
/// Gets the schedule for a culture
/// </summary>
/// <param name="culture"></param>
/// <param name="action"></param>
/// <returns></returns>
public IEnumerable<ContentSchedule> GetSchedule(string culture, ContentScheduleAction? action = null)
{
+6 -2
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Composing;
@@ -55,8 +56,11 @@ namespace Umbraco.Core.Models
/// </returns>
internal static string[] GetUserAvatarUrls(this IUser user, ICacheProvider staticCache)
{
//check if the user has explicitly removed all avatars including a gravatar, this will be possible and the value will be "none"
if (user.Avatar == "none")
// If FIPS is required, never check the Gravatar service as it only supports MD5 hashing.
// Unfortunately, if the FIPS setting is enabled on Windows, using MD5 will throw an exception
// and the website will not run.
// Also, check if the user has explicitly removed all avatars including a gravatar, this will be possible and the value will be "none"
if (user.Avatar == "none" || CryptoConfig.AllowOnlyFipsAlgorithms)
{
return new string[0];
}
@@ -211,12 +211,20 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
//.Where(x => Equals(x, default(TId)) == false)
.ToArray();
if (ids.Length > 2000)
// can't query more than 2000 ids at a time... but if someone is really querying 2000+ entities,
// the additional overhead of fetching them in groups is minimal compared to the lookup time of each group
const int maxParams = 2000;
if (ids.Length <= maxParams)
{
throw new InvalidOperationException("Cannot perform a query with more than 2000 parameters");
return CachePolicy.GetAll(ids, PerformGetAll);
}
return CachePolicy.GetAll(ids, PerformGetAll);
var entities = new List<TEntity>();
foreach (var groupOfIds in ids.InGroupsOf(maxParams))
{
entities.AddRange(CachePolicy.GetAll(groupOfIds.ToArray(), PerformGetAll));
}
return entities;
}
/// <summary>
+5 -3
View File
@@ -194,8 +194,8 @@
<Compile Include="Configuration\CommaDelimitedConfigurationElement.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
<Compile Include="Configuration\Dashboard\AccessItem.cs" />
<Compile Include="Configuration\Dashboard\AccessType.cs" />
<Compile Include="Configuration\Dashboard\AccessRule.cs" />
<Compile Include="Configuration\Dashboard\AccessRuleType.cs" />
<Compile Include="Configuration\Dashboard\AreaCollection.cs" />
<Compile Include="Configuration\Dashboard\AreaElement.cs" />
<Compile Include="Configuration\Dashboard\AreasElement.cs" />
@@ -203,7 +203,7 @@
<Compile Include="Configuration\Dashboard\ControlElement.cs" />
<Compile Include="Configuration\Dashboard\DashboardSection.cs" />
<Compile Include="Configuration\Dashboard\IAccess.cs" />
<Compile Include="Configuration\Dashboard\IAccessItem.cs" />
<Compile Include="Configuration\Dashboard\IAccessRule.cs" />
<Compile Include="Configuration\Dashboard\IArea.cs" />
<Compile Include="Configuration\Dashboard\IDashboardControl.cs" />
<Compile Include="Configuration\Dashboard\IDashboardSection.cs" />
@@ -334,7 +334,9 @@
<Compile Include="Logging\Serilog\LoggerConfigExtensions.cs" />
<Compile Include="Logging\Serilog\Enrichers\Log4NetLevelMapperEnricher.cs" />
<Compile Include="Manifest\ContentAppDefinitionConverter.cs" />
<Compile Include="Manifest\DashboardAccessRuleConverter.cs" />
<Compile Include="Manifest\ManifestContentAppDefinition.cs" />
<Compile Include="Manifest\ManifestDashboardDefinition.cs" />
<Compile Include="Migrations\IncompleteMigrationExpressionException.cs" />
<Compile Include="Migrations\MigrationBase_Extra.cs" />
<Compile Include="Migrations\Upgrade\V_7_10_0\RenamePreviewFolder.cs" />
@@ -6,10 +6,10 @@
<area>settings</area>
</areas>
<tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption="hello">
<control panelCaption="hello">
views/dashboard/settings/settingsdashboardintro.html
</control>
<control showOnce="false" addPanel="false" panelCaption="">
<control panelCaption="">
views/dashboard/settings/settingsdashboardvideos.html
</control>
</tab>
@@ -23,10 +23,10 @@
<area>developer</area>
</areas>
<tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/developer/developerdashboardintro.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/developer/developerdashboardvideos.html
</control>
</tab>
@@ -37,7 +37,7 @@
<area>media</area>
</areas>
<tab caption="Content">
<control showOnce="false" addPanel="false" panelCaption="">
<control panelCaption="">
views/dashboard/media/mediafolderbrowser.html
</control>
</tab>
@@ -45,13 +45,13 @@
<access>
<grant>admin</grant>
</access>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/media/mediadashboardintro.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/media/desktopmediauploader.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/media/mediadashboardvideos.html
</control>
</tab>
@@ -70,25 +70,25 @@
<access>
<grant>admin</grant>
</access>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/default/startupdashboardintro.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/default/startupdashboardkits.html
<access>
<deny>editor</deny>
<deny>writer</deny>
</access>
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/default/startupdashboardvideos.html
</control>
</tab>
<tab caption="Last Edits">
<control addPanel="true" MaxRecords="30">dashboard/latestEdits.ascx</control>
<control MaxRecords="30">dashboard/latestEdits.ascx</control>
</tab>
<tab caption="Change Password">
<control addPanel="true">
<control >
views/dashboard/changepassword.html
</control>
</tab>
@@ -100,13 +100,13 @@
<area>member</area>
</areas>
<tab caption="Get Started">
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/members/membersdashboardintro.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
members/membersearch.ascx
</control>
<control showOnce="true" addPanel="true" panelCaption="">
<control panelCaption="">
views/dashboard/members/membersdashboardvideos.html
</control>
</tab>
@@ -56,11 +56,11 @@ namespace Umbraco.Tests.Configurations.DashboardSettings
Assert.AreEqual(3, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.Count());
Assert.AreEqual("translator", SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(0).Value);
Assert.AreEqual(AccessType.Deny, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(0).Action);
Assert.AreEqual(AccessRuleType.Deny, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(0).Type);
Assert.AreEqual("hello", SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(1).Value);
Assert.AreEqual(AccessType.Grant, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(1).Action);
Assert.AreEqual(AccessRuleType.Grant, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(1).Type);
Assert.AreEqual("world", SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(2).Value);
Assert.AreEqual(AccessType.GrantBySection, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(2).Action);
Assert.AreEqual(AccessRuleType.GrantBySection, SettingsSection.Sections.ElementAt(3).AccessRights.Rules.ElementAt(2).Type);
}
[Test]
@@ -94,21 +94,17 @@ namespace Umbraco.Tests.Configurations.DashboardSettings
public void Test_Tab_Access()
{
Assert.AreEqual(1, SettingsSection.Sections.ElementAt(2).Tabs.ElementAt(1).AccessRights.Rules.Count());
Assert.AreEqual(AccessType.Grant, SettingsSection.Sections.ElementAt(2).Tabs.ElementAt(1).AccessRights.Rules.ElementAt(0).Action);
Assert.AreEqual(AccessRuleType.Grant, SettingsSection.Sections.ElementAt(2).Tabs.ElementAt(1).AccessRights.Rules.ElementAt(0).Type);
Assert.AreEqual("admin", SettingsSection.Sections.ElementAt(2).Tabs.ElementAt(1).AccessRights.Rules.ElementAt(0).Value);
}
[Test]
public void Test_Control()
{
Assert.AreEqual(true, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).ShowOnce);
Assert.AreEqual(true, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).AddPanel);
Assert.AreEqual("hello", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).PanelCaption);
Assert.AreEqual("views/dashboard/settings/settingsdashboardintro.html",
SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(0).ControlPath);
Assert.AreEqual(false, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).ShowOnce);
Assert.AreEqual(false, SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).AddPanel);
Assert.AreEqual("", SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).PanelCaption);
Assert.AreEqual("views/dashboard/settings/settingsdashboardvideos.html",
SettingsSection.Sections.ElementAt(0).Tabs.ElementAt(0).Controls.ElementAt(1).ControlPath);
@@ -118,9 +114,9 @@ namespace Umbraco.Tests.Configurations.DashboardSettings
public void Test_Control_Access()
{
Assert.AreEqual(2, SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.Count());
Assert.AreEqual(AccessType.Deny, SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(0).Action);
Assert.AreEqual(AccessRuleType.Deny, SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(0).Type);
Assert.AreEqual("editor", SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(0).Value);
Assert.AreEqual(AccessType.Deny, SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(1).Action);
Assert.AreEqual(AccessRuleType.Deny, SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(1).Type);
Assert.AreEqual("writer", SettingsSection.Sections.ElementAt(3).Tabs.ElementAt(0).Controls.ElementAt(1).AccessRights.Rules.ElementAt(1).Value);
}
}
@@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.Dashboard;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
using Umbraco.Core.PropertyEditors;
@@ -383,5 +384,53 @@ javascript: ['~/test.js',/*** some note about stuff asd09823-4**09234*/ '~/test2
Assert.AreEqual("icon-bar", app1.Icon);
Assert.AreEqual("/App_Plugins/MyPackage/ContentApps/MyApp2.html", app1.View);
}
[Test]
public void CanParseManifest_Dashboards()
{
const string json = @"{'dashboards': [
{
'name': 'First One',
'alias': 'something',
'view': '~/App_Plugins/MyPackage/Dashboards/one.html',
'sections': [ 'content' ],
'access': [ {'grant':'user'}, {'deny':'foo'} ]
},
{
'name': 'Second-One',
'alias': 'something.else',
'weight': -1,
'view': '~/App_Plugins/MyPackage/Dashboards/two.html',
'sections': [ 'forms' ],
}
]}";
var manifest = _parser.ParseManifest(json);
Assert.AreEqual(2, manifest.Dashboards.Length);
Assert.IsInstanceOf<ManifestDashboardDefinition>(manifest.Dashboards[0]);
var db0 = manifest.Dashboards[0];
Assert.AreEqual("something", db0.Alias);
Assert.AreEqual("First One", db0.Name);
Assert.AreEqual(100, db0.Weight);
Assert.AreEqual("/App_Plugins/MyPackage/Dashboards/one.html", db0.View);
Assert.AreEqual(1, db0.Sections.Length);
Assert.AreEqual("content", db0.Sections[0]);
Assert.AreEqual(2, db0.AccessRules.Length);
Assert.AreEqual(AccessRuleType.Grant, db0.AccessRules[0].Type);
Assert.AreEqual("user", db0.AccessRules[0].Value);
Assert.AreEqual(AccessRuleType.Deny, db0.AccessRules[1].Type);
Assert.AreEqual("foo", db0.AccessRules[1].Value);
Assert.IsInstanceOf<ManifestDashboardDefinition>(manifest.Dashboards[1]);
var db1 = manifest.Dashboards[1];
Assert.AreEqual("something.else", db1.Alias);
Assert.AreEqual("Second-One", db1.Name);
Assert.AreEqual(-1, db1.Weight);
Assert.AreEqual("/App_Plugins/MyPackage/Dashboards/two.html", db1.View);
Assert.AreEqual(1, db1.Sections.Length);
Assert.AreEqual("forms", db1.Sections[0]);
}
}
}
+13 -24
View File
@@ -282,48 +282,29 @@ gulp.task('dependencies', function () {
],
"base": "./node_modules/jquery/dist"
},
{
"name": "jquery-migrate",
"src": ["./node_modules/jquery-migrate/dist/jquery-migrate.min.js"],
"base": "./node_modules/jquery-migrate/dist"
},
{
"name": "jquery-ui",
"src": ["./node_modules/jquery-ui-dist/jquery-ui.min.js"],
"base": "./node_modules/jquery-ui-dist"
},
{
"name": "jquery-validate",
"src": ["./node_modules/jquery-validation/dist/jquery.validate.min.js"],
"base": "./node_modules/jquery-validation/dist"
},
{
"name": "jquery-validation-unobtrusive",
"src": ["./node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"],
"base": "./node_modules/jquery-validation-unobtrusive/dist"
"name": "jquery-ui-touch-punch",
"src": ["./node_modules/jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"],
"base": "./node_modules/jquery-ui-touch-punch"
},
{
"name": "lazyload-js",
"src": ["./node_modules/lazyload-js/lazyload.min.js"],
"base": "./node_modules/lazyload-js"
},
// TODO: We can optimize here:
// we don't have to ship with the moment-with-locales libraries
// we lazyload the user locale
{
"name": "moment",
"src": [
"./node_modules/moment/min/moment.min.js",
"./node_modules/moment/min/moment-with-locales.js",
"./node_modules/moment/min/moment-with-locales.min.js"
],
"src": ["./node_modules/moment/min/moment.min.js"],
"base": "./node_modules/moment/min"
},
{
"name": "moment",
"src": [
"./node_modules/moment/locale/*.js"
],
"src": ["./node_modules/moment/locale/*.js"],
"base": "./node_modules/moment/locale"
},
{
@@ -344,6 +325,14 @@ gulp.task('dependencies', function () {
"src": ["./node_modules/signalr/jquery.signalR.js"],
"base": "./node_modules/signalr"
},
{
"name": "spectrum",
"src": [
"./node_modules/spectrum-colorpicker/spectrum.js",
"./node_modules/spectrum-colorpicker/spectrum.css"
],
"base": "./node_modules/spectrum-colorpicker"
},
{
"name": "tinymce",
"src": [
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -1,180 +0,0 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function ($) {
// Detect touch support
$.support.touch = 'ontouchend' in document;
// Ignore browsers without touch support
if (!$.support.touch) {
return;
}
var mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
_mouseDestroy = mouseProto._mouseDestroy,
touchHandled;
/**
* Simulate a mouse event based on a corresponding touch event
* @param {Object} event A touch event
* @param {String} simulatedType The corresponding mouse event
*/
function simulateMouseEvent (event, simulatedType) {
// Ignore multi-touch events
if (event.originalEvent.touches.length > 1) {
return;
}
event.preventDefault();
var touch = event.originalEvent.changedTouches[0],
simulatedEvent = document.createEvent('MouseEvents');
// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);
// Dispatch the simulated event to the target element
event.target.dispatchEvent(simulatedEvent);
}
/**
* Handle the jQuery UI widget's touchstart events
* @param {Object} event The widget element's touchstart event
*/
mouseProto._touchStart = function (event) {
var self = this;
// Ignore the event if another widget is already being handled
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
return;
}
// Set the flag to prevent other widgets from inheriting the touch event
touchHandled = true;
// Track movement to determine if interaction was a click
self._touchMoved = false;
// Simulate the mouseover event
simulateMouseEvent(event, 'mouseover');
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
// Simulate the mousedown event
simulateMouseEvent(event, 'mousedown');
};
/**
* Handle the jQuery UI widget's touchmove events
* @param {Object} event The document's touchmove event
*/
mouseProto._touchMove = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Interaction was not a click
this._touchMoved = true;
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
};
/**
* Handle the jQuery UI widget's touchend events
* @param {Object} event The document's touchend event
*/
mouseProto._touchEnd = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Simulate the mouseup event
simulateMouseEvent(event, 'mouseup');
// Simulate the mouseout event
simulateMouseEvent(event, 'mouseout');
// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved) {
// Simulate the click event
simulateMouseEvent(event, 'click');
}
// Unset the flag to allow other widgets to inherit the touch event
touchHandled = false;
};
/**
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
* This method extends the widget with bound touch event handlers that
* translate touch events to mouse events and pass them to the widget's
* original mouse event handling methods.
*/
mouseProto._mouseInit = function () {
var self = this;
// Delegate the touch handlers to the widget's element
self.element.bind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
});
// Call the original $.ui.mouse init method
_mouseInit.call(self);
};
/**
* Remove the touch event handlers
*/
mouseProto._mouseDestroy = function () {
var self = this;
// Delegate the touch handlers to the widget's element
self.element.unbind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
});
// Call the original $.ui.mouse destroy method
_mouseDestroy.call(self);
};
})(jQuery);
File diff suppressed because one or more lines are too long
@@ -1,519 +0,0 @@
/***
Spectrum Colorpicker v1.3.3
https://github.com/bgrins/spectrum
Author: Brian Grinstead
License: MIT
***/
.sp-container {
position:absolute;
top:0;
left:0;
display:inline-block;
*display: inline;
*zoom: 1;
/* https://github.com/bgrins/spectrum/issues/40 */
z-index: 9999994;
overflow: hidden;
}
.sp-container.sp-flat {
position: relative;
}
/* Fix for * { box-sizing: border-box; } */
.sp-container,
.sp-container * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
.sp-top {
position:relative;
width: 100%;
display:inline-block;
}
.sp-top-inner {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
}
.sp-color {
position: absolute;
top:0;
left:0;
bottom:0;
right:20%;
}
.sp-hue {
position: absolute;
top:0;
right:0;
bottom:0;
left:84%;
height: 100%;
}
.sp-clear-enabled .sp-hue {
top:33px;
height: 77.5%;
}
.sp-fill {
padding-top: 80%;
}
.sp-sat, .sp-val {
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
}
.sp-alpha-enabled .sp-top {
margin-bottom: 18px;
}
.sp-alpha-enabled .sp-alpha {
display: block;
}
.sp-alpha-handle {
position:absolute;
top:-4px;
bottom: -4px;
width: 6px;
left: 50%;
cursor: pointer;
border: 1px solid black;
background: white;
opacity: .8;
}
.sp-alpha {
display: none;
position: absolute;
bottom: -14px;
right: 0;
left: 0;
height: 8px;
}
.sp-alpha-inner {
border: solid 1px #333;
}
.sp-clear {
display: none;
}
.sp-clear.sp-clear-display {
background-position: center;
}
.sp-clear-enabled .sp-clear {
display: block;
position:absolute;
top:0px;
right:0;
bottom:0;
left:84%;
height: 28px;
}
/* Don't allow text selection */
.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
-webkit-user-select:none;
-moz-user-select: -moz-none;
-o-user-select:none;
user-select: none;
}
.sp-container.sp-input-disabled .sp-input-container {
display: none;
}
.sp-container.sp-buttons-disabled .sp-button-container {
display: none;
}
.sp-palette-only .sp-picker-container {
display: none;
}
.sp-palette-disabled .sp-palette-container {
display: none;
}
.sp-initial-disabled .sp-initial {
display: none;
}
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
.sp-sat {
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
}
.sp-val {
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
}
.sp-hue {
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}
/* IE filters do not support multiple color stops.
Generate 6 divs, line them up, and do two color gradients for each.
Yes, really.
*/
.sp-1 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
}
.sp-2 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
}
.sp-3 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
}
.sp-4 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
}
.sp-5 {
height:16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
}
.sp-6 {
height:17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
}
.sp-hidden {
display: none !important;
}
/* Clearfix hack */
.sp-cf:before, .sp-cf:after { content: ""; display: table; }
.sp-cf:after { clear: both; }
.sp-cf { *zoom: 1; }
/* Mobile devices, make hue slider bigger so it is easier to slide */
@media (max-device-width: 480px) {
.sp-color { right: 40%; }
.sp-hue { left: 63%; }
.sp-fill { padding-top: 60%; }
}
.sp-dragger {
border-radius: 5px;
height: 5px;
width: 5px;
border: 1px solid #fff;
background: #000;
cursor: pointer;
position:absolute;
top:0;
left: 0;
}
.sp-slider {
position: absolute;
top:0;
cursor:pointer;
height: 3px;
left: -1px;
right: -1px;
border: 1px solid #000;
background: white;
opacity: .8;
}
/*
Theme authors:
Here are the basic themeable display options (colors, fonts, global widths).
See http://bgrins.github.io/spectrum/themes/ for instructions.
*/
.sp-container {
border-radius: 0;
background-color: #ECECEC;
border: solid 1px #f0c49B;
padding: 0;
}
.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear
{
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.sp-top
{
margin-bottom: 3px;
}
.sp-color, .sp-hue, .sp-clear
{
border: solid 1px #666;
}
/* Input */
.sp-input-container {
float:right;
width: 100px;
margin-bottom: 4px;
}
.sp-initial-disabled .sp-input-container {
width: 100%;
}
.sp-input {
font-size: 12px !important;
border: 1px inset;
padding: 4px 5px;
margin: 0;
width: 100%;
background:transparent;
border-radius: 3px;
color: #222;
}
.sp-input:focus {
border: 1px solid orange;
}
.sp-input.sp-validation-error
{
border: 1px solid red;
background: #fdd;
}
.sp-picker-container , .sp-palette-container
{
float:left;
position: relative;
padding: 10px;
padding-bottom: 300px;
margin-bottom: -290px;
}
.sp-picker-container
{
width: 172px;
border-left: solid 1px #fff;
}
/* Palettes */
.sp-palette-container
{
border-right: solid 1px #ccc;
}
.sp-palette .sp-thumb-el {
display: block;
position:relative;
float:left;
width: 24px;
height: 15px;
margin: 3px;
cursor: pointer;
border:solid 2px transparent;
}
.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
border-color: orange;
}
.sp-thumb-el
{
position:relative;
}
/* Initial */
.sp-initial
{
float: left;
border: solid 1px #333;
}
.sp-initial span {
width: 30px;
height: 25px;
border:none;
display:block;
float:left;
margin:0;
}
.sp-initial .sp-clear-display {
background-position: center;
}
/* Buttons */
.sp-button-container {
float: right;
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-replacer {
margin:0;
overflow:hidden;
cursor:pointer;
padding: 4px;
display:inline-block;
*zoom: 1;
*display: inline;
border: solid 1px #91765d;
background: #eee;
color: #333;
vertical-align: middle;
}
.sp-replacer:hover, .sp-replacer.sp-active {
border-color: #F0C49B;
color: #111;
}
.sp-replacer.sp-disabled {
cursor:default;
border-color: silver;
color: silver;
}
.sp-dd {
padding: 2px 0;
height: 16px;
line-height: 16px;
float:left;
font-size:10px;
}
.sp-preview
{
position:relative;
width:25px;
height: 20px;
border: solid 1px #222;
margin-right: 5px;
float:left;
z-index: 0;
}
.sp-palette
{
*width: 220px;
max-width: 220px;
}
.sp-palette .sp-thumb-el
{
width:16px;
height: 16px;
margin:2px 1px;
border: solid 1px #d0d0d0;
}
.sp-container
{
padding-bottom:0;
}
/* Buttons: http://hellohappy.org/css3-buttons/ */
.sp-container button {
background-color: #eeeeee;
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
border: 1px solid #ccc;
border-bottom: 1px solid #bbb;
border-radius: 3px;
color: #333;
font-size: 14px;
line-height: 1;
padding: 5px 4px;
text-align: center;
text-shadow: 0 1px 0 #eee;
vertical-align: middle;
}
.sp-container button:hover {
background-color: #dddddd;
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
border: 1px solid #bbb;
border-bottom: 1px solid #999;
cursor: pointer;
text-shadow: 0 1px 0 #ddd;
}
.sp-container button:active {
border: 1px solid #aaa;
border-bottom: 1px solid #888;
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
}
.sp-cancel
{
font-size: 11px;
color: #d93f3f !important;
margin:0;
padding:2px;
margin-right: 5px;
vertical-align: middle;
text-decoration:none;
}
.sp-cancel:hover
{
color: #d93f3f !important;
text-decoration: underline;
}
.sp-palette span:hover, .sp-palette span.sp-thumb-active
{
border-color: #000;
}
.sp-preview, .sp-alpha, .sp-thumb-el
{
position:relative;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
}
.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner
{
display:block;
position:absolute;
top:0;left:0;bottom:0;right:0;
}
.sp-palette .sp-thumb-inner
{
background-position: 50% 50%;
background-repeat: no-repeat;
}
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
}
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
}
.sp-clear-display {
background-repeat:no-repeat;
background-position: center;
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
}
File diff suppressed because one or more lines are too long
+6048 -5548
View File
File diff suppressed because it is too large Load Diff
+41 -41
View File
@@ -5,7 +5,7 @@
"build": "gulp"
},
"dependencies": {
"ace-builds": "1.3.3",
"ace-builds": "1.4.2",
"angular": "1.7.5",
"angular-animate": "1.7.5",
"angular-cookies": "1.7.5",
@@ -17,57 +17,57 @@
"angular-route": "1.7.5",
"angular-sanitize": "1.7.5",
"angular-touch": "1.7.5",
"angular-ui-sortable": "0.15.0",
"angular-ui-sortable": "0.19.0",
"animejs": "2.2.0",
"bootstrap-social": "4.8.0",
"clipboard": "2.0.0",
"diff": "3.4.0",
"bootstrap-social": "5.1.1",
"clipboard": "2.0.4",
"diff": "3.5.0",
"flatpickr": "4.5.2",
"font-awesome": "4.7.0",
"jquery": "2.2.4",
"jquery-migrate": "1.4.0",
"jquery": "3.3.1",
"jquery-ui-dist": "1.12.1",
"jquery-validation": "1.17.0",
"jquery-validation-unobtrusive": "3.2.10",
"jquery-ui-touch-punch": "0.2.3",
"lazyload-js": "1.0.0",
"moment": "2.10.6",
"moment": "2.22.2",
"ng-file-upload": "12.2.13",
"nouislider": "12.1.0",
"npm": "^6.4.1",
"signalr": "2.3.0",
"tinymce": "4.8.3",
"typeahead.js": "0.10.5",
"signalr": "2.4.0",
"spectrum-colorpicker": "1.8.0",
"tinymce": "4.9.0",
"typeahead.js": "0.11.1",
"underscore": "1.9.1"
},
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/preset-env": "^7.1.0",
"autoprefixer": "^6.5.0",
"bower-installer": "^1.2.0",
"gulp-clean-css": "3.10.0",
"cssnano": "^3.7.6",
"gulp": "^3.9.1",
"gulp-babel": "^8.0.0-beta.2",
"gulp-concat": "^2.6.0",
"gulp-connect": "5.0.0",
"@babel/core": "7.1.6",
"@babel/preset-env": "7.1.6",
"autoprefixer": "9.3.1",
"gulp-clean-css": "4.0.0",
"cssnano": "4.1.7",
"gulp-connect": "5.6.1",
"gulp-babel": "8.0.0",
"gulp-concat": "2.6.1",
"gulp-connect": "5.6.1",
"gulp-eslint": "^5.0.0",
"gulp-imagemin": "^4.1.0",
"gulp-less": "^3.5.0",
"gulp-ngdocs": "^0.3.0",
"gulp-open": "^2.1.0",
"gulp-postcss": "^6.2.0",
"gulp-rename": "^1.2.2",
"gulp-sort": "^2.0.0",
"gulp-watch": "^4.3.10",
"gulp-wrap": "^0.13.0",
"gulp-wrap-js": "^0.4.1",
"jasmine-core": "3.1.0",
"karma": "^2.0.2",
"karma-jasmine": "^1.1.2",
"karma-phantomjs-launcher": "^1.0.4",
"less": "^2.7.3",
"lodash": "^4.17.5",
"merge-stream": "^1.0.1",
"run-sequence": "^2.2.1"
"gulp-imagemin": "5.0.3",
"gulp-less": "4.0.1",
"gulp-ngdocs": "0.3.0",
"gulp-open": "3.0.1",
"gulp-postcss": "8.0.0",
"gulp-rename": "1.4.0",
"gulp-sort": "2.0.0",
"gulp-watch": "5.0.1",
"gulp-wrap": "0.14.0",
"gulp-wrap-js": "0.4.1",
"jasmine-core": "3.3.0",
"karma": "^3.1.3",
"karma-jasmine": "2.0.1",
"karma-phantomjs-launcher": "1.0.4",
"less": "^3.9.0",
"lodash": "4.17.11",
"merge-stream": "1.0.1",
"run-sequence": "^2.2.1",
"marked": "^0.5.2",
"event-stream": "3.3.4"
}
}
@@ -161,7 +161,6 @@
vm.errorMsg = "";
resetInputValidation();
vm.view = "login";
setFieldFocus("loginForm", "username");
}
function showRequestPasswordReset() {
@@ -169,14 +168,12 @@
resetInputValidation();
vm.view = "request-password-reset";
vm.showEmailResetConfirmation = false;
setFieldFocus("requestPasswordResetForm", "email");
}
function showSetPassword() {
vm.errorMsg = "";
resetInputValidation();
vm.view = "set-password";
setFieldFocus("setPasswordForm", "password");
}
function loginSubmit(login, password) {
@@ -395,12 +392,6 @@
});
}
function setFieldFocus(form, field) {
$timeout(function () {
$("form[name='" + form + "'] input[name='" + field + "']").focus();
});
}
function show2FALoginDialog(view, callback) {
// TODO: show 2FA window
}
@@ -97,13 +97,6 @@
eventsService.unsubscribe(evts[e]);
}
evts.push(eventsService.on("editors.documentType.saved", function (name, args) {
// if this content item uses the updated doc type we need to reload the content item
if (args && args.documentType && args.documentType.key === $scope.content.documentType.key) {
loadContent();
}
}));
evts.push(eventsService.on("editors.content.reload", function (name, args) {
// if this content item uses the updated doc type we need to reload the content item
if(args && args.node && args.node.key === $scope.content.key) {
@@ -1,7 +1,7 @@
(function () {
'use strict';
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource) {
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) {
function link(scope, element, attrs, umbVariantContentCtrl) {
@@ -35,7 +35,9 @@
"content_unpublished",
"content_published",
"content_publishedPendingChanges",
"content_notCreated"
"content_notCreated",
"prompt_unsavedChanges",
"prompt_doctypeChangeWarning"
];
localizationService.localizeMany(keys)
@@ -45,6 +47,8 @@
labels.published = data[2];
labels.publishedPendingChanges = data[3];
labels.notCreated = data[4];
labels.unsavedChanges = data[5];
labels.doctypeChangeWarning = data[6];
setNodePublishStatus(scope.node);
@@ -87,9 +91,40 @@
};
scope.openDocumentType = function (documentType) {
var editor = {
const variantIsDirty = _.some(scope.node.variants, function(variant) {
return variant.isDirty;
});
// add confirmation dialog before opening the doc type editor
if(variantIsDirty) {
const confirm = {
title: labels.unsavedChanges,
view: "default",
content: labels.doctypeChangeWarning,
submitButtonLabelKey: "general_continue",
closeButtonLabelKey: "general_cancel",
submit: function() {
openDocTypeEditor(documentType);
overlayService.close();
},
close: function() {
overlayService.close();
}
};
overlayService.open(confirm);
} else {
openDocTypeEditor(documentType);
}
};
function openDocTypeEditor(documentType) {
const editor = {
id: documentType.id,
submit: function(model) {
const args = { node: scope.node };
eventsService.emit('editors.content.reload', args);
editorService.close();
},
close: function() {
@@ -97,7 +132,7 @@
}
};
editorService.documentTypeEditor(editor);
};
}
scope.openTemplate = function () {
var templateEditor = {
@@ -14,7 +14,7 @@ angular.module("umbraco.directives")
};
element.bind("focus", function(){
element.on("focus", function(){
var range = document.createRange();
range.selectNodeContents(element[0]);
@@ -25,7 +25,7 @@ angular.module("umbraco.directives")
});
element.bind("blur keyup change", function() {
element.on("blur keyup change", function() {
scope.$apply(read);
});
}
@@ -46,7 +46,7 @@ function fixNumber($parse) {
return;
}
elem.bind('input', function (e) {
elem.on('input', function (e) {
var validity = elem.prop('validity');
scope.$apply(function () {
ctrl.$setValidity('number', !validity.badInput);
@@ -5,7 +5,7 @@ angular.module("umbraco.directives").directive('focusWhen', function ($timeout)
attrs.$observe("focusWhen", function (newValue) {
if (newValue === "true") {
$timeout(function () {
elm.focus();
elm.trigger("focus");
});
}
});
@@ -43,15 +43,15 @@ angular.module("umbraco.directives")
// when keycombo is enter and a link or button has focus - click the link or button instead of using the hotkey
if (keyCombo === "enter" && clickableElements.indexOf(activeElementType) === 0) {
document.activeElement.click();
document.activeElement.trigger( "click" );
} else {
element.click();
element.trigger("click");
}
}
} else {
element.focus();
element.trigger("focus");
}
}, options);
@@ -25,7 +25,7 @@ angular.module("umbraco.directives")
});
}
$(element).click(function (event) {
$(element).on("click", function (event) {
if (event.metaKey || event.ctrlKey) {
return;
}
@@ -16,7 +16,7 @@ angular.module("umbraco.directives")
});
}
$(element).keypress(function (event) {
$(element).on("keypress", function (event) {
if (event.which === 13) {
event.preventDefault();
}
@@ -1,7 +1,7 @@
angular.module("umbraco.directives")
.directive('selectOnFocus', function () {
return function (scope, el, attrs) {
$(el).bind("click", function () {
$(el).on("click", function () {
var editmode = $(el).data("editmode");
//If editmode is true a click is handled like a normal click
if (!editmode) {
@@ -11,7 +11,7 @@ angular.module("umbraco.directives")
$(el).data("editmode", true);
}
}).
bind("blur", function () {
on("blur", function () {
//Reset on focus lost
$(el).data("editmode", false);
});
@@ -5,7 +5,7 @@ angular.module("umbraco.directives")
var update = function() {
//if it uses its default naming
if(element.val() === "" || attr.focusOnFilled){
element.focus();
element.trigger("focus");
}
};
@@ -142,8 +142,8 @@ angular.module("umbraco.directives")
});
scope.$on('$destroy', function() {
element.unbind('keyup keydown keypress change', update);
element.unbind('blur', update(true));
element.off('keyup keydown keypress change', update);
element.off('blur', update(true));
unbindModelWatcher();
// clean up IE dom element
@@ -67,7 +67,7 @@ angular.module("umbraco.directives")
$timeout(function () {
if (scope.value === null) {
editor.focus();
editor.trigger("focus");
}
}, 400);
@@ -266,7 +266,7 @@ angular.module("umbraco.directives")
//ie hack
if(window.navigator.userAgent.indexOf("MSIE ") >= 0){
var ranger = element.find("input");
ranger.bind("change",function(){
ranger.on("change",function(){
scope.$apply(function(){
scope.dimensions.scale.current = ranger.val();
});
@@ -500,7 +500,7 @@ Opens an overlay to show a custom YSOD. </br>
overlayNumber = overlayHelper.registerOverlay();
$(document).bind("keydown.overlay-" + overlayNumber, function(event) {
$(document).on("keydown.overlay-" + overlayNumber, function(event) {
if (event.which === 27) {
@@ -527,7 +527,7 @@ Opens an overlay to show a custom YSOD. </br>
var submitOnEnterValue = submitOnEnter ? document.activeElement.getAttribute("overlay-submit-on-enter") : "";
if(clickableElements.indexOf(activeElementType) === 0) {
document.activeElement.click();
document.activeElement.trigger("click");
event.preventDefault();
} else if(activeElementType === "TEXTAREA" && !submitOnEnter) {
@@ -557,7 +557,7 @@ Opens an overlay to show a custom YSOD. </br>
overlayHelper.unregisterOverlay();
$(document).unbind("keydown.overlay-" + overlayNumber);
$(document).off("keydown.overlay-" + overlayNumber);
isRegistered = false;
}
@@ -582,12 +582,12 @@ Opens an overlay to show a custom YSOD. </br>
var overlayIndex = overlayNumber - 1;
var indentSize = overlayIndex * 20;
var overlayWidth = el.context.clientWidth;
var overlayWidth = el[0].clientWidth;
el.css('width', overlayWidth - indentSize);
if(scope.position === "center" && overlayIndex > 0 || scope.position === "target" && overlayIndex > 0) {
var overlayTopPosition = el.context.offsetTop;
var overlayTopPosition = el[0].offsetTop;
el.css('top', overlayTopPosition + indentSize);
}
@@ -621,8 +621,8 @@ Opens an overlay to show a custom YSOD. </br>
mousePositionClickY = scope.model.event.pageY;
// element size
elementHeight = el.context.clientHeight;
elementWidth = el.context.clientWidth;
elementHeight = el[0].clientHeight;
elementWidth = el[0].clientWidth;
// move element to this position
position.left = mousePositionClickX - (elementWidth / 2);
@@ -5,7 +5,7 @@
@scope
@description
Use this directive to render tab content. For an example see: {@link umbraco.directives.directive:umbTabsContent umbTabsContent}
Use this directive to render tab content. For an example see: {@link umbraco.directives.directive:umbTabContent umbTabContent}
@param {string=} tab The tab.
@@ -75,7 +75,7 @@ Use this directive to render a tabs navigation.
<h3>Use in combination with</h3>
<ul>
<li>{@link umbraco.directives.directive:umbTabsContent umbTabsContent}</li>
<li>{@link umbraco.directives.directive:umbTabContent umbTabContent}</li>
</ul>
@param {string=} tabs A collection of tabs.
@@ -128,12 +128,12 @@ Use this directive to render a tabs navigation.
});
}
$(window).bind('resize.tabsNav', function () {
$(window).on('resize.tabsNav', function () {
calculateWidth();
});
scope.$on('$destroy', function() {
$(window).unbind('resize.tabsNav');
$(window).off('resize.tabsNav');
});
}
@@ -104,8 +104,8 @@ Use this directive to render a tooltip.
};
// element size
elementHeight = el.context.clientHeight;
elementWidth = el.context.clientWidth;
elementHeight = el[0].clientHeight;
elementWidth = el[0].clientWidth;
position.left = event.pageX - (elementWidth / 2);
position.top = event.pageY;
@@ -12,7 +12,7 @@ function umbFileUpload() {
restrict: "A",
scope: true, //create a new scope
link: function (scope, el, attrs) {
el.bind('change', function (event) {
el.on('change', function (event) {
var files = event.target.files;
//emit event upward
scope.$emit("filesSelected", { files: files });
@@ -87,7 +87,7 @@ angular.module('umbraco.directives')
if (focusSet) {
currentIndex++;
}
listItems[currentIndex].focus();
listItems[currentIndex].trigger("focus");
focusSet = true;
}
}
@@ -95,7 +95,7 @@ angular.module('umbraco.directives')
function arrowUp() {
if (currentIndex > 0) {
currentIndex--;
listItems[currentIndex].focus();
listItems[currentIndex].trigger("focus");
}
}
@@ -32,7 +32,7 @@
}));
//no isolate scope to listen to element destroy
element.bind('$destroy', function () {
element.on('$destroy', function () {
for (var u in unsubscribe) {
unsubscribe[u]();
}
@@ -2,7 +2,7 @@ angular.module('umbraco.directives.validation')
.directive('valTriggerChange', function($sniffer) {
return {
link : function(scope, elem, attrs) {
elem.bind('click', function(){
elem.on('click', function(){
$(attrs.valTriggerChange).trigger($sniffer.hasEvent('input') ? 'input' : 'change');
});
},
@@ -96,7 +96,7 @@ angular.module('umbraco.services')
function loadLocales(locales, supportedLocales) {
var localeUrls = getMomentLocales(locales, supportedLocales);
if (localeUrls.length >= 1) {
return assetsService.load(localeUrls, $rootScope);
return service.load(localeUrls, $rootScope);
}
else {
$q.when(true);
@@ -45,8 +45,6 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve
appState.setMenuState("showMenuDialog", false);
appState.setGlobalState("stickyNavigation", false);
appState.setGlobalState("showTray", false);
//$("#search-form input").focus();
break;
case 'menu':
appState.setGlobalState("navMode", "menu");
@@ -69,12 +67,6 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve
appState.setMenuState("showMenu", false);
appState.setSectionState("showSearchResults", true);
appState.setMenuState("showMenuDialog", false);
//TODO: This would be much better off in the search field controller listening to appState changes
$timeout(function() {
$("#search-field").focus();
});
break;
default:
appState.setGlobalState("navMode", "default");
@@ -31,7 +31,7 @@ function windowResizeListener($rootScope) {
register: function (fn) {
registered.push(fn);
if (inited === false) {
$(window).bind('resize', resize);
$(window).on('resize', resize);
inited = true;
}
},
@@ -13,7 +13,7 @@ function MainController($scope, $location, appState, treeService, notificationsS
//the null is important because we do an explicit bool check on this in the view
$scope.authenticated = null;
$scope.touchDevice = appState.getGlobalState("touchDevice");
$scope.editors = [];
$scope.infiniteMode = false;
$scope.overlay = {};
$scope.drawer = {};
$scope.search = {};
@@ -160,12 +160,12 @@ function MainController($scope, $location, appState, treeService, notificationsS
}));
// event for infinite editors
evts.push(eventsService.on("appState.editors.add", function (name, args) {
$scope.editors = args.editors;
evts.push(eventsService.on("appState.editors.open", function (name, args) {
$scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
evts.push(eventsService.on("appState.editors.remove", function (name, args) {
$scope.editors = args.editors;
evts.push(eventsService.on("appState.editors.close", function (name, args) {
$scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
//ensure to unregister from all events!
@@ -241,6 +241,15 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
init();
}));
// event for infinite editors
evts.push(eventsService.on("appState.editors.open", function (name, args) {
$scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
evts.push(eventsService.on("appState.editors.close", function (name, args) {
$scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
/**
* Based on the current state of the application, this configures the scope variables that control the main tree and language drop down
*/
@@ -116,7 +116,6 @@
@import "components/umb-confirm-action.less";
@import "components/umb-keyboard-shortcuts-overview.less";
@import "components/umb-checkbox-list.less";
@import "components/umb-radiobuttons-list.less";
@import "components/umb-locked-field.less";
@import "components/umb-tabs.less";
@import "components/umb-load-indicator.less";
@@ -177,6 +176,7 @@
@import "utilities/theme/_opacity.less";
@import "utilities/typography/_text-decoration.less";
@import "utilities/typography/_white-space.less";
@import "utilities/typography/_word-break.less";
@import "utilities/_flexbox.less";
@import "utilities/_spacing.less";
@import "utilities/_text-align.less";
@@ -204,6 +204,7 @@
box-sizing: border-box;
background: @gray-10;
border-bottom: 1px solid @purple-l3;
pointer-events: none;
}
.umb-overlay__item-details-title-wrapper {
@@ -1,80 +0,0 @@
.umb-radiobuttons{
&__label{
position: relative;
padding: 0;
&-text{
margin: 0 0 0 32px;
position: relative;
top: 1px;
}
}
&__input{
position: absolute;
top: 0;
left: 0;
opacity: 0;
&:focus ~ .umb-radiobuttons__state{
box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%);
}
&:focus:checked ~ .umb-radiobuttons__state{
box-shadow: none;
}
&:checked ~ .umb-radiobuttons__state{
&:before{
width: 100%;
height: 100%;
}
}
&:checked ~ .umb-radiobuttons__state .umb-radiobuttons__icon{
opacity: 1;
}
}
&__state{
display: flex;
flex-wrap: wrap;
border: 1px solid @gray-8;
border-radius: 100%;
width: 22px;
height: 22px;
position: relative;
&:before{
content: "";
background: @green;
width: 0;
height: 0;
transition: .1s ease-out;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
border-radius: 100%;
}
}
&__icon{
color: @white;
text-align: center;
font-size: 15px;
opacity: 0;
transition: .3s ease-out;
&:before{
position: absolute;
top: 2px;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
}
}
@@ -0,0 +1,7 @@
/*
WORD BREAK
*/
.word-normal { word-break: normal; }
.word-wrap { word-break: break-all; }
.word-nowrap { word-break: keep-all; }
@@ -18,18 +18,13 @@
<umb-tab-content ng-repeat="tab in dashboard.tabs" ng-if="tab.active" tab="tab" class="row-fluid">
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide">
<div ng-repeat="property in tab.properties">
<div class="clearfix" ng-switch-when="false">
<div class="clearfix">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<div ng-include="property.path"></div>
</div>
<div class="umb-dashboard-control clearfix" ng-switch-when="true">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
</div>
</div>
</umb-tab-content>
@@ -40,4 +35,4 @@
</form>
</div>
</div>
@@ -101,7 +101,7 @@ angular.module("umbraco")
}
$scope.upload = function(v) {
angular.element(".umb-file-dropzone-directive .file-select").click();
angular.element(".umb-file-dropzone-directive .file-select").trigger("click");
};
$scope.dragLeave = function(el, event) {
@@ -123,11 +123,14 @@
oldProperty.isObject = true;
}
// create new property object used in the diff table
// diff requires a string
property.value = property.value ? property.value : "";
oldProperty.value = oldProperty.value ? oldProperty.value : "";
var diffProperty = {
"alias": property.alias,
"label": property.label,
"diff": (property.value || oldProperty.value) ? JsDiff.diffWords(property.value, oldProperty.value) : "",
"diff": JsDiff.diffWords(property.value, oldProperty.value),
"isObject": (property.isObject || oldProperty.isObject) ? true : false
};
@@ -63,7 +63,7 @@
</tr>
<tr ng-repeat="property in vm.diff.properties track by property.alias">
<td class="bold">{{property.label}}</td>
<td ng-class="{'pre-line': property.isObject}">
<td ng-class="{'pre-line': property.isObject, 'word-wrap': !property.isObject}">
<span ng-repeat="part in property.diff">
<ins ng-if="part.added">{{part.value}}</ins>
<del ng-if="part.removed">{{part.value}}</del>
@@ -1,18 +1,12 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Editors.TreePickerController",
function ($scope,
$q,
entityResource,
eventsService,
$log,
searchService,
angularHelper,
$timeout,
localizationService,
treeService,
contentResource,
mediaResource,
memberResource,
languageResource) {
//used as the result selection
@@ -1,518 +0,0 @@
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController",
function ($scope, $q, entityResource, eventsService, $log, searchService, angularHelper, $timeout, localizationService, treeService, contentResource, mediaResource, memberResource) {
var tree = null;
var dialogOptions = $scope.model;
$scope.treeReady = false;
$scope.dialogTreeEventHandler = $({});
$scope.section = dialogOptions.section;
$scope.treeAlias = dialogOptions.treeAlias;
$scope.multiPicker = dialogOptions.multiPicker;
$scope.hideHeader = (typeof dialogOptions.hideHeader) === "boolean" ? dialogOptions.hideHeader : true;
// if you need to load a not initialized tree set this value to false - default is true
$scope.onlyInitialized = dialogOptions.onlyInitialized;
$scope.searchInfo = {
searchFromId: dialogOptions.startNodeId,
searchFromName: null,
showSearch: false,
results: [],
selectedSearchResults: []
}
$scope.model.selection = [];
//Used for toggling an empty-state message
//Some trees can have no items (dictionary & forms email templates)
$scope.hasItems = true;
$scope.emptyStateMessage = dialogOptions.emptyStateMessage;
var node = dialogOptions.currentNode;
//This is called from ng-init
//it turns out it is called from the angular html : / Have a look at views/common / overlays / contentpicker / contentpicker.html you'll see ng-init.
//this is probably an anti pattern IMO and shouldn't be used
$scope.init = function (contentType) {
if (contentType === "content") {
$scope.entityType = "Document";
if (!$scope.model.title) {
$scope.model.title = localizationService.localize("defaultdialogs_selectContent");
}
} else if (contentType === "member") {
$scope.entityType = "Member";
if (!$scope.model.title) {
$scope.model.title = localizationService.localize("defaultdialogs_selectMember");
}
} else if (contentType === "media") {
$scope.entityType = "Media";
if (!$scope.model.title) {
$scope.model.title = localizationService.localize("defaultdialogs_selectMedia");
}
}
}
var searchText = "Search...";
localizationService.localize("general_search").then(function (value) {
searchText = value + "...";
});
// Allow the entity type to be passed in but defaults to Document for backwards compatibility.
$scope.entityType = dialogOptions.entityType ? dialogOptions.entityType : "Document";
//min / max values
if (dialogOptions.minNumber) {
dialogOptions.minNumber = parseInt(dialogOptions.minNumber, 10);
}
if (dialogOptions.maxNumber) {
dialogOptions.maxNumber = parseInt(dialogOptions.maxNumber, 10);
}
if (dialogOptions.section === "member") {
$scope.entityType = "Member";
}
else if (dialogOptions.section === "media") {
$scope.entityType = "Media";
}
// Search and listviews is only working for content, media and member section
var searchableSections = ["content", "media", "member"];
$scope.enableSearh = searchableSections.indexOf($scope.section) !== -1;
//if a alternative startnode is used, we need to check if it is a container
if ($scope.enableSearh && dialogOptions.startNodeId && dialogOptions.startNodeId !== -1 && dialogOptions.startNodeId !== "-1") {
entityResource.getById(dialogOptions.startNodeId, $scope.entityType).then(function(node) {
if (node.metaData.IsContainer) {
openMiniListView(node);
}
initTree();
});
}
else {
initTree();
}
//Configures filtering
if (dialogOptions.filter) {
dialogOptions.filterExclude = false;
dialogOptions.filterAdvanced = false;
//used advanced filtering
if (angular.isFunction(dialogOptions.filter)) {
dialogOptions.filterAdvanced = true;
}
else if (angular.isObject(dialogOptions.filter)) {
dialogOptions.filterAdvanced = true;
}
else {
if (dialogOptions.filter.startsWith("!")) {
dialogOptions.filterExclude = true;
dialogOptions.filterTypes = dialogOptions.filter.substring(1);
} else {
dialogOptions.filterExclude = false;
dialogOptions.filterTypes = dialogOptions.filter;
}
//used advanced filtering
if (dialogOptions.filter.startsWith("{")) {
dialogOptions.filterAdvanced = true;
//convert to object
dialogOptions.filter = angular.fromJson(dialogOptions.filter);
}
}
$scope.filter = {
filterAdvanced: dialogOptions.filterAdvanced,
filterExclude: dialogOptions.filterExclude,
filter: dialogOptions.filterTypes
};
}
function initTree() {
//create the custom query string param for this tree
$scope.customTreeParams = dialogOptions.startNodeId ? "startNodeId=" + dialogOptions.startNodeId : "";
$scope.customTreeParams += dialogOptions.customTreeParams ? "&" + dialogOptions.customTreeParams : "";
$scope.treeReady = true;
}
function nodeExpandedHandler(ev, args) {
// open mini list view for list views
if (args.node.metaData.isContainer) {
openMiniListView(args.node);
}
if (angular.isArray(args.children)) {
//iterate children
_.each(args.children, function (child) {
//now we need to look in the already selected search results and
// toggle the check boxes for those ones that are listed
var exists = _.find($scope.searchInfo.selectedSearchResults, function (selected) {
return child.id == selected.id;
});
if (exists) {
child.selected = true;
}
});
//check filter
performFiltering(args.children);
}
}
//gets the tree object when it loads
function treeLoadedHandler(ev, args) {
//args.tree contains children (args.tree.root.children)
$scope.hasItems = args.tree.root.children.length > 0;
tree = args.tree;
var nodeHasPath = typeof node !== "undefined" && typeof node.path !== "undefined";
var startNodeNotDefined = typeof dialogOptions.startNodeId === "undefined" || dialogOptions.startNodeId === "" || dialogOptions.startNodeId === "-1";
if (startNodeNotDefined && nodeHasPath) {
$scope.dialogTreeEventHandler.syncTree({ path: node.path, activate: false });
}
}
//wires up selection
function nodeSelectHandler(ev, args) {
args.event.preventDefault();
args.event.stopPropagation();
if (args.node.metaData.isSearchResult) {
//check if the item selected was a search result from a list view
//unselect
select(args.node.name, args.node.id);
//remove it from the list view children
var listView = args.node.parent();
listView.children = _.reject(listView.children, function (child) {
return child.id == args.node.id;
});
//remove it from the custom tracked search result list
$scope.searchInfo.selectedSearchResults = _.reject($scope.searchInfo.selectedSearchResults, function (i) {
return i.id == args.node.id;
});
}
else {
eventsService.emit("dialogs.treePickerController.select", args);
if (args.node.filtered) {
return;
}
//This is a tree node, so we don't have an entity to pass in, it will need to be looked up
//from the server in this method.
if ($scope.model.select) {
$scope.model.select(args.node)
} else {
select(args.node.name, args.node.id);
//toggle checked state
args.node.selected = args.node.selected === true ? false : true;
}
}
}
/** Method used for selecting a node */
function select(text, id, entity) {
//if we get the root, we just return a constructed entity, no need for server data
if (id < 0) {
var rootNode = {
alias: null,
icon: "icon-folder",
id: id,
name: text
};
if ($scope.multiPicker) {
if (entity) {
multiSelectItem(entity);
} else {
multiSelectItem(rootNode);
}
}
else {
$scope.model.selection.push(rootNode);
$scope.model.submit($scope.model);
}
}
else {
if ($scope.multiPicker) {
if (entity) {
multiSelectItem(entity);
} else {
//otherwise we have to get it from the server
entityResource.getById(id, $scope.entityType).then(function (ent) {
multiSelectItem(ent);
});
}
}
else {
$scope.hideSearch();
//if an entity has been passed in, use it
if (entity) {
$scope.model.selection.push(entity);
$scope.model.submit($scope.model);
} else {
//otherwise we have to get it from the server
entityResource.getById(id, $scope.entityType).then(function (ent) {
$scope.model.selection.push(ent);
$scope.model.submit($scope.model);
});
}
}
}
}
function multiSelectItem(item) {
var found = false;
var foundIndex = 0;
if ($scope.model.selection.length > 0) {
for (var i = 0; $scope.model.selection.length > i; i++) {
var selectedItem = $scope.model.selection[i];
if (selectedItem.id === item.id) {
found = true;
foundIndex = i;
}
}
}
if (found) {
$scope.model.selection.splice(foundIndex, 1);
} else {
$scope.model.selection.push(item);
}
}
function performFiltering(nodes) {
if (!dialogOptions.filter) {
return;
}
//remove any list view search nodes from being filtered since these are special nodes that always must
// be allowed to be clicked on
nodes = _.filter(nodes, function (n) {
return !angular.isObject(n.metaData.listViewNode);
});
if (dialogOptions.filterAdvanced) {
//filter either based on a method or an object
var filtered = angular.isFunction(dialogOptions.filter)
? _.filter(nodes, dialogOptions.filter)
: _.where(nodes, dialogOptions.filter);
angular.forEach(filtered, function (value, key) {
value.filtered = true;
if (dialogOptions.filterCssClass) {
if (!value.cssClasses) {
value.cssClasses = [];
}
value.cssClasses.push(dialogOptions.filterCssClass);
}
});
} else {
var a = dialogOptions.filterTypes.toLowerCase().replace(/\s/g, '').split(',');
angular.forEach(nodes, function (value, key) {
var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0;
if (!dialogOptions.filterExclude && !found || dialogOptions.filterExclude && found) {
value.filtered = true;
if (dialogOptions.filterCssClass) {
if (!value.cssClasses) {
value.cssClasses = [];
}
value.cssClasses.push(dialogOptions.filterCssClass);
}
}
});
}
}
$scope.multiSubmit = function (result) {
entityResource.getByIds(result, $scope.entityType).then(function (ents) {
$scope.submit(ents);
});
};
/** method to select a search result */
$scope.selectResult = function (evt, result) {
if (result.filtered) {
return;
}
result.selected = result.selected === true ? false : true;
//since result = an entity, we'll pass it in so we don't have to go back to the server
select(result.name, result.id, result);
//add/remove to our custom tracked list of selected search results
if (result.selected) {
$scope.searchInfo.selectedSearchResults.push(result);
}
else {
$scope.searchInfo.selectedSearchResults = _.reject($scope.searchInfo.selectedSearchResults, function (i) {
return i.id == result.id;
});
}
//ensure the tree node in the tree is checked/unchecked if it already exists there
if (tree) {
var found = treeService.getDescendantNode(tree.root, result.id);
if (found) {
found.selected = result.selected;
}
}
};
$scope.hideSearch = function () {
//Traverse the entire displayed tree and update each node to sync with the selected search results
if (tree) {
//we need to ensure that any currently displayed nodes that get selected
// from the search get updated to have a check box!
function checkChildren(children) {
_.each(children, function (child) {
//check if the id is in the selection, if so ensure it's flagged as selected
var exists = _.find($scope.searchInfo.selectedSearchResults, function (selected) {
return child.id == selected.id;
});
//if the curr node exists in selected search results, ensure it's checked
if (exists) {
child.selected = true;
}
//if the curr node does not exist in the selected search result, and the curr node is a child of a list view search result
else if (child.metaData.isSearchResult) {
//if this tree node is under a list view it means that the node was added
// to the tree dynamically under the list view that was searched, so we actually want to remove
// it all together from the tree
var listView = child.parent();
listView.children = _.reject(listView.children, function (c) {
return c.id == child.id;
});
}
//check if the current node is a list view and if so, check if there's any new results
// that need to be added as child nodes to it based on search results selected
if (child.metaData.isContainer) {
child.cssClasses = _.reject(child.cssClasses, function (c) {
return c === 'tree-node-slide-up-hide-active';
});
var listViewResults = _.filter($scope.searchInfo.selectedSearchResults, function (i) {
return i.parentId == child.id;
});
_.each(listViewResults, function (item) {
var childExists = _.find(child.children, function (c) {
return c.id == item.id;
});
if (!childExists) {
var parent = child;
child.children.unshift({
id: item.id,
name: item.name,
cssClass: "icon umb-tree-icon sprTree " + item.icon,
level: child.level + 1,
metaData: {
isSearchResult: true
},
hasChildren: false,
parent: function () {
return parent;
}
});
}
});
}
//recurse
if (child.children && child.children.length > 0) {
checkChildren(child.children);
}
});
}
checkChildren(tree.root.children);
}
$scope.searchInfo.showSearch = false;
$scope.searchInfo.searchFromId = dialogOptions.startNodeId;
$scope.searchInfo.searchFromName = null;
$scope.searchInfo.results = [];
}
$scope.onSearchResults = function (results) {
//filter all items - this will mark an item as filtered
performFiltering(results);
//now actually remove all filtered items so they are not even displayed
results = _.filter(results, function (item) {
return !item.filtered;
});
$scope.searchInfo.results = results;
//sync with the curr selected results
_.each($scope.searchInfo.results, function (result) {
var exists = _.find($scope.model.selection, function (selectedId) {
return result.id == selectedId;
});
if (exists) {
result.selected = true;
}
});
$scope.searchInfo.showSearch = true;
};
$scope.dialogTreeEventHandler.bind("treeLoaded", treeLoadedHandler);
$scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler);
$scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler);
$scope.$on('$destroy', function () {
$scope.dialogTreeEventHandler.unbind("treeLoaded", treeLoadedHandler);
$scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler);
$scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler);
});
$scope.selectListViewNode = function (node) {
select(node.name, node.id);
//toggle checked state
node.selected = node.selected === true ? false : true;
};
$scope.closeMiniListView = function () {
$scope.miniListView = undefined;
};
function openMiniListView(node) {
$scope.miniListView = node;
}
});
@@ -161,7 +161,7 @@
<div class="control-group" ng-class="{error: vm.loginForm.username.$invalid}">
<label><localize key="general_username">Username</localize></label>
<input type="text" ng-model="vm.login" name="username" class="-full-width-input" localize="placeholder" placeholder="@placeholders_usernameHint" />
<input type="text" ng-model="vm.login" name="username" class="-full-width-input" localize="placeholder" placeholder="@placeholders_usernameHint" focus-when="{{vm.view === 'login'}}" />
</div>
<div class="control-group" ng-class="{error: vm.loginForm.password.$invalid}">
@@ -199,7 +199,7 @@
<form method="POST" name="vm.requestPasswordResetForm" ng-submit="vm.requestPasswordResetSubmit(email)">
<div class="control-group" ng-class="{error: requestPasswordResetForm.email.$invalid}">
<label><localize key="general_email">Email</localize></label>
<input type="email" val-email ng-model="email" name="email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" />
<input type="email" val-email ng-model="email" name="email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" focus-when="{{vm.view === 'request-password-reset'}}" />
</div>
<div class="control-group" ng-show="requestPasswordResetForm.$invalid">
@@ -230,7 +230,7 @@
<div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.password.$invalid}">
<label><localize key="user_newPassword">New password</localize></label>
<input type="password" ng-model="vm.password" name="password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" />
<input type="password" ng-model="vm.password" name="password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" focus-when="{{vm.view === 'set-password'}}" />
</div>
<div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}">
@@ -19,7 +19,7 @@
<div id="tree" ng-show="authenticated">
<umb-tree
api="treeApi"
on-init="onTreeInit()" >
on-init="onTreeInit()">
</umb-tree>
</div>
</div>
@@ -44,6 +44,9 @@
</umb-context-dialog>
</div>
<div class="umb-editor__overlay" ng-show="infiniteMode"></div>
</div>
</div>
@@ -33,8 +33,10 @@
<umb-property-editor model="preValue" is-pre-value="true"></umb-property-editor>
</umb-property>
<button type="button" class="btn" ng-click="toggleEditListViewDataTypeSettings()"><localize key="general_close">Close</localize></button>
<button type="button" class="btn btn-success" ng-click="saveListViewDataType()"><localize key="buttons_saveListView"></localize></button>
<div class="text-right">
<button type="button" class="btn btn-link" ng-click="toggleEditListViewDataTypeSettings()"><localize key="general_close">Close</localize></button>
<button type="button" class="btn btn-success" ng-click="saveListViewDataType()"><localize key="buttons_saveListView"></localize></button>
</div>
</div>
</div>
@@ -1,7 +1,7 @@
<select ng-model="model.value">
<select ng-model="model.value" required>
<option value="STRING">String</option>
<option value="DECIMAL">Decimal</option>
<option value="DATETIME">Date/time</option>
<option value="INT">Integer</option>
<option value="TEXT">Long string</option>
</select>
</select>
@@ -6,7 +6,8 @@
<input type="checkbox" name="checkboxlist"
value="{{item.key}}"
ng-model="item.checked"
ng-change="changed(item)" />
ng-change="changed(item)"
ng-required="model.validation.mandatory && !model.value.length" />
{{item.val}}
</label>
</li>
@@ -5,10 +5,11 @@
<localize key="colorpicker_noColors">You haven't defined any colors</localize>
</div>
<umb-color-swatches colors="model.config.items"
selected-color="model.value.value"
size="m"
use-label="model.useLabel">
<umb-color-swatches
colors="model.config.items"
selected-color="model.value"
size="m"
use-label="model.useLabel">
</umb-color-swatches>
<input type="hidden" name="modelValue" ng-model="model.value" val-property-validator="validateMandatory" />
@@ -77,8 +77,16 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo
// if we run in single mode we'll store the value in a local variable
// so we can pass an array as the model as our PropertyValueEditor expects that
$scope.model.singleDropdownValue = "";
if (!Object.toBoolean($scope.model.config.multiple)) {
if (!Object.toBoolean($scope.model.config.multiple) && $scope.model.value) {
$scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value;
}
// if we run in multiple mode, make sure the model is an array (in case the property was previously saved in single mode)
// also explicitly set the model to null if it's an empty array, so mandatory validation works on the client
if ($scope.model.config.multiple === "1" && $scope.model.value) {
$scope.model.value = !Array.isArray($scope.model.value) ? [$scope.model.value] : $scope.model.value;
if ($scope.model.value.length === 0) {
$scope.model.value = null;
}
}
});
@@ -5,7 +5,8 @@
ng-switch-default
ng-change="updateSingleDropdownValue()"
ng-model="model.singleDropdownValue"
ng-options="item.value as item.value for item in model.config.items">
ng-options="item.value as item.value for item in model.config.items"
ng-required="model.validation.mandatory">
<option></option>
</select>
@@ -15,5 +16,6 @@
ng-switch-when="true"
multiple
ng-model="model.value"
ng-options="item.value as item.value for item in model.config.items"></select>
ng-options="item.value as item.value for item in model.config.items"
ng-required="model.validation.mandatory"></select>
</div>
@@ -69,4 +69,8 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesControlle
//there was an error, do the highlight (will be set back by the directive)
$scope.hasError = true;
};
$scope.sortableOptions = {
axis: 'y'
}
});
@@ -58,7 +58,7 @@
</div>
<div ui-sortable="sortableOptions" class="umb-cropsizes__sortable">
<div ui-sortable="sortableOptions" class="umb-cropsizes__sortable" ng-model="model.value">
<div class="control-group umb-prevalues-multivalues__listitem" ng-repeat="item in model.value">
<i class="icon icon-navigation handle"></i>
<div class="umb-prevalues-multivalues__left">
@@ -37,7 +37,7 @@
</div>
<div class="umb-nested-content__footer-bar" ng-hide="nodes.length >= maxItems">
<a class="umb-nested-content__icon" ng-click="openNodeTypePicker($event)" prevent-default>
<a href class="umb-nested-content__icon" ng-click="openNodeTypePicker($event)" prevent-default>
<i class="icon icon-add"></i>
</a>
</div>
@@ -1,17 +1,12 @@
<div class="umb-property-editor umb-radiobuttons" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<ul class="unstyled">
<li ng-repeat="item in configItems track by item.id">
<label class="radio umb-radiobuttons__label">
<label class="radio">
<input type="radio" name="{{htmlId}}"
value="{{item.id}}"
ng-model="model.value"
class="umb-radiobuttons__input" />
<div class="umb-radiobuttons__state">
<i class="umb-radiobuttons__icon icon-check" aria-hidden="true"></i>
<span class="umb-radiobuttons__label-text">{{item.value}}</span>
</div>
ng-model="model.value" />
{{item.value}}
</label>
</li>
</ul>
</div>
</div>
@@ -191,7 +191,7 @@
$timeout(function() {
var nameField = angular.element(document.querySelector('[data-element="editor-name-field"]'));
if (nameField) {
nameField.bind('blur', function(event) {
nameField.on('blur', function(event) {
if (event.target.value) {
vm.save(true);
}
@@ -531,26 +531,24 @@
// copy to clip board success
function copySuccess() {
if (vm.page.copyPasswordButtonState != "success") {
vm.page.copyPasswordButtonState = "success";
if (vm.page.copyPasswordButtonState !== "success") {
$timeout(function(){
vm.page.copyPasswordButtonState = "success";
});
$timeout(function () {
resetClipboardButtonState()
resetClipboardButtonState();
}, 1000);
}
}
// copy to clip board error
function copyError() {
if (vm.page.copyPasswordButtonState != "error") {
vm.page.copyPasswordButtonState = "error";
if (vm.page.copyPasswordButtonState !== "error") {
$timeout(function() {
vm.page.copyPasswordButtonState = "error";
});
$timeout(function () {
resetClipboardButtonState()
resetClipboardButtonState();
}, 1000);
}
}
@@ -4,7 +4,7 @@ describe('admin edit user', function() {
browser().navigateTo('/admin/users/new');
input('user.email').enter('admin@abc.com');
input('user.password').enter('changeme');
element('button.login').click();
element('button.login').trigger('click');
});
it('enables the save button when the user info is filled in correctly', function() {
+3
View File
@@ -0,0 +1,3 @@
/Umbraco/**
/Umbraco_Client/**
+5 -9
View File
@@ -151,13 +151,6 @@
<Compile Include="Umbraco\Create.aspx.designer.cs">
<DependentUpon>create.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Dashboard\UserControlProxy.aspx.cs">
<DependentUpon>UserControlProxy.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\Dashboard\UserControlProxy.aspx.designer.cs">
<DependentUpon>UserControlProxy.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Developer\Macros\EditMacro.aspx.cs">
<DependentUpon>editMacro.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -236,9 +229,9 @@
</Compile>
<Content Include="Config\Splashes\booting.aspx" />
<Content Include="Config\Splashes\noNodes.aspx" />
<Content Include="Umbraco\Dashboard\UserControlProxy.aspx" />
<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>
@@ -460,7 +453,10 @@
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<WebPublishingTasks Condition="exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
<!-- Temporary addition for the VS2019 preview - can be removed when VS2019 final is released, then v16 above will be used -->
<WebPublishingTasks Condition="exists('$(ProgramFiles32)\Microsoft Visual Studio\2019\Preview\MSBuild\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll')">$(ProgramFiles32)\Microsoft Visual Studio\2019\Preview\MSBuild\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<!-- get TransformXml task from WebPublishingtasks -->
<UsingTask TaskName="TransformXml" AssemblyFile="$(WebPublishingTasks)" Condition="'$(WebPublishingTasks)' != ''" />
@@ -67,7 +67,7 @@
<div id="contentcolumn">
<div class="umb-editor" ng-view></div>
<div class="umb-editor__overlay" ng-if="editors.length > 0"></div>
<div class="umb-editor__overlay" ng-if="infiniteMode"></div>
<umb-editors></umb-editors>
</div>
@@ -1863,9 +1863,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="configurationServiceFileNotFound">File does not exist: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Unable to find <strong>'%0%'</strong> in config file <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">There was an error, check log for full error: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Members - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Content - Total XML: %0%, Total published: %1%, Total invalid: %2%</key>
<key alias="databaseSchemaValidationCheckDatabaseOk">Database - The database schema is correct for this version of Umbraco</key>
<key alias="databaseSchemaValidationCheckDatabaseErrors">%0% problems were detected with your database schema (Check the log for details)</key>
<key alias="databaseSchemaValidationCheckDatabaseLogMessage">Some errors were detected while validating the database schema against the current version of Umbraco.</key>
@@ -1934,7 +1931,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="notificationEmailsCheckSuccessMessage"><![CDATA[Notification email has been set to <strong>%0%</strong>.]]></key>
<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</key>
<key alias="scheduledHealthCheckEmailSubject">Umbraco Health Check Status: %0%</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Disable URL tracker</key>
@@ -340,6 +340,7 @@
<key alias="confirmListViewPublish">Publishing will make the selected items visible on the site.</key>
<key alias="confirmListViewUnpublish">Unpublishing will remove the selected items and all their descendants from the site.</key>
<key alias="confirmUnpublish">Unpublishing will remove this page and all its descendants from the site.</key>
<key alias="doctypeChangeWarning">You have unsaved changes. Making changes to the Document Type will discard the changes.</key>
</area>
<area alias="bulk">
<key alias="done">Done</key>
@@ -1913,9 +1914,6 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="configurationServiceFileNotFound">File does not exist: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Unable to find <strong>'%0%'</strong> in config file <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">There was an error, check log for full error: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Members - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Content - Total XML: %0%, Total published: %1%, Total invalid: %2%</key>
<key alias="databaseSchemaValidationCheckDatabaseOk">Database - The database schema is correct for this version of Umbraco</key>
<key alias="databaseSchemaValidationCheckDatabaseErrors">%0% problems were detected with your database schema (Check the log for details)</key>
<key alias="databaseSchemaValidationCheckDatabaseLogMessage">Some errors were detected while validating the database schema against the current version of Umbraco.</key>
@@ -1984,7 +1982,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="notificationEmailsCheckSuccessMessage"><![CDATA[Notification email has been set to <strong>%0%</strong>.]]></key>
<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</key>
<key alias="scheduledHealthCheckEmailSubject">Umbraco Health Check Status: %0%</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Disable URL tracker</key>
+189 -186
View File
@@ -5,8 +5,8 @@
<link>https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files</link>
</creator>
<area alias="actions">
<key alias="assignDomain">Administrar hostnames</key>
<key alias="auditTrail">Auditoría</key>
<key alias="assignDomain">Administrar dominios</key>
<key alias="auditTrail">Historial</key>
<key alias="browse">Nodo de Exploración</key>
<key alias="changeDocType">Cambiar tipo de documento</key>
<key alias="copy">Copiar</key>
@@ -20,26 +20,26 @@
<key alias="exportDocumentType">Exportar Documento (tipo)</key>
<key alias="importDocumentType">Importar Documento (tipo)</key>
<key alias="importPackage">Importar Paquete</key>
<key alias="liveEdit">Editar en lienzo</key>
<key alias="logout">Salir</key>
<key alias="liveEdit">Editar en vivo</key>
<key alias="logout">Cerrar sesión</key>
<key alias="move">Mover</key>
<key alias="notify">Notificaciones</key>
<key alias="protect">Acceso Público</key>
<key alias="publish">Publicar</key>
<key alias="unpublish">Unpublish</key>
<key alias="unpublish">Retirar publicación</key>
<key alias="refreshNode">Recargar Nodos</key>
<key alias="republish">Republicar sitio completo</key>
<key alias="rename" version="7.3.0">Renombrar</key>
<key alias="restore" version="7.3.0">Restaurar</key>
<key alias="SetPermissionsForThePage">Establecer permisos para la página %0%</key>
<key alias="chooseWhereToMove">Elije dónde mover</key>
<key alias="chooseWhereToMove">Elige dónde mover</key>
<key alias="toInTheTreeStructureBelow">En el árbol de contenido</key>
<key alias="rights">Permisos</key>
<key alias="rollback">Deshacer</key>
<key alias="sendtopublish">Enviar a Publicar</key>
<key alias="sendToTranslate">Enviar a Traducir</key>
<key alias="setGroup">Establecer grupo</key>
<key alias="sort">Ordernar</key>
<key alias="sort">Ordenar</key>
<key alias="translate">Traducir</key>
<key alias="update">Actualizar</key>
<key alias="setPermissions">Establecer permisos</key>
@@ -54,7 +54,7 @@
</area>
<area alias="actionDescriptions">
<key alias="assignDomain">Permitir acceso para asignar cultura y dominios</key>
<key alias="auditTrail">Permitir acceso para ver informes de nodos</key>
<key alias="auditTrail">Permitir acceso para ver el historial de un nodo</key>
<key alias="browse">Permitir acceso para ver un nodo</key>
<key alias="changeDocType">Permitir acceso para cambiar el tipo de documento de un nodo</key>
<key alias="copy">Permitir acceso para copiar un nodo</key>
@@ -79,7 +79,7 @@
<key alias="invalidNode">Nodo no válido.</key>
<key alias="invalidDomain">Formato de dominio no válido.</key>
<key alias="duplicateDomain">Este dominio ya ha sido asignado.</key>
<key alias="language">Language</key>
<key alias="language">Idioma</key>
<key alias="domain">Dominio</key>
<key alias="domainCreated">El nuevo dominio %0% ha sido creado</key>
<key alias="domainDeleted">El dominio %0% ha sido borrado</key>
@@ -89,9 +89,12 @@
<key alias="domainHelp"><![CDATA[p.ej.: "tudominio.com", "www.tudominio.com", "tudominio.com:8080" o
"https://www.tudominio.com/".<br /><br />Los dominios de un nivel están soportados, por ej. "example.com/en". De todas formas deberían de evitarse. Mejor usar la configuración cultural especificada arriba.]]></key>
<key alias="inherit">Heredar</key>
<key alias="setLanguage">Cultura</key>
<key alias="setLanguageHelp"><![CDATA[Configura la cultura para los nodos por debajo del nodo actual,<br /> o hereda la cultura de los nodos padres. También se aplicará<br />
para el nodo actual, a menos que un dominio por debajo lo aplique también.]]></key>
<key alias="setLanguage">Idioma</key>
<key alias="setLanguageHelp">
<![CDATA[Configura el idioma para los nodos por debajo del nodo actual,<br /> o hereda el idioma de los nodos padres. También se aplicará<br />
para el nodo actual, a menos que un dominio por debajo lo aplique también.]]>
</key>
<key alias="setDomains">Dominios</key>
</area>
<area alias="auditTrails">
@@ -112,7 +115,7 @@
<key alias="justifyLeft">Alinear a la Izquierda</key>
<key alias="justifyRight">Alinear a la Derecha</key>
<key alias="linkInsert">Insertar Link</key>
<key alias="linkLocal">Insertar link local (anchor)</key>
<key alias="linkLocal">Insertar link local (ancla)</key>
<key alias="listBullet">Lista en Viñetas</key>
<key alias="listNumeric">Lista Numérica</key>
<key alias="macroInsert">Insertar macro</key>
@@ -134,7 +137,7 @@
</area>
<area alias="changeDocType">
<key alias="changeDocTypeInstruction">Para cambiar el tipo de documento al contenido seleccionado, primero selecciona uno de la lista de tipos válidos.</key>
<key alias="changeDocTypeInstruction2">Entonces confirma el mapeo de propiedades del tipo actual al nuevo y haz click en Guardar.</key>
<key alias="changeDocTypeInstruction2">Entonces confirma el mapeo de propiedades del tipo actual al nuevo y haz clic en Guardar.</key>
<key alias="contentRepublished">El contenido se ha vuelto a publicar.</key>
<key alias="currentProperty">Propiedad actual</key>
<key alias="currentType">Tipo actual</key>
@@ -157,8 +160,8 @@
<key alias="about">Acerca de</key>
<key alias="alias">Link alternativo</key>
<key alias="alternativeTextHelp">(como describe la imagen sobre el teléfono)</key>
<key alias="alternativeUrls">Vinculos Alternativos</key>
<key alias="clickToEdit">Click para editar esta entrada</key>
<key alias="alternativeUrls">Vínculos Alternativos</key>
<key alias="clickToEdit">Clic para editar esta entrada</key>
<key alias="createBy">Creado por</key>
<key alias="createByDesc" version="7.0">Autor original</key>
<key alias="updatedBy" version="7.0">Actualizado por</key>
@@ -183,16 +186,16 @@
<key alias="nodeName">Título de la página</key>
<key alias="otherElements">Propiedades</key>
<key alias="parentNotPublished">Este documento ha sido publicado pero no es visible porque el padre '%0%' no esta publicado</key>
<key alias="parentNotPublishedAnomaly">Upss: este documento está publicado pero no está en la caché (error interno)</key>
<key alias="parentNotPublishedAnomaly">Ups: este documento está publicado pero no está en la caché (error interno)</key>
<key alias="getUrlException">No se pudo obtener la url</key>
<key alias="routeError">Este documento está publicado pero su url colisionará con contenido %0%</key>
<key alias="routeError">Este documento está publicado pero tu url colisionará con contenido %0%</key>
<key alias="publish">Publicar</key>
<key alias="publishStatus">Estado de la Publicación</key>
<key alias="releaseDate">Publicar el</key>
<key alias="unpublishDate">Despublicar el</key>
<key alias="unpublishDate">Retirar publicación el</key>
<key alias="removeDate">Fecha de Eliminación</key>
<key alias="sortDone">El Orden esta actualizado</key>
<key alias="sortHelp">Para organizar los nodos, simplemente arrastre los nodos o realice un clic en uno de los encabezados de columna. Puede seleccionar multiple nodos manteniendo presionados "Shift" o "Control" mientras selecciona</key>
<key alias="sortHelp">Para organizar los nodos, simplemente arrastra los nodos o realice un clic en uno de los encabezados de columna. Puedes seleccionar múltiple nodos manteniendo presionados "Shift" o "Control" mientras seleccionas</key>
<key alias="statistics">Estadísticas</key>
<key alias="titleOptional">Título (opcional)</key>
<key alias="altTextOptional">Texto alternativo (opcional)</key>
@@ -203,16 +206,16 @@
<key alias="uploadClear">Eliminar archivo</key>
<key alias="urls">Vínculo al documento</key>
<key alias="memberof">Miembro de grupo(s)</key>
<key alias="notmemberof">No es miembreo de grupo(s)</key>
<key alias="notmemberof">No es miembro de grupo(s)</key>
<key alias="childItems" version="7.0">Nodos hijo</key>
<key alias="target" version="7.0">Target</key>
<key alias="target" version="7.0">Destino</key>
<key alias="scheduledPublishServerTime">Esto se traduce en la siguiente hora en el servidor:</key>
<key alias="scheduledPublishDocumentation"><![CDATA[<a href="https://our.umbraco.com/documentation/Getting-Started/Data/Scheduled-Publishing/#timezones" target="_blank">¿Esto qué significa?</a>]]></key>
<key alias="nestedContentDeleteItem">¿Estás seguro que quieres eliminar este elemento?</key>
<key alias="nestedContentEditorNotSupported">Propiedad %0% utiliza editor %1% que no está soportado por Nested Content.</key>
<key alias="addTextBox">Añadir otra caja de texto</key>
<key alias="removeTextBox">Eliminar caja de texto</key>
<key alias="contentRoot">Raiz de contenido</key>
<key alias="contentRoot">Raíz de contenido</key>
</area>
<area alias="blueprints">
<key alias="createBlueprintFrom">Crear nueva Plantilla de Contenido desde '%0%'</key>
@@ -224,7 +227,7 @@
<key alias="blueprintDescription">Una Plantilla de Contenido es contenido predefinido que un editor puede usar como base para crear nuevo contenido</key>
</area>
<area alias="media">
<key alias="clickToUpload">Haz click para subir archivos</key>
<key alias="clickToUpload">Haz clic para subir archivos</key>
</area>
<area alias="member">
<key alias="createNewMember">Crear nuevo miembro</key>
@@ -234,7 +237,7 @@
<key alias="chooseNode">¿Dónde quieres crear el nuevo %0%</key>
<key alias="createUnder">Crear debajo de</key>
<key alias="createContentBlueprint">Selecciona el Tipo de Documento para el que quieres crear una plantilla de contenido</key>
<key alias="updateData">Elije un tipo y un título</key>
<key alias="updateData">Elige un tipo y un título</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[No hay disponibles tipos de documentos permitidos. Debes habilitarlos en la sección "Ajustes" en <strong>"Tipos de documentos"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[No hay disponibles tipos de medios permitidos. Debes habilitarlos en la sección "Ajustes" en <strong>"Tipos de medios"</strong>.]]></key>
<key alias="documentTypeWithoutTemplate">Tipo de Documento sin plantilla</key>
@@ -291,16 +294,16 @@
<key alias="anchorInsert">Nombre</key>
<key alias="assignDomain">Administrar dominios</key>
<key alias="closeThisWindow">Cerrar esta ventana</key>
<key alias="confirmdelete">Esta usted seguro que desea borrar</key>
<key alias="confirmdisable">Esta usted seguro que desea deshabilitar</key>
<key alias="confirmEmptyTrashcan">Por favor seleccione esta casilla para confirmar la eliminación de %0% entrada(s)</key>
<key alias="confirmlogout">Esta usted seguro?</key>
<key alias="confirmSure">Esta usted Seguro?</key>
<key alias="confirmdelete">Estás seguro que quieres borrar</key>
<key alias="confirmdisable">Estás seguro que quieres deshabilitar</key>
<key alias="confirmEmptyTrashcan">Por favor selecciona esta casilla para confirmar la eliminación de %0% entrada(s)</key>
<key alias="confirmlogout">¿Estás seguro?</key>
<key alias="confirmSure">¿Estás seguro?</key>
<key alias="cut">Cortar</key>
<key alias="editdictionary">Editar entrada del Diccionario</key>
<key alias="editlanguage">Editar idioma</key>
<key alias="insertAnchor">Agregar enlace interno</key>
<key alias="insertCharacter">Insertar caracter</key>
<key alias="insertCharacter">Insertar carácter</key>
<key alias="insertgraphicheadline">Insertar titular gráfico</key>
<key alias="insertimage">Insertar imagen</key>
<key alias="insertlink">Insertar enlace</key>
@@ -318,9 +321,9 @@
<key alias="permissionsSet">Establecer permisos para</key>
<key alias="permissionsSetForGroup">Establecer permisos para %0% para grupo %1%</key>
<key alias="permissionsHelp">Selecciona el grupo de usuarios para el cual quieres establecer permisos</key>
<key alias="recycleBinDeleting">Se está vaciando la papelera. No cierre esta ventana mientras se ejecuta este proceso</key>
<key alias="recycleBinDeleting">Se está vaciando la papelera. No cierres esta ventana mientras se ejecuta este proceso</key>
<key alias="recycleBinIsEmpty">La papelera está vacía</key>
<key alias="recycleBinWarning">No podrá recuperar los items una vez sean borrados de la papelera</key>
<key alias="recycleBinWarning">No podrás recuperar los elementos una vez sean borrados de la papelera</key>
<key alias="regexSearchError"><![CDATA[El servicio web <a target='_blank' href='http://regexlib.com'>regexlib.com</a> está experimentando algunos problemas en estos momentos, de los cuales no somos responsables. Pedimos disculpas por las molestias.]]></key>
<key alias="regexSearchHelp">Buscar una expresión regular para agregar validación a un campo de formulario. Ejemplo: 'correo electrónico', código postal "," url "</key>
<key alias="removeMacro">Eliminar macro</key>
@@ -331,15 +334,15 @@
<key alias="tableColumns">Número de columnas</key>
<key alias="tableRows">Número de filas</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Coloca un 'placeholder' id</strong> al colocar un ID en tu 'placeholder' puedes insertar contenido en esta plantilla desde una plantilla hija, referenciando este ID usando un elemento<code>&lt;asp:content /&gt;</code>.]]></key>
<key alias="templateContentPlaceHolderHelp">Seleccione una tecla de la lista abajo indicada. Sólo puede elegir a partir de la ID de la plantilla actual del dominio.</key>
<key alias="thumbnailimageclickfororiginal">Haga clic sobre la imagen para verla a tamaño completo.</key>
<key alias="treepicker">Seleccionar item</key>
<key alias="viewCacheItem">Ver item en la caché</key>
<key alias="templateContentPlaceHolderHelp">Selecciona una tecla de la lista abajo indicada. Sólo puedes elegir a partir de la ID de la plantilla actual del dominio.</key>
<key alias="thumbnailimageclickfororiginal">Haz clic sobre la imagen para verla a tamaño completo.</key>
<key alias="treepicker">Seleccionar elemento</key>
<key alias="viewCacheItem">Ver elemento en la caché</key>
<key alias="relateToOriginalLabel">Relacionar con original</key>
<key alias="includeDescendants">Incluir descendientes</key>
<key alias="theFriendliestCommunity">La amigable comunidad</key>
<key alias="linkToPage">Enlazar a página</key>
<key alias="openInNewWindow">Abre el documento enlazado en una nueva ventana o Opens the linked document in a new window o pestaña</key>
<key alias="openInNewWindow">Abre el documento enlazado en una nueva ventana o pestaña</key>
<key alias="linkToMedia">Enlazar a medio</key>
<key alias="selectContentStartNode">Selecciona nodo de inicio de contenido</key>
<key alias="selectMedia">Selecciona medio</key>
@@ -355,8 +358,8 @@
<key alias="selectSections">Selecciona secciones</key>
<key alias="selectUsers">Selecciona usuarios</key>
<key alias="noIconsFound">No se encontraron iconos</key>
<key alias="noMacroParams">No hay parametros para esta macro</key>
<key alias="noMacros">No hay maros disponibles para insertar</key>
<key alias="noMacroParams">No hay parámetros para esta macro</key>
<key alias="noMacros">No hay macros disponibles para insertar</key>
<key alias="externalLoginProviders">Proveedores de login externo</key>
<key alias="exceptionDetail">Detalles de la Excepción</key>
<key alias="stacktrace">Stacktrace</key>
@@ -368,7 +371,7 @@
<key alias="selectSnippet">Selecciona snippet</key>
</area>
<area alias="dictionaryItem">
<key alias="description">Editar las diferentes versiones lingüísticas para la entrada en el diccionario '% 0%' debajo añadir otros idiomas en el menu de 'idiomas' en el menú de la izquierda</key>
<key alias="description">Editar las diferentes versiones lingüísticas para la entrada en el diccionario '% 0%' debajo añadir otros idiomas en el menú de 'idiomas' en el menú de la izquierda</key>
<key alias="displayName"><![CDATA[nombre de la cultura
]]></key>
<key alias="changeKeyError"><![CDATA[
@@ -405,15 +408,15 @@
</area>
<area alias="renamecontainer">
<key alias="renamed">Renombrado</key>
<key alias="enterNewFolderName">Introduce un nuevo nombre para la carpeta aqui</key>
<key alias="enterNewFolderName">Introduce un nuevo nombre para la carpeta aquí</key>
<key alias="folderWasRenamed">%0% fue renombrada a %1%</key>
</area>
<area alias="editdatatype">
<key alias="addPrevalue">añadir prevalor</key>
<key alias="addPrevalue">añadir valor preestablecido</key>
<key alias="dataBaseDatatype"><![CDATA[Base de datos
]]></key>
<key alias="guid">Tipo de datos GUID</key>
<key alias="renderControl">Tipo de datos GUIDprestar control</key>
<key alias="renderControl">Renderizar control</key>
<key alias="rteButtons">Botones</key>
<key alias="rteEnableAdvancedSettings">Habilitar la configuración avanzada para</key>
<key alias="rteEnableContextMenu">Habilitar menú contextual</key>
@@ -437,31 +440,34 @@
<key alias="errorExistsWithoutTab">%0% ya existe</key>
<key alias="errorHeader">Se han encontrado los siguientes errores:</key>
<key alias="errorHeaderWithoutTab">Se han encontrado los siguientes errores:</key>
<key alias="errorInPasswordFormat">La clave debe tener como mínimo %0% caracteres y %1% caracter(es) no alfanuméricos</key>
<key alias="errorInPasswordFormat">La clave debe tener como mínimo %0% caracteres y %1% carácter(es) no alfanuméricos</key>
<key alias="errorIntegerWithoutTab">%0% debe ser un número entero</key>
<key alias="errorMandatory">Debe llenar los campos del %0% al %1%</key>
<key alias="errorMandatoryWithoutTab">Debe llenar el campo %0%</key>
<key alias="errorRegExp">Debe poner el formato correcto del %0% al %1% </key>
<key alias="errorRegExpWithoutTab">Debe poner un formato correcto en %0%</key>
<key alias="errorMandatory">Debes llenar los campos del %0% al %1%</key>
<key alias="errorMandatoryWithoutTab">Debes llenar el campo %0%</key>
<key alias="errorRegExp">Debes poner el formato correcto del %0% al %1% </key>
<key alias="errorRegExpWithoutTab">Debes poner un formato correcto en %0%</key>
</area>
<area alias="errors">
<key alias="receivedErrorFromServer">Se recibió un error desde el servidor</key>
<key alias="dissallowedMediaType">El tipo de archivo especificado ha sido deshabilitado por el administrador</key>
<key alias="codemirroriewarning">NOTA: Aunque CodeMirror esté activado en los ajustes de configuracion, no se muestra en Internet Explorer debido a que no es lo suficientemente estable.'</key>
<key alias="contentTypeAliasAndNameNotNull">Debe llenar el alias y el nombre en el propertytype</key>
<key alias="codemirroriewarning">NOTA: Aunque CodeMirror esté activado en los ajustes de configuración, no se muestra en Internet Explorer debido a que no es lo suficientemente estable.'</key>
<key alias="contentTypeAliasAndNameNotNull">Debes rellenar el alias y el nombre en el tipo de propiedad</key>
<key alias="filePermissionsError">Hay un problema de lectura y escritura al acceder a un archivo o carpeta</key>
<key alias="macroErrorLoadingPartialView">Error cargando Vista Parcial (archivo: %0%)</key>
<key alias="macroErrorLoadingUsercontrol">Error cargando userControl '%0%'</key>
<key alias="missingTitle"><![CDATA[Por favor, introduzca un título
]]></key>
<key alias="missingType">Por favor, elija un tipo </key>
<key alias="pictureResizeBiggerThanOrg">Usted está a punto de hacer la foto más grande que el tamaño original. ¿Está seguro de que desea continuar?</key>
<key alias="missingType">Por favor, elige un tipo </key>
<key alias="pictureResizeBiggerThanOrg">Estás a punto de hacer la foto más grande que el tamaño original. ¿Estás seguro de que desea continuar?</key>
<key alias="startNodeDoesNotExists"><![CDATA[Startnode suprimido, por favor, póngase en contacto con su administrador
]]></key>
<key alias="stylesMustMarkBeforeSelect">Por favor, marque el contenido antes de cambiar de estilo</key>
<key alias="stylesNoStylesOnPage">No active estilos disponibles</key>
<key alias="tableColMergeLeft"><![CDATA[Por favor, coloque el cursor a la izquierda de las dos celdas que quiere combinar
]]></key>
<key alias="stylesMustMarkBeforeSelect">Por favor, marca el contenido antes de cambiar de estilo</key>
<key alias="stylesNoStylesOnPage">No actives estilos disponibles</key>
<key alias="tableColMergeLeft">
<![CDATA[Por favor, coloca el cursor a la izquierda de las dos celdas que quieres combinar
]]>
</key>
<key alias="tableSplitNotSplittable"><![CDATA[No se puede dividir una celda que no ha sido combinada.
]]></key>
</area>
@@ -471,7 +477,7 @@
<key alias="actions">Acciones</key>
<key alias="add">Añadir</key>
<key alias="alias">Alias</key>
<key alias="areyousure">¿Está seguro?</key>
<key alias="areyousure">¿Estás seguro?</key>
<key alias="border">Borde</key>
<key alias="by">o</key>
<key alias="cancel">Cancelar</key>
@@ -492,7 +498,7 @@
<key alias="deleted">Borrado</key>
<key alias="deleting">Borrando...</key>
<key alias="design">Diseño</key>
<key alias="dictionary">Dictionario</key>
<key alias="dictionary">Diccionario</key>
<key alias="dimensions">Dimensiones</key>
<key alias="down">Abajo</key>
<key alias="download">Descargar</key>
@@ -512,11 +518,11 @@
<key alias="innerMargin">Margen interno</key>
<key alias="insert">Insertar</key>
<key alias="install">Instalar</key>
<key alias="invalid">Invalido</key>
<key alias="invalid">Inválido</key>
<key alias="justify">Justificar</key>
<key alias="label">Etiqueta</key>
<key alias="language">Idioma</key>
<key alias="last">Ultimo</key>
<key alias="last">Último</key>
<key alias="layout">Diseño</key>
<key alias="loading">Cargando</key>
<key alias="locked">Bloqueado</key>
@@ -528,7 +534,7 @@
<key alias="message">Mensaje</key>
<key alias="move">Mover</key>
<key alias="name">Nombre</key>
<key alias="new">New</key>
<key alias="new">Nuevo</key>
<key alias="next">Próximo</key>
<key alias="no">No</key>
<key alias="of">de</key>
@@ -590,7 +596,7 @@
<key alias="saving">Guardando...</key>
<key alias="current">actual</key>
<key alias="embed">Insertar</key>
<key alias="selected">selecionado</key>
<key alias="selected">seleccionado</key>
</area>
<area alias="colors">
<key alias="blue">Azul</key>
@@ -607,9 +613,9 @@
<key alias="shortcut">Atajos</key>
<key alias="showShortcuts">mostrar atajos</key>
<key alias="toggleListView">Activar/Desactivar vista de lista</key>
<key alias="toggleAllowAsRoot">Activar/Desactivar permitir como raiz</key>
<key alias="commentLine">Act/Desact Comentar líneas</key>
<key alias="removeLine">Elimiar línea</key>
<key alias="toggleAllowAsRoot">Activar/Desactivar permitir como raíz</key>
<key alias="commentLine">Comentar/Descomentar líneas</key>
<key alias="removeLine">Eliminar línea</key>
<key alias="copyLineUp">Copiar líneas arriba</key>
<key alias="copyLineDown">Copiar líneas abajo</key>
<key alias="moveLineUp">Mover líneas arriba</key>
@@ -629,18 +635,18 @@
</area>
<area alias="installer">
<key alias="databaseErrorCannotConnect">El instalador no puede conectar con la base de datos.</key>
<key alias="databaseErrorWebConfig">No se ha podido guardar el archivo Web.config. Por favor, modifique la cadena de conexión manualmente.</key>
<key alias="databaseFound">Su base de datos ha sido encontrada y ha sido identificada como</key>
<key alias="databaseErrorWebConfig">No se ha podido guardar el archivo Web.config. Por favor, modifica la cadena de conexión manualmente.</key>
<key alias="databaseFound">Tu base de datos ha sido encontrada y ha sido identificada como</key>
<key alias="databaseHeader">Configuración de la base de datos</key>
<key alias="databaseInstall"><![CDATA[Pulse el botón <strong> instalar </ strong> para instalar %0% la base de datos de Umbraco]]></key>
<key alias="databaseInstallDone"><![CDATA[Se ha copiado Umbraco %0% a la base de datos. Pulse <strong>Próximo</strong> para continuar]]></key>
<key alias="databaseNotFound"><![CDATA[<p>¡No se ha encontrado ninguna base de datos! Mira si la información en la "connection string" del “web.config” es correcta.</p> <p>Para continuar, edite el "web.config" (bien sea usando Visual Studio o su editor de texto preferido), vaya al final del archivo y añada la cadena de conexión para la base de datos con el nombre (key) "umbracoDbDSN" y guarde el archivo. </p> <p>Pinche en <strong>reintentar</strong> cuando haya terminado.<br /><a href="https://our.umbraco.com/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Pinche aquí para mayor información de como editar el web.config (en inglés)</a></p>]]></key>
<key alias="databaseInstall"><![CDATA[Pulsa el botón <strong> instalar </ strong> para instalar %0% la base de datos de Umbraco]]></key>
<key alias="databaseInstallDone"><![CDATA[Se ha copiado Umbraco %0% a la base de datos. Pulsa <strong>Próximo</strong> para continuar]]></key>
<key alias="databaseNotFound"><![CDATA[<p>¡No se ha encontrado ninguna base de datos! Mira si la información en la cadena de conexión del “web.config” es correcta.</p> <p>Para continuar, edita el "web.config" (bien sea usando Visual Studio o tu editor de texto preferido), ve al final del archivo y añade la cadena de conexión para la base de datos con el nombre (key) "umbracoDbDSN" y guarda el archivo. </p> <p>Pincha en <strong>reintentar</strong> cuando hayas terminado.<br /><a href="https://our.umbraco.com/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">Pincha aquí para mayor información de como editar el web.config (en inglés)</a></p>]]></key>
<key alias="databaseText"><![CDATA[Para completar este paso, debes conocer la información correspondiente a tu servidor de base de datos ("cadena de conexión").<br /> Por favor, contacta con tu ISP si es necesario. Si estás realizando la instalación en una máquina o servidor local, quizás necesites información de tu administrador de sistemas.]]></key>
<key alias="databaseUpgrade"><![CDATA[<p> Pinche en <strong>actualizar</strong> para actualizar la base de datos a Umbraco %0%</p> <p> Ningún contenido será borrado de la base de datos y seguirá funcionando después de la actualización </p> ]]></key>
<key alias="databaseUpgradeDone"><![CDATA[La base de datos ha sido actualizada a la versión 0%.<br />Pinche en <strong>Próximo</strong> para continuar. ]]></key>
<key alias="databaseUpToDate"><![CDATA[La base de datos está actualizada. Pinche en <strong>próximo</strong> para continuar con el asistente de configuración]]></key>
<key alias="databaseUpgrade"><![CDATA[<p> Pincha en <strong>actualizar</strong> para actualizar la base de datos a Umbraco %0%</p> <p> Ningún contenido será borrado de la base de datos y seguirá funcionando después de la actualización </p> ]]></key>
<key alias="databaseUpgradeDone"><![CDATA[La base de datos ha sido actualizada a la versión 0%.<br />Pincha en <strong>Próximo</strong> para continuar. ]]></key>
<key alias="databaseUpToDate"><![CDATA[La base de datos está actualizada. Pincha en <strong>próximo</strong> para continuar con el asistente de configuración]]></key>
<key alias="defaultUserChangePass"><![CDATA[<strong>La contraseña del usuario por defecto debe ser cambiada</strong>]]></key>
<key alias="defaultUserDisabled"><![CDATA[<strong>El usuario por defecto ha sido desabilitado o ha perdido el acceso a Umbraco!</strong></p><p>Pinche en <b>Próximo</b> para continuar.]]></key>
<key alias="defaultUserDisabled"><![CDATA[<strong>El usuario por defecto ha sido deshabilitado o ha perdido el acceso a Umbraco!</strong></p><p>Pincha en <b>Próximo</b> para continuar.]]></key>
<key alias="defaultUserPassChanged"><![CDATA[<strong>¡La contraseña del usuario por defecto ha sido cambiada desde que se instaló!</strong></p><p>No hay que realizar ninguna tarea más. Pulsa <strong>Siguiente</strong> para proseguir.]]></key>
<key alias="defaultUserPasswordChanged">¡La contraseña se ha cambiado!</key>
<key alias="greatStart">Ten un buen comienzo, visita nuestros videos de introducción</key>
@@ -659,15 +665,15 @@
<key alias="permissionsResolveFolderIssues">Resolviendo problemas con directorios</key>
<key alias="permissionsResolveFolderIssuesLink">Sigue este enlace para más información sobre problemas con ASP.NET y creación de directorios</key>
<key alias="permissionsSettingUpPermissions">Configurando los permisos de directorios</key>
<key alias="permissionsText">Umbraco necesita permisos de lectura/escritura en algunos directorios para poder almacenar archivos tales como imagenes y PDFs. También almacena datos en la caché para mejorar el rendimiento de su sitio web</key>
<key alias="permissionsText">Umbraco necesita permisos de lectura/escritura en algunos directorios para poder almacenar archivos tales como imágenes y PDFs. También almacena datos en la caché para mejorar el rendimiento de tu sitio web</key>
<key alias="runwayFromScratch">Quiero empezar de cero</key>
<key alias="runwayFromScratchText"><![CDATA[Tu sitio web está completamente vacío en estos momentos, lo cual es perfecto si quieres empezar de cero y crear tus propios tipos de documentos y plantillas (<a href="http://Umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>). Todavía podrás elegir instalar Runway más adelante. Por favor ve a la sección del Desarrollador y elije Paquetes.]]></key>
<key alias="runwayFromScratchText"><![CDATA[Tu sitio web está completamente vacío en estos momentos, lo cual es perfecto si quieres empezar de cero y crear tus propios tipos de documentos y plantillas (<a href="http://Umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">aprende cómo</a>). Todavía podrás elegir instalar Runway más adelante. Por favor ve a la sección del Desarrollador y elige Paquetes.]]></key>
<key alias="runwayHeader">Acabas de configurar una nueva plataforma Umbraco. ¿Qué deseas hacer ahora?</key>
<key alias="runwayInstalled">Se ha instalado Runway</key>
<key alias="runwayInstalledText"><![CDATA[Tienes puestos los cimientos. Selecciona los módulos que desees instalar sobre ellos.<br /> Esta es nuestra lista de módulos recomendados, selecciona los que desees instalar, o mira la <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">lista completa de módulos</a> ]]></key>
<key alias="runwayOnlyProUsers">Sólo recomendado para usuarios expertos</key>
<key alias="runwaySimpleSite">Quiero empezar con un sitio web sencillo</key>
<key alias="runwaySimpleSiteText"><![CDATA[<p> "Runway" es un sitio web sencillo que contiene unos tipos de documentos y plantillas básicos. El instalador puede configurar Runway por ti de forma automática, pero fácilmente puedes editarlo, extenderlo o eliminarlo. No es necesario y puedes usar Umbrao perfectamente sin él. Sin embargo, Runway ofrece unos cimientos sencillos basados en buenas prácticas para iniciarte más rápido que nunca. Si eliges instalar Runway, puedes seleccionar bloques de construcción básicos llamados Módulos de Runway de forma opcional para realzar tus páginas de Runway. </> <small> <em>Incluido con Runway:</em> Página de inicio, página de Cómo empezar, página de Instalación de módulos.<br /> <em>Módulos opcionales:</em> Navegación superior, Mapa del sitio, Contacto, Galería. </small> ]]></key>
<key alias="runwaySimpleSiteText"><![CDATA[<p> "Runway" es un sitio web sencillo que contiene unos tipos de documentos y plantillas básicos. El instalador puede configurar Runway por ti de forma automática, pero fácilmente puedes editarlo, extenderlo o eliminarlo. No es necesario y puedes usar Umbraco perfectamente sin él. Sin embargo, Runway ofrece unos cimientos sencillos basados en buenas prácticas para iniciarte más rápido que nunca. Si eliges instalar Runway, puedes seleccionar bloques de construcción básicos llamados Módulos de Runway de forma opcional para realzar tus páginas de Runway. </> <small> <em>Incluido con Runway:</em> Página de inicio, página de Cómo empezar, página de Instalación de módulos.<br /> <em>Módulos opcionales:</em> Navegación superior, Mapa del sitio, Contacto, Galería. </small> ]]></key>
<key alias="runwayWhatIsRunway">¿Qué es Runway?</key>
<key alias="step1">Paso 1 de 5. Aceptar los términos de la licencia</key>
<key alias="step2">Paso 2 de 5. Configuración de la base de datos</key>
@@ -685,15 +691,15 @@
<key alias="Version3">Umbraco versión 3</key>
<key alias="Version4">Umbraco versión 4</key>
<key alias="watch">Mirar</key>
<key alias="welcomeIntro"><![CDATA[El asistente de configuración le guiará en los pasos para instalar <strong>Umbraco %0%</strong> o actualizar la versión 3.0 a <strong>Umbraco %0%</strong>. <br /><br /> Pinche en <strong>"próximo"</strong> para empezar con el asistente de configuración.]]></key>
<key alias="welcomeIntro"><![CDATA[El asistente de configuración te guiará en los pasos para instalar <strong>Umbraco %0%</strong> o actualizar la versión 3.0 a <strong>Umbraco %0%</strong>. <br /><br /> Pincha en <strong>"próximo"</strong> para empezar con el asistente de configuración.]]></key>
</area>
<area alias="language">
<key alias="cultureCode">Código de cultura</key>
<key alias="displayName">Nombre de cultura</key>
</area>
<area alias="lockout">
<key alias="lockoutWillOccur">No ha habido ninguna actividad y su sessión se cerrará en </key>
<key alias="renewSession">Renovar su sesión para guardar sus cambios</key>
<key alias="lockoutWillOccur">No ha habido ninguna actividad y tu sesión se cerrará en </key>
<key alias="renewSession">Renovar tu sesión para guardar sus cambios</key>
</area>
<area alias="login">
<key alias="greeting0">Feliz super domingo</key>
@@ -708,10 +714,10 @@
<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href="http://umbraco.com" style="text-decoration: none" target="_blank">umbraco.com</a></p> ]]></key>
<key alias="forgottenPassword">¿Olvidaste tu contraseña?</key>
<key alias="forgottenPasswordInstruction">Enviaremos un email a la dirección especificada con un enlace para restaurar tu contraseña</key>
<key alias="requestPasswordResetConfirmation">Un email con instrucciones para restaurar tu contraseña será enviado a la dirección especificada si esta está registrada.</key>
<key alias="returnToLogin">Volver a formularion de acceso</key>
<key alias="requestPasswordResetConfirmation">Un email con instrucciones para restaurar tu contraseña será enviado a la dirección especificada si ésta está registrada.</key>
<key alias="returnToLogin">Volver al formulario de acceso</key>
<key alias="setPasswordInstruction">Por favor, introduce una nueva contraseña</key>
<key alias="setPasswordConfirmation">Tu contraseña has sido actualizada</key>
<key alias="setPasswordConfirmation">Tu contraseña ha sido actualizada</key>
<key alias="resetCodeExpired">El enlace pulsado es inválido o ha caducado</key>
<key alias="resetPasswordEmailCopySubject">Umbraco: Restaurar contraseña</key>
<key alias="resetPasswordEmailCopyFormat"><![CDATA[
@@ -802,36 +808,36 @@
<key alias="tree">Contenido</key>
</area>
<area alias="moveOrCopy">
<key alias="choose">Elija una página arriba...</key>
<key alias="choose">Elige una página arriba...</key>
<key alias="copyDone">%0% ha sido copiado al %1%</key>
<key alias="copyTo">Seleccione donde el documento %0% debe ser copiado abajo</key>
<key alias="copyTo">Selecciona donde el documento %0% debe ser copiado abajo</key>
<key alias="moveDone">%0% ha sido movido a %1%</key>
<key alias="moveTo">Seleccione debajo donde mover el documento %0%</key>
<key alias="nodeSelected">ha sido seleccionado como raíz de su nuevo contenido, haga click sobre 'ok' debajo.</key>
<key alias="noNodeSelected">No ha seleccionado ningún nodo. Seleccione un nodo en la lista mostrada arriba antes the pinchar en 'continuar' (continue)</key>
<key alias="notAllowedByContentType">No se puede colgar el nodo actual bajo el nodo elegido debido a su tipo</key>
<key alias="moveTo">Selecciona debajo donde mover el documento %0%</key>
<key alias="nodeSelected">ha sido seleccionado como raíz de tu nuevo contenido, haga clic sobre 'ok' debajo.</key>
<key alias="noNodeSelected">No ha seleccionado ningún nodo. Selecciona un nodo en la lista mostrada arriba antes de pinchar en 'continuar'</key>
<key alias="notAllowedByContentType">No se puede colgar el nodo actual bajo el nodo elegido debido a tu tipo</key>
<key alias="notAllowedByPath">El nodo actual no puede moverse a ninguna de sus subpáginas</key>
<key alias="notAllowedAtRoot">El nodo actual no puede existir en la raiz</key>
<key alias="notValid">Acción no permitida. No tiene permisos suficientes para uno o más subnodos.'</key>
<key alias="notAllowedAtRoot">El nodo actual no puede existir en la raíz</key>
<key alias="notValid">Acción no permitida. No tienes permisos suficientes para uno o más subnodos.'</key>
<key alias="relateToOriginal">Relacionar elemento copiado al original</key>
</area>
<area alias="notifications">
<key alias="editNotifications">Edite su notificación para %0%</key>
<key alias="mailBody">Hola %0% Esto es un e-mail automático para informarle que la tarea '%1%' ha sido realizada sobre la página '%2%' por el usuario '%3%' Vaya a http://%4%/#/content/content/edit/%5% para editarla. ¡Espero que tenga un buen día! Saludos del robot de Umbraco</key>
<key alias="editNotifications">Edita tu notificación para %0%</key>
<key alias="mailBody">Hola %0% Esto es un e-mail automático para informarte que la tarea '%1%' ha sido realizada sobre la página '%2%' por el usuario '%3%' Vaya a http://%4%/#/content/content/edit/%5% para editarla. ¡Espero que tenga un buen día! Saludos del robot de Umbraco</key>
<key alias="mailBodyHtml"><![CDATA[<p>Hola %0%</p> <p>Esto es un e-mail generado automáticamente para informarle que la tarea <strong>'%1%'</strong> ha sido realizada sobre la página <a href="http://%4%/#/content/content/edit/%5%"><strong>'%2%'</strong></a> por el usuario <strong>'%3%'</strong> </p> <div style="margin: 8px 0; padding: 8px; display: block;"> <br /> <a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EDIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <br /> </div> <p> <h3>Resumen de actualización:</h3> <table style="width: 100%;"> %6% </table> </p> <div style="margin: 8px 0; padding: 8px; display: block;"> <br /> <a style="color: white; font-weight: bold; background-color: #66cc66; text-decoration : none; margin-right: 20px; border: 8px solid #66cc66; width: 150px;" href="http://%4%/actions/publish.aspx?id=%5%">&nbsp;&nbsp;PUBLISH&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EDIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a> &nbsp; <a style="color: white; font-weight: bold; background-color: #ca4a4a; text-decoration : none; margin-right: 20px; border: 8px solid #ca4a4a; width: 150px;" href="http://%4%/actions/delete.aspx?id=%5%">&nbsp;&nbsp;&nbsp;&nbsp;DELETE&nbsp;&nbsp;&nbsp;&nbsp;</a> <br /> </div> <p>¡Espero que tenga un buen día!<br /><br /> Saludos del robot Umbraco. </p>]]></key>
<key alias="mailSubject">[%0%] Notificación acerca de %1% realizado en %2%</key>
<key alias="notifications">Notificaciones</key>
</area>
<area alias="packager">
<key alias="chooseLocalPackageText"><![CDATA[Elige un paquete de tu máquina, seleccionando el botón Examinar<br />y localizando el paquete. Los paquetes de Umbraco normalmente tienen la extensión ".umb" o ".zip".]]></key>
<key alias="dropHere">Suelte para subir archivo</key>
<key alias="orClickHereToUpload">o pulse aquí para elegir paquete</key>
<key alias="dropHere">Suelta para subir archivo</key>
<key alias="orClickHereToUpload">o Pulsa aquí para elegir paquete</key>
<key alias="uploadPackage">Subir paquete</key>
<key alias="localPackageDescription">Instala un paquete local seleccionándolo desde tu ordenador. Sólo instala paquetes de fuentes que conoces y en las que confías</key>
<key alias="localPackageDescription">Instala un paquete local seleccionándolo desde tu ordenador. instala sólo paquetes de fuentes que conoces y en las que confías</key>
<key alias="uploadAnother">Subir otro paquete</key>
<key alias="cancelAndUploadAnother">Cancelar y subir otro paquete</key>
<key alias="packageLicense">Licencia</key>
<key alias="accept">Aceptop</key>
<key alias="accept">Aceptar</key>
<key alias="termsOfUse">términos de uso</key>
<key alias="packageInstall">Instalar paquete</key>
<key alias="installFinish">Terminar</key>
@@ -847,13 +853,13 @@
<key alias="packageHas">tiene</key>
<key alias="packageKarmaPoints">puntos de karma</key>
<key alias="packageInfo">Información</key>
<key alias="packageOwner">Propetarioa</key>
<key alias="packageOwner">Propietario</key>
<key alias="packageContrib">Contribuidores</key>
<key alias="packageCreated">Creado</key>
<key alias="packageCurrentVersion">Versión actual</key>
<key alias="packageNetVersion">Versión .NET</key>
<key alias="packageDownloads">Descargas</key>
<key alias="packageLikes">Gustas</key>
<key alias="packageLikes">Me Gusta</key>
<key alias="packageCompatibility">Compatibilidad</key>
<key alias="packageCompatibilityDescription">Este paquete es compatible con las siguientes versiones de Umbraco, declaradas según miembros de la comunidad. No se puede garantizar compatibilidad completa para versiones declaradas debajo del 100%</key>
<key alias="packageExternalSources">Fuentes externas</key>
@@ -867,13 +873,13 @@
<key alias="packageNoItemsText"><![CDATA[Este archivo de paquete no contiene ningún elemento para desinstalar.<br /><br />Puedes eliminarlo del sistema de forma segura seleccionando la opción "desinstalar paquete" de abajo.]]></key>
<key alias="packageNoUpgrades">No hay actualizaciones disponibles</key>
<key alias="packageOptions">Opciones del paquete</key>
<key alias="packageReadme">Leeme del paquete</key>
<key alias="packageReadme">Léeme del paquete</key>
<key alias="packageRepository">Repositorio de paquetes</key>
<key alias="packageUninstallConfirm">Confirma la desinstalación</key>
<key alias="packageUninstalledHeader">El paquete ha sido desinstalado</key>
<key alias="packageUninstalledText">El paquete se ha desinstalado correctamente</key>
<key alias="packageUninstallHeader">Desinstalar paquete</key>
<key alias="packageUninstallText"><![CDATA[Debajo puedes deseleccionar elementos que no desees eliminar en este momento. Cuando elijas "confirmar la desinstalación" todos los elementos marcados serán eliminados.<br /> <span style="color: Red; font-weight: bold;">Nota:</span> cualquier documento, archivo etc dependiente de los elementos eliminados, dejará de funcionar, y puede conllevar inestabilidad en el sistema, por lo que lleva cuidado al desinstalar elementos. En caso de duda, contacta con el autor del paquete.]]></key>
<key alias="packageUninstallText"><![CDATA[Debajo puedes deseleccionar elementos que no desees eliminar en este momento. Cuando eliges "confirmar la desinstalación" todos los elementos marcados serán eliminados.<br /> <span style="color: Red; font-weight: bold;">Nota:</span> cualquier documento, archivo etc dependiente de los elementos eliminados, dejará de funcionar, y puede conllevar inestabilidad en el sistema, por lo que lleva cuidado al desinstalar elementos. En caso de duda, contacta con el autor del paquete.]]></key>
<key alias="packageUpgradeDownload">Descargar actualización del repositorio</key>
<key alias="packageUpgradeHeader">Actualizar paquete</key>
<key alias="packageUpgradeInstructions">Instrucciones de actualización</key>
@@ -893,27 +899,27 @@
</area>
<area alias="paste">
<key alias="doNothing">Pegar con formato completo (No recomendado)</key>
<key alias="errorMessage">El texto que estás intentando pegar contiene caractéres o formato especial. El problema puede ser debido al copiar texto desde Microsoft Word. Umbraco puede eliminar estos caractéres o formato especial automáticamente, de esa manera el contenido será más adecuado para la web.</key>
<key alias="errorMessage">El texto que estás intentando pegar contiene caracteres o formato especial. El problema puede ser debido al copiar texto desde Microsoft Word. Umbraco puede eliminar estos caracteres o formato especial automáticamente, de esa manera el contenido será más adecuado para la web.</key>
<key alias="removeAll">Pegar como texto sin formato</key>
<key alias="removeSpecialFormattering">Pegar, pero quitando el formato (Recomendado)</key>
</area>
<area alias="publicAccess">
<key alias="paAdvanced">Proteccion basada en roles</key>
<key alias="paAdvancedHelp"><![CDATA[Si desea controlar el acceso a la página usando autenticación basada en roles,<br /> usando los grupos de miembros de Umbraco.]]></key>
<key alias="paAdvancedNoGroups">Necesita crear un grupo de miembros antes de poder usar autenticación basada en roles</key>
<key alias="paAdvanced">Protección basada en roles</key>
<key alias="paAdvancedHelp"><![CDATA[Si deseas controlar el acceso a la página usando autenticación basada en roles,<br /> usando los grupos de miembros de Umbraco.]]></key>
<key alias="paAdvancedNoGroups">Necesitas crear un grupo de miembros antes de poder usar autenticación basada en roles</key>
<key alias="paErrorPage">Página de error</key>
<key alias="paErrorPageHelp">Usada cuando alguien hace login, pero no tiene acceso</key>
<key alias="paHowWould">Elija cómo restringir el acceso a esta página</key>
<key alias="paHowWould">Elige cómo restringir el acceso a esta página</key>
<key alias="paIsProtected">%0% está protegido</key>
<key alias="paIsRemoved">Protección borrada de %0%</key>
<key alias="paLoginPage">Página de login</key>
<key alias="paLoginPageHelp">Elija la página que contenga el formulario de login</key>
<key alias="paLoginPageHelp">Elige la página que contenga el formulario de login</key>
<key alias="paRemoveProtection">Borrar protección</key>
<key alias="paSelectPages">Elija las páginas que contendrán el formulario de login y mensajes de error</key>
<key alias="paSelectRoles">Elija los roles que tendrán acceso a esta página</key>
<key alias="paSetLogin">Elija el login y password para esta página</key>
<key alias="paSelectPages">Elige las páginas que contendrán el formulario de login y mensajes de error</key>
<key alias="paSelectRoles">Elige los roles que tendrán acceso a esta página</key>
<key alias="paSetLogin">Elige el login y contraseña para esta página</key>
<key alias="paSimple">Protección de usuario único</key>
<key alias="paSimpleHelp">Si sólo necesita configurar una protección simple usando un único login y password</key>
<key alias="paSimpleHelp">Si sólo necesita configurar una protección simple usando un único login y contraseña</key>
</area>
<area alias="publish">
<key alias="contentPublishedFailedAwaitingRelease"><![CDATA[
@@ -936,7 +942,7 @@
<key alias="nodePublish">%0% se ha publicado</key>
<key alias="nodePublishAll">%0% y sus subpáginas se han publicado</key>
<key alias="publishAll">Publicar %0% y todas sus subpáginas</key>
<key alias="publishHelp"><![CDATA[Pulsa en <em>aceptar</em> para publicar <strong>%0%</strong> y por lo tanto, hacer que su contenido esté disponible al público.<br/><br /> Puedes publicar esta página y todas sus subpáginas marcando <em>publicar todos los hijos</em> debajo. ]]></key>
<key alias="publishHelp"><![CDATA[Pulsa en <em>aceptar</em> para publicar <strong>%0%</strong> y por lo tanto, hacer que tu contenido esté disponible al público.<br/><br /> Puedes publicar esta página y todas sus subpáginas marcando <em>publicar todos los hijos</em> debajo. ]]></key>
</area>
<area alias="colorpicker">
<key alias="noColors">No has configurado ningún color</key>
@@ -956,7 +962,7 @@
<key alias="link">Enlace</key>
<key alias="newWindow">Abrir en una nueva ventana</key>
<key alias="captionPlaceholder">Introduce texto</key>
<key alias="externalLinkPlaceholder">Introduzce el enlace</key>
<key alias="externalLinkPlaceholder">Introduce el enlace</key>
</area>
<area alias="imagecropper">
<key alias="reset">Reiniciar</key>
@@ -965,11 +971,11 @@
</area>
<area alias="rollback">
<key alias="currentVersion">Versión actual</key>
<key alias="diffHelp"><![CDATA[Esto muestra las diferencias entre la versión actual y la versión seleccionada<br /><del>Red</del> el texto de la versión seleccionada no se mostrará. , <ins>green means added</ins>]]></key>
<key alias="diffHelp"><![CDATA[Esto muestra las diferencias entre la versión actual y la versión seleccionada<br /><del>Red</del> el texto de la versión seleccionada no se mostrará. , <ins>el verde significa añadido</ins>]]></key>
<key alias="documentRolledBack">Se ha recuperado la última versión del documento.</key>
<key alias="htmlHelp">Esto muestra la versión seleccionada como html, si desea ver la diferencia entre 2 versiones al mismo tiempo, por favor use la vista diff</key>
<key alias="htmlHelp">Esto muestra la versión seleccionada como html, si deseas ver la diferencia entre 2 versiones al mismo tiempo, por favor usa la vista diff</key>
<key alias="rollbackTo">Volver a</key>
<key alias="selectVersion">Elija versión</key>
<key alias="selectVersion">Elige versión</key>
<key alias="view">Ver</key>
</area>
<area alias="scripts">
@@ -996,7 +1002,7 @@
<area alias="settings">
<key alias="defaulttemplate">Plantilla por defecto</key>
<key alias="dictionary editor egenskab">Clave de diccionario</key>
<key alias="importDocumentTypeHelp">Para importar un tipo de documento encuentre el fichero ".udt" en su ordenador haciendo click sobre el botón "Navegar" y pulsando "Importar" (se le solicitará confirmación en la siguiente pantalla)</key>
<key alias="importDocumentTypeHelp">Para importar un tipo de documento encuentra el fichero ".udt" en tu ordenador haciendo clic sobre el botón "Navegar" y pulsando "Importar" (se te solicitará confirmación en la siguiente pantalla)</key>
<key alias="newtabname">Nuevo nombre de la pestaña</key>
<key alias="nodetype">Tipo de nodo</key>
<key alias="objecttype">Tipo</key>
@@ -1009,19 +1015,19 @@
<key alias="contentTypeEnabled">Tipo de Contenido Maestro activado</key>
<key alias="contentTypeUses">Este Tipo de Contenido usa</key>
<key alias="asAContentMasterType">como Tipo de Contenido Maestro. Las pestañas para los Tipos de Contenido Maestros no se muestran y solo se pueden modificar desde el Tipo de Contenido Maestro</key>
<key alias="noPropertiesDefinedOnTab">No existen propiedades para esta pestaña. Haga clic en el enlace "añadir nueva propiedad" para crear una nueva propiedad.</key>
<key alias="noPropertiesDefinedOnTab">No existen propiedades para esta pestaña. Haz clic en el enlace "añadir nueva propiedad" para crear una nueva propiedad.</key>
<key alias="addIcon">Añadir icono</key>
</area>
<area alias="sort">
<key alias="sortOrder">Ordenar</key>
<key alias="sortCreationDate">Fecha Creado</key>
<key alias="sortDone">Ordenación completa</key>
<key alias="sortHelp">Arrastra las diferentes páginas debajo para colocarlas como deberían estar. O haz click en las cabeceras de las columnas para ordenar todas las páginas</key>
<key alias="sortPleaseWait"><![CDATA[Espere por favor, las páginas están siendo ordenadas. El proceso puede durar un poco.]]></key>
<key alias="sortHelp">Arrastra las diferentes páginas debajo para colocarlas como deberían estar o haz clic en las cabeceras de las columnas para ordenar todas las páginas</key>
<key alias="sortPleaseWait"><![CDATA[Espera por favor, las páginas están siendo ordenadas. El proceso puede durar un poco.]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">Validación</key>
<key alias="validationFailedMessage">Los errors de validación deben ser arreglados antes de que el elemento pueda ser guardado</key>
<key alias="validationFailedMessage">Los errores de validación deben ser arreglados antes de que el elemento pueda ser guardado</key>
<key alias="operationFailedHeader">Fallo</key>
<key alias="operationSavedHeader">Guardado</key>
<key alias="invalidUserPermissionsText">Insuficientes permisos de usuario, no se pudo completar la operación</key>
@@ -1072,7 +1078,7 @@
<key alias="contentUnpublished">Contenido oculto</key>
<key alias="partialViewSavedHeader">Vista parcial guardada</key>
<key alias="partialViewSavedText">Vista parcial guardada sin errores</key>
<key alias="partialViewErrorHeader">ista parcial no guardada</key>
<key alias="partialViewErrorHeader">Vista parcial no guardada</key>
<key alias="partialViewErrorText">Error guardando el archivo.</key>
<key alias="permissionsSavedFor">Permisos guardados para</key>
<key alias="deleteUserGroupsSuccess">Borrados %0% grupos de usuario</key>
@@ -1082,7 +1088,7 @@
<key alias="enableUserSuccess">%0% usuario activado</key>
<key alias="disableUserSuccess">%0% desactivado</key>
<key alias="setUserGroupOnUsersSuccess">Grupos de usuario establecidos</key>
<key alias="unlockUsersSuccess">%0% usuarios desbloquedaos</key>
<key alias="unlockUsersSuccess">%0% usuarios desbloqueados</key>
<key alias="unlockUserSuccess">%0% está desbloqueado</key>
</area>
<area alias="stylesheet">
@@ -1099,21 +1105,21 @@
<key alias="insertContentArea">Insertar área de contenido</key>
<key alias="insertContentAreaPlaceHolder">Insertar marcador de posición de área de contenido</key>
<key alias="insert">Insertar</key>
<key alias="insertDesc">Elije que insertar en tu plantilla</key>
<key alias="insertDesc">Elige que insertar en tu plantilla</key>
<key alias="insertDictionaryItem">Insertar objeto del diccionario</key>
<key alias="insertDictionaryItemDesc">A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites.</key>
<key alias="insertDictionaryItemDesc">Un objeto de diccionario es una variable para un texto traducible, lo que facilita crear sitios multi idioma.</key>
<key alias="insertMacro">Insertar macro</key>
<key alias="insertMacroDesc">
Una Macor es un componente configurable que es genial como partes reutilizables de tu diseño,
Una Macro es un componente configurable que es genial como partes reutilizables de tu diseño,
donde necesites una forma de proporcionar parámetros,
como galerías, formularios y listas.
</key>
<key alias="insertPageField">Insertar campo de página de Umbraco</key>
<key alias="insertPageFieldDesc">Muestra el valor de una propiedad de la página actual, con opciones para modificar el valor or usar valores alternativos.</key>
<key alias="insertPageFieldDesc">Muestra el valor de una propiedad de la página actual, con opciones para modificar el valor o usar valores alternativos.</key>
<key alias="insertPartialView">Vista parcial</key>
<key alias="insertPartialViewDesc">
Una vista parcial es una platilla separada que puede ser mostrada dentro de otra plantilla.
Es útil para reutilizar código or para distribuir plantillas complejas en archivos separados.
Es útil para reutilizar código o para distribuir plantillas complejas en archivos separados.
</key>
<key alias="mastertemplate">Plantilla principal</key>
<key alias="noMaster">Sin principal</key>
@@ -1129,12 +1135,12 @@
<key alias="renderSection">Muestra una sección nombrada</key>
<key alias="renderSectionDesc"><![CDATA[
Muestra un area nombrada de una plantilla hija insertando <code>@RenderSection(name)</code> placeholder.
Esto muestra un area de una plantilla hija rodeada de la corresponsiente definición <code>@section [name]{ ... }</code>.
Esto muestra un area de una plantilla hija rodeada de la correspondiente definición <code>@section [name]{ ... }</code>.
]]></key>
<key alias="sectionName">Nombre de sección</key>
<key alias="sectionMandatory">Sección es obligatoria</key>
<key alias="sectionMandatoryDesc">
Si obligatoria, la plantilla hija debe contener una definición de <code>@section</code> o se mostrará un error.
Si está marcada como obligatoria, la plantilla hija debe contener una definición de <code>@section</code> o se mostrará un error.
</key>
<key alias="queryBuilder">Constructor de consultas</key>
<key alias="itemsReturned">elementos devueltos, en</key>
@@ -1170,20 +1176,20 @@
<key alias="template">Plantilla</key>
</area>
<area alias="grid">
<key alias="media">Image</key>
<key alias="media">Imagen</key>
<key alias="macro">Macro</key>
<key alias="insertControl">Insertar control</key>
<key alias="chooseLayout">Elije configuración</key>
<key alias="chooseLayout">Elige configuración</key>
<key alias="addRows">Añade más filas</key>
<key alias="addElement">Añadir contenido</key>
<key alias="dropElement">Soltar contenido</key>
<key alias="settingsApplied">Settings applied</key>
<key alias="settingsApplied">Configuración aplicada</key>
<key alias="contentNotAllowed">Contenido no permitido aquí</key>
<key alias="contentAllowed">Contenido permitido aquí</key>
<key alias="clickToEmbed">Pulse para insertar</key>
<key alias="clickToInsertImage">Pulse para insertar imagen</key>
<key alias="clickToEmbed">Pulsa para insertar</key>
<key alias="clickToInsertImage">Pulsa para insertar imagen</key>
<key alias="placeholderImageCaption">Leyenda de imagen...</key>
<key alias="placeholderWriteHere">Escribe aqui...</key>
<key alias="placeholderWriteHere">Escribe aquí...</key>
<key alias="gridLayouts">Plantillas de Grid</key>
<key alias="gridLayoutsDetail">Las plantillas son el área de trabajo para el editor de grids, normalmente sólo necesitas una o dos plantillas diferentes</key>
<key alias="addGridLayout">Añadir plantilla de grid</key>
@@ -1209,16 +1215,16 @@
</area>
<area alias="contentTypeEditor">
<key alias="compositions">Composiciones</key>
<key alias="noTabs">No has añadido nunguna pestaña</key>
<key alias="noTabs">No has añadido ninguna pestaña</key>
<key alias="inheritedFrom">Heredado de</key>
<key alias="addProperty">Añadir propiedad</key>
<key alias="requiredLabel">Etiqueta requerida</key>
<key alias="enableListViewHeading">Activar vista de lista</key>
<key alias="enableListViewDescription">Configura la página para mostrar una lista de sus hijas que puedes ordenar y buscar, los hijas no se mostrarán en el árbol de contenido</key>
<key alias="allowedTemplatesHeading">Platillas permitidas</key>
<key alias="allowedTemplatesDescription">Elije que plantillas se permite a los editores utilizar en contenido de este tipo</key>
<key alias="allowAsRootHeading">Permitir como raiz</key>
<key alias="allowAsRootDescription">Permite a los editores crear contenido de este tipo en la raiz del árbol de contenido</key>
<key alias="allowedTemplatesDescription">Elige que plantillas se permite a los editores utilizar en contenido de este tipo</key>
<key alias="allowAsRootHeading">Permitir como raíz</key>
<key alias="allowAsRootDescription">Permite a los editores crear contenido de este tipo en la raíz del árbol de contenido</key>
<key alias="childNodesHeading">Tipos de nodos hijos permitidos</key>
<key alias="childNodesDescription">Permite contenido de los tipos permitidos ser creados debajo de este tipo de contenido </key>
<key alias="chooseChildNode">Elegir nodo hijo</key>
@@ -1265,15 +1271,15 @@
<key alias="casing">MAYÚSCULA/minúscula</key>
<key alias="chooseField">Elegir campo</key>
<key alias="convertLineBreaks">Convertir a salto de línea</key>
<key alias="convertLineBreaksDescription">Sí, convertir salto de linea</key>
<key alias="convertLineBreaksDescription">Sí, convertir salto de línea</key>
<key alias="convertLineBreaksHelp">Reemplaza los saltos de línea con la etiqueta HTML &amp;lt;br&amp;gt;</key>
<key alias="customFields">Campos personalizados</key>
<key alias="dateOnly">Si, solamente la fecha</key>
<key alias="formatAndEncoding">Formato y codificación</key>
<key alias="formatAsDate">Cambiar formato a fecha</key>
<key alias="formatAsDateDescr">Formatear el valor como una fecha o una fecha con hora , de acuerdo con la cultura activa</key>
<key alias="formatAsDateDescr">Formatear el valor como una fecha o una fecha con hora, de acuerdo con el idioma activa</key>
<key alias="htmlEncode">Codificar HTML</key>
<key alias="htmlEncodeHelp">Se reemplazarán los caracteres especiales por su código HTML equivalente.</key>
<key alias="htmlEncodeHelp">Se reemplazarán los caracteres especiales por tu código HTML equivalente.</key>
<key alias="insertedAfter">Será insertado después del valor del campo</key>
<key alias="insertedBefore">Será insertado antes del valor del campo</key>
<key alias="lowercase">Minúscula</key>
@@ -1289,8 +1295,8 @@
<key alias="uppercase">Mayúscula</key>
<key alias="urlEncode">Codificar URL</key>
<key alias="urlEncodeHelp">Formateará los caracteres especiales de las URLs</key>
<key alias="usedIfAllEmpty">Sólo será usado cuando el campo superior esté vacio</key>
<key alias="usedIfEmpty">Este campo será usado unicamente si el campo primario está vacío</key>
<key alias="usedIfAllEmpty">Sólo será usado cuando el campo superior esté vacío</key>
<key alias="usedIfEmpty">Este campo será usado únicamente si el campo primario está vacío</key>
<key alias="withTime">Si, con el tiempo. Separador:</key>
</area>
<area alias="translation">
@@ -1301,15 +1307,15 @@
<key alias="mailBody"><![CDATA[
Hola %0%.
Este mail se ha generado automáticamente para informale que %2% ha solicitado que el documento '%1%' sea traducido en '%5%'.
Este mail se ha generado automáticamente para informale que %2% has solicitado que el documento '%1%' sea traducido en '%5%'.
Para editarlo, vaya a la dirección http://%3%/translation/details.aspx?id=%4% o inicie la sesión en umbraco y vaya a http://%3% para ver las tareas pendientes de traducir.
Para editarlo, vaya a la dirección http://%3%/translation/details.aspx?id=%4% o inicia sesión en umbraco y ve a http://%3% para ver las tareas pendientes de traducir.
Espero que tenga un buen dia.
Saludos de parte de el robot de Umbraco
]]></key>
<key alias="noTranslators">No se encontraron usuarios traductores. Por favor, crea un usuario traductor antes de empezar a mandar contenido para su traducción</key>
<key alias="noTranslators">No se encontraron usuarios traductores. Por favor, crea un usuario traductor antes de empezar a mandar contenido para tu traducción</key>
<key alias="pageHasBeenSendToTranslation">La página '%0%' se ha mandado a traducción</key>
<key alias="sendToTranslate">Manda la página '%0%' a traducción</key>
<key alias="totalWords">Total de palabras</key>
@@ -1366,17 +1372,17 @@
<key alias="accessHelp">Basado en los grupos asignados y los nodos iniciales, el usuario tiene acceso a los siguientes nodos.</key>
<key alias="assignAccess">Asignar acceso</key>
<key alias="administrators">Administrador</key>
<key alias="categoryField">Campo de categoria</key>
<key alias="categoryField">Campo de categoría</key>
<key alias="changePassword">Cambiar contraseña</key>
<key alias="changePhoto">Cambiar foto</key>
<key alias="newPassword">Nueva contraseña</key>
<key alias="noLockouts">no ha sido bloqueado</key>
<key alias="noPasswordChange">La contraseña no se ha cambiado</key>
<key alias="confirmNewPassword">Confirma nueva contraseña</key>
<key alias="changePasswordDescription">Puede cambiar su contraseña para acceder al 'back office' de Umbraco rellenando el siguiente formulario y haciendo clic en el botón 'Cambiar contraseña'</key>
<key alias="changePasswordDescription">Puedes cambiar tu contraseña para acceder al 'back office' de Umbraco rellenando el siguiente formulario y haciendo clic en el botón 'Cambiar contraseña'</key>
<key alias="contentChannel">Canal de contenido</key>
<key alias="createAnotherUser">Crear otro usuario</key>
<key alias="createUserHelp">Crear nuevos usuarios para darles acceso a Umbraco. Cuando un nuevo usuario es creado, una nueva contrasela será generada y la podrás compartir con el usuario.</key>
<key alias="createUserHelp">Crear nuevos usuarios para darles acceso a Umbraco. Cuando un nuevo usuario es creado, una nueva contraseña será generada y la podrás compartir con el usuario.</key>
<key alias="descriptionField">Campo descriptivo</key>
<key alias="disabled">Deshabilitar usuario</key>
<key alias="documentType">Tipo de documento</key>
@@ -1388,39 +1394,39 @@
<key alias="inviteAnotherUser">Invitar otro usuario</key>
<key alias="inviteUserHelp">Invita nuevos usuarios para darles acceso a Umbraco. Un email de invitación será enviado al usuario con información sobre cómo acceder a Umbraco.</key>
<key alias="language">Idioma</key>
<key alias="languageHelp">Establecer el idioma que verás en menús y dialogos</key>
<key alias="languageHelp">Establecer el idioma que verás en menús y diálogos</key>
<key alias="lastLockoutDate">Última fecha bloqueado</key>
<key alias="lastLogin">Último acceso</key>
<key alias="lastPasswordChangeDate">Última contraseña cambiada</key>
<key alias="loginname">Acceso</key>
<key alias="mediastartnode">Nodo de comienzo en la libreria de medios</key>
<key alias="mediastartnodehelp">Limitar la librería de medios al siguiente nodo de inicio</key>
<key alias="mediastartnode">Nodo de comienzo en la biblioteca de medios</key>
<key alias="mediastartnodehelp">Limitar la biblioteca de medios al siguiente nodo de inicio</key>
<key alias="mediastartnodes">Nodos de inicio para Medios</key>
<key alias="mediastartnodeshelp">Limitar la librería de medios a los siguientes nodos de inicio</key>
<key alias="mediastartnodeshelp">Limitar la biblioteca de medios a los siguientes nodos de inicio</key>
<key alias="modules">Secciones</key>
<key alias="noConsole">Deshabilitar acceso a Umbraco</key>
<key alias="noLogin">no se ha conectado aún</key>
<key alias="oldPassword">Contraseña antigüa</key>
<key alias="oldPassword">Contraseña antigua</key>
<key alias="password">Contraseña</key>
<key alias="resetPassword">Reiniciar contraseña</key>
<key alias="passwordChanged">Su contraseña ha sido cambiada</key>
<key alias="passwordConfirm">Por favor confirme su nueva contraseña</key>
<key alias="passwordEnterNew">Introduzca su nueva contraseña</key>
<key alias="passwordChanged">Tu contraseña ha sido cambiada</key>
<key alias="passwordConfirm">Por favor confirma tu nueva contraseña</key>
<key alias="passwordEnterNew">Introduce tu nueva contraseña</key>
<key alias="passwordIsBlank">La nueva contraseña no puede estar vacía</key>
<key alias="passwordCurrent">Contraseña actual</key>
<key alias="passwordInvalid">Contraseña actual inválida</key>
<key alias="passwordIsDifferent">La nueva contraseña no coincide con la contraseña de confirmación. Por favor, vuela a intentarlo!'</key>
<key alias="passwordMismatch">La contraseña de confirmación no coincide con la nueva contraseña!'</key>
<key alias="passwordIsDifferent">La nueva contraseña no coincide con la contraseña de confirmación. Por favor, vuele a intentarlo!</key>
<key alias="passwordMismatch">La contraseña de confirmación no coincide con la nueva contraseña!</key>
<key alias="permissionReplaceChildren">Reemplazar los permisos de los nodos hijo</key>
<key alias="permissionSelectedPages">Estas modificando los permisos para las páginas:</key>
<key alias="permissionSelectedPages">Estás modificando los permisos para las páginas:</key>
<key alias="permissionSelectPages">Selecciona las páginas para modificar sus permisos</key>
<key alias="removePhoto">Eliminar photo</key>
<key alias="removePhoto">Eliminar imagen</key>
<key alias="permissionsDefault">Permisos por defecto</key>
<key alias="permissionsGranular">Permisos granulares</key>
<key alias="permissionsGranularHelp">Establecer permisos para nodos especificos</key>
<key alias="permissionsGranularHelp">Establecer permisos para nodos específicos</key>
<key alias="profile">Perfil</key>
<key alias="searchAllChildren">Buscar en todos los hijos</key>
<key alias="sectionsHelp">Añadir secciones para dar aceso a usuarios</key>
<key alias="sectionsHelp">Añadir secciones para dar acceso a usuarios</key>
<key alias="selectUserGroups">Seleccionar grupos de usuarios</key>
<key alias="noStartNode">Nodo de inicio no seleccionado</key>
<key alias="noStartNodes">Nodos de inicio no seleccionado</key>
@@ -1446,7 +1452,7 @@
<key alias="sessionExpires" version="7.0">La sesión caduca en</key>
<key alias="inviteUser">Invitar usuario</key>
<key alias="createUser">Crear usuario</key>
<key alias="sendInvite">Enviar invitatión</key>
<key alias="sendInvite">Enviar invitación</key>
<key alias="backToUsers">Volver a usuarios</key>
<key alias="inviteEmailCopySubject">Umbraco: Invitación</key>
<key alias="inviteEmailCopyFormat"><![CDATA[
@@ -1546,7 +1552,7 @@
<key alias="validateAsEmail">Validar como email</key>
<key alias="validateAsNumber">Validar como número</key>
<key alias="validateAsUrl">Validar como Url</key>
<key alias="enterCustomValidation">...or introduce tu propia validación</key>
<key alias="enterCustomValidation">...o introduce tu propia validación</key>
<key alias="fieldIsMandatory">Campo obligatorio</key>
<key alias="validationRegExp">Introduce una expresión regular</key>
<key alias="minCount">Necesitas añadir al menos</key>
@@ -1590,17 +1596,14 @@
<key alias="configurationServiceFileNotFound">Archivo no existe: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[No se puedo encontrar <strong>'%0%'</strong> en archivo de configuración <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">Hubo un error, revisa los logs para ver el error completo: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Miembros - Total XML: %0%, Total: %1%, Total invalidos: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Total XML: %0%, Total: %1%, Total invalidos: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Contenido - Total XML: %0%, Total publicados: %1%, Total invalidos: %2%</key>
<key alias="httpsCheckValidCertificate">El certificado de tu sitio es válido.</key>
<key alias="httpsCheckInvalidCertificate">Error validando certificado: '%0%'</key>
<key alias="httpsCheckExpiredCertificate">El ceriticado SSL de tu sitio ha caducado.</key>
<key alias="httpsCheckExpiringCertificate">El ceriticado SSL de tu sitio caducará en %0% días.</key>
<key alias="healthCheckInvalidUrl">Error pinging la URL %0% - '%1%'</key>
<key alias="httpsCheckExpiredCertificate">El certificado SSL de tu sitio ha caducado.</key>
<key alias="httpsCheckExpiringCertificate">El certificado SSL de tu sitio caducará en %0% días.</key>
<key alias="healthCheckInvalidUrl">Error haciendo ping a la URL %0% - '%1%'</key>
<key alias="httpsCheckIsCurrentSchemeHttps">Actualmente estás %0% viendo el sitio usando el esquema HTTPS.</key>
<key alias="httpsCheckConfigurationRectifyNotPossible">El appSetting 'umbracoUseSSL' está configurado como 'false' en tu archivo web.config. Una vez que accedes al sitio usando HTTPS, debería ser configuraio como 'true'.</key>
<key alias="httpsCheckConfigurationCheckResult">Ele appSetting 'umbracoUseSSL' está configurado como '%0%' en tu archivo your web.config, tus cookies son %1% marcadas como seguras.</key>
<key alias="httpsCheckConfigurationRectifyNotPossible">El appSetting 'umbracoUseSSL' está configurado como 'false' en tu archivo web.config. Una vez que accedes al sitio usando HTTPS, debería ser configurado como 'true'.</key>
<key alias="httpsCheckConfigurationCheckResult">Ele appSetting 'umbracoUseSSL' está configurado como '%0%' en tu archivo web.config, tus cookies son %1% marcadas como seguras.</key>
<key alias="httpsCheckEnableHttpsError">No se pudo actualizar 'umbracoUseSSL' en tu archivo web.config. Error: %0%</key>
<!-- The following keys don't get tokens passed in -->
<key alias="httpsCheckEnableHttpsButton">Activar HTTPS</key>
@@ -1610,8 +1613,8 @@
<key alias="cannotRectifyShouldNotEqual">No se pudo arreglar chequeo con un valor de comparación 'ShouldNotEqual'.</key>
<key alias="cannotRectifyShouldEqualWithValue">No se pudo arreglar chequeo con un valor de comparación 'ShouldEqual' con el valor introducido.</key>
<key alias="valueToRectifyNotProvided">Valor para arreglar chequeo no introducido.</key>
<key alias="compilationDebugCheckSuccessMessage">Modo Debug en compilacion está desactivado.</key>
<key alias="compilationDebugCheckErrorMessage">Modo Debug en compilacion está activado. Se recomienda desactivarlo antes de publicar el sitio.</key>
<key alias="compilationDebugCheckSuccessMessage">Modo Debug en compilación está desactivado.</key>
<key alias="compilationDebugCheckErrorMessage">Modo Debug en compilación está activado. Se recomienda desactivarlo antes de publicar el sitio.</key>
<key alias="compilationDebugCheckRectifySuccessMessage">Modo Debug en compilación se ha desactivado correctamente.</key>
<key alias="traceModeCheckSuccessMessage">Modo Trace está desactivado.</key>
<key alias="traceModeCheckErrorMessage">Modo Trace está activado. Se recomienda desactivarlo antes de publicar el sitio.</key>
@@ -1630,23 +1633,23 @@
<key alias="optionalFilePermissionFailed"><![CDATA[Los siguientes archivos se deben configurar con permisos de escritura para ciertas operaciones en Umbraco pero no se pudieron acceder: <strong>%0%</strong>. Opcional.]]></key>
<key alias="clickJackingCheckHeaderFound"><![CDATA[El header or meta-tag <strong>X-Frame-Options</strong> usado para controlar si un sitio puede ser IFRAMEd por otra fue encontrado.]]></key>
<key alias="clickJackingCheckHeaderNotFound"><![CDATA[El header or meta-tag <strong>X-Frame-Options</strong> usado para controlar si un sitio puede ser IFRAMEd por otra no se ha encontrado.]]></key>
<key alias="setHeaderInConfig">Establecer Header en Config</key>
<key alias="clickJackingSetHeaderInConfigDescription">Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites.</key>
<key alias="clickJackingSetHeaderInConfigSuccess">A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file.</key>
<key alias="setHeaderInConfigError">Could not update web.config file. Error: %0%</key>
<key alias="setHeaderInConfig">Establecer Cabecera en Config</key>
<key alias="clickJackingSetHeaderInConfigDescription">Añade una entrada a la sección httpProtocol/customHeaders del archivo web.config para prevenir que el sitio sea incrustado en un iframe por otros sitios web.</key>
<key alias="clickJackingSetHeaderInConfigSuccess">Una entrada ha sido añadida a la sección httpProtocol/customHeaders del archivo web.config para prevenir que el sitio sea incrustado en un iframe por otros sitios web.</key>
<key alias="setHeaderInConfigError">No se ha podido actualizar el archivo web.config. Error: %0%</key>
<!-- The following key get these tokens passed in:
0: Comma delimitted list of headers found
-->
<key alias="excessiveHeadersFound"><![CDATA[The following headers revealing information about the website technology were found: <strong>%0%</strong>.]]></key>
<key alias="excessiveHeadersNotFound">No se ha encontrado ninguna cabecerá que revele información sobre la tecnología del sitio.</key>
<key alias="excessiveHeadersNotFound">No se ha encontrado ninguna cabecera que revele información sobre la tecnología del sitio.</key>
<key alias="smtpMailSettingsNotFound">No se encontró system.net/mailsettings en Web.config.</key>
<key alias="smtpMailSettingsHostNotConfigured">En la sección system.net/mailsettings section de web.config, el host no está configurado.</key>
<key alias="smtpMailSettingsConnectionSuccess">Los valores SMTP están configurados correctamente y el servicio opera con normalidad.</key>
<key alias="smtpMailSettingsConnectionFail">El servidor SMTP configurado con host '%0%' y puerto '%1%' no se pudo alcanzar. Por favor revisa que la configuración en la sección system.net/mailsettings del archivo Web.config es correcta.</key>
<key alias="notificationEmailsCheckSuccessMessage"><![CDATA[Email de notificación has sido configurado como <strong>%0%</strong>.]]></key>
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[El email de notificación está todavía configurado en su valor por defecto: <strong>%0%</strong>.]]></key>
<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</key>
<key alias="scheduledHealthCheckEmailSubject">Status de los Chequeos de Salud de Umbraco: %0%</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Desactivar URL tracker</key>
@@ -1658,7 +1661,7 @@
<key alias="removeButton">Eliminar</key>
<key alias="confirmRemove">¿Estás seguro que quieres eliminar la redirección de '%0%' a '%1%'?</key>
<key alias="redirectRemoved">Redirección URL eliminada.</key>
<key alias="redirectRemoveError">Error removing redirect URL.</key>
<key alias="redirectRemoveError">Error borrando la redirección URL.</key>
<key alias="confirmDisable">¿Seguro que quieres desactivar URL tracker?</key>
<key alias="disabledConfirm">URL tracker ha sido desactivado.</key>
<key alias="disableError">Error desactivando URL tracker, más información se puede encontrar en los logs.</key>
@@ -1790,9 +1790,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<key alias="configurationServiceFileNotFound">Le fichier n'existe pas : '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Impossible de trouver <strong>'%0%'</strong> dans le fichier config <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">Une erreur est survenue, consultez le log pour voir l'erreur complète : %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Total XML : %0%, Total : %1%</key>
<key alias="xmlDataIntegrityCheckMedia">Total XML : %0%, Total : %1%</key>
<key alias="xmlDataIntegrityCheckContent">Total XML : %0%, Total publié : %1%</key>
<key alias="databaseSchemaValidationCheckDatabaseOk">Base de données - Le schéma de la base de données est correct pour cette version de Umbraco</key>
<key alias="databaseSchemaValidationCheckDatabaseErrors">%0% problèmes ont été détectés avec le schéma de votre base de données (Voyez le fichier log pour les détails)</key>
<key alias="databaseSchemaValidationCheckDatabaseLogMessage">Des erreurs ont été détectées lors de la validation du schéma de la base de données par rapport à la version actuelle de Umbraco.</key>
@@ -1861,7 +1858,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<key alias="notificationEmailsCheckSuccessMessage"><![CDATA[Un email de notification a été envoyé à <strong>%0%</strong>.]]></key>
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[L'adresse email de notification est toujours à sa valeur par défaut : <strong>%0%</strong>.]]></key>
<key alias="scheduledHealthCheckEmailBody"><![CDATA[<html><body><p>Les résultats de l'exécution du Umbraco Health Checks planifiée le %0% à %1% sont les suivants :</p>%2%</body></html>]]></key>
<key alias="scheduledHealthCheckEmailSubject">Statut du Umbraco Health Check</key>
<key alias="scheduledHealthCheckEmailSubject">Statut du Umbraco Health Check: %0%</key>
</area>
<area alias="redirectUrls">
<key alias="disableUrlTracker">Désactiver URL tracker</key>
@@ -1886,4 +1883,4 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<area alias="textbox">
<key alias="characters_left">caractères restant</key>
</area>
</language>
</language>
@@ -1356,9 +1356,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je
<key alias="configurationServiceFileNotFound">Het volgende bestand bestaat niet: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[<strong>'%0%'</strong> kon niet gevonden worden in configuratie bestand <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">Er is een fout opgetreden. Bekijk de log file voor de volledige fout: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Members - Totaal XML: %0%, Totaal: %1%, Total incorrect: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Totaal XML: %0%, Totaal: %1%, Total incorrect: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Content - Totaal XML: %0%, Totaal gepubliceerd: %1%, Total incorrect: %2%</key>
<key alias="httpsCheckValidCertificate">Het cerficaat van de website is ongeldig.</key>
<key alias="httpsCheckInvalidCertificate">Cerficaat validatie foutmelding: '%0%'</key>
<key alias="healthCheckInvalidUrl">Fout bij pingen van URL %0% - '%1%'</key>
@@ -1434,9 +1434,6 @@ Naciśnij przycisk <strong>instaluj</strong>, aby zainstalować bazę danych Umb
<key alias="configurationServiceFileNotFound">Plik nie istnieje: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Nie można znaleźć <strong>'%0%'</strong> w pliku konfiguracyjnym <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">Wystąpił błąd, sprawdź logi, aby wyświetlić pełen opis błędu: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Członkowie - Suma XML: %0%, Suma: %1%, Suma niepoprawnych: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Suma XML: %0%, Suma: %1%, Suma niepoprawnych: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Zawartość - Suma XML: %0%, Suma opublikowanych: %1%, Suma niepoprawnych: %2%</key>
<key alias="httpsCheckValidCertificate">Certifikat Twojej strony jest poprawny.</key>
<key alias="httpsCheckInvalidCertificate">Błąd walidacji certyfikatu: '%0%'</key>
<key alias="httpsCheckExpiredCertificate">Certyfikat SSL Twojej strony wygasł.</key>
@@ -1513,4 +1510,4 @@ Naciśnij przycisk <strong>instaluj</strong>, aby zainstalować bazę danych Umb
<area alias="textbox">
<key alias="characters_left">pozostało znaków</key>
</area>
</language>
</language>
@@ -715,9 +715,6 @@
<key alias="configurationServiceFileNotFound">Файл не существует: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Не найден параметр <strong>'%0%'</strong> в файле конфигурации <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">Обнаружена ошибка, для получения полной информации обратитесь к журналу: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Участники - всего в XML: %0%, всего: %1%, с ошибками: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Медиа - всего в XML: %0%, всего: %1%Б с ошибками: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Содержимое - всего в XML: %0%, всего опубликовано: %1%, с ошибками: %2%</key>
<key alias="healthCheckInvalidUrl">Ошибка проверки адреса URL %0% - '%1%'</key>
<key alias="httpsCheckValidCertificate">Сертификат Вашего веб-сайта отмечен как проверенный.</key>
<key alias="httpsCheckInvalidCertificate">Ошибка проверки сертификата: '%0%'</key>
@@ -781,7 +778,7 @@
<key alias="notificationEmailsCheckSuccessMessage"><![CDATA[Адрес для отправки уведомлений установлен в <strong>%0%</strong>.]]></key>
<key alias="notificationEmailsCheckErrorMessage"><![CDATA[Адрес для отправки уведомлений все еще установлен в значение по-умолчанию <strong>%0%</strong>.]]></key>
<key alias="scheduledHealthCheckEmailBody"><![CDATA[<html><body><p>Зафиксированы следующие результаты автоматической проверки состояния Umbraco по расписанию, запущенной на %0% в %1%:</p>%2%</body></html>]]></key>
<key alias="scheduledHealthCheckEmailSubject">Результат проверки состояния Umbraco</key>
<key alias="scheduledHealthCheckEmailSubject">Результат проверки состояния Umbraco: %0%</key>
</area>
<area alias="help">
<key alias="theBestUmbracoVideoTutorials">Лучшие обучающие видео-курсы по Umbraco</key>
@@ -1873,4 +1870,4 @@
<key alias="invalidNumber">Не является числом</key>
<key alias="invalidEmail">неверный формат email-адреса</key>
</area>
</language>
</language>
@@ -1221,9 +1221,6 @@
<key alias="configurationServiceFileNotFound">File does not exist: '%0%'.</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[Unable to find <strong>'%0%'</strong> in config file <strong>'%1%'</strong>.]]></key>
<key alias="configurationServiceError">There was an error, check log for full error: %0%.</key>
<key alias="xmlDataIntegrityCheckMembers">Members - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckMedia">Media - Total XML: %0%, Total: %1%, Total invalid: %2%</key>
<key alias="xmlDataIntegrityCheckContent">Content - Total XML: %0%, Total published: %1%, Total invalid: %2%</key>
<key alias="httpsCheckValidCertificate">Your site certificate was marked as valid.</key>
<key alias="httpsCheckInvalidCertificate">Certificate validation error: '%0%'</key>
<key alias="httpsCheckInvalidUrl">Error pinging the URL %0% - '%1%'</key>
@@ -1292,4 +1289,4 @@
<key alias="enabledConfirm">现在已启用 url 跟踪程序。</key>
<key alias="enableError">启用 url 跟踪程序时出错, 可以在日志文件中找到更多信息。</key>
</area>
</language>
</language>
@@ -1199,9 +1199,6 @@
<key alias="configurationServiceFileNotFound">檔案不存在:%0%。</key>
<key alias="configurationServiceNodeNotFound"><![CDATA[於設定檔<strong>'%1%'</strong>中無法找到<strong>'%0%'</strong>。]]></key>
<key alias="configurationServiceError">有錯誤產生,請參閱下列錯誤的紀錄:%0%。</key>
<key alias="xmlDataIntegrityCheckMembers">成員 - 所有XML:%0%,總共:%1%,不合格:%2%</key>
<key alias="xmlDataIntegrityCheckMedia">媒體 - 所有XML:%0%,總共發佈:%1%,不合格:%2%</key>
<key alias="xmlDataIntegrityCheckContent">內容 - 所有XML:%0%,總共發佈:%1%,不合格:%2%</key>
<key alias="httpsCheckInvalidCertificate">憑證驗證錯誤:%0%</key>
<key alias="healthCheckInvalidUrl">網址探查錯誤:%0% - '%1%'</key>
<key alias="httpsCheckIsCurrentSchemeHttps">您目前使用HTTPS瀏覽本站:%0%</key>
@@ -1270,4 +1267,4 @@
<key alias="enabledConfirm">轉址追蹤器已開啟。</key>
<key alias="enableError">啟動轉址追蹤器錯誤,更多資訊請參閱您的紀錄檔。</key>
</area>
</language>
</language>
@@ -1,25 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserControlProxy.aspx.cs" Inherits="Umbraco.Web.UI.Umbraco.Dashboard.UserControlProxy" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web.UI.JavaScript" Assembly="umbraco" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<cc1:UmbracoClientDependencyLoader runat="server" ID="ClientLoader" />
<umb:CssInclude ID="CssInclude1" runat="server" FilePath="assets/css/umbraco.css" PathNameAlias="UmbracoRoot" />
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="Application/NamespaceManager.js" PathNameAlias="UmbracoClient" Priority="0" />
<umb:JsInclude ID="JsInclude4" runat="server" FilePath="lib/jquery-migrate/jquery-migrate.min.js" PathNameAlias="UmbracoRoot" Priority="1" />
</head>
<body style="overflow: scroll">
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="container" runat="server" />
</div>
</form>
</body>
</html>
@@ -1,40 +0,0 @@
using System;
using System.Web.UI;
using Umbraco.Core.IO;
namespace Umbraco.Web.UI.Umbraco.Dashboard
{
public partial class UserControlProxy : Pages.UmbracoEnsuredPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var path = Request.QueryString["ctrl"];
if (string.IsNullOrEmpty(path) == false)
{
path = IOHelper.FindFile(path);
try
{
var c = LoadControl(path);
container.Controls.Add(c);
}
catch (Exception ee)
{
container.Controls.Add(
new LiteralControl(
"<p class=\"umbracoErrorMessage\">Could not load control: '" + path +
"'. <br/><span class=\"guiDialogTiny\"><strong>Error message:</strong> " +
ee.ToString() + "</span></p>"));
}
}
}
}
}

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