Merge branch 'temp8' into temp8-dirty-tracking-on-variants
This commit is contained in:
@@ -23,7 +23,7 @@ We recommend running the site with the Visual Studio since you'll be able to rem
|
||||
|
||||
### Making code changes
|
||||
|
||||
* _[The process for making code changes in v8 is the same as v7](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/docs/CONTRIBUTING.md)_
|
||||
* _[The process for making code changes in v8 is the same as v7](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md)_
|
||||
* Any .NET changes you make you just need to compile
|
||||
* Any Angular/JS changes you make you will need to make sure you are running the Gulp build. Easiest way to do this is from within Visual Studio in the `Task Runner Explorer`. You can find this window by pressing `ctrl + q` and typing in `Task Runner Explorer`. In this window you'll see all Gulp tasks, double click on the `dev` task, this will compile the angular solution and start a file watcher, then any html/js changes you make are automatically built.
|
||||
* When making js changes, you should have the chrome developer tools open to ensure that cache is disabled
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace Umbraco.Core.Manifest
|
||||
// show: [ // optional, default is always show
|
||||
// '-content/foo', // hide for content type 'foo'
|
||||
// '+content/*', // show for all other content types
|
||||
// '+media/*' // show for all media types
|
||||
// '+media/*', // show for all media types
|
||||
// '+role/admin' // show for admin users. Role based permissions will override others.
|
||||
// ]
|
||||
// },
|
||||
// ...
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// <returns>The Sql statement.</returns>
|
||||
public static Sql<ISqlContext> Where<TDto>(this Sql<ISqlContext> sql, Expression<Func<TDto, bool>> predicate, string alias = null)
|
||||
{
|
||||
var (s, a) = sql.SqlContext.Visit(predicate, alias);
|
||||
var (s, a) = sql.SqlContext.VisitDto(predicate, alias);
|
||||
return sql.Where(s, a);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// <returns>The Sql statement.</returns>
|
||||
public static Sql<ISqlContext> Where<TDto1, TDto2>(this Sql<ISqlContext> sql, Expression<Func<TDto1, TDto2, bool>> predicate, string alias1 = null, string alias2 = null)
|
||||
{
|
||||
var (s, a) = sql.SqlContext.Visit(predicate, alias1, alias2);
|
||||
var (s, a) = sql.SqlContext.VisitDto(predicate, alias1, alias2);
|
||||
return sql.Where(s, a);
|
||||
}
|
||||
|
||||
@@ -321,9 +321,9 @@ namespace Umbraco.Core.Persistence
|
||||
/// Appends an ORDER BY DESC clause to the Sql statement.
|
||||
/// </summary>
|
||||
/// <param name="sql">The Sql statement.</param>
|
||||
/// <param name="fields">Expression specifying the fields.</param>
|
||||
/// <param name="fields">Fields.</param>
|
||||
/// <returns>The Sql statement.</returns>
|
||||
public static Sql<ISqlContext> OrderByDescending(this Sql<ISqlContext> sql, params object[] fields)
|
||||
public static Sql<ISqlContext> OrderByDescending(this Sql<ISqlContext> sql, params string[] fields)
|
||||
{
|
||||
return sql.Append("ORDER BY " + string.Join(", ", fields.Select(x => x + " DESC")));
|
||||
}
|
||||
@@ -664,7 +664,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// Adds columns to a SELECT Sql statement.
|
||||
/// </summary>
|
||||
/// <param name="sql">The origin sql.</param>
|
||||
/// <param name="fields">Expression indicating the column to select.</param>
|
||||
/// <param name="fields">Columns to select.</param>
|
||||
/// <returns>The Sql statement.</returns>
|
||||
public static Sql<ISqlContext> AndSelect(this Sql<ISqlContext> sql, params string[] fields)
|
||||
{
|
||||
@@ -688,7 +688,6 @@ namespace Umbraco.Core.Persistence
|
||||
return sql.Append(", " + string.Join(", ", sql.GetColumns(columnExpressions: fields)));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds columns to a SELECT Sql statement.
|
||||
/// </summary>
|
||||
|
||||
@@ -19,6 +19,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <remarks>Current version is first, and then versions are ordered with most recent first.</remarks>
|
||||
IEnumerable<TEntity> GetAllVersions(int nodeId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets versions.
|
||||
/// </summary>
|
||||
/// <remarks>Current version is first, and then versions are ordered with most recent first.</remarks>
|
||||
IEnumerable<TEntity> GetAllVersionsSlim(int nodeId, int skip, int take);
|
||||
|
||||
/// <summary>
|
||||
/// Gets version identifiers.
|
||||
/// </summary>
|
||||
|
||||
@@ -53,6 +53,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// gets all versions, current first
|
||||
public abstract IEnumerable<TEntity> GetAllVersions(int nodeId);
|
||||
|
||||
// gets all versions, current first
|
||||
public virtual IEnumerable<TEntity> GetAllVersionsSlim(int nodeId, int skip, int take)
|
||||
=> GetAllVersions(nodeId).Skip(skip).Take(take);
|
||||
|
||||
// gets all version ids, current first
|
||||
public virtual IEnumerable<int> GetVersionIds(int nodeId, int maxRows)
|
||||
{
|
||||
@@ -252,8 +256,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// if we do not do this then we end up with issues where we are ordering by a field that has duplicate values (i.e. the 'text' column
|
||||
// is empty for many nodes) - see: http://issues.umbraco.org/issue/U4-8831
|
||||
|
||||
var dbfield = GetQuotedFieldName("umbracoNode", "id");
|
||||
(dbfield, _) = SqlContext.Visit<NodeDto>(x => x.NodeId); // fixme?!
|
||||
var (dbfield, _) = SqlContext.VisitDto<NodeDto>(x => x.NodeId);
|
||||
if (ordering.IsCustomField || !ordering.OrderBy.InvariantEquals("id"))
|
||||
{
|
||||
psql.OrderBy(GetAliasedField(dbfield, sql)); // fixme why aliased?
|
||||
@@ -262,7 +265,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// create prepared sql
|
||||
// ensure it's single-line as NPoco PagingHelper has issues with multi-lines
|
||||
psql = Sql(psql.SQL.ToSingleLine(), psql.Arguments);
|
||||
|
||||
|
||||
// replace the magic culture parameter (see DocumentRepository.GetBaseQuery())
|
||||
if (!ordering.Culture.IsNullOrWhiteSpace())
|
||||
@@ -353,6 +355,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (ordering.Culture.IsNullOrWhiteSpace())
|
||||
return GetAliasedField(SqlSyntax.GetFieldName<NodeDto>(x => x.Text), sql);
|
||||
|
||||
// "variantName" alias is defined in DocumentRepository.GetBaseQuery
|
||||
// fixme - what if it is NOT a document but a ... media or whatever?
|
||||
// previously, we inserted the join+select *here* so we were sure to have it,
|
||||
// but now that's not the case anymore!
|
||||
return "variantName";
|
||||
}
|
||||
|
||||
@@ -433,7 +439,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// sort and filter
|
||||
sql = PreparePageSql(sql, filter, ordering);
|
||||
|
||||
|
||||
// get a page of DTOs and the total count
|
||||
var pagedResult = Database.Page<TDto>(pageIndex + 1, pageSize, sql);
|
||||
totalRecords = Convert.ToInt32(pagedResult.TotalItems);
|
||||
|
||||
@@ -95,6 +95,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return GetBaseQuery(queryType, true);
|
||||
}
|
||||
|
||||
// gets the COALESCE expression for variant/invariant name
|
||||
private string VariantNameSqlExpression
|
||||
=> SqlContext.VisitDto<ContentVersionCultureVariationDto, NodeDto>((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql;
|
||||
|
||||
protected virtual Sql<ISqlContext> GetBaseQuery(QueryType queryType, bool current)
|
||||
{
|
||||
var sql = SqlContext.Sql();
|
||||
@@ -116,7 +120,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto))
|
||||
.Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 =>
|
||||
r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv")))
|
||||
.AndSelect(SqlContext.Visit<ContentVersionCultureVariationDto, NodeDto>((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql + " AS variantName");
|
||||
|
||||
// select the variant name, coalesce to the invariant name, as "variantName"
|
||||
.AndSelect(VariantNameSqlExpression + " AS variantName");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -135,18 +141,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
.LeftJoin<ContentVersionDto>(nested =>
|
||||
nested.InnerJoin<DocumentVersionDto>("pdv")
|
||||
.On<ContentVersionDto, DocumentVersionDto>((left, right) => left.Id == right.Id && right.Published, "pcv", "pdv"), "pcv")
|
||||
.On<DocumentDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId, aliasRight: "pcv");
|
||||
.On<DocumentDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId, aliasRight: "pcv")
|
||||
|
||||
//the magic [[[ISOCODE]]] will be replaced in ContentRepositoryBase.GetPage() by the current Iso code
|
||||
sql
|
||||
// left join on optional culture variation
|
||||
//the magic "[[[ISOCODE]]]" parameter value will be replaced in ContentRepositoryBase.GetPage() by the actual ISO code
|
||||
.LeftJoin<ContentVersionCultureVariationDto>(nested =>
|
||||
nested.InnerJoin<LanguageDto>("lang").On<ContentVersionCultureVariationDto, LanguageDto>((ccv, lang) => ccv.LanguageId == lang.Id && lang.IsoCode == "[[[ISOCODE]]]", "ccv", "lang"), "ccv")
|
||||
.On<ContentVersionDto, ContentVersionCultureVariationDto>((version, ccv) => version.Id == ccv.VersionId, "pcv", "ccv");
|
||||
.On<ContentVersionDto, ContentVersionCultureVariationDto>((version, ccv) => version.Id == ccv.VersionId, aliasRight: "ccv");
|
||||
|
||||
sql
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
|
||||
|
||||
// this would ensure we don't get the published version - keep for reference
|
||||
//sql
|
||||
// .WhereAny(
|
||||
@@ -157,7 +162,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (current)
|
||||
sql.Where<ContentVersionDto>(x => x.Current); // always get the current version
|
||||
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -216,6 +220,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return MapDtosToContent(Database.Fetch<DocumentDto>(sql), true);
|
||||
}
|
||||
|
||||
public override IEnumerable<IContent> GetAllVersionsSlim(int nodeId, int skip, int take)
|
||||
{
|
||||
var sql = GetBaseQuery(QueryType.Many, false)
|
||||
.Where<NodeDto>(x => x.NodeId == nodeId)
|
||||
.OrderByDescending<ContentVersionDto>(x => x.Current)
|
||||
.AndByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
return MapDtosToContent(Database.Fetch<DocumentDto>(sql), true, true);
|
||||
}
|
||||
|
||||
public override IContent GetVersion(int versionId)
|
||||
{
|
||||
var sql = GetBaseQuery(QueryType.Single, false)
|
||||
@@ -246,7 +260,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// however, it's not just so we have access to AddingEntity
|
||||
// there are tons of things at the end of the methods, that can only work with a true Content
|
||||
// and basically, the repository requires a Content, not an IContent
|
||||
var content = (Content)entity;
|
||||
var content = (Content) entity;
|
||||
|
||||
content.AddingEntity();
|
||||
var publishing = content.PublishedState == PublishedState.Publishing;
|
||||
@@ -420,7 +434,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// however, it's not just so we have access to AddingEntity
|
||||
// there are tons of things at the end of the methods, that can only work with a true Content
|
||||
// and basically, the repository requires a Content, not an IContent
|
||||
var content = (Content)entity;
|
||||
var content = (Content) entity;
|
||||
|
||||
// check if we need to make any database changes at all
|
||||
if ((content.PublishedState == PublishedState.Published || content.PublishedState == PublishedState.Unpublished) && !content.IsEntityDirty() && !content.IsAnyUserPropertyDirty())
|
||||
@@ -707,30 +721,27 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
Sql<ISqlContext> filterSql = null;
|
||||
|
||||
// Here we create a default where clause from a temp IContent which will look in the contentVersion table for the content name
|
||||
// if we are searching in a list view that contains variants, we want to look in the contentVersionCultureVariation table instead.
|
||||
// The resulting clause will be used in the foreach below to compare against the original clause that comes from the "filter" and if they are the same
|
||||
// we know that we are searching a list view and the proper where clause will be replaced to look in contentVersionCultureVariation table for the names.
|
||||
var temp = Query<IContent>().Where(x => x.Name.Contains("foo"));
|
||||
var clause = temp.GetWhereClauses().First().Item1.Split(' ')[0];
|
||||
|
||||
// if we have a filter, map its clauses to an Sql statement
|
||||
if (filter != null)
|
||||
{
|
||||
// if the clause works on "name", we need to swap the field and use the variantName instead,
|
||||
// so that querying also works on variant content (for instance when searching a listview).
|
||||
|
||||
// figure out how the "name" field is going to look like - so we can look for it
|
||||
var nameField = SqlContext.VisitModelField<IContent>(x => x.Name);
|
||||
|
||||
filterSql = Sql();
|
||||
foreach (var filterClause in filter.GetWhereClauses())
|
||||
{
|
||||
// fixme - is this the right way of doing it???
|
||||
var clauseSql = filterClause.Item1;
|
||||
var clauseArgs = filterClause.Item2;
|
||||
|
||||
//
|
||||
var where = filterClause.Item1.Split(' ')[0] == clause
|
||||
// normally, this would be the field alias (variantName) of the coalesce result between ContentVersionCulture and NodeDto names, however
|
||||
// you can't refer to field alias in a WHERE clause so we have to put the coalesce calculation instead which refers to the original field
|
||||
? SqlContext.Visit<ContentVersionCultureVariationDto, NodeDto>((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql
|
||||
: filterClause.Item1;
|
||||
// replace the name field
|
||||
// we cannot reference an aliased field in a WHERE clause, so have to repeat the expression here
|
||||
clauseSql = clauseSql.Replace(nameField, VariantNameSqlExpression);
|
||||
|
||||
filterSql.Append(
|
||||
where.Contains("COALESCE") ? $"AND upper({where}) LIKE upper(@0)" : $"AND ({where})",
|
||||
filterClause.Item2);
|
||||
// append the clause
|
||||
filterSql.Append($"AND ({clauseSql})", clauseArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -910,7 +921,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return base.ApplySystemOrdering(ref sql, ordering);
|
||||
}
|
||||
|
||||
private IEnumerable<IContent> MapDtosToContent(List<DocumentDto> dtos, bool withCache = false)
|
||||
private IEnumerable<IContent> MapDtosToContent(List<DocumentDto> dtos, bool withCache = false, bool slim = false)
|
||||
{
|
||||
var temps = new List<TempContent<Content>>();
|
||||
var contentTypes = new Dictionary<int, IContentType>();
|
||||
@@ -928,7 +939,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var cached = IsolatedCache.GetCacheItem<IContent>(RepositoryCacheKeys.GetKey<IContent>(dto.NodeId));
|
||||
if (cached != null && cached.VersionId == dto.DocumentVersionDto.ContentVersionDto.Id)
|
||||
{
|
||||
content[i] = (Content)cached;
|
||||
content[i] = (Content) cached;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -943,18 +954,21 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
var c = content[i] = ContentBaseFactory.BuildEntity(dto, contentType);
|
||||
|
||||
// need templates
|
||||
var templateId = dto.DocumentVersionDto.TemplateId;
|
||||
if (templateId.HasValue && templateId.Value > 0)
|
||||
templateIds.Add(templateId.Value);
|
||||
if (dto.Published)
|
||||
if (!slim)
|
||||
{
|
||||
templateId = dto.PublishedVersionDto.TemplateId;
|
||||
// need templates
|
||||
var templateId = dto.DocumentVersionDto.TemplateId;
|
||||
if (templateId.HasValue && templateId.Value > 0)
|
||||
templateIds.Add(templateId.Value);
|
||||
if (dto.Published)
|
||||
{
|
||||
templateId = dto.PublishedVersionDto.TemplateId;
|
||||
if (templateId.HasValue && templateId.Value > 0)
|
||||
templateIds.Add(templateId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// need properties
|
||||
// need temps, for properties, templates and variations
|
||||
var versionId = dto.DocumentVersionDto.Id;
|
||||
var publishedVersionId = dto.Published ? dto.PublishedVersionDto.Id : 0;
|
||||
var temp = new TempContent<Content>(dto.NodeId, versionId, publishedVersionId, contentType, c)
|
||||
@@ -965,25 +979,28 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
temps.Add(temp);
|
||||
}
|
||||
|
||||
// load all required templates in 1 query, and index
|
||||
var templates = _templateRepository.GetMany(templateIds.ToArray())
|
||||
.ToDictionary(x => x.Id, x => x);
|
||||
|
||||
// load all properties for all documents from database in 1 query - indexed by version id
|
||||
var properties = GetPropertyCollections(temps);
|
||||
|
||||
// assign templates and properties
|
||||
foreach (var temp in temps)
|
||||
if (!slim)
|
||||
{
|
||||
// complete the item
|
||||
if (temp.Template1Id.HasValue && templates.TryGetValue(temp.Template1Id.Value, out var template))
|
||||
temp.Content.Template = template;
|
||||
if (temp.Template2Id.HasValue && templates.TryGetValue(temp.Template2Id.Value, out template))
|
||||
temp.Content.PublishTemplate = template;
|
||||
temp.Content.Properties = properties[temp.VersionId];
|
||||
// load all required templates in 1 query, and index
|
||||
var templates = _templateRepository.GetMany(templateIds.ToArray())
|
||||
.ToDictionary(x => x.Id, x => x);
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
temp.Content.ResetDirtyProperties(false);
|
||||
// load all properties for all documents from database in 1 query - indexed by version id
|
||||
var properties = GetPropertyCollections(temps);
|
||||
|
||||
// assign templates and properties
|
||||
foreach (var temp in temps)
|
||||
{
|
||||
// complete the item
|
||||
if (temp.Template1Id.HasValue && templates.TryGetValue(temp.Template1Id.Value, out var template))
|
||||
temp.Content.Template = template;
|
||||
if (temp.Template2Id.HasValue && templates.TryGetValue(temp.Template2Id.Value, out template))
|
||||
temp.Content.PublishTemplate = template;
|
||||
temp.Content.Properties = properties[temp.VersionId];
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
temp.Content.ResetDirtyProperties(false);
|
||||
}
|
||||
}
|
||||
|
||||
// set variations, if varying
|
||||
|
||||
@@ -8,12 +8,12 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
@@ -100,7 +100,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
case QueryType.Many:
|
||||
sql = sql.Select<ContentDto>(r =>
|
||||
r.Select(x => x.NodeDto)
|
||||
.Select(x => x.ContentVersionDto));
|
||||
.Select(x => x.ContentVersionDto))
|
||||
|
||||
// ContentRepositoryBase expects a variantName field to order by name
|
||||
// for now, just return the plain invariant node name
|
||||
// fixme media should support variants !!
|
||||
.AndSelect<NodeDto>(x => Alias(x.Text, "variantName"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
@@ -114,9 +114,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
case QueryType.Single:
|
||||
case QueryType.Many:
|
||||
sql = sql.Select<MemberDto>(r =>
|
||||
r.Select(x => x.ContentVersionDto)
|
||||
.Select(x => x.ContentDto, r1 =>
|
||||
r1.Select(x => x.NodeDto)));
|
||||
r.Select(x => x.ContentVersionDto)
|
||||
.Select(x => x.ContentDto, r1 =>
|
||||
r1.Select(x => x.NodeDto)))
|
||||
|
||||
// ContentRepositoryBase expects a variantName field to order by name
|
||||
// so get it here, though for members it's just the plain node name
|
||||
.AndSelect<NodeDto>(x => Alias(x.Text, "variantName"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ namespace Umbraco.Core.Persistence
|
||||
/// <param name="expression">An expression to visit.</param>
|
||||
/// <param name="alias">An optional table alias.</param>
|
||||
/// <returns>A SQL statement, and arguments, corresponding to the expression.</returns>
|
||||
public static (string Sql, object[] Args) Visit<TDto>(this ISqlContext sqlContext, Expression<Func<TDto, object>> expression, string alias = null)
|
||||
public static (string Sql, object[] Args) VisitDto<TDto>(this ISqlContext sqlContext, Expression<Func<TDto, object>> expression, string alias = null)
|
||||
{
|
||||
var expresionist = new PocoToSqlExpressionVisitor<TDto>(sqlContext, alias);
|
||||
var visited = expresionist.Visit(expression);
|
||||
return (visited, expresionist.GetSqlParameters());
|
||||
var visitor = new PocoToSqlExpressionVisitor<TDto>(sqlContext, alias);
|
||||
var visited = visitor.Visit(expression);
|
||||
return (visited, visitor.GetSqlParameters());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -33,11 +33,11 @@ namespace Umbraco.Core.Persistence
|
||||
/// <param name="expression">An expression to visit.</param>
|
||||
/// <param name="alias">An optional table alias.</param>
|
||||
/// <returns>A SQL statement, and arguments, corresponding to the expression.</returns>
|
||||
public static (string Sql, object[] Args) Visit<TDto, TOut>(this ISqlContext sqlContext, Expression<Func<TDto, TOut>> expression, string alias = null)
|
||||
public static (string Sql, object[] Args) VisitDto<TDto, TOut>(this ISqlContext sqlContext, Expression<Func<TDto, TOut>> expression, string alias = null)
|
||||
{
|
||||
var expresionist = new PocoToSqlExpressionVisitor<TDto>(sqlContext, alias);
|
||||
var visited = expresionist.Visit(expression);
|
||||
return (visited, expresionist.GetSqlParameters());
|
||||
var visitor = new PocoToSqlExpressionVisitor<TDto>(sqlContext, alias);
|
||||
var visited = visitor.Visit(expression);
|
||||
return (visited, visitor.GetSqlParameters());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -50,11 +50,11 @@ namespace Umbraco.Core.Persistence
|
||||
/// <param name="alias1">An optional table alias for the first DTO.</param>
|
||||
/// <param name="alias2">An optional table alias for the second DTO.</param>
|
||||
/// <returns>A SQL statement, and arguments, corresponding to the expression.</returns>
|
||||
public static (string Sql, object[] Args) Visit<TDto1, TDto2>(this ISqlContext sqlContext, Expression<Func<TDto1, TDto2, object>> expression, string alias1 = null, string alias2 = null)
|
||||
public static (string Sql, object[] Args) VisitDto<TDto1, TDto2>(this ISqlContext sqlContext, Expression<Func<TDto1, TDto2, object>> expression, string alias1 = null, string alias2 = null)
|
||||
{
|
||||
var expresionist = new PocoToSqlExpressionVisitor<TDto1, TDto2>(sqlContext, alias1, alias2);
|
||||
var visited = expresionist.Visit(expression);
|
||||
return (visited, expresionist.GetSqlParameters());
|
||||
var visitor = new PocoToSqlExpressionVisitor<TDto1, TDto2>(sqlContext, alias1, alias2);
|
||||
var visited = visitor.Visit(expression);
|
||||
return (visited, visitor.GetSqlParameters());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,11 +68,42 @@ namespace Umbraco.Core.Persistence
|
||||
/// <param name="alias1">An optional table alias for the first DTO.</param>
|
||||
/// <param name="alias2">An optional table alias for the second DTO.</param>
|
||||
/// <returns>A SQL statement, and arguments, corresponding to the expression.</returns>
|
||||
public static (string Sql, object[] Args) Visit<TDto1, TDto2, TOut>(this ISqlContext sqlContext, Expression<Func<TDto1, TDto2, TOut>> expression, string alias1 = null, string alias2 = null)
|
||||
public static (string Sql, object[] Args) VisitDto<TDto1, TDto2, TOut>(this ISqlContext sqlContext, Expression<Func<TDto1, TDto2, TOut>> expression, string alias1 = null, string alias2 = null)
|
||||
{
|
||||
var expresionist = new PocoToSqlExpressionVisitor<TDto1, TDto2>(sqlContext, alias1, alias2);
|
||||
var visited = expresionist.Visit(expression);
|
||||
return (visited, expresionist.GetSqlParameters());
|
||||
var visitor = new PocoToSqlExpressionVisitor<TDto1, TDto2>(sqlContext, alias1, alias2);
|
||||
var visited = visitor.Visit(expression);
|
||||
return (visited, visitor.GetSqlParameters());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Visit a model expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model.</typeparam>
|
||||
/// <param name="sqlContext">An <see cref="ISqlContext"/>.</param>
|
||||
/// <param name="expression">An expression to visit.</param>
|
||||
/// <returns>A SQL statement, and arguments, corresponding to the expression.</returns>
|
||||
public static (string Sql, object[] Args) VisitModel<TModel>(this ISqlContext sqlContext, Expression<Func<TModel, object>> expression)
|
||||
{
|
||||
var visitor = new ModelToSqlExpressionVisitor<TModel>(sqlContext.SqlSyntax, sqlContext.Mappers);
|
||||
var visited = visitor.Visit(expression);
|
||||
return (visited, visitor.GetSqlParameters());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Visit a model expression representing a field.
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">The type of the model.</typeparam>
|
||||
/// <param name="sqlContext">An <see cref="ISqlContext"/>.</param>
|
||||
/// <param name="field">An expression to visit, representing a field.</param>
|
||||
/// <returns>The name of the field.</returns>
|
||||
public static string VisitModelField<TModel>(this ISqlContext sqlContext, Expression<Func<TModel, object>> field)
|
||||
{
|
||||
var (sql, _) = sqlContext.VisitModel(field);
|
||||
|
||||
// going to return "<field> = @0"
|
||||
// take the first part only
|
||||
var pos = sql.IndexOf(' ');
|
||||
return sql.Substring(0, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,9 +307,9 @@ namespace Umbraco.Core.Runtime
|
||||
throw new BootFailedException("A connection string is configured but Umbraco could not connect to the database.");
|
||||
}
|
||||
|
||||
// if we already know we want to upgrade, no need to look for migrations...
|
||||
if (_state.Level == RuntimeLevel.Upgrade)
|
||||
return;
|
||||
// if we already know we want to upgrade,
|
||||
// still run EnsureUmbracoUpgradeState to get the states
|
||||
// (v7 will just get a null state, that's ok)
|
||||
|
||||
// else
|
||||
// look for a matching migration entry - bypassing services entirely - they are not 'up' yet
|
||||
|
||||
@@ -134,6 +134,12 @@ namespace Umbraco.Core.Services
|
||||
/// <remarks>Versions are ordered with current first, then most recent first.</remarks>
|
||||
IEnumerable<IContent> GetVersions(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all versions of a document.
|
||||
/// </summary>
|
||||
/// <remarks>Versions are ordered with current first, then most recent first.</remarks>
|
||||
IEnumerable<IContent> GetVersionsSlim(int id, int skip, int take);
|
||||
|
||||
/// <summary>
|
||||
/// Gets top versions of a document.
|
||||
/// </summary>
|
||||
@@ -461,5 +467,21 @@ namespace Umbraco.Core.Services
|
||||
IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rollback
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back the content to a specific version.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the content node.</param>
|
||||
/// <param name="versionId">The version id to roll back to.</param>
|
||||
/// <param name="culture">An optional culture to roll back.</param>
|
||||
/// <param name="userId">The identifier of the user who is performing the roll back.</param>
|
||||
/// <remarks>
|
||||
/// <para>When no culture is specified, all cultures are rolled back.</para>
|
||||
/// </remarks>
|
||||
OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,6 +474,19 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of an <see cref="IContent"/> objects versions by Id
|
||||
/// </summary>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetVersionsSlim(int id, int skip, int take)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _documentRepository.GetAllVersionsSlim(id, skip, take);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all version Ids for the given content item ordered so latest is first
|
||||
/// </summary>
|
||||
@@ -2538,5 +2551,68 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rollback
|
||||
|
||||
public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0)
|
||||
{
|
||||
var evtMsgs = EventMessagesFactory.Get();
|
||||
|
||||
//Get the current copy of the node
|
||||
var content = GetById(id);
|
||||
|
||||
//Get the version
|
||||
var version = GetVersion(versionId);
|
||||
|
||||
//Good ole null checks
|
||||
if (content == null || version == null)
|
||||
{
|
||||
return new OperationResult(OperationResultType.FailedCannot, evtMsgs);
|
||||
}
|
||||
|
||||
//Store the result of doing the save of content for the rollback
|
||||
OperationResult rollbackSaveResult;
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
var rollbackEventArgs = new RollbackEventArgs<IContent>(content);
|
||||
|
||||
//Emit RollingBack event aka before
|
||||
if (scope.Events.DispatchCancelable(RollingBack, this, rollbackEventArgs))
|
||||
{
|
||||
scope.Complete();
|
||||
return OperationResult.Cancel(evtMsgs);
|
||||
}
|
||||
|
||||
//Copy the changes from the version
|
||||
content.CopyFrom(version, culture);
|
||||
|
||||
//Save the content for the rollback
|
||||
rollbackSaveResult = Save(content, userId);
|
||||
|
||||
//Depending on the save result - is what we log & audit along with what we return
|
||||
if (rollbackSaveResult.Success == false)
|
||||
{
|
||||
//Log the error/warning
|
||||
Logger.Error<ContentService>("User '{UserId}' was unable to rollback content '{ContentId}' to version '{VersionId}'", userId, id, versionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Emit RolledBack event aka after
|
||||
rollbackEventArgs.CanCancel = false;
|
||||
scope.Events.Dispatch(RolledBack, this, rollbackEventArgs);
|
||||
|
||||
//Logging & Audit message
|
||||
Logger.Info<ContentService>("User '{UserId}' rolled back content '{ContentId}' to version '{VersionId}'", userId, id, versionId);
|
||||
Audit(AuditType.RollBack, $"Content '{content.Name}' was rolled back to version '{versionId}'", userId, id);
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
return rollbackSaveResult;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
@@ -2415,6 +2416,22 @@ namespace Umbraco.Tests.Services
|
||||
}
|
||||
Console.WriteLine("-");
|
||||
|
||||
var versionsSlim = ServiceContext.ContentService.GetVersionsSlim(page.Id, 0, 50).ToArray();
|
||||
Assert.AreEqual(5, versionsSlim.Length);
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
Console.Write("[{0}] ", i);
|
||||
Console.WriteLine(versionsSlim[i].UpdateDate.ToString("O").Substring(11));
|
||||
Console.WriteLine(" fr: {0}", versionsSlim[i].GetUpdateDate("fr")?.ToString("O").Substring(11));
|
||||
Console.WriteLine(" da: {0}", versionsSlim[i].GetUpdateDate("da")?.ToString("O").Substring(11));
|
||||
}
|
||||
Console.WriteLine("-");
|
||||
|
||||
// what we do in the controller to get rollback versions
|
||||
var versionsSlimFr = versionsSlim.Where(x => x.UpdateDate == x.GetUpdateDate("fr")).ToArray();
|
||||
Assert.AreEqual(3, versionsSlimFr.Length);
|
||||
|
||||
// alas, at the moment we do *not* properly track 'dirty' for cultures, meaning
|
||||
// that we cannot synchronize dates the way we do with publish dates - and so this
|
||||
// would fail - the version UpdateDate is greater than the cultures'.
|
||||
@@ -2830,6 +2847,107 @@ namespace Umbraco.Tests.Services
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Paged_Children_WithFilterAndOrder()
|
||||
{
|
||||
var languageService = ServiceContext.LocalizationService;
|
||||
|
||||
var langUk = new Language("en-UK") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
var langDa = new Language("da-DK");
|
||||
|
||||
languageService.Save(langFr);
|
||||
languageService.Save(langUk);
|
||||
languageService.Save(langDa);
|
||||
|
||||
var contentTypeService = ServiceContext.ContentTypeService;
|
||||
|
||||
var contentType = contentTypeService.Get("umbTextpage");
|
||||
contentType.Variations = ContentVariation.Culture;
|
||||
contentTypeService.Save(contentType);
|
||||
|
||||
var contentService = ServiceContext.ContentService;
|
||||
|
||||
var o = new[] { 2, 1, 3, 0, 4 }; // randomly different
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var contentA = new Content(null, -1, contentType);
|
||||
contentA.SetCultureName("contentA" + i + "uk", langUk.IsoCode);
|
||||
contentA.SetCultureName("contentA" + o[i] + "fr", langFr.IsoCode);
|
||||
contentA.SetCultureName("contentX" + i + "da", langDa.IsoCode);
|
||||
contentService.Save(contentA);
|
||||
|
||||
var contentB = new Content(null, -1, contentType);
|
||||
contentB.SetCultureName("contentB" + i + "uk", langUk.IsoCode);
|
||||
contentB.SetCultureName("contentB" + o[i] + "fr", langFr.IsoCode);
|
||||
contentB.SetCultureName("contentX" + i + "da", langDa.IsoCode);
|
||||
contentService.Save(contentB);
|
||||
}
|
||||
|
||||
// get all
|
||||
var list = contentService.GetPagedChildren(-1, 0, 100, out var total).ToList();
|
||||
|
||||
Console.WriteLine("ALL");
|
||||
WriteList(list);
|
||||
|
||||
// 10 items (there's already a Home content in there...)
|
||||
Assert.AreEqual(11, total);
|
||||
Assert.AreEqual(11, list.Count);
|
||||
|
||||
// filter
|
||||
list = contentService.GetPagedChildren(-1, 0, 100, out total,
|
||||
SqlContext.Query<IContent>().Where(x => x.Name.Contains("contentX")),
|
||||
Ordering.By("name", culture: langFr.IsoCode)).ToList();
|
||||
|
||||
Assert.AreEqual(0, total);
|
||||
Assert.AreEqual(0, list.Count);
|
||||
|
||||
// filter
|
||||
list = contentService.GetPagedChildren(-1, 0, 100, out total,
|
||||
SqlContext.Query<IContent>().Where(x => x.Name.Contains("contentX")),
|
||||
Ordering.By("name", culture: langDa.IsoCode)).ToList();
|
||||
|
||||
Console.WriteLine("FILTER BY NAME da:'contentX'");
|
||||
WriteList(list);
|
||||
|
||||
Assert.AreEqual(10, total);
|
||||
Assert.AreEqual(10, list.Count);
|
||||
|
||||
// filter
|
||||
list = contentService.GetPagedChildren(-1, 0, 100, out total,
|
||||
SqlContext.Query<IContent>().Where(x => x.Name.Contains("contentA")),
|
||||
Ordering.By("name", culture: langFr.IsoCode)).ToList();
|
||||
|
||||
Console.WriteLine("FILTER BY NAME fr:'contentA', ORDER ASC");
|
||||
WriteList(list);
|
||||
|
||||
Assert.AreEqual(5, total);
|
||||
Assert.AreEqual(5, list.Count);
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
Assert.AreEqual("contentA" + i + "fr", list[i].GetCultureName(langFr.IsoCode));
|
||||
|
||||
list = contentService.GetPagedChildren(-1, 0, 100, out total,
|
||||
SqlContext.Query<IContent>().Where(x => x.Name.Contains("contentA")),
|
||||
Ordering.By("name", direction: Direction.Descending, culture: langFr.IsoCode)).ToList();
|
||||
|
||||
Console.WriteLine("FILTER BY NAME fr:'contentA', ORDER DESC");
|
||||
WriteList(list);
|
||||
|
||||
Assert.AreEqual(5, total);
|
||||
Assert.AreEqual(5, list.Count);
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
Assert.AreEqual("contentA" + (4-i) + "fr", list[i].GetCultureName(langFr.IsoCode));
|
||||
}
|
||||
|
||||
private void WriteList(List<IContent> list)
|
||||
{
|
||||
foreach (var content in list)
|
||||
Console.WriteLine("[{0}] {1} {2} {3} {4}", content.Id, content.Name, content.GetCultureName("en-UK"), content.GetCultureName("fr-FR"), content.GetCultureName("da-DK"));
|
||||
Console.WriteLine("-");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_SaveRead_Variations()
|
||||
{
|
||||
|
||||
@@ -64,6 +64,8 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
internal ScopeProvider ScopeProvider => Current.ScopeProvider as ScopeProvider;
|
||||
|
||||
protected ISqlContext SqlContext => Container.GetInstance<ISqlContext>();
|
||||
|
||||
public override void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
@@ -6,21 +6,22 @@ var wrap = require("gulp-wrap-js");
|
||||
var sort = require('gulp-sort');
|
||||
var connect = require('gulp-connect');
|
||||
var open = require('gulp-open');
|
||||
const babel = require("gulp-babel");
|
||||
var babel = require("gulp-babel");
|
||||
var runSequence = require('run-sequence');
|
||||
const imagemin = require('gulp-imagemin');
|
||||
var imagemin = require('gulp-imagemin');
|
||||
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
// js
|
||||
const eslint = require('gulp-eslint');
|
||||
var eslint = require('gulp-eslint');
|
||||
|
||||
//Less + css
|
||||
var postcss = require('gulp-postcss');
|
||||
var less = require('gulp-less');
|
||||
var autoprefixer = require('autoprefixer');
|
||||
var cssnano = require('cssnano');
|
||||
var cleanCss = require("gulp-clean-css");
|
||||
|
||||
// Documentation
|
||||
var gulpDocs = require('gulp-ngdocs');
|
||||
@@ -49,14 +50,14 @@ function processJs(files, out) {
|
||||
}
|
||||
|
||||
function processLess(files, out) {
|
||||
|
||||
var processors = [
|
||||
autoprefixer,
|
||||
cssnano({zindex: false}),
|
||||
cssnano({zindex: false})
|
||||
];
|
||||
|
||||
return gulp.src(files)
|
||||
.pipe(less())
|
||||
.pipe(cleanCss())
|
||||
.pipe(postcss(processors))
|
||||
.pipe(rename(out))
|
||||
.pipe(gulp.dest(root + targets.css));
|
||||
@@ -329,7 +330,7 @@ gulp.task('dependencies', function () {
|
||||
"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",
|
||||
"./node_modules/moment/min/moment-with-locales.min.js"
|
||||
],
|
||||
"base": "./node_modules/moment/min"
|
||||
},
|
||||
|
||||
+109
-80
@@ -1266,7 +1266,7 @@
|
||||
"array-slice": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
|
||||
"integrity": "sha1-42jqFfibxwaff/uJrsOmx9SsItQ=",
|
||||
"integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
|
||||
"dev": true
|
||||
},
|
||||
"array-union": {
|
||||
@@ -1440,7 +1440,7 @@
|
||||
"base": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
|
||||
"integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
|
||||
"integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cache-base": "^1.0.1",
|
||||
@@ -1464,7 +1464,7 @@
|
||||
"is-accessor-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -1473,7 +1473,7 @@
|
||||
"is-data-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -1482,7 +1482,7 @@
|
||||
"is-descriptor": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
@@ -1680,7 +1680,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -1696,7 +1696,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -1822,7 +1822,7 @@
|
||||
"braces": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
||||
"integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
|
||||
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-flatten": "^1.1.0",
|
||||
@@ -1948,7 +1948,7 @@
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
|
||||
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -2014,7 +2014,7 @@
|
||||
"cache-base": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
|
||||
"integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=",
|
||||
"integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"collection-visit": "^1.0.0",
|
||||
@@ -2225,7 +2225,7 @@
|
||||
"class-utils": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
|
||||
"integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=",
|
||||
"integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
@@ -2245,6 +2245,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||
"integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map": "~0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
||||
@@ -2458,7 +2475,7 @@
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -2700,7 +2717,7 @@
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
|
||||
"dev": true
|
||||
},
|
||||
"convert-source-map": {
|
||||
@@ -3114,7 +3131,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3211,7 +3228,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3227,7 +3244,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -3318,7 +3335,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3379,7 +3396,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3439,7 +3456,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3532,7 +3549,7 @@
|
||||
"define-property": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
|
||||
"integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=",
|
||||
"integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.2",
|
||||
@@ -3542,7 +3559,7 @@
|
||||
"is-accessor-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -3551,7 +3568,7 @@
|
||||
"is-data-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -3560,7 +3577,7 @@
|
||||
"is-descriptor": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
@@ -3828,7 +3845,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3925,7 +3942,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3941,7 +3958,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -4034,7 +4051,7 @@
|
||||
"end-of-stream": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
@@ -4048,7 +4065,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -4064,7 +4081,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -4246,7 +4263,7 @@
|
||||
"errno": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
||||
"integrity": "sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg=",
|
||||
"integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4955,7 +4972,7 @@
|
||||
"extglob": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
|
||||
"integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=",
|
||||
"integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -4989,7 +5006,7 @@
|
||||
"is-accessor-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -4998,7 +5015,7 @@
|
||||
"is-data-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -5007,7 +5024,7 @@
|
||||
"is-descriptor": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
@@ -6042,7 +6059,7 @@
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
@@ -6272,7 +6289,7 @@
|
||||
"global-modules": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
||||
"integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=",
|
||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"global-prefix": "^1.0.1",
|
||||
@@ -6384,7 +6401,7 @@
|
||||
},
|
||||
"got": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
|
||||
"integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6422,7 +6439,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6510,6 +6527,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"gulp-clean-css": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-3.10.0.tgz",
|
||||
"integrity": "sha512-7Isf9Y690o/Q5MVjEylH1H7L8WeZ89woW7DnhD5unTintOdZb67KdOayRgp9trUFo+f9UyJtuatV42e/+kghPg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clean-css": "4.2.1",
|
||||
"plugin-error": "1.0.1",
|
||||
"through2": "2.0.3",
|
||||
"vinyl-sourcemaps-apply": "0.2.1"
|
||||
}
|
||||
},
|
||||
"gulp-concat": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
|
||||
@@ -6588,7 +6617,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6604,7 +6633,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -6921,7 +6950,7 @@
|
||||
},
|
||||
"lodash": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz",
|
||||
"integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -8015,7 +8044,7 @@
|
||||
"is-absolute": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
||||
"integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=",
|
||||
"integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-relative": "^1.0.0",
|
||||
@@ -8119,7 +8148,7 @@
|
||||
"is-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
|
||||
"integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=",
|
||||
"integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^0.1.6",
|
||||
@@ -8130,7 +8159,7 @@
|
||||
"kind-of": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
|
||||
"integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=",
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -8261,7 +8290,7 @@
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
|
||||
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -8353,7 +8382,7 @@
|
||||
"is-relative": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
||||
"integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=",
|
||||
"integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-unc-path": "^1.0.0"
|
||||
@@ -8410,7 +8439,7 @@
|
||||
"is-unc-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
|
||||
"integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=",
|
||||
"integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"unc-path-regex": "^0.1.2"
|
||||
@@ -8437,7 +8466,7 @@
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-zip": {
|
||||
@@ -8946,7 +8975,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -8962,7 +8991,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -9055,7 +9084,7 @@
|
||||
"livereload-js": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz",
|
||||
"integrity": "sha1-w6si6Kr1vzUF2A0JjLrWdyZUjJo=",
|
||||
"integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==",
|
||||
"dev": true
|
||||
},
|
||||
"load-json-file": {
|
||||
@@ -9293,7 +9322,7 @@
|
||||
"lodash.merge": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
|
||||
"integrity": "sha1-rcJdnLmbk5HFliTzefu6YNcRHVQ=",
|
||||
"integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.partialright": {
|
||||
@@ -9712,7 +9741,7 @@
|
||||
"make-iterator": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
|
||||
"integrity": "sha1-KbM/MSqo9UfEpeSQ9Wr87JkTOtY=",
|
||||
"integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.2"
|
||||
@@ -9871,7 +9900,7 @@
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
"integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=",
|
||||
"integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
@@ -9934,7 +9963,7 @@
|
||||
"mixin-deep": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
|
||||
"integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=",
|
||||
"integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"for-in": "^1.0.2",
|
||||
@@ -9944,7 +9973,7 @@
|
||||
"is-extendable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
@@ -14070,7 +14099,7 @@
|
||||
"promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||
"integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=",
|
||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -14283,7 +14312,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -14299,7 +14328,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -14506,7 +14535,7 @@
|
||||
"regex-not": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||
"integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=",
|
||||
"integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.2",
|
||||
@@ -14742,7 +14771,7 @@
|
||||
"ret": {
|
||||
"version": "0.1.15",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"dev": true
|
||||
},
|
||||
"right-align": {
|
||||
@@ -15050,7 +15079,7 @@
|
||||
"set-value": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
|
||||
"integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=",
|
||||
"integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
@@ -15155,7 +15184,7 @@
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
"integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=",
|
||||
"integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base": "^0.11.1",
|
||||
@@ -15191,7 +15220,7 @@
|
||||
"snapdragon-node": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
|
||||
"integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=",
|
||||
"integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^1.0.0",
|
||||
@@ -15211,7 +15240,7 @@
|
||||
"is-accessor-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -15220,7 +15249,7 @@
|
||||
"is-data-descriptor": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
@@ -15229,7 +15258,7 @@
|
||||
"is-descriptor": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
@@ -15242,7 +15271,7 @@
|
||||
"snapdragon-util": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
|
||||
"integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=",
|
||||
"integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.2.0"
|
||||
@@ -15441,7 +15470,7 @@
|
||||
"split-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
"integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=",
|
||||
"integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.0"
|
||||
@@ -15567,7 +15596,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -15583,7 +15612,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -15758,7 +15787,7 @@
|
||||
},
|
||||
"strip-dirs": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz",
|
||||
"integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -15787,7 +15816,7 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -15948,7 +15977,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -16265,7 +16294,7 @@
|
||||
"to-regex": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
|
||||
"integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=",
|
||||
"integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^2.0.2",
|
||||
@@ -16365,7 +16394,7 @@
|
||||
"type-is": {
|
||||
"version": "1.6.16",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||
"integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=",
|
||||
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
@@ -16713,7 +16742,7 @@
|
||||
"vendors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
|
||||
"integrity": "sha1-f8te759WI7FWvOqJ7DfWNnbyGAE=",
|
||||
"integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
@@ -16770,7 +16799,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -16786,7 +16815,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -16987,7 +17016,7 @@
|
||||
"websocket-extensions": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
|
||||
"integrity": "sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk=",
|
||||
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
|
||||
"dev": true
|
||||
},
|
||||
"when": {
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
"@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",
|
||||
|
||||
@@ -103,6 +103,17 @@
|
||||
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) {
|
||||
$scope.page.loading = true;
|
||||
loadContent().then(function() {
|
||||
$scope.page.loading = false;
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+16
@@ -114,6 +114,22 @@
|
||||
scope.node.template = templateAlias;
|
||||
};
|
||||
|
||||
scope.openRollback = function() {
|
||||
|
||||
var rollback = {
|
||||
node: scope.node,
|
||||
submit: function(model) {
|
||||
const args = { node: scope.node };
|
||||
eventsService.emit("editors.content.reload", args);
|
||||
editorService.close();
|
||||
},
|
||||
close: function() {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
editorService.rollback(rollback);
|
||||
};
|
||||
|
||||
function loadAuditTrail() {
|
||||
|
||||
//don't load this if it's already done
|
||||
|
||||
@@ -808,8 +808,106 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
),
|
||||
"Failed to create blueprint from content with id " + contentId
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentResource#getRollbackVersions
|
||||
* @methodOf umbraco.resources.contentResource
|
||||
*
|
||||
* @description
|
||||
* Returns an array of previous version id's, given a node id and a culture
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* contentResource.getRollbackVersions(id, culture)
|
||||
* .then(function(versions) {
|
||||
* alert('its here!');
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Int} id Id of node
|
||||
* @param {Int} culture if provided, the results will be for this specific culture/variant
|
||||
* @returns {Promise} resourcePromise object containing the versions
|
||||
*
|
||||
*/
|
||||
getRollbackVersions: function (contentId, culture) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersions", {
|
||||
contentId: contentId,
|
||||
culture: culture
|
||||
})
|
||||
),
|
||||
"Failed to get rollback versions for content item with id " + contentId
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentResource#getRollbackVersion
|
||||
* @methodOf umbraco.resources.contentResource
|
||||
*
|
||||
* @description
|
||||
* Returns a previous version of a content item
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* contentResource.getRollbackVersion(versionId, culture)
|
||||
* .then(function(version) {
|
||||
* alert('its here!');
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Int} versionId The version Id
|
||||
* @param {Int} culture if provided, the results will be for this specific culture/variant
|
||||
* @returns {Promise} resourcePromise object containing the version
|
||||
*
|
||||
*/
|
||||
getRollbackVersion: function (versionId, culture) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersion", {
|
||||
versionId: versionId,
|
||||
culture: culture
|
||||
})
|
||||
),
|
||||
"Failed to get version for content item with id " + versionId
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentResource#rollback
|
||||
* @methodOf umbraco.resources.contentResource
|
||||
*
|
||||
* @description
|
||||
* Roll backs a content item to a previous version
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* contentResource.rollback(contentId, versionId, culture)
|
||||
* .then(function() {
|
||||
* alert('its here!');
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Int} id Id of node
|
||||
* @param {Int} versionId The version Id
|
||||
* @param {Int} culture if provided, the results will be for this specific culture/variant
|
||||
* @returns {Promise} resourcePromise object
|
||||
*
|
||||
*/
|
||||
rollback: function (contentId, versionId, culture) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl("contentApiBaseUrl", "PostRollbackContent", {
|
||||
contentId: contentId, versionId:versionId, culture:culture
|
||||
})
|
||||
),
|
||||
"Failed to roll back content item with id " + contentId
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
hotKey: "ctrl+u",
|
||||
hotKeyWhenHidden: true,
|
||||
alias: "unpublish",
|
||||
addEllipsis: args.content.variants && args.content.variants.length > 1 ? "true" : "false"
|
||||
addEllipsis: "true"
|
||||
};
|
||||
case "SCHEDULE":
|
||||
//schedule publish - schedule doesn't have a permission letter so
|
||||
|
||||
@@ -180,6 +180,25 @@
|
||||
open(editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.editorService#rollback
|
||||
* @methodOf umbraco.services.editorService
|
||||
*
|
||||
* @description
|
||||
* Opens a rollback editor in infinite editing.
|
||||
* @param {String} editor.node The node to rollback
|
||||
* @param {Callback} editor.submit Saves, submits, and closes the editor
|
||||
* @param {Callback} editor.close Closes the editor
|
||||
* @returns {Object} editor object
|
||||
*/
|
||||
|
||||
function rollback(editor) {
|
||||
editor.view = "views/common/infiniteeditors/rollback/rollback.html";
|
||||
editor.size = "small";
|
||||
open(editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.editorService#linkPicker
|
||||
@@ -481,6 +500,7 @@
|
||||
copy: copy,
|
||||
move: move,
|
||||
embed: embed,
|
||||
rollback: rollback,
|
||||
linkPicker: linkPicker,
|
||||
mediaPicker: mediaPicker,
|
||||
iconPicker: iconPicker,
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
}
|
||||
|
||||
.umb-button--xs {
|
||||
padding: 5px 16px;
|
||||
padding: 5px 13px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
.umb-box-header {
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.umb-box-header-title {
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
.umb-user-cards {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: -10px;
|
||||
display: grid;
|
||||
grid-gap: 20px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
}
|
||||
|
||||
.umb-user-card {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 100%;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.umb-user-card:hover,
|
||||
@@ -21,49 +16,6 @@
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 33.33%;
|
||||
max-width: 33.33%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1400px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 25%;
|
||||
max-width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1700px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 20%;
|
||||
max-width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 1900px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 16.66%;
|
||||
max-width: 16.66%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 2200px) {
|
||||
.umb-user-card {
|
||||
flex: 0 0 14.28%;
|
||||
max-width: 14.28%;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-user-card__content {
|
||||
position: relative;
|
||||
padding: 15px;
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
// Container styles
|
||||
// --------------------------------------------------
|
||||
.umb-property-editor {
|
||||
min-width:66.6%;
|
||||
@media (max-width: 800px) {
|
||||
width: 100%;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
min-width:66.6%;
|
||||
}
|
||||
|
||||
&-pull {
|
||||
float:left;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
.ws-normal { white-space: normal; }
|
||||
.nowrap { white-space: nowrap; }
|
||||
.pre { white-space: pre; }
|
||||
.pre-wrap { white-space: pre-wrap; }
|
||||
.pre-line { white-space: pre-line; }
|
||||
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function RollbackController($scope, contentResource, localizationService, assetsService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.rollback = rollback;
|
||||
vm.changeLanguage = changeLanguage;
|
||||
vm.changeVersion = changeVersion;
|
||||
vm.submit = submit;
|
||||
vm.close = close;
|
||||
|
||||
//////////
|
||||
|
||||
function onInit() {
|
||||
|
||||
vm.loading = true;
|
||||
vm.variantVersions = [];
|
||||
vm.diff = null;
|
||||
vm.currentVersion = null;
|
||||
vm.rollbackButtonDisabled = true;
|
||||
|
||||
// find the current version for invariant nodes
|
||||
if($scope.model.node.variants.length === 1) {
|
||||
vm.currentVersion = $scope.model.node.variants[0];
|
||||
}
|
||||
|
||||
// find the current version for nodes with variants
|
||||
if($scope.model.node.variants.length > 1) {
|
||||
var active = _.find($scope.model.node.variants, function (v) {
|
||||
return v.active;
|
||||
});
|
||||
|
||||
// preselect the language in the dropdown
|
||||
if(active) {
|
||||
vm.selectedLanguage = active;
|
||||
vm.currentVersion = active;
|
||||
}
|
||||
}
|
||||
|
||||
// set default title
|
||||
if(!$scope.model.title) {
|
||||
localizationService.localize("actions_rollback").then(function(value){
|
||||
$scope.model.title = value;
|
||||
});
|
||||
}
|
||||
|
||||
// Load in diff library
|
||||
assetsService.loadJs('lib/jsdiff/diff.min.js', $scope).then(function () {
|
||||
|
||||
getVersions().then(function(){
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function changeLanguage(language) {
|
||||
vm.currentVersion = language;
|
||||
getVersions();
|
||||
}
|
||||
|
||||
function changeVersion(version) {
|
||||
|
||||
if(version && version.versionId) {
|
||||
|
||||
const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null;
|
||||
|
||||
contentResource.getRollbackVersion(version.versionId, culture)
|
||||
.then(function(data){
|
||||
vm.previousVersion = data;
|
||||
vm.previousVersion.versionId = version.versionId;
|
||||
createDiff(vm.currentVersion, vm.previousVersion);
|
||||
vm.rollbackButtonDisabled = false;
|
||||
});
|
||||
|
||||
} else {
|
||||
vm.diff = null;
|
||||
vm.rollbackButtonDisabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
function getVersions() {
|
||||
|
||||
const nodeId = $scope.model.node.id;
|
||||
const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null;
|
||||
|
||||
return contentResource.getRollbackVersions(nodeId, culture)
|
||||
.then(function(data){
|
||||
vm.previousVersions = data.map(version => {
|
||||
version.displayValue = version.versionDate + " - " + version.versionAuthorName;
|
||||
return version;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This will load in a new version
|
||||
*/
|
||||
function createDiff(currentVersion, previousVersion) {
|
||||
|
||||
vm.diff = {};
|
||||
vm.diff.properties = [];
|
||||
|
||||
// find diff in name
|
||||
vm.diff.name = JsDiff.diffWords(currentVersion.name, previousVersion.name);
|
||||
|
||||
// extract all properties from the tabs and create new object for the diff
|
||||
currentVersion.tabs.forEach((tab, tabIndex) => {
|
||||
tab.properties.forEach((property, propertyIndex) => {
|
||||
var oldProperty = previousVersion.tabs[tabIndex].properties[propertyIndex];
|
||||
|
||||
// we have to make properties storing values as object into strings (Grid, nested content, etc.)
|
||||
if(property.value instanceof Object) {
|
||||
property.value = JSON.stringify(property.value, null, 1);
|
||||
property.isObject = true;
|
||||
}
|
||||
|
||||
if(oldProperty.value instanceof Object) {
|
||||
oldProperty.value = JSON.stringify(oldProperty.value, null, 1);
|
||||
oldProperty.isObject = true;
|
||||
}
|
||||
|
||||
// create new property object used in the diff table
|
||||
var diffProperty = {
|
||||
"alias": property.alias,
|
||||
"label": property.label,
|
||||
"diff": (property.value || oldProperty.value) ? JsDiff.diffWords(property.value, oldProperty.value) : "",
|
||||
"isObject": (property.isObject || oldProperty.isObject) ? true : false
|
||||
};
|
||||
|
||||
vm.diff.properties.push(diffProperty);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function rollback() {
|
||||
|
||||
vm.rollbackButtonState = "busy";
|
||||
|
||||
const nodeId = $scope.model.node.id;
|
||||
const versionId = vm.previousVersion.versionId;
|
||||
const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null;
|
||||
|
||||
return contentResource.rollback(nodeId, versionId, culture)
|
||||
.then(data => {
|
||||
vm.rollbackButtonState = "success";
|
||||
submit();
|
||||
}, error => {
|
||||
vm.rollbackButtonState = "error";
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function submit() {
|
||||
if($scope.model.submit) {
|
||||
$scope.model.submit($scope.model.submit);
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
onInit();
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.RollbackController", RollbackController);
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,104 @@
|
||||
<div ng-controller="Umbraco.Editors.RollbackController as vm">
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
<umb-load-indicator
|
||||
ng-if="vm.loading">
|
||||
</umb-load-indicator>
|
||||
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
<div ng-if="model.node.variants.length > 1">
|
||||
<h5><localize key="general_language"></localize></h5>
|
||||
<select
|
||||
class="input-block-level"
|
||||
ng-model="vm.selectedLanguage"
|
||||
ng-options="variant as variant.language.name for variant in model.node.variants track by variant.language.culture"
|
||||
ng-change="vm.changeLanguage(vm.selectedLanguage)">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<h5><localize key="rollback_currentVersion"></localize></h5>
|
||||
<p>{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})</p>
|
||||
|
||||
<h5><localize key="rollback_rollbackTo"></localize></h5>
|
||||
<select
|
||||
class="input-block-level"
|
||||
ng-model="vm.selectedVersion"
|
||||
ng-options="version.displayValue for version in vm.previousVersions track by version.versionId"
|
||||
ng-change="vm.changeVersion(vm.selectedVersion)">
|
||||
<option value=""><localize key="general_choose">Choose</localize>...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.diff" class="diff" style="border-top: 1px solid #e9e9eb; margin-top: 30px;">
|
||||
|
||||
<h5>Changes</h5>
|
||||
<small style="margin-bottom: 15px; display: block;"><localize key="rollback_diffHelp"></localize></small>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="bold">Name</td>
|
||||
<td>
|
||||
<span ng-repeat="part in vm.diff.name">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
</span>
|
||||
</td>
|
||||
</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}">
|
||||
<span ng-repeat="part in property.diff">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
action="vm.close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
state="vm.rollbackButtonState"
|
||||
label-key="actions_rollback"
|
||||
disabled="vm.rollbackButtonDisabled"
|
||||
action="vm.rollback()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
@@ -41,7 +41,19 @@
|
||||
</umb-box>
|
||||
|
||||
<umb-box data-element="node-info-history">
|
||||
<umb-box-header title-key="general_history"></umb-box-header>
|
||||
|
||||
<umb-box-header
|
||||
title-key="general_history">
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="outline"
|
||||
action="openRollback()"
|
||||
label-key="actions_rollback"
|
||||
size="xs"
|
||||
add-ellipsis="true">
|
||||
</umb-button>
|
||||
</umb-box-header>
|
||||
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<div style="position: relative;">
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<div class="umb-box-header" ng-transclude>
|
||||
<div class="umb-box-header-title" ng-if="title || titleKey">
|
||||
<localize ng-if="titleKey" key="{{titleKey}}"></localize>
|
||||
<span ng-if="title">{{title}}</span>
|
||||
</div>
|
||||
<div class="umb-box-header-description" ng-if="description || descriptionKey">
|
||||
<localize ng-if="descriptionKey" key="{{descriptionKey}}"></localize>
|
||||
<span ng-if="description">{{description}}</span>
|
||||
<div class="umb-box-header">
|
||||
<div>
|
||||
<div class="umb-box-header-title" ng-if="title || titleKey">
|
||||
<localize ng-if="titleKey" key="{{titleKey}}"></localize>
|
||||
<span ng-if="title">{{title}}</span>
|
||||
</div>
|
||||
<div class="umb-box-header-description" ng-if="description || descriptionKey">
|
||||
<localize ng-if="descriptionKey" key="{{descriptionKey}}"></localize>
|
||||
<span ng-if="description">{{description}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="umb-property-editor" ng-class="{'-not-clickable': preview}">
|
||||
<div class="umb-property-editor db" ng-class="{'-not-clickable': preview}">
|
||||
<div ng-include="propertyEditorView"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function ContentRollbackController($scope, assetsService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.rollback = rollback;
|
||||
vm.loadVersion = loadVersion;
|
||||
vm.closeDialog = closeDialog;
|
||||
|
||||
function onInit() {
|
||||
|
||||
vm.loading = true;
|
||||
vm.variantVersions = [];
|
||||
vm.diff = null;
|
||||
|
||||
// Load in diff library
|
||||
assetsService.loadJs('lib/jsdiff/diff.min.js', $scope).then(function () {
|
||||
|
||||
var currentLanguage = $scope.currentNode.metaData.culture;
|
||||
|
||||
vm.currentVersion = {
|
||||
"id": 1,
|
||||
"createDate": "22/08/2018 13.32",
|
||||
"name": "Forside",
|
||||
"properties": [
|
||||
{
|
||||
"alias": "headline",
|
||||
"label": "Headline",
|
||||
"value": "Velkommen"
|
||||
},
|
||||
{
|
||||
"alias": "text",
|
||||
"label": "Text",
|
||||
"value": "This is my danish Content"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
vm.previousVersions = [
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Forside",
|
||||
"createDate": "21/08/2018 19.25"
|
||||
}
|
||||
];
|
||||
|
||||
vm.loading = false;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function rollback() {
|
||||
console.log("rollback");
|
||||
}
|
||||
|
||||
/**
|
||||
* This will load in a new version
|
||||
*/
|
||||
function loadVersion(id) {
|
||||
|
||||
// fake load version
|
||||
var currentLanguage = $scope.currentNode.metaData.culture;
|
||||
|
||||
vm.diff = {};
|
||||
vm.diff.properties = [];
|
||||
|
||||
var oldVersion = {
|
||||
"id": 2,
|
||||
"name": "Foride",
|
||||
"properties": [
|
||||
{
|
||||
"alias": "headline",
|
||||
"label": "Headline",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"alias": "text",
|
||||
"label": "Text",
|
||||
"value": "This is my danish Content Test"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// find diff in name
|
||||
vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, oldVersion.name);
|
||||
|
||||
// find diff in properties
|
||||
angular.forEach(vm.currentVersion.properties,
|
||||
function(newProperty, index){
|
||||
var oldProperty = oldVersion.properties[index];
|
||||
var diffProperty = {
|
||||
"alias": newProperty.alias,
|
||||
"label": newProperty.label,
|
||||
"diff": JsDiff.diffWords(newProperty.value, oldProperty.value)
|
||||
};
|
||||
vm.diff.properties.push(diffProperty);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This will close the dialog
|
||||
*/
|
||||
function closeDialog() {
|
||||
$scope.nav.hideDialog();
|
||||
}
|
||||
|
||||
onInit();
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Content.RollbackController", ContentRollbackController);
|
||||
|
||||
})();
|
||||
@@ -25,7 +25,7 @@
|
||||
<span>{{ variant.language.name }}</span>
|
||||
</label>
|
||||
|
||||
<div ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<div class="umb-permission__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</div>
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<div ng-controller="Umbraco.Editors.Content.RollbackController as vm">
|
||||
|
||||
<div class="umb-dialog-body" ng-cloak>
|
||||
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<div class="umb-pane" ng-show="!vm.loading">
|
||||
|
||||
<div>
|
||||
<h5>Rollback {{ currentNode.name }}</h5>
|
||||
|
||||
<h5><localize key="rollback_currentVersion"></localize></h5>
|
||||
<p>{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})</p>
|
||||
|
||||
<h5><localize key="rollback_rollbackTo"></localize></h5>
|
||||
<select
|
||||
class="input-block-level"
|
||||
ng-model="vm.selectedVersion"
|
||||
ng-options="version.createDate for version in vm.previousVersions track by version.id"
|
||||
ng-change="vm.loadVersion(vm.selectedVersion.id)">
|
||||
<option value=""><localize key="general_choose">Choose</localize>...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.diff" class="diff" style="border-top: 1px solid #e9e9eb; margin-top: 30px;">
|
||||
|
||||
<h5>Changes</h5>
|
||||
<small style="margin-bottom: 15px; display: block;"><localize key="rollback_diffHelp"></localize></small>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="bold">Name</td>
|
||||
<td>
|
||||
<span ng-repeat="part in vm.diff.name">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-repeat="property in vm.diff.properties track by property.alias">
|
||||
<td class="bold">{{property.label}}</td>
|
||||
<td>
|
||||
<span ng-repeat="part in property.diff">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
|
||||
<umb-button
|
||||
label-key="general_close"
|
||||
disabled="vm.saveState === 'busy'"
|
||||
action="vm.closeDialog()"
|
||||
type="button"
|
||||
button-style="link">
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
label-key="buttons_rollback"
|
||||
disabled="vm.saveState === 'busy'"
|
||||
state="vm.saveState"
|
||||
action="vm.rollback()"
|
||||
type="button"
|
||||
button-style="success">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -31,6 +31,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Language</th>
|
||||
<th>ISO</th>
|
||||
<th>Default</th>
|
||||
<th>Mandatory</th>
|
||||
<th>Fallback</th>
|
||||
@@ -42,6 +43,9 @@
|
||||
<i class="icon-globe" style="color: #BBBABF; margin-right: 5px;"></i>
|
||||
<span class="bold">{{ language.name }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{ language.culture }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<umb-checkmark
|
||||
ng-if="language.isDefault"
|
||||
|
||||
@@ -262,13 +262,12 @@
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<umb-button type="button" ng-if="model.user.userDisplayState.key !== 'Invited'"
|
||||
<umb-button type="button" ng-if="model.changePasswordModel.isChanging === false && model.user.userDisplayState.key !== 'Invited'"
|
||||
button-style="[info,block]"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Change password"
|
||||
label-key="general_changePassword"
|
||||
state="changePasswordButtonState"
|
||||
ng-if="model.changePasswordModel.isChanging === false"
|
||||
size="s">
|
||||
</umb-button>
|
||||
|
||||
|
||||
@@ -349,6 +349,7 @@
|
||||
<Content Include="Umbraco\Developer\Packages\editPackage.aspx" />
|
||||
<Content Include="Umbraco\Dialogs\protectPage.aspx" />
|
||||
<Content Include="Umbraco\Dialogs\rollBack.aspx" />
|
||||
<Content Include="Umbraco\Dialogs\sendToTranslation.aspx" />
|
||||
<Content Include="Umbraco\Config\Create\UI.xml" />
|
||||
<Content Include="Umbraco\Config\Lang\en.xml">
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
<div ng-cloak ng-animate="'fade'" id="fact" class="absolute-center clearfix" ng-show="installer.fact">
|
||||
<h2>Did you know</h2>
|
||||
<p ng-bind-html-unsafe="installer.fact"></p>
|
||||
<p ng-bind-html="installer.fact"></p>
|
||||
</div>
|
||||
|
||||
<h3 ng-cloak ng-animate="'fade'" id="feedback" ng-show="installer.feedback">{{installer.feedback}}</h3>
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master"AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %>
|
||||
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
<script type="text/javascript">
|
||||
function doSubmit() { document.Form1["ok"].click() }
|
||||
|
||||
var functionsFrame = this;
|
||||
var tabFrame = this;
|
||||
var isDialog = true;
|
||||
var submitOnEnter = true;
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.propertyItemheader {
|
||||
width: 140px !Important;
|
||||
}
|
||||
|
||||
.diff {
|
||||
margin-top: 10px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
border-top: 1px solid #efefef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.diff table td {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.diff del {
|
||||
background: rgb(255, 230, 230) none repeat scroll 0%;
|
||||
-moz-background-clip: -moz-initial;
|
||||
-moz-background-origin: -moz-initial;
|
||||
-moz-background-inline-policy: -moz-initial;
|
||||
}
|
||||
|
||||
.diff ins {
|
||||
background: rgb(230, 255, 230) none repeat scroll 0%;
|
||||
-moz-background-clip: -moz-initial;
|
||||
-moz-background-origin: -moz-initial;
|
||||
-moz-background-inline-policy: -moz-initial;
|
||||
}
|
||||
|
||||
.diff .diffnotice {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
<div class="umb-dialog-body">
|
||||
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="js/umbracoCheckKeys.js" PathNameAlias="UmbracoRoot" />
|
||||
|
||||
<cc1:Feedback ID="feedBackMsg" runat="server" />
|
||||
|
||||
<cc1:Pane ID="pp_selectVersion" runat="server" Text="Select a version to compare with the current version">
|
||||
<cc1:PropertyPanel id="pp_currentVersion" Text="Current version" runat="server">
|
||||
<asp:Literal ID="currentVersionTitle" runat="server" />
|
||||
<small>(<asp:Literal ID="currentVersionMeta" runat="server" />)</small></cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_rollBackTo" Text="Rollback to" runat="server">
|
||||
<asp:DropDownList OnSelectedIndexChanged="version_load" ID="allVersions" runat="server" Width="400px" AutoPostBack="True" CssClass="guiInputTextTiny" />
|
||||
</cc1:PropertyPanel>
|
||||
|
||||
<cc1:PropertyPanel id="pp_view" Text="View" runat="server">
|
||||
<small>
|
||||
<asp:RadioButtonList ID="rbl_mode" runat="server" OnSelectedIndexChanged="version_load" RepeatDirection="Horizontal">
|
||||
<asp:ListItem Selected="True" Value="diff">Diff</asp:ListItem>
|
||||
<asp:ListItem Value="html">Html</asp:ListItem>
|
||||
</asp:RadioButtonList>
|
||||
</small>
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
|
||||
<asp:Panel ID="diffPanel" Visible="false" runat="server" Height="300px">
|
||||
<div class="diff">
|
||||
<div class="diffnotice">
|
||||
<p>
|
||||
<asp:Literal ID="lt_notice" runat="server" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table border="0" style="width: 95%;">
|
||||
<asp:Literal ID="propertiesCompare" runat="server"></asp:Literal>
|
||||
</table>
|
||||
</div>
|
||||
</asp:Panel>
|
||||
</div>
|
||||
|
||||
<div runat="server" id="pl_buttons" class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("general/cancel")%></a>
|
||||
<asp:Button ID="Button1" runat="server" visible="false" CssClass="btn btn-primary" OnClick="doRollback_Click"></asp:Button>
|
||||
</div>
|
||||
</asp:Content>
|
||||
@@ -8,21 +8,21 @@ function UmbracoSpeechBubble(id) {
|
||||
this.GenerateSpeechBubble();
|
||||
}
|
||||
|
||||
UmbracoSpeechBubble.prototype.GenerateSpeechBubble = function() {
|
||||
UmbracoSpeechBubble.prototype.GenerateSpeechBubble = function () {
|
||||
|
||||
var sbHtml = document.getElementById(this.id);
|
||||
|
||||
sbHtml.innerHTML = '' +
|
||||
'<div class="speechBubbleTop"></div>' +
|
||||
'<div class="speechBubbleContent">' +
|
||||
'<img id="' + this.id + 'Icon" style="float: left; margin: 0px 5px 10px 3px;" />' +
|
||||
' <img class="speechClose" onClick="UmbSpeechBubble.Hide();" id="' + this.id + 'close" src="/umbraco/images/speechBubble/speechBubble_close.gif" width="18" height="18" border="0" alt="Close"' +
|
||||
' onmouseover="this.src = \'/umbraco/images/speechBubble/speechBubble_close_over.gif\';" onmouseout="this.src=\'images/speechBubble/speechBubble_close.gif\';">' +
|
||||
' <div style="float: right; width: 186px; margin-right: 10px;"><h3 id="' + this.id + 'Header">The header!</h3>' +
|
||||
' <p style="width: 185px" id="' + this.id + 'Message">Default Text Container!<br /></p></div><br style="clear: both" />' +
|
||||
'</div>' +
|
||||
'<div class="speechBubbleBottom"></div>'
|
||||
}
|
||||
'<div class="speechBubbleTop"></div>' +
|
||||
'<div class="speechBubbleContent">' +
|
||||
'<img id="' + this.id + 'Icon" style="float: left; margin: 0px 5px 10px 3px;" />' +
|
||||
' <img class="speechClose" onClick="UmbSpeechBubble.Hide();" id="' + this.id + 'close" src="/umbraco/images/speechBubble/speechBubble_close.gif" width="18" height="18" border="0" alt="Close"' +
|
||||
' onmouseover="this.src = \'/umbraco/images/speechBubble/speechBubble_close_over.gif\';" onmouseout="this.src=\'images/speechBubble/speechBubble_close.gif\';">' +
|
||||
' <div style="float: right; width: 186px; margin-right: 10px;"><h3 id="' + this.id + 'Header">The header!</h3>' +
|
||||
' <p style="width: 185px" id="' + this.id + 'Message">Default Text Container!<br /></p></div><br style="clear: both" />' +
|
||||
'</div>' +
|
||||
'<div class="speechBubbleBottom"></div>';
|
||||
};
|
||||
|
||||
UmbracoSpeechBubble.prototype.ShowMessage = function (icon, header, message, dontAutoHide) {
|
||||
var speechBubble = jQuery("#" + this.id);
|
||||
@@ -46,7 +46,7 @@ UmbracoSpeechBubble.prototype.ShowMessage = function (icon, header, message, don
|
||||
jQuery(".speechClose").show();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
UmbracoSpeechBubble.prototype.Hide = function () {
|
||||
if (!this.ie) {
|
||||
@@ -54,7 +54,7 @@ UmbracoSpeechBubble.prototype.Hide = function () {
|
||||
} else {
|
||||
jQuery("#" + this.id).hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize
|
||||
var UmbSpeechBubble = null
|
||||
@@ -65,4 +65,4 @@ function InitUmbracoSpeechBubble() {
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
InitUmbracoSpeechBubble();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.ContentApps;
|
||||
|
||||
// the namespace here is intentional - although defined in Umbraco.Web assembly,
|
||||
// this class should be visible when using Umbraco.Core.Components, alongside
|
||||
@@ -32,7 +33,15 @@ namespace Umbraco.Core.Components
|
||||
/// <returns></returns>
|
||||
internal static ActionCollectionBuilder Actions(this Composition composition)
|
||||
=> composition.Container.GetInstance<ActionCollectionBuilder>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content apps collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <returns></returns>
|
||||
public static ContentAppDefinitionCollectionBuilder ContentApps(this Composition composition)
|
||||
=> composition.Container.GetInstance<ContentAppDefinitionCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content finders collection builder.
|
||||
/// </summary>
|
||||
|
||||
@@ -1702,5 +1702,93 @@ namespace Umbraco.Web.Editors
|
||||
Services.NotificationService.SetNotifications(Security.CurrentUser, content, notifyOptions);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IEnumerable<RollbackVersion> GetRollbackVersions(int contentId, string culture = null)
|
||||
{
|
||||
var rollbackVersions = new List<RollbackVersion>();
|
||||
var writerIds = new HashSet<int>();
|
||||
|
||||
//Return a list of all versions of a specific content node
|
||||
// fixme - cap at 50 versions for now?
|
||||
var versions = Services.ContentService.GetVersionsSlim(contentId, 0, 50);
|
||||
|
||||
//Not all nodes are variants & thus culture can be null
|
||||
if (culture != null)
|
||||
{
|
||||
//Get cultures that were published with the version = their update date is equal to the version's
|
||||
versions = versions.Where(x => x.UpdateDate == x.GetUpdateDate(culture));
|
||||
}
|
||||
|
||||
//First item is our current item/state (cant rollback to ourselves)
|
||||
versions = versions.Skip(1);
|
||||
|
||||
foreach (var version in versions)
|
||||
{
|
||||
var rollbackVersion = new RollbackVersion
|
||||
{
|
||||
VersionId = version.VersionId,
|
||||
VersionDate = version.UpdateDate,
|
||||
VersionAuthorId = version.WriterId
|
||||
};
|
||||
|
||||
rollbackVersions.Add(rollbackVersion);
|
||||
|
||||
writerIds.Add(version.WriterId);
|
||||
}
|
||||
|
||||
var users = Services.UserService
|
||||
.GetUsersById(writerIds.ToArray())
|
||||
.ToDictionary(x => x.Id, x => x.Name);
|
||||
|
||||
foreach (var rollbackVersion in rollbackVersions)
|
||||
{
|
||||
if (users.TryGetValue(rollbackVersion.VersionAuthorId, out var userName))
|
||||
rollbackVersion.VersionAuthorName = userName;
|
||||
}
|
||||
|
||||
return rollbackVersions;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ContentVariantDisplay GetRollbackVersion(int versionId, string culture = null)
|
||||
{
|
||||
var version = Services.ContentService.GetVersion(versionId);
|
||||
var content = MapToDisplay(version);
|
||||
|
||||
return culture == null
|
||||
? content.Variants.FirstOrDefault() //No culture set - so this is an invariant node - so just list me the first item in here
|
||||
: content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*")
|
||||
{
|
||||
var rollbackResult = Services.ContentService.Rollback(contentId, versionId, culture, Security.GetUserId().ResultOr(0));
|
||||
|
||||
if (rollbackResult.Success)
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
|
||||
var notificationModel = new SimpleNotificationModel();
|
||||
|
||||
switch (rollbackResult.Result)
|
||||
{
|
||||
case OperationResultType.Failed:
|
||||
case OperationResultType.FailedCannot:
|
||||
case OperationResultType.FailedExceptionThrown:
|
||||
case OperationResultType.NoOperation:
|
||||
default:
|
||||
notificationModel.AddErrorNotification(
|
||||
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
|
||||
null); //TODO: There is no specific failed to save error message AFAIK
|
||||
break;
|
||||
case OperationResultType.FailedCancelledByEvent:
|
||||
notificationModel.AddErrorNotification(
|
||||
Services.TextService.Localize("speechBubbles/operationCancelledHeader"),
|
||||
Services.TextService.Localize("speechBubbles/operationCancelledText"));
|
||||
break;
|
||||
}
|
||||
|
||||
return Request.CreateValidationErrorResponse(notificationModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,12 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
{
|
||||
get
|
||||
{
|
||||
var currentVersion = UmbracoVersion.Local;
|
||||
|
||||
//fixme - in this case there's a db but the version is cleared which is fine and a normal way to force the upgrader
|
||||
// to execute, but before we would detect the current version via the DB like DatabaseSchemaResult.DetermineInstalledVersion
|
||||
// what now, do we need to?
|
||||
if (currentVersion == null)
|
||||
currentVersion = new Semver.SemVersion(0);
|
||||
// fixme - if UmbracoVersion.Local is null?
|
||||
// it means that there is a database but the web.config version is cleared
|
||||
// that was a "normal" way to force the upgrader to execute, and we would detect the current
|
||||
// version via the DB like DatabaseSchemaResult.DetermineInstalledVersion - magic, do we really
|
||||
// need this now?
|
||||
var currentVersion = (UmbracoVersion.Local ?? new Semver.SemVersion(0)).ToString();
|
||||
|
||||
var newVersion = UmbracoVersion.SemanticVersion.ToString();
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
[DataContract(Name = "rollbackVersion", Namespace = "")]
|
||||
public class RollbackVersion
|
||||
{
|
||||
[DataMember(Name = "versionId")]
|
||||
public int VersionId { get; set; }
|
||||
|
||||
[DataMember(Name = "versionDate")]
|
||||
public DateTime VersionDate { get; set; }
|
||||
|
||||
[DataMember(Name = "versionAuthorId")]
|
||||
public int VersionAuthorId { get; set; }
|
||||
|
||||
[DataMember(Name = "versionAuthorName")]
|
||||
public string VersionAuthorName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,6 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
AddActionNode<ActionSort>(item, menu, true);
|
||||
|
||||
AddActionNode<ActionRollback>(item, menu);
|
||||
AddActionNode<ActionToPublish>(item, menu, convert: true);
|
||||
AddActionNode<ActionAssignDomain>(item, menu);
|
||||
AddActionNode<ActionRights>(item, menu, convert: true);
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
<Compile Include="Media\TypeDetector\SvgDetector.cs" />
|
||||
<Compile Include="Media\TypeDetector\TIFFDetector.cs" />
|
||||
<Compile Include="Media\UploadAutoFillProperties.cs" />
|
||||
<Compile Include="Models\ContentEditing\RollbackVersion.cs" />
|
||||
<Compile Include="Models\ContentEditing\UnpublishContent.cs" />
|
||||
<Compile Include="Models\Mapping\MappingOperationOptionsExtensions.cs" />
|
||||
<Compile Include="ContentApps\ContentAppDefinitionCollection.cs" />
|
||||
@@ -1310,12 +1311,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx.designer.cs">
|
||||
<DependentUpon>editPackage.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\rollBack.aspx.cs">
|
||||
<DependentUpon>rollBack.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\rollBack.aspx.designer.cs">
|
||||
<DependentUpon>rollBack.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\templateControls\DisableEventValidation.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\templateControls\Item.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\templateControls\ItemRenderer.cs" />
|
||||
@@ -1400,9 +1395,6 @@
|
||||
<Content Include="umbraco.presentation\umbraco\developer\Packages\editPackage.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\rollBack.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Web References\org.umbraco.update\checkforupgrade.disco" />
|
||||
@@ -1456,10 +1448,7 @@
|
||||
<CachedSettingsPropName>umbraco_org_umbraco_update_CheckForUpgrade</CachedSettingsPropName>
|
||||
</WebReferenceUrl>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="umbraco.presentation\umbraco\settings\" />
|
||||
<Folder Include="umbraco.presentation\umbraco\translation\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!--
|
||||
copied from Microsoft.CSharp.targets
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
<%@ Page Language="c#" CodeBehind="rollBack.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master" AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %>
|
||||
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
<script type="text/javascript">
|
||||
function doSubmit() { document.Form1["ok"].click() }
|
||||
|
||||
var functionsFrame = this;
|
||||
var tabFrame = this;
|
||||
var isDialog = true;
|
||||
var submitOnEnter = true;
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.propertyItemheader {
|
||||
width: 140px !Important;
|
||||
}
|
||||
|
||||
.diff {
|
||||
margin-top: 10px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
border-top: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.diff table td {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.diff del {
|
||||
background: rgb(255, 230, 230) none repeat scroll 0%;
|
||||
-moz-background-clip: -moz-initial;
|
||||
-moz-background-origin: -moz-initial;
|
||||
-moz-background-inline-policy: -moz-initial;
|
||||
}
|
||||
|
||||
.diff ins {
|
||||
background: rgb(230, 255, 230) none repeat scroll 0%;
|
||||
-moz-background-clip: -moz-initial;
|
||||
-moz-background-origin: -moz-initial;
|
||||
-moz-background-inline-policy: -moz-initial;
|
||||
}
|
||||
|
||||
.diff .diffnotice {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
<div class="umb-dialog-body">
|
||||
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="js/umbracoCheckKeys.js" PathNameAlias="UmbracoRoot" />
|
||||
|
||||
<cc1:Feedback ID="feedBackMsg" runat="server" />
|
||||
|
||||
<cc1:Pane ID="pp_selectVersion" runat="server" Text="Select a version to compare with the current version">
|
||||
<cc1:PropertyPanel id="pp_currentVersion" Text="Current version" runat="server">
|
||||
<asp:Literal ID="currentVersionTitle" runat="server" />
|
||||
<small>(<asp:Literal ID="currentVersionMeta" runat="server" />)</small></cc1:PropertyPanel>
|
||||
<cc1:PropertyPanel ID="pp_rollBackTo" Text="Rollback to" runat="server">
|
||||
<asp:DropDownList OnSelectedIndexChanged="version_load" ID="allVersions" runat="server" Width="400px" AutoPostBack="True" CssClass="guiInputTextTiny" />
|
||||
</cc1:PropertyPanel>
|
||||
|
||||
<cc1:PropertyPanel id="pp_view" Text="View" runat="server">
|
||||
<small>
|
||||
<asp:RadioButtonList ID="rbl_mode" runat="server" OnSelectedIndexChanged="version_load" RepeatDirection="Horizontal">
|
||||
<asp:ListItem Selected="True" Value="diff">Diff</asp:ListItem>
|
||||
<asp:ListItem Value="html">Html</asp:ListItem>
|
||||
</asp:RadioButtonList>
|
||||
</small>
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
|
||||
<asp:Panel ID="diffPanel" Visible="false" runat="server" Height="300px">
|
||||
<div class="diff">
|
||||
<div class="diffnotice">
|
||||
<p>
|
||||
<asp:Literal ID="lt_notice" runat="server" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table border="0" style="width: 95%;">
|
||||
<asp:Literal ID="propertiesCompare" runat="server"></asp:Literal>
|
||||
</table>
|
||||
</div>
|
||||
</asp:Panel>
|
||||
</div>
|
||||
|
||||
<div runat="server" id="pl_buttons" class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("general/cancel")%></a>
|
||||
<asp:Button ID="Button1" runat="server" Visible="false" CssClass="btn btn-primary" OnClick="doRollback_Click"></asp:Button>
|
||||
</div>
|
||||
</asp:Content>
|
||||
@@ -1,156 +0,0 @@
|
||||
//TODO: REbuild this in angular and then remove
|
||||
|
||||
//using System;
|
||||
//using System.Collections;
|
||||
//using System.ComponentModel;
|
||||
//using System.Data;
|
||||
//using System.Drawing;
|
||||
//using System.Linq;
|
||||
//using System.Web;
|
||||
//using System.Web.SessionState;
|
||||
//using System.Web.UI;
|
||||
//using System.Web.UI.WebControls;
|
||||
//using System.Web.UI.HtmlControls;
|
||||
//
|
||||
//using umbraco.cms.businesslogic.web;
|
||||
//using umbraco.cms.businesslogic.property;
|
||||
|
||||
//namespace umbraco.presentation.dialogs
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// Summary description for rollBack.
|
||||
// /// </summary>
|
||||
// public partial class rollBack : UmbracoEnsuredPage
|
||||
// {
|
||||
// public rollBack()
|
||||
// {
|
||||
// CurrentApp = Constants.Applications.Content.ToString();
|
||||
|
||||
// }
|
||||
// private Document currentDoc = new Document(int.Parse(helper.Request("nodeId")));
|
||||
|
||||
// protected void version_load(object sender, EventArgs e) {
|
||||
|
||||
// if (allVersions.SelectedValue != "")
|
||||
// {
|
||||
// diffPanel.Visible = true;
|
||||
// Document rollback = new Document(currentDoc.Id, new Guid(allVersions.SelectedValue));
|
||||
|
||||
// propertiesCompare.Text = "<tr><th style='width: 25%;' valign='top'>" + Services.TextService.Localize("general/name") + ":</th><td>" + rollback.Text + "</td></tr>";
|
||||
// propertiesCompare.Text += "<tr><th style='width: 25%;' valign='top'>" + Services.TextService.Localize("content/createDate") + ":</th><td>" + rollback.VersionDate.ToLongDateString() + " " + rollback.VersionDate.ToLongTimeString() + " " + Services.TextService.Localize("general/by") + ": " + rollback.User.Name + "</td></tr>";
|
||||
|
||||
// if (rbl_mode.SelectedValue == "diff")
|
||||
// lt_notice.Text = Services.TextService.Localize("rollback/diffHelp");
|
||||
// else
|
||||
// lt_notice.Text = Services.TextService.Localize("rollback/htmlHelp");
|
||||
|
||||
|
||||
// var props = rollback.GenericProperties;
|
||||
// foreach (Property p in props)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
|
||||
// if (p.Value != null)
|
||||
// {
|
||||
|
||||
// //new property value...
|
||||
// string thevalue = p.Value.ToString();
|
||||
|
||||
// if (rbl_mode.SelectedValue == "diff")
|
||||
// {
|
||||
|
||||
// //if display mode is set to diff...
|
||||
// thevalue = library.StripHtml(p.Value.ToString());
|
||||
// Property cP = currentDoc.getProperty(p.PropertyType);
|
||||
// if (cP != null && cP.Value != null)
|
||||
// {
|
||||
|
||||
// string cThevalue = library.StripHtml(cP.Value.ToString());
|
||||
|
||||
// propertiesCompare.Text += "<tr><th style='width: 25%;' valign='top'>" + p.PropertyType.Name + ":</th><td>" + library.ReplaceLineBreaks(cms.businesslogic.utilities.Diff.Diff2Html(cThevalue, thevalue)) + "</td></tr>";
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //If no current version of the value... display with no diff.
|
||||
// propertiesCompare.Text += "<tr><th style='width: 25%;' valign='top'>" + p.PropertyType.Name + ":</th><td>" + thevalue + "</td></tr>";
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //If display mode is html
|
||||
// propertiesCompare.Text += "<tr><th style='width: 25%;' valign='top'>" + p.PropertyType.Name + ":</th><td>" + thevalue + "</td></tr>";
|
||||
// }
|
||||
|
||||
// //previewVersionContent.Controls.Add(new LiteralControl("<div style=\"margin-top: 4px; border: 1px solid #DEDEDE; padding: 4px;\"><p style=\"padding: 0px; margin: 0px;\" class=\"guiDialogNormal\"><b>" + p.PropertyType.Name + "</b><br/>"));
|
||||
// //previewVersionContent.Controls.Add(new LiteralControl(thevalue));
|
||||
|
||||
// }
|
||||
// //previewVersionContent.Controls.Add(new LiteralControl("</p></div>"));
|
||||
// }
|
||||
// catch { }
|
||||
// }
|
||||
|
||||
// Button1.Visible = true;
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// diffPanel.Visible = false;
|
||||
// Button1.Visible = false;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// protected void Page_Load(object sender, System.EventArgs e)
|
||||
// {
|
||||
|
||||
// if (String.IsNullOrEmpty(allVersions.SelectedValue))
|
||||
// rbl_mode.AutoPostBack = false;
|
||||
// else
|
||||
// rbl_mode.AutoPostBack = true;
|
||||
|
||||
// currentVersionTitle.Text = currentDoc.Text;
|
||||
// currentVersionMeta.Text = Services.TextService.Localize("content/createDate") + ": " + currentDoc.VersionDate.ToShortDateString() + " " + currentDoc.VersionDate.ToShortTimeString();
|
||||
|
||||
// if (!IsPostBack) {
|
||||
// allVersions.Items.Add(new ListItem(Services.TextService.Localize("rollback/selectVersion")+ "...", ""));
|
||||
|
||||
// foreach (DocumentVersionList dl in currentDoc.GetVersions())
|
||||
// {
|
||||
// //we don't need to show the current version
|
||||
// if (dl.Version == currentDoc.Version)
|
||||
// continue;
|
||||
//
|
||||
// allVersions.Items.Add(new ListItem(dl.Text + " (" + Services.TextService.Localize("content/createDate") + ": " + dl.Date.ToShortDateString() + " " + dl.Date.ToShortTimeString() + ")", dl.Version.ToString()));
|
||||
// }
|
||||
// Button1.Text = Services.TextService.Localize("actions/rollback");
|
||||
// }
|
||||
// }
|
||||
// protected void doRollback_Click(object sender, System.EventArgs e)
|
||||
// {
|
||||
// if (allVersions.SelectedValue.Trim() != "")
|
||||
// {
|
||||
// Document d = new Document(int.Parse(helper.Request("nodeId")));
|
||||
// d.RollBack(new Guid(allVersions.SelectedValue), Security.CurrentUser);
|
||||
|
||||
// BusinessLogic.Log.Add(BusinessLogic.LogTypes.RollBack, Security.CurrentUser, d.Id, "Version rolled back to revision '" + allVersions.SelectedValue + "'");
|
||||
|
||||
// Document rollback = new Document(d.Id, new Guid(allVersions.SelectedValue));
|
||||
// feedBackMsg.type = global::Umbraco.Web._Legacy.Controls.Feedback.feedbacktype.success;
|
||||
// string[] vars = {rollback.Text, rollback.VersionDate.ToLongDateString()};
|
||||
|
||||
// feedBackMsg.Text = ui.Text("rollback", "documentRolledBack", vars, new global::umbraco.BusinessLogic.User(0)) + "</p><p><a href='#' onclick='" + ClientTools.Scripts.CloseModalWindow() + "'>" + Services.TextService.Localize("closeThisWindow") + "</a>";
|
||||
// diffPanel.Visible = false;
|
||||
// pl_buttons.Visible = false;
|
||||
//
|
||||
// ClientTools.ReloadLocationIfMatched(string.Format("/content/content/edit/{0}", d.Id));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace umbraco.presentation.dialogs {
|
||||
|
||||
|
||||
public partial class rollBack {
|
||||
|
||||
/// <summary>
|
||||
/// JsInclude1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::ClientDependency.Core.Controls.JsInclude JsInclude1;
|
||||
|
||||
/// <summary>
|
||||
/// feedBackMsg control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Umbraco.Web._Legacy.Controls.Feedback feedBackMsg;
|
||||
|
||||
/// <summary>
|
||||
/// pp_selectVersion control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Umbraco.Web._Legacy.Controls.Pane pp_selectVersion;
|
||||
|
||||
/// <summary>
|
||||
/// pp_currentVersion control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_currentVersion;
|
||||
|
||||
/// <summary>
|
||||
/// currentVersionTitle control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal currentVersionTitle;
|
||||
|
||||
/// <summary>
|
||||
/// currentVersionMeta control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal currentVersionMeta;
|
||||
|
||||
/// <summary>
|
||||
/// pp_rollBackTo control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_rollBackTo;
|
||||
|
||||
/// <summary>
|
||||
/// allVersions control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.DropDownList allVersions;
|
||||
|
||||
/// <summary>
|
||||
/// pp_view control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_view;
|
||||
|
||||
/// <summary>
|
||||
/// rbl_mode control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.RadioButtonList rbl_mode;
|
||||
|
||||
/// <summary>
|
||||
/// diffPanel control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Panel diffPanel;
|
||||
|
||||
/// <summary>
|
||||
/// lt_notice control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal lt_notice;
|
||||
|
||||
/// <summary>
|
||||
/// propertiesCompare control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal propertiesCompare;
|
||||
|
||||
/// <summary>
|
||||
/// pl_buttons control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.HtmlControls.HtmlGenericControl pl_buttons;
|
||||
|
||||
/// <summary>
|
||||
/// Button1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Button Button1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user