Merge branch 'user-group-permissions' into temp-U4-10175

This commit is contained in:
Stephan
2017-07-26 15:18:37 +02:00
324 changed files with 410 additions and 16127 deletions
+4 -4
View File
@@ -16,19 +16,19 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
+34 -9
View File
@@ -118,7 +118,8 @@ namespace Umbraco.Core.Models.Membership
private DateTime _lastLoginDate;
private DateTime _lastLockoutDate;
private bool _defaultToLiveEditing;
private IDictionary<string, object> _additionalData;
private IDictionary<string, object> _additionalData;
private object _additionalDataLock = new object();
private static readonly Lazy<PropertySelectors> Ps = new Lazy<PropertySelectors>();
@@ -565,13 +566,23 @@ namespace Umbraco.Core.Models.Membership
/// <summary>
/// This is used as an internal cache for this entity - specifically for calculating start nodes so we don't re-calculated all of the time
/// </summary>
[IgnoreDataMember]
[IgnoreDataMember]
[DoNotClone]
internal IDictionary<string, object> AdditionalData
{
get { return _additionalData ?? (_additionalData = new Dictionary<string, object>()); }
get
{
lock (_additionalDataLock)
{
return _additionalData ?? (_additionalData = new Dictionary<string, object>());
}
}
}
[IgnoreDataMember]
[DoNotClone]
internal object AdditionalDataLock { get { return _additionalDataLock; } }
public override object DeepClone()
{
var clone = (User)base.DeepClone();
@@ -580,15 +591,29 @@ namespace Umbraco.Core.Models.Membership
//manually clone the start node props
clone._startContentIds = _startContentIds.ToArray();
clone._startMediaIds = _startMediaIds.ToArray();
//This ensures that any value in the dictionary that is deep cloneable is cloned too
foreach (var key in clone.AdditionalData.Keys.ToArray())
// this value has been cloned and points to the same object
// which obviously is bad - needs to point to a new object
clone._additionalDataLock = new object();
if (_additionalData != null)
{
var deepCloneable = clone.AdditionalData[key] as IDeepCloneable;
if (deepCloneable != null)
// clone._additionalData points to the same dictionary, which is bad, because
// changing one clone impacts all of them - so we need to reset it with a fresh
// dictionary that will contain the same values - and, if some values are deep
// cloneable, they should be deep-cloned too
var cloneAdditionalData = clone._additionalData = new Dictionary<string, object>();
lock (_additionalDataLock)
{
clone.AdditionalData[key] = deepCloneable.DeepClone();
foreach (var kvp in _additionalData)
{
var deepCloneable = kvp.Value as IDeepCloneable;
cloneAdditionalData[kvp.Key] = deepCloneable == null ? kvp.Value : deepCloneable.DeepClone();
}
}
}
}
//need to create new collections otherwise they'll get copied by ref
clone._userGroups = new HashSet<IReadOnlyUserGroup>(_userGroups);
clone._allowedSections = _allowedSections != null ? new List<string>(_allowedSections) : null;
+50 -33
View File
@@ -141,31 +141,23 @@ namespace Umbraco.Core.Models
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", "path");
var formattedPath = "," + path + ",";
var formattedRecycleBinId = "," + recycleBinId.ToInvariantString() + ",";
// check for no access
if (startNodeIds.Length == 0)
return false;
//check for root path access
//TODO: This logic may change
if (startNodeIds.Length == 0 || startNodeIds.Contains(Constants.System.Root))
// check for root access
if (startNodeIds.Contains(Constants.System.Root))
return true;
//only users with root access have access to the recycle bin so if the above check didn't pass than access is denied
if (formattedPath.Contains(formattedRecycleBinId))
{
var formattedPath = "," + path + ",";
// only users with root access have access to the recycle bin,
// if the above check didn't pass then access is denied
if (formattedPath.Contains("," + recycleBinId + ","))
return false;
}
//check for normal paths
foreach (var startNodeId in startNodeIds)
{
var formattedStartNodeId = "," + startNodeId.ToInvariantString() + ",";
var hasAccess = formattedPath.Contains(formattedStartNodeId);
if (hasAccess)
return true;
}
return false;
// check for a start node in the path
return startNodeIds.Any(x => formattedPath.Contains("," + x + ","));
}
/// <summary>
@@ -181,6 +173,7 @@ namespace Umbraco.Core.Models
return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.AdminGroupAlias);
}
// calc. start nodes, combining groups' and user's, and excluding what's in the bin
public static int[] CalculateContentStartNodeIds(this IUser user, IEntityService entityService)
{
const string cacheKey = "AllContentStartNodes";
@@ -195,6 +188,7 @@ namespace Umbraco.Core.Models
return vals;
}
// calc. start nodes, combining groups' and user's, and excluding what's in the bin
public static int[] CalculateMediaStartNodeIds(this IUser user, IEntityService entityService)
{
const string cacheKey = "AllMediaStartNodes";
@@ -212,22 +206,23 @@ namespace Umbraco.Core.Models
private static int[] FromUserCache(IUser user, string cacheKey)
{
var entityUser = user as User;
if (entityUser != null)
if (entityUser == null) return null;
lock (entityUser.AdditionalDataLock)
{
object allContentStartNodes;
if (entityUser.AdditionalData.TryGetValue(cacheKey, out allContentStartNodes))
{
var asArray = allContentStartNodes as int[];
if (asArray != null) return asArray;
}
return entityUser.AdditionalData.TryGetValue(cacheKey, out allContentStartNodes)
? allContentStartNodes as int[]
: null;
}
return null;
}
private static void ToUserCache(IUser user, string cacheKey, int[] vals)
{
var entityUser = user as User;
if (entityUser != null)
if (entityUser == null) return;
lock (entityUser.AdditionalDataLock)
{
entityUser.AdditionalData[cacheKey] = vals;
}
@@ -238,7 +233,23 @@ namespace Umbraco.Core.Models
return test.StartsWith(path) && test.Length > path.Length && test[path.Length] == ',';
}
//TODO: Unit test this
private static string GetBinPath(UmbracoObjectTypes objectType)
{
var binPath = Constants.System.Root + ",";
switch (objectType)
{
case UmbracoObjectTypes.Document:
binPath += Constants.System.RecycleBinContent;
break;
case UmbracoObjectTypes.Media:
binPath += Constants.System.RecycleBinMedia;
break;
default:
throw new ArgumentOutOfRangeException("objectType");
}
return binPath;
}
internal static int[] CombineStartNodes(UmbracoObjectTypes objectType, int[] groupSn, int[] userSn, IEntityService entityService)
{
// assume groupSn and userSn each don't contain duplicates
@@ -246,13 +257,17 @@ namespace Umbraco.Core.Models
var asn = groupSn.Concat(userSn).Distinct().ToArray();
var paths = entityService.GetAllPaths(objectType, asn).ToDictionary(x => x.Id, x => x.Path);
paths[-1] = "-1"; // entityService does not get that one
paths[Constants.System.Root] = Constants.System.Root.ToString(); // entityService does not get that one
var binPath = GetBinPath(objectType);
var lsn = new List<int>();
foreach (var sn in groupSn)
{
string snp;
if (paths.TryGetValue(sn, out snp) == false) continue; // ignore
if (paths.TryGetValue(sn, out snp) == false) continue; // ignore rogue node (no path)
if (StartsWithPath(snp, binPath)) continue; // ignore bin
if (lsn.Any(x => StartsWithPath(snp, paths[x]))) continue; // skip if something above this sn
lsn.RemoveAll(x => StartsWithPath(paths[x], snp)); // remove anything below this sn
@@ -262,10 +277,12 @@ namespace Umbraco.Core.Models
var usn = new List<int>();
foreach (var sn in userSn)
{
if (groupSn.Contains(sn)) continue;
if (groupSn.Contains(sn)) continue; // ignore, already there
string snp;
if (paths.TryGetValue(sn, out snp) == false) continue; // ignore
if (paths.TryGetValue(sn, out snp) == false) continue; // ignore rogue node (no path)
if (StartsWithPath(snp, binPath)) continue; // ignore bin
if (usn.Any(x => StartsWithPath(paths[x], snp))) continue; // skip if something below this sn
usn.RemoveAll(x => StartsWithPath(snp, paths[x])); // remove anything above this sn
@@ -94,8 +94,18 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSevenZe
WHERE u.id = 0");
// Rename some groups for consistency (plural form)
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Writers' WHERE userGroupName = 'Writer'");
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Translators' WHERE userGroupName = 'Translator'");
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Writers' WHERE userGroupAlias = 'writer'");
Execute.Sql("UPDATE umbracoUserGroup SET userGroupName = 'Translators' WHERE userGroupAlias = 'translator'");
//Ensure all built in groups have a start node of -1
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'editor'");
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'editor'");
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'writer'");
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'writer'");
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'translator'");
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'translator'");
Execute.Sql("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'admin'");
Execute.Sql("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'admin'");
}
private void MigrateUserPermissions()
+7 -1
View File
@@ -370,13 +370,19 @@ namespace Umbraco.Core.Services
public IEnumerable<IUmbracoEntity> GetPagedDescendants(IEnumerable<int> ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "")
{
totalRecords = 0;
var idsA = ids.ToArray();
if (idsA.Length == 0)
return Enumerable.Empty<IUmbracoEntity>();
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder;
var idsA = ids.ToArray();
if (idsA.All(x => x != Constants.System.Root))
{
var clauses = new List<Expression<Func<IUmbracoEntity, bool>>>();
+8 -12
View File
@@ -70,21 +70,17 @@
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.Owin.Security, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
+4 -4
View File
@@ -16,19 +16,19 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
+4 -4
View File
@@ -7,10 +7,10 @@
<package id="Log4Net.Async" version="2.0.4" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.1.0" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.9.9" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
+4 -4
View File
@@ -13,19 +13,19 @@
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+2 -2
View File
@@ -165,7 +165,7 @@
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
@@ -181,7 +181,7 @@
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
</dependentAssembly>
+30 -19
View File
@@ -14,12 +14,15 @@ namespace Umbraco.Tests.Models
[TestFixture]
public class UserExtensionsTests
{
[TestCase(2, "-1,1,2", "-1,1,2,3,4,5", true)]
[TestCase(6, "-1,1,2,3,4,5,6", "-1,1,2,3,4,5", false)]
[TestCase(-1, "-1", "-1,1,2,3,4,5", true)]
[TestCase(5, "-1,1,2,3,4,5", "-1,1,2,3,4,5", true)]
[TestCase(-1, "-1", "-1,-20,1,2,3,4,5", true)]
[TestCase(1, "-1,-20,1", "-1,-20,1,2,3,4,5", false)]
[TestCase(-1, "-1", "-1,1,2,3,4,5", true)] // below root start node
[TestCase(2, "-1,1,2", "-1,1,2,3,4,5", true)] // below start node
[TestCase(5, "-1,1,2,3,4,5", "-1,1,2,3,4,5", true)] // at start node
[TestCase(6, "-1,1,2,3,4,5,6", "-1,1,2,3,4,5", false)] // above start node
[TestCase(-1, "-1", "-1,-20,1,2,3,4,5", true)] // below root start node, bin
[TestCase(1, "-1,-20,1", "-1,-20,1,2,3,4,5", false)] // below bin start node
public void Determines_Path_Based_Access_To_Content(int startNodeId, string startNodePath, string contentPath, bool outcome)
{
var userMock = new Mock<IUser>();
@@ -27,15 +30,12 @@ namespace Umbraco.Tests.Models
var user = userMock.Object;
var content = Mock.Of<IContent>(c => c.Path == contentPath && c.Id == 5);
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[]
{
Mock.Of<IUmbracoEntity>(entity => entity.Id == startNodeId && entity.Path == startNodePath)
});
var entityService = entityServiceMock.Object;
var esmock = new Mock<IEntityService>();
esmock
.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns<UmbracoObjectTypes, int[]>((type, ids) => new [] { new EntityPath { Id = startNodeId, Path = startNodePath } });
Assert.AreEqual(outcome, user.HasPathAccess(content, entityService));
Assert.AreEqual(outcome, user.HasPathAccess(content, esmock.Object));
}
[TestCase("", "1", "1")] // single user start, top level
@@ -52,6 +52,9 @@ namespace Umbraco.Tests.Models
[TestCase("3", "2,5", "2,5")] // user and group start, restrict
[TestCase("3", "2,1", "2,1")] // user and group start, expand
[TestCase("3,8", "2,6", "3,2")] // exclude bin
[TestCase("", "6", "")] // exclude bin
public void CombineStartNodes(string groupSn, string userSn, string expected)
{
// 1
@@ -59,15 +62,23 @@ namespace Umbraco.Tests.Models
// 5
// 2
// 4
// bin
// 6
// 7
// 8
var paths = new Dictionary<int, string>
{
{ 1, "-1, 1" },
{ 2, "-1, 2" },
{ 3, "-1, 1, 3" },
{ 4, "-1, 2, 4" },
{ 5, "-1, 1, 3, 5" },
{ 1, "-1,1" },
{ 2, "-1,2" },
{ 3, "-1,1,3" },
{ 4, "-1,2,4" },
{ 5, "-1,1,3,5" },
{ 6, "-1,-20,6" },
{ 7, "-1,-20,7" },
{ 8, "-1,-20,7,8" },
};
var esmock = new Mock<IEntityService>();
esmock
.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
@@ -27,15 +27,12 @@ namespace Umbraco.Tests.UI
}
[TestCase(typeof(XsltTasks), DefaultApps.developer)]
[TestCase(typeof(templateTasks), DefaultApps.settings)]
[TestCase(typeof(StylesheetTasks), DefaultApps.settings)]
[TestCase(typeof(stylesheetPropertyTasks), DefaultApps.settings)]
[TestCase(typeof(ScriptTasks), DefaultApps.settings)]
[TestCase(typeof(MemberGroupTasks), DefaultApps.member)]
[TestCase(typeof(dictionaryTasks), DefaultApps.settings)]
[TestCase(typeof(macroTasks), DefaultApps.developer)]
[TestCase(typeof(languageTasks), DefaultApps.settings)]
[TestCase(typeof(DLRScriptingTasks), DefaultApps.developer)]
[TestCase(typeof(CreatedPackageTasks), DefaultApps.developer)]
public void Check_Assigned_Apps_For_Tasks(Type taskType, DefaultApps app)
{
@@ -19,6 +19,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
@@ -83,8 +84,8 @@ namespace Umbraco.Tests.Web.Controllers
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234")).Returns(permissionSet);
var userService = userServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 9876 && entity.Path == "-1,9876") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 9876 && entity.Path == "-1,9876") });
var entityService = entityServiceMock.Object;
//act
@@ -131,6 +132,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var contentMock = new Mock<IContent>();
contentMock.Setup(c => c.Path).Returns("-1,1234,5678");
@@ -162,6 +164,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] {new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>())});
var user = userMock.Object;
var contentServiceMock = new Mock<IContentService>();
var contentService = contentServiceMock.Object;
@@ -183,6 +186,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var contentServiceMock = new Mock<IContentService>();
var contentService = contentServiceMock.Object;
@@ -211,8 +215,8 @@ namespace Umbraco.Tests.Web.Controllers
var userServiceMock = new Mock<IUserService>();
var userService = userServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
var entityService = entityServiceMock.Object;
//act
@@ -235,8 +239,8 @@ namespace Umbraco.Tests.Web.Controllers
var userServiceMock = new Mock<IUserService>();
var userService = userServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
var entityService = entityServiceMock.Object;
//act
@@ -252,6 +256,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
@@ -309,6 +314,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var userServiceMock = new Mock<IUserService>();
@@ -92,8 +92,8 @@ namespace Umbraco.Tests.Web.Controllers
var userServiceMock = new Mock<IUserService>();
var userService = userServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 5 && entity.Path == "-1,5") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 5 && entity.Path == "-1,5") });
var entityService = entityServiceMock.Object;
var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable<ContentItemBasic>), userService, entityService);
@@ -19,6 +19,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(9);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var mediaMock = new Mock<IMedia>();
mediaMock.Setup(m => m.Path).Returns("-1,1234,5678");
@@ -71,8 +72,8 @@ namespace Umbraco.Tests.Web.Controllers
mediaServiceMock.Setup(x => x.GetById(1234)).Returns(media);
var mediaService = mediaServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] {Mock.Of<IUmbracoEntity>(entity => entity.Id == 9876 && entity.Path == "-1,9876")});
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] {Mock.Of<EntityPath>(entity => entity.Id == 9876 && entity.Path == "-1,9876")});
var entityService = entityServiceMock.Object;
//act
@@ -88,6 +89,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
var mediaService = mediaServiceMock.Object;
@@ -112,8 +114,8 @@ namespace Umbraco.Tests.Web.Controllers
var mediaServiceMock = new Mock<IMediaService>();
var mediaService = mediaServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
var entityService = entityServiceMock.Object;
//act
@@ -129,6 +131,7 @@ namespace Umbraco.Tests.Web.Controllers
//arrange
var userMock = new Mock<IUser>();
userMock.Setup(u => u.Id).Returns(0);
userMock.Setup(u => u.Groups).Returns(new[] { new ReadOnlyUserGroup(1, "admin", "", -1, -1, "admin", new string[0], new List<string>()) });
var user = userMock.Object;
var mediaServiceMock = new Mock<IMediaService>();
var mediaService = mediaServiceMock.Object;
@@ -153,8 +156,8 @@ namespace Umbraco.Tests.Web.Controllers
var mediaServiceMock = new Mock<IMediaService>();
var mediaService = mediaServiceMock.Object;
var entityServiceMock = new Mock<IEntityService>();
entityServiceMock.Setup(x => x.GetAll(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<IUmbracoEntity>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
entityServiceMock.Setup(x => x.GetAllPaths(It.IsAny<UmbracoObjectTypes>(), It.IsAny<int[]>()))
.Returns(new[] { Mock.Of<EntityPath>(entity => entity.Id == 1234 && entity.Path == "-1,1234") });
var entityService = entityServiceMock.Object;
//act
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "Umbraco",
"name": "umbraco",
"version": "7",
"homepage": "https://github.com/umbraco/Umbraco-CMS",
"authors": [
@@ -1,69 +0,0 @@
/**
* editor_plugin_src.js
*
* Copyright 2012, Umbraco
* Released under MIT License.
*
* License: http://opensource.org/licenses/mit-license.html
*/
(function () {
var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM;
/**
* This plugin modifies the standard TinyMCE context menu, with umbraco specific changes.
*
* @class tinymce.plugins.umbContextMenu
*/
tinymce.create('tinymce.plugins.UmbracoContextMenu', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @method init
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init: function (ed) {
if (ed.plugins.contextmenu) {
ed.plugins.contextmenu.onContextMenu.add(function (th, menu, event) {
var keys = UmbClientMgr.uiKeys();
$.each(menu.items, function (idx, el) {
switch (el.settings.cmd) {
case "Cut":
el.settings.title = keys['defaultdialogs_cut'];
break;
case "Copy":
el.settings.title = keys['general_copy'];
break;
case "Paste":
el.settings.title = keys['defaultdialogs_paste'];
break;
case "mceAdvLink":
case "mceLink":
el.settings.title = keys['defaultdialogs_insertlink'];
break;
case "UnLink":
el.settings.title = keys['relatedlinks_removeLink'];
break;
case "mceImage":
el.settings.title = keys['defaultdialogs_insertimage'];
el.settings.cmd = "mceUmbimage";
break;
}
});
});
}
}
});
// Register plugin
tinymce.PluginManager.add('umbracocontextmenu', tinymce.plugins.UmbracoContextMenu);
})();
@@ -1,69 +0,0 @@
/**
* editor_plugin_src.js
*
* Copyright 2012, Umbraco
* Released under MIT License.
*
* License: http://opensource.org/licenses/mit-license.html
*/
(function () {
var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM;
/**
* This plugin modifies the standard TinyMCE context menu, with umbraco specific changes.
*
* @class tinymce.plugins.umbContextMenu
*/
tinymce.create('tinymce.plugins.UmbracoContextMenu', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @method init
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init: function (ed) {
if (ed.plugins.contextmenu) {
ed.plugins.contextmenu.onContextMenu.add(function (th, menu, event) {
var keys = UmbClientMgr.uiKeys();
$.each(menu.items, function (idx, el) {
switch (el.settings.cmd) {
case "Cut":
el.settings.title = keys['defaultdialogs_cut'];
break;
case "Copy":
el.settings.title = keys['general_copy'];
break;
case "Paste":
el.settings.title = keys['defaultdialogs_paste'];
break;
case "mceAdvLink":
case "mceLink":
el.settings.title = keys['defaultdialogs_insertlink'];
break;
case "UnLink":
el.settings.title = keys['relatedlinks_removeLink'];
break;
case "mceImage":
el.settings.title = keys['defaultdialogs_insertimage'];
el.settings.cmd = "mceUmbimage";
break;
}
});
});
}
}
});
// Register plugin
tinymce.PluginManager.add('umbracocontextmenu', tinymce.plugins.UmbracoContextMenu);
})();
Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 B

@@ -1,19 +0,0 @@
tinyMCEPopup.requireLangPack();
var ExampleDialog = {
init : function() {
var f = document.forms[0];
// Get the selected contents as text and place it in the input
f.someval.value = tinyMCEPopup.editor.selection.getContent({format : 'text'});
f.somearg.value = tinyMCEPopup.getWindowArg('some_custom_arg');
},
insert : function() {
// Insert the contents from the input into the document
tinyMCEPopup.editor.execCommand('mceInsertContent', false, document.forms[0].someval.value);
tinyMCEPopup.close();
}
};
tinyMCEPopup.onInit.add(ExampleDialog.init, ExampleDialog);
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en.example',{
desc : 'This is just a template button'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en.example_dlg',{
title : 'This is just a example title'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en_us.example',{
desc : 'This is just a template button'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en_us.example_dlg',{
title : 'This is just a example title'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('it.example',{
desc : 'Esempio di pulsante'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('it.example_dlg',{
title : 'Esempio di titolo'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ja.example',{
desc : 'これはテンプレートボタンです'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ja.example_dlg',{
title : 'これは見出しの例です'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ru.example',{
desc : 'Это просто образец кнопки'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ru.example_dlg',{
title : 'Это просто пример заголовка'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('sv.example',{
desc : 'Detta är bara en mallknapp'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('sv.example_dlg',{
title : 'Detta är bara ett exempel på en titel'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('zh.example',{
desc : '这是示例按钮'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('zh.example_dlg',{
title : '这是示例标题'
});
@@ -1,182 +0,0 @@
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @author Moxiecode
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function () {
// Load plugin specific language pack
// tinymce.PluginManager.requireLangPack('umbraco');
tinymce.create('tinymce.plugins.umbracocss', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init: function (ed, url) {
this.editor = ed;
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
ed.addCommand('mceumbracosetstyle', function () {
alert('blah');
});
// Add a node change handler, selects the button in the UI when a image is selected
ed.onNodeChange.add(function (ed, cm, n) {
var c = cm.get('umbracostyles');
var formatSelected = false;
if (c) {
// check for element
var el = tinymce.DOM.getParent(n, ed.dom.isBlock);
if (el) {
for (var i = 0; i < c.items.length; i++) {
if (c.items[i].value == el.nodeName.toLowerCase()) {
c.select(el.nodeName.toLowerCase());
formatSelected = true;
}
}
}
// check for class
if (n.className != '') {
if (c) {
c.select('.' + n.className);
}
} else if (c && !formatSelected) {
c.select(); // reset selector if no class or block elements
}
}
/* if (c = cm.get('styleselect')) {
if (n.className) {
t._importClasses();
c.select(n.className);
} else
c.select();
}
if (c = cm.get('formatselect')) {
p = DOM.getParent(n, DOM.isBlock);
if (p)
c.select(p.nodeName.toLowerCase());
}
*/
});
},
/**
* Creates control instances based in the incomming name. This method is normally not
* needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
* but you sometimes need to create more complex controls like listboxes, split buttons etc then this
* method can be used to create those.
*
* @param {String} n Name of the control to create.
* @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
* @return {tinymce.ui.Control} New control instance or null if no control was created.
*/
createControl: function (n, cm) {
// add style dropdown
if (n == 'umbracocss') {
var umbracoStyles = this.editor.getParam('theme_umbraco_styles').split(';');
var styles = cm.createListBox('umbracostyles', {
title: this.editor.getLang('umbraco.style_select'),
onselect: function (v) {
if (v == '') {
if (styles.selectedValue.indexOf('.') == 0) {
// remove style
var selectedStyle = styles.selectedValue;
var styleObj = tinymce.activeEditor.formatter.get('umb' + selectedStyle.substring(1, selectedStyle.length));
if (styleObj == undefined) {
tinymce.activeEditor.formatter.register('umb' + selectedStyle.substring(1, selectedStyle.length), {
inline: 'span',
selector: '*',
classes: selectedStyle.substring(1, selectedStyle.length)
});
}
tinyMCE.activeEditor.formatter.remove('umb' + selectedStyle.substring(1, selectedStyle.length));
// tinymce.activeEditor.execCommand('mceSetStyleInfo', 0, { command: 'removeformat' });
} else {
// remove block element
tinymce.activeEditor.execCommand('FormatBlock', false, 'p');
}
}
else if (v.indexOf('.') != '0') {
tinymce.activeEditor.execCommand('FormatBlock', false, v);
} else {
// use new formatting engine
if (tinymce.activeEditor.formatter.get('umb' + v.substring(1, v.length)) == undefined) {
tinymce.activeEditor.formatter.register('umb' + v.substring(1, v.length), {
inline: 'span',
selector: '*',
classes: v.substring(1, v.length)
});
}
var styleObj = tinymce.activeEditor.formatter.get('umb' + v.substring(1, v.length));
tinyMCE.activeEditor.formatter.apply('umb' + v.substring(1, v.length));
// tinyMCE.activeEditor.execCommand('mceSetCSSClass', false, v.substring(1, v.length));
}
return false;
}
});
// add styles
for (var i = 0; i < umbracoStyles.length; i++) {
if (umbracoStyles[i] != '') {
var name = umbracoStyles[i].substring(0, umbracoStyles[i].indexOf("="));
var alias = umbracoStyles[i].substring(umbracoStyles[i].indexOf("=") + 1, umbracoStyles[i].length);
if (alias.indexOf('.') < 0)
alias = alias.toLowerCase();
else if (alias.length > 1) {
// register with new formatter engine (can't access from here so a hack in the set style above!)
// tinyMCE.activeEditor.formatter.register('umb' + alias.substring(1, alias.length), {
// classes: alias.substring(1, alias.length)
// });
}
styles.add(name, alias);
}
}
return styles;
}
return null;
},
/**
* Returns information about the plugin as a name/value array.
* The current keys are longname, author, authorurl, infourl and version.
*
* @return {Object} Name/value array containing information about the plugin.
*/
getInfo: function () {
return {
longname: 'Umbraco CSS/Styling Plugin',
author: 'Umbraco',
authorurl: 'http://umbraco.org',
infourl: 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',
version: "1.0"
};
}
});
// Register plugin
tinymce.PluginManager.add('umbracocss', tinymce.plugins.umbracocss);
})();
@@ -1,92 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#embed_dlg.title}</title>
<script type="text/javascript" src="../../../ui/jquery.js"></script>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="js/dialog.js"></script>
<script type="text/javascript" src="../../utils/mctabs.js"></script>
<style>
#previewContainer
{
height:195px;
width:550px;
overflow:auto;
}
#source
{
width:99%;
height:270px;
}
#url
{
width:400px;
}
.size
{
width:50px;
}
</style>
</head>
<body>
<form onsubmit="UmbracoEmbedDialog.insert();return false;" action="#">
<div class="tabs" role="presentation">
<ul>
<li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#embed_dlg.general}</a></span></li>
<li id="source_tab" aria-controls="source_panel"><span><a href="javascript:mcTabs.displayTab('source_tab','source_panel');" onmousedown="return false;">{#embed_dlg.source}</a></span></li>
</ul>
</div>
<div class="panel_wrapper">
<div id="general_panel" class="panel current">
<fieldset>
<legend>{#embed_dlg.general}</legend>
<table role="presentation" border="0" cellpadding="4" cellspacing="0">
<tr>
<td><label for="media_type">{#embed_dlg.url}</label></td>
<td>
<input type="text" id="url" onChange="UmbracoEmbedDialog.showPreview()"/>
</td>
</tr>
<tr id="dimensions">
<td><label for="width">{#embed_dlg.size}</label></td>
<td>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><input type="text" id="width" name="width" value="500" class="size" onchange="UmbracoEmbedDialog.changeSize('width');" onfocus="UmbracoEmbedDialog.beforeResize();"/> x <input type="text" id="height" name="height" value="300" class="size" onchange="UmbracoEmbedDialog.changeSize('height');" onfocus="UmbracoEmbedDialog.beforeResize();" /></td>
<td>&nbsp;&nbsp;<input id="constrain" type="checkbox" name="constrain" class="checkbox" checked="checked" /></td>
<td><label id="constrainlabel" for="constrain">{#embed_dlg.constrain_proportions}</label></td>
</tr>
</table>
</td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>{#embed_dlg.preview}</legend>
<div id="previewContainer">
<div id="preview">
</div>
</div>
</fieldset>
</div>
<div id="source_panel" class="panel">
<fieldset>
<legend>{#embed_dlg.source}</legend>
<textarea id="source" onkeyup="UmbracoEmbedDialog.changeSource();" onchange="UmbracoEmbedDialog.updatePreviewFromSource();"></textarea>
</fieldset>
</div>
</div>
<div class="mceActionPanel">
<input type="button" id="insert" name="insert" value="{#insert}" onclick="UmbracoEmbedDialog.insert();" disabled="disabled"/>
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</form>
</body>
</html>
@@ -1 +0,0 @@
(function(){tinymce.PluginManager.requireLangPack("example");tinymce.create("tinymce.plugins.ExamplePlugin",{init:function(a,b){a.addCommand("mceExample",function(){a.windowManager.open({file:b+"/dialog.htm",width:320+parseInt(a.getLang("example.delta_width",0)),height:120+parseInt(a.getLang("example.delta_height",0)),inline:1},{plugin_url:b,some_custom_arg:"custom arg"})});a.addButton("example",{title:"example.desc",cmd:"mceExample",image:b+"/img/example.gif"});a.onNodeChange.add(function(d,c,e){c.setActive("example",e.nodeName=="IMG")})},createControl:function(b,a){return null},getInfo:function(){return{longname:"Example plugin",author:"Some author",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example",version:"1.0"}}});tinymce.PluginManager.add("example",tinymce.plugins.ExamplePlugin)})();
@@ -1,84 +0,0 @@
/**
* editor_plugin_src.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://tinymce.moxiecode.com/license
* Contributing: http://tinymce.moxiecode.com/contributing
*/
(function() {
// Load plugin specific language pack
tinymce.PluginManager.requireLangPack('umbracoembed');
tinymce.create('tinymce.plugins.umbracoembed', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init : function(ed, url) {
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
ed.addCommand('mceUmbracoEmbed', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 600 + parseInt(ed.getLang('example.delta_width', 0)),
height : 400 + parseInt(ed.getLang('example.delta_height', 0)),
inline : 1
}, {
plugin_url : url, // Plugin absolute URL
some_custom_arg : 'custom arg' // Custom argument
});
});
// Register example button
ed.addButton('umbracoembed', {
title : 'umbracoembed.desc',
cmd : 'mceUmbracoEmbed',
image : url + '/img/embed.gif'
});
// Add a node change handler, selects the button in the UI when a image is selected
/*ed.onNodeChange.add(function(ed, cm, n) {
cm.setActive('example', n.nodeName == 'IMG');
});*/
},
/**
* Creates control instances based in the incomming name. This method is normally not
* needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
* but you sometimes need to create more complex controls like listboxes, split buttons etc then this
* method can be used to create those.
*
* @param {String} n Name of the control to create.
* @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
* @return {tinymce.ui.Control} New control instance or null if no control was created.
*/
createControl : function(n, cm) {
return null;
},
/**
* Returns information about the plugin as a name/value array.
* The current keys are longname, author, authorurl, infourl and version.
*
* @return {Object} Name/value array containing information about the plugin.
*/
getInfo : function() {
return {
longname : 'Umbraco Embed',
author : 'Tim Geyssens',
authorurl : 'http://http://umbraco.com/',
infourl : 'http://http://umbraco.com/',
version : "1.0"
};
}
});
// Register plugin
tinymce.PluginManager.add('umbracoembed', tinymce.plugins.umbracoembed);
})();
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

@@ -1,90 +0,0 @@
tinyMCEPopup.requireLangPack();
var UmbracoEmbedDialog = {
insert: function () {
// Insert the contents from the input into the document
tinyMCEPopup.editor.execCommand('mceInsertContent', false, $('#source').val());
tinyMCEPopup.close();
},
showPreview: function () {
$('#insert').attr('disabled', 'disabled');
var url = $('#url').val();
var width = $('#width').val(); ;
var height = $('#height').val(); ;
$('#preview').html('<img src="img/ajax-loader.gif" alt="loading"/>');
$('#source').val('');
$.ajax({
type: 'POST',
async: true,
url: '../../../../base/EmbedMediaService/Embed/',
data: { url: url, width: width, height: height },
dataType: 'json',
success: function (result) {
switch (result.Status) {
case 0:
//not supported
$('#preview').html('Not Supported');
break;
case 1:
//error
$('#preview').html('Error');
break;
case 2:
$('#preview').html(result.Markup);
$('#source').val(result.Markup);
if (result.SupportsDimensions) {
$('#dimensions').show();
} else {
$('#dimensions').hide();
}
$('#insert').removeAttr('disabled');
break;
}
},
error: function (xhr, ajaxOptions, thrownError) {
$('#preview').html("Error");
}
});
},
beforeResize: function () {
this.width = parseInt($('#width').val(), 10);
this.height = parseInt($('#height').val(), 10);
},
changeSize: function (type) {
var width, height, scale, size;
if ($('#constrain').is(':checked')) {
width = parseInt($('#width').val(), 10);
height = parseInt($('#height').val(), 10);
if (type == 'width') {
this.height = Math.round((width / this.width) * height);
$('#height').val(this.height);
} else {
this.width = Math.round((height / this.height) * width);
$('#width').val(this.width);
}
}
if ($('#url').val() != '') {
UmbracoEmbedDialog.showPreview();
}
},
changeSource: function (type) {
if ($('#source').val() != '') {
$('#insert').removeAttr('disabled');
}
else {
$('#insert').attr('disabled', 'disabled');
}
},
updatePreviewFromSource: function (type) {
var sourceVal = $('#source').val();
if (sourceVal != '') {
$('#preview').html(sourceVal);
}
}
};
@@ -1,3 +0,0 @@
tinyMCE.addI18n('da.umbracoembed', {
desc: 'Inds\u00E6t ekstern mediefil'
});
@@ -1,9 +0,0 @@
tinyMCE.addI18n('da.embed_dlg', {
title: 'Inds\u00E6t ekstern mediefil',
general: 'Generelt',
url: 'Url:',
size: 'Dimensioner:',
constrain_proportions: 'Bevar proportioner',
preview: 'Vis',
source: 'Vis kilde'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('de.embed_dlg', {
title: 'Medien von Drittanbietern einbetten',
general: 'Allgemein',
url: 'Url:',
size: 'Abmessungen:',
constrain_proportions: 'Proportionen beibehalten',
preview: 'Vorschau',
source: 'Quellcode'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('de.embed_dlg', {
title: 'Medien von Drittanbietern einbetten',
general: 'Allgemein',
url: 'Url:',
size: 'Abmessungen:',
constrain_proportions: 'Proportionen beibehalten',
preview: 'Vorschau',
source: 'Quellcode'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en.umbracoembed', {
desc: 'Embed third party media'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('en.embed_dlg', {
title: 'Embed third party media',
general: 'General',
url: 'Url:',
size: 'Size:',
constrain_proportions: 'Constrain',
preview: 'Preview',
source: 'Source'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en_us.umbracoembed', {
desc: 'Embed third party media'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('en_us.embed_dlg', {
title: 'Embed third party media',
general: 'General',
url: 'Url:',
size: 'Size:',
constrain_proportions: 'Constrain',
preview: 'Preview',
source: 'Source'
});
@@ -1,9 +0,0 @@
tinyMCE.addI18n('en.embed_dlg', {
title: 'Integra media di terze parti',
general: 'Generale',
url: 'Url:',
size: 'Dimensione:',
constrain_proportions: 'Vincolo',
preview: 'Anteprima',
source: 'Sorgente'
});
@@ -1,9 +0,0 @@
tinyMCE.addI18n('it.embed_dlg', {
title: 'Integra media di terze parti',
general: 'Generale',
url: 'Url:',
size: 'Dimensione:',
constrain_proportions: 'Vincolo',
preview: 'Anteprima',
source: 'Sorgente'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('ja.embed_dlg', {
title: 'サードパーティメディアの埋め込み',
general: '一般',
url: 'Url:',
size: 'サイズ:',
constrain_proportions: '制約',
preview: 'プレビュー',
source: 'ソース'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('ja.embed_dlg', {
title: サードパーティメディアの埋め込み',
general: '一般',
url: 'Url:',
size: 'サイズ:',
constrain_proportions: '制約',
preview: 'プレビュー',
source: 'ソース'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('ru.embed_dlg', {
title: 'Вставить внеший элемент медиа',
general: 'Общее',
url: 'Ссылка:',
size: 'Размер:',
constrain_proportions: 'Сохранять пропорции',
preview: 'Просмотр',
source: 'Источник'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('ru.embed_dlg', {
title: 'Вставить внеший элемент медиа',
general: 'Общее',
url: 'Ссылка:',
size: 'Размер:',
constrain_proportions: 'Сохранять пропорции',
preview: 'Просмотр',
source: 'Источник'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('sv.embed_dlg', {
title: 'Bädda in tredjeparts media',
general: 'Generell',
url: 'Url:',
size: 'Storlek:',
constrain_proportions: 'Bibehåll proportioner',
preview: 'Förhandsgranska',
source: 'Källa'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('sv.embed_dlg', {
title: 'Bädda in tredjeparts media',
general: 'Generell',
url: 'Url:',
size: 'Storlek:',
constrain_proportions: 'Bibehåll proportioner',
preview: 'Förhandsgranska',
source: 'Källa'
});
@@ -1,10 +0,0 @@
tinyMCE.addI18n('zh.embed_dlg', {
title: '嵌入第三方媒体',
general: '普通',
url: '链接:',
size: '尺寸:',
constrain_proportions: '约束比例',
preview: '预览',
source: '源'
});
@@ -1,9 +0,0 @@
tinyMCE.addI18n('zh.embed_dlg', {
title: '嵌入第三方媒体',
general: '普通',
url: '链接:',
size: '尺寸:',
constrain_proportions: '约束比例',
preview: '预览',
source: '源'
});
@@ -1,52 +0,0 @@
/**
* $Id: editor_plugin_src.js 677 2008-03-07 13:52:41Z spocke $
*
* @author Moxiecode
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function() {
// tinymce.PluginManager.requireLangPack('umbraco');
tinymce.create('tinymce.plugins.UmbracoImagePlugin', {
init: function(ed, url) {
// Register commands
ed.addCommand('mceUmbimage', function() {
// Internal image object like a flash placeholder
if (ed.dom.getAttrib(ed.selection.getNode(), 'class').indexOf('mceItem') != -1)
return;
ed.windowManager.open({
/* UMBRACO SPECIFIC: Load Umbraco modal window */
file: tinyMCE.activeEditor.getParam('umbraco_path') + '/plugins/tinymce3/insertImage.aspx',
width: 575 + ed.getLang('umbracoimg.delta_width', 0),
height: 505 + ed.getLang('umbracoimg.delta_height', 0),
inline: 1
}, {
plugin_url: url
});
});
// Register buttons
ed.addButton('image', {
title: 'advimage.image_desc',
cmd: 'mceUmbimage'
});
},
getInfo: function() {
return {
longname: 'Umbraco image dialog',
author: 'Umbraco',
authorurl: 'http://umbraco.org',
infourl: 'http://umbraco.org',
version: "1.0"
};
}
});
// Register plugin
tinymce.PluginManager.add('umbracoimg', tinymce.plugins.UmbracoImagePlugin);
})();
@@ -1,332 +0,0 @@
var ImageDialog = {
preInit: function() {
var url;
tinyMCEPopup.requireLangPack();
if (url = tinyMCEPopup.getParam("external_image_list_url"))
document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');
},
init: function(ed) {
var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, dom = ed.dom, n = ed.selection.getNode();
tinyMCEPopup.resizeToInnerSize();
if (n.nodeName == 'IMG') {
nl.src.value = dom.getAttrib(n, 'src');
nl.width.value = dom.getAttrib(n, 'width');
nl.height.value = dom.getAttrib(n, 'height');
nl.alt.value = dom.getAttrib(n, 'alt');
nl.orgHeight.value = dom.getAttrib(n, 'rel').split(",")[1];
nl.orgWidth.value = dom.getAttrib(n, 'rel').split(",")[0];
}
// If option enabled default contrain proportions to checked
if ((ed.getParam("advimage_constrain_proportions", true)) && f.constrain)
f.constrain.checked = true;
this.changeAppearance();
this.showPreviewImage(nl.src.value, 1);
},
insert: function(file, title) {
var ed = tinyMCEPopup.editor, t = this, f = document.forms[0];
if (f.src.value === '') {
if (ed.selection.getNode().nodeName == 'IMG') {
ed.dom.remove(ed.selection.getNode());
ed.execCommand('mceRepaint');
}
tinyMCEPopup.close();
return;
}
if (tinyMCEPopup.getParam("accessibility_warnings", 1)) {
if (!f.alt.value) {
tinyMCEPopup.confirm(tinyMCEPopup.getLang('advimage_dlg.missing_alt'), function(s) {
if (s)
t.insertAndClose();
});
return;
}
}
t.insertAndClose();
},
insertAndClose: function() {
var ed = tinyMCEPopup.editor, f = document.forms[0], nl = f.elements, v, args = {}, el;
tinyMCEPopup.restoreSelection();
// Fixes crash in Safari
if (tinymce.isWebKit)
ed.getWin().focus();
if (!ed.settings.inline_styles) {
args = {
vspace: nl.vspace.value,
hspace: nl.hspace.value,
border: nl.border.value,
align: getSelectValue(f, 'align')
};
} else {
// Remove deprecated values
args = {
vspace: '',
hspace: '',
border: '',
align: ''
};
}
tinymce.extend(args, {
src: nl.src.value,
width: nl.width.value,
height: nl.height.value,
alt: nl.alt.value,
title: nl.alt.value,
rel: nl.orgWidth.value + ',' + nl.orgHeight.value
});
args.onmouseover = args.onmouseout = '';
el = ed.selection.getNode();
if (el && el.nodeName == 'IMG') {
ed.dom.setAttribs(el, args);
} else {
ed.execCommand('mceInsertContent', false, '<img id="__mce_tmp" />', { skip_undo: 1 });
ed.dom.setAttribs('__mce_tmp', args);
ed.dom.setAttrib('__mce_tmp', 'id', '');
ed.undoManager.add();
}
tinyMCEPopup.close();
},
getAttrib: function(e, at) {
var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2;
if (ed.settings.inline_styles) {
switch (at) {
case 'align':
if (v = dom.getStyle(e, 'float'))
return v;
if (v = dom.getStyle(e, 'vertical-align'))
return v;
break;
case 'hspace':
v = dom.getStyle(e, 'margin-left')
v2 = dom.getStyle(e, 'margin-right');
if (v && v == v2)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
case 'vspace':
v = dom.getStyle(e, 'margin-top')
v2 = dom.getStyle(e, 'margin-bottom');
if (v && v == v2)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
case 'border':
v = 0;
tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) {
sv = dom.getStyle(e, 'border-' + sv + '-width');
// False or not the same as prev
if (!sv || (sv != v && v !== 0)) {
v = 0;
return false;
}
if (sv)
v = sv;
});
if (v)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
}
}
if (v = dom.getAttrib(e, at))
return v;
return '';
},
setSwapImage: function(st) {
var f = document.forms[0];
f.onmousemovecheck.checked = st;
setBrowserDisabled('overbrowser', !st);
setBrowserDisabled('outbrowser', !st);
if (f.over_list)
f.over_list.disabled = !st;
if (f.out_list)
f.out_list.disabled = !st;
f.onmouseoversrc.disabled = !st;
f.onmouseoutsrc.disabled = !st;
},
resetImageData: function() {
var f = document.forms[0];
f.elements.width.value = f.elements.height.value = '';
},
updateImageData: function(img, st) {
var f = document.forms[0];
if (!st) {
f.elements.width.value = img.width;
f.elements.height.value = img.height;
}
this.preloadImg = img;
},
changeAppearance: function() {
var ed = tinyMCEPopup.editor, f = document.forms[0], img = document.getElementById('alignSampleImg');
if (img) {
if (ed.getParam('inline_styles')) {
ed.dom.setAttrib(img, 'style', f.style.value);
} else {
img.align = f.align.value;
img.border = f.border.value;
img.hspace = f.hspace.value;
img.vspace = f.vspace.value;
}
}
},
changeHeight: function() {
var f = document.forms[0], tp, t = this;
alert(t.preloadImg);
if (!f.constrain.checked || !t.preloadImg) {
return;
}
if (f.width.value == '' || f.height.value == '')
return;
tp = (parseInt(f.width.value) / parseInt(t.preloadImg.width)) * t.preloadImg.height;
f.height.value = tp.toFixed(0);
},
changeWidth: function() {
var f = document.forms[0], tp, t = this;
if (!f.constrain.checked || !t.preloadImg) {
return;
}
if (f.width.value == '' || f.height.value == '')
return;
tp = (parseInt(f.height.value) / parseInt(t.preloadImg.height)) * t.preloadImg.width;
f.width.value = tp.toFixed(0);
},
updateStyle: function(ty) {
var dom = tinyMCEPopup.dom, st, v, f = document.forms[0], img = dom.create('img', { style: dom.get('style').value });
if (tinyMCEPopup.editor.settings.inline_styles) {
// Handle align
if (ty == 'align') {
dom.setStyle(img, 'float', '');
dom.setStyle(img, 'vertical-align', '');
v = getSelectValue(f, 'align');
if (v) {
if (v == 'left' || v == 'right')
dom.setStyle(img, 'float', v);
else
img.style.verticalAlign = v;
}
}
// Handle border
if (ty == 'border') {
dom.setStyle(img, 'border', '');
v = f.border.value;
if (v || v == '0') {
if (v == '0')
img.style.border = '0';
else
img.style.border = v + 'px solid black';
}
}
// Handle hspace
if (ty == 'hspace') {
dom.setStyle(img, 'marginLeft', '');
dom.setStyle(img, 'marginRight', '');
v = f.hspace.value;
if (v) {
img.style.marginLeft = v + 'px';
img.style.marginRight = v + 'px';
}
}
// Handle vspace
if (ty == 'vspace') {
dom.setStyle(img, 'marginTop', '');
dom.setStyle(img, 'marginBottom', '');
v = f.vspace.value;
if (v) {
img.style.marginTop = v + 'px';
img.style.marginBottom = v + 'px';
}
}
// Merge
dom.get('style').value = dom.serializeStyle(dom.parseStyle(img.style.cssText));
}
},
changeMouseMove: function() {
},
showPreviewImage: function(u, st) {
if (!u) {
tinyMCEPopup.dom.setHTML('prev', '');
return;
}
if (!st && tinyMCEPopup.getParam("advimage_update_dimensions_onchange", true))
this.resetImageData();
u = tinyMCEPopup.editor.documentBaseURI.toAbsolute(u);
if (!st)
tinyMCEPopup.dom.setHTML('prev', '<img id="previewImg" src="' + u + '" border="0" onload="ImageDialog.updateImageData(this);" onerror="ImageDialog.resetImageData();" />');
else
tinyMCEPopup.dom.setHTML('prev', '<img id="previewImg" src="' + u + '" border="0" onload="ImageDialog.updateImageData(this, 1);" />');
}
};
ImageDialog.preInit();
tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog);
@@ -1,43 +0,0 @@
tinyMCE.addI18n('en.umbimage_dlg', {
tab_general: 'General',
tab_appearance: 'Appearance',
tab_advanced: 'Advanced',
general: 'General',
title: 'Title',
preview: 'Preview',
constrain_proportions: 'Constrain proportions',
langdir: 'Language direction',
langcode: 'Language code',
long_desc: 'Long description link',
style: 'Style',
classes: 'Classes',
ltr: 'Left to right',
rtl: 'Right to left',
id: 'Id',
map: 'Image map',
swap_image: 'Swap image',
alt_image: 'Alternative image',
mouseover: 'for mouse over',
mouseout: 'for mouse out',
misc: 'Miscellaneous',
example_img: 'Appearance preview image',
missing_alt: 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.',
dialog_title: 'Insert/edit image',
src: 'Image URL',
alt: 'Image description',
list: 'Image list',
border: 'Border',
dimensions: 'Dimensions',
vspace: 'Vertical space',
hspace: 'Horizontal space',
align: 'Alignment',
align_baseline: 'Baseline',
align_top: 'Top',
align_middle: 'Middle',
align_bottom: 'Bottom',
align_texttop: 'Text top',
align_textbottom: 'Text bottom',
align_left: 'Left',
align_right: 'Right',
image_list: 'Image list'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('en_us.umbimage_dlg', {
tab_general: 'General',
tab_appearance: 'Appearance',
tab_advanced: 'Advanced',
general: 'General',
title: 'Title',
preview: 'Preview',
constrain_proportions: 'Constrain proportions',
langdir: 'Language direction',
langcode: 'Language code',
long_desc: 'Long description link',
style: 'Style',
classes: 'Classes',
ltr: 'Left to right',
rtl: 'Right to left',
id: 'Id',
map: 'Image map',
swap_image: 'Swap image',
alt_image: 'Alternative image',
mouseover: 'for mouse over',
mouseout: 'for mouse out',
misc: 'Miscellaneous',
example_img: 'Appearance preview image',
missing_alt: 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.',
dialog_title: 'Insert/edit image',
src: 'Image URL',
alt: 'Image description',
list: 'Image list',
border: 'Border',
dimensions: 'Dimensions',
vspace: 'Vertical space',
hspace: 'Horizontal space',
align: 'Alignment',
align_baseline: 'Baseline',
align_top: 'Top',
align_middle: 'Middle',
align_bottom: 'Bottom',
align_texttop: 'Text top',
align_textbottom: 'Text bottom',
align_left: 'Left',
align_right: 'Right',
image_list: 'Image list'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('he.umbimage_dlg', {
tab_general: 'General',
tab_appearance: 'Appearance',
tab_advanced: 'Advanced',
general: 'General',
title: 'Title',
preview: 'Preview',
constrain_proportions: 'Constrain proportions',
langdir: 'Language direction',
langcode: 'Language code',
long_desc: 'Long description link',
style: 'Style',
classes: 'Classes',
ltr: 'Left to right',
rtl: 'Right to left',
id: 'Id',
map: 'Image map',
swap_image: 'Swap image',
alt_image: 'Alternative image',
mouseover: 'for mouse over',
mouseout: 'for mouse out',
misc: 'Miscellaneous',
example_img: 'Appearance preview image',
missing_alt: 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.',
dialog_title: 'Insert/edit image',
src: 'Image URL',
alt: 'Image description',
list: 'Image list',
border: 'Border',
dimensions: 'Dimensions',
vspace: 'Vertical space',
hspace: 'Horizontal space',
align: 'Alignment',
align_baseline: 'Baseline',
align_top: 'Top',
align_middle: 'Middle',
align_bottom: 'Bottom',
align_texttop: 'Text top',
align_textbottom: 'Text bottom',
align_left: 'Left',
align_right: 'Right',
image_list: 'Image list'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('it.umbimage_dlg', {
tab_general: 'Generale',
tab_appearance: 'Aspetto',
tab_advanced: 'Avanzate',
general: 'Generale',
title: 'Titolo',
preview: 'Anteprima',
constrain_proportions: 'Vincola proporzioni',
langdir: 'Direzione lingua',
langcode: 'Codice lingua',
long_desc: 'Descrizione lunga del collegamento',
style: 'Stile',
classes: 'Classi',
ltr: 'Da sinistra a destra',
rtl: 'Da destra a sinistra',
id: 'Id',
map: 'Image map',
swap_image: 'Swap immagine',
alt_image: 'Testo alternativo',
mouseover: 'Mouse over',
mouseout: 'Mouse out',
misc: 'Varie',
example_img: 'Aspetto anteprima immagine',
missing_alt: 'Sei sicuro di voler continuare senza includere una Descrizione dell'immagine? Se non lo fai l'immagine potrebbe risultare non accessibile per gli utenti con disabilit\u00E0, o per chi utilizza un browser di testo, o per chi naviga senza immagini.',
dialog_title: 'Inserisci/Modifica immagine',
src: 'URL immagine',
alt: 'Descrizione immagine',
list: 'Immagine lista',
border: 'Bordo',
dimensions: 'Dimensioni',
vspace: 'Spaziatura verticale',
hspace: 'Spaziatura orizzontale',
align: 'Allineamento',
align_baseline: 'Baseline',
align_top: 'Top',
align_middle: 'Middle',
align_bottom: 'Bottom',
align_texttop: 'Testo superiore',
align_textbottom: 'Testo inferiore',
align_left: 'Sinistra',
align_right: 'Destra',
image_list: 'Immagine lista'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('ja.umbimage_dlg', {
tab_general: '一般',
tab_appearance: '表示',
tab_advanced: '高度な設定',
general: '一般',
title: 'タイトル',
preview: 'プレビュー',
constrain_proportions: '縦横比の維持',
langdir: '文章の方向',
langcode: '言語コード',
long_desc: '詳細な説明のリンク',
style: 'スタイル',
classes: 'クラス',
ltr: '左から右',
rtl: '右から左',
id: 'Id',
map: 'イメージマップ',
swap_image: '画像の入れ替え',
alt_image: '別の画像',
mouseover: 'マウスカーソルがかかる時',
mouseout: 'マウスカーソルが外れる時',
misc: 'その他',
example_img: '画像のプレビューの様子',
missing_alt: '画像の説明を含めずに続けますか?画像の説明がないと目の不自由な方、テキスト表示だけのブラウザを使用している方、画像の表示を止めてる方がアクセスできないかもしれません。',
dialog_title: '画像の挿入/編集',
src: '画像のURL',
alt: '画像の説明',
list: '画像の一覧',
border: '枠線',
dimensions: '寸法',
vspace: '上下の余白',
hspace: '左右の余白',
align: '配置',
align_baseline: 'ベースライン揃え',
align_top: '上揃え',
align_middle: '中央揃え',
align_bottom: '下揃え',
align_texttop: 'テキストの上端揃え',
align_textbottom: 'テキストの下端揃え',
align_left: '左寄せ',
align_right: '右寄せ',
image_list: '画像の一覧'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('ru.umbimage_dlg', {
tab_general: 'Общее',
tab_appearance: 'Вид',
tab_advanced: 'Дополнительно',
general: 'Общие свойства',
title: 'Заголовок',
preview: 'Предпросмотр',
constrain_proportions: 'Сохранять пропорции',
langdir: 'Направление языка',
langcode: 'Код языка',
long_desc: 'Ссылка на длинное описание',
style: 'Стиль',
classes: 'Классы CSS',
ltr: 'Слева напрапво',
rtl: 'Справа налево',
id: 'Id',
map: 'Карта',
swap_image: 'Замена',
alt_image: 'Альтернатива',
mouseover: 'при заходе мыши',
mouseout: 'при выходе мыши',
misc: 'Разное',
example_img: 'Пример внешнего вида',
missing_alt: 'Вы уверены, что хотите продолжить без указания описания изображения? Без описания изображение может оказаться недоступным некоторым категориям пользователей с ограниченными возможностями, или использующим текстовый браузер, а также пользователям, отключившим показ изображений.',
dialog_title: 'Вставить/изменить изображение',
src: 'URL изображения',
alt: 'Описание изображения',
list: 'Список',
border: 'Рамка',
dimensions: 'Размеры',
vspace: 'Отступ по вертикали',
hspace: 'Отступ по горизонтали',
align: 'Выравнивание',
align_baseline: 'По базовой линии',
align_top: 'По верху',
align_middle: 'По центру',
align_bottom: 'По низу',
align_texttop: 'По верху текста',
align_textbottom: 'По низу текста',
align_left: 'По левому краю',
align_right: 'По правому краю',
image_list: 'Список изображений'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('sv.umbimage_dlg', {
tab_general: 'Generellt',
tab_appearance: 'Utseende',
tab_advanced: 'Avancerat',
general: 'Generellt',
title: 'Titel',
preview: 'Förhandsgranska',
constrain_proportions: 'Bibehåll proportioner',
langdir: 'Språkdirektion',
langcode: 'Språkkod',
long_desc: 'Lång länkbeskrivning',
style: 'Stil',
classes: 'Klasser',
ltr: 'Vänster till höger',
rtl: 'höger till vänster',
id: 'Id',
map: 'Bildkarta',
swap_image: 'Byt bild',
alt_image: 'Alternativ bild',
mouseover: 'För musen över',
mouseout: 'för musen utanför',
misc: 'Blandat',
example_img: 'Visning av bildförhandsgranskning',
missing_alt: 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.',
dialog_title: 'Infoga/redigera bild',
src: 'Bild URL',
alt: 'Bildbeskrivning',
list: 'Bildlista',
border: 'Ram',
dimensions: 'Dimensioner',
vspace: 'Vertikalt avstånd',
hspace: 'Horisontellt avstånd',
align: 'Position',
align_baseline: 'Baslinje',
align_top: 'Toppen',
align_middle: 'Mitten',
align_bottom: 'Botten',
align_texttop: 'Text topp',
align_textbottom: 'Text botten',
align_left: 'Vänster',
align_right: 'Höger',
image_list: 'Bildlista'
});
@@ -1,43 +0,0 @@
tinyMCE.addI18n('zh.umbimage_dlg', {
tab_general: '普通',
tab_appearance: '外观',
tab_advanced: '高级',
general: '普通',
title: '标题',
preview: '预览',
constrain_proportions: '约束比例',
langdir: '语言书写方向',
langcode: '语言代码',
long_desc: '长原文链接',
style: '样式',
classes: '类',
ltr: '从左到右',
rtl: '从右到左',
id: 'Id',
map: '图片热区',
swap_image: '交换图片',
alt_image: '替代图片',
mouseover: '鼠标移入',
mouseout: '鼠标移出',
misc: '其它',
example_img: '样图外观',
missing_alt: '你确定不要图片替代文字吗?替代文字可以在图片无法显示时显示。',
dialog_title: '插入/编辑图片',
src: '图片URL',
alt: '图片描述',
list: '图片列表',
border: '边框',
dimensions: '尺寸',
vspace: '垂直间距',
hspace: '水平间距',
align: '对齐',
align_baseline: '对齐底线',
align_top: '顶部对齐',
align_middle: '中间对齐',
align_bottom: '底部对齐',
align_texttop: '对齐文字顶部',
align_textbottom: '对齐文字底部',
align_left: '左对齐',
align_right: '右对齐',
image_list: '图片列表'
});
@@ -1,5 +0,0 @@
/**
* This file is intentionally left empty
* For reference, see: http://issues.umbraco.org/issue/U4-9724
* The logic for the umbracoLink plugin now lives in ~/Umbraco/Js/umbraco.services.js
*/
@@ -1,27 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#example_dlg.title}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="js/dialog.js"></script>
</head>
<body>
<form onsubmit="ExampleDialog.insert();return false;" action="#">
<p>Here is a example dialog.</p>
<p>Selected text: <input id="someval" name="someval" type="text" class="text" /></p>
<p>Custom arg: <input id="somearg" name="somearg" type="text" class="text" /></p>
<div class="mceActionPanel">
<div style="float: left">
<input type="button" id="insert" name="insert" value="{#insert}" onclick="ExampleDialog.insert();" />
</div>
<div style="float: right">
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</div>
</form>
</body>
</html>
@@ -1,145 +0,0 @@
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @author Moxiecode
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function() {
// Load plugin specific language pack
// tinymce.PluginManager.requireLangPack('umbraco');
tinymce.create('tinymce.plugins.umbracomacro', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init: function(ed, url) {
var t = this;
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
ed.addCommand('mceumbracomacro', function() {
var se = ed.selection;
var urlParams = "";
var el = se.getNode();
// ie selector bug
if (!ed.dom.hasClass(el, 'umbMacroHolder')) {
el = ed.dom.getParent(el, 'div.umbMacroHolder');
}
var attrString = "";
if (ed.dom.hasClass(el, 'umbMacroHolder')) {
for (var i = 0; i < el.attributes.length; i++) {
attrName = el.attributes[i].nodeName.toLowerCase();
if (attrName != "mce_serialized") {
if (el.attributes[i].nodeValue && (attrName != 'ismacro' && attrName != 'style' && attrName != 'contenteditable')) {
attrString += el.attributes[i].nodeName + '=' + escape(t._utf8_encode(el.attributes[i].nodeValue)) + '&'; //.replace(/#/g, "%23").replace(/\</g, "%3C").replace(/\>/g, "%3E").replace(/\"/g, "%22") + '&';
}
}
}
// vi trunkerer strengen ved at fjerne et evt. overskydende amp;
if (attrString.length > 0)
attrString = attrString.substr(0, attrString.length - 1);
urlParams = "&" + attrString;
} else {
urlParams = '&umbPageId=' + tinyMCE.activeEditor.getParam('theme_umbraco_pageId') + '&umbVersionId=' + tinyMCE.activeEditor.getParam('theme_umbraco_versionId');
}
ed.windowManager.open({
file: tinyMCE.activeEditor.getParam('umbraco_path') + '/plugins/tinymce3/insertMacro.aspx?editor=trueurl' + urlParams,
width: 480 + parseInt(ed.getLang('umbracomacro.delta_width', 0)),
height: 470 + parseInt(ed.getLang('umbracomacro.delta_height', 0)),
inline: 1
}, {
plugin_url: url // Plugin absolute URL
});
});
// Register example button
ed.addButton('umbracomacro', {
title: 'umbracomacro.desc',
cmd: 'mceumbracomacro',
image: url + '/img/insMacro.gif'
});
// Add a node change handler, test if we're editing a macro
ed.onNodeChange.addToTop(function(ed, cm, n) {
var macroElement = ed.dom.getParent(ed.selection.getStart(), 'div.umbMacroHolder');
// mark button if it's a macro
cm.setActive('umbracomacro', macroElement && ed.dom.hasClass(macroElement, 'umbMacroHolder'));
});
},
_utf8_encode: function(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
/**
* Creates control instances based in the incomming name. This method is normally not
* needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
* but you sometimes need to create more complex controls like listboxes, split buttons etc then this
* method can be used to create those.
*
* @param {String} n Name of the control to create.
* @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
* @return {tinymce.ui.Control} New control instance or null if no control was created.
*/
createControl: function(n, cm) {
return null;
},
/**
* Returns information about the plugin as a name/value array.
* The current keys are longname, author, authorurl, infourl and version.
*
* @return {Object} Name/value array containing information about the plugin.
*/
getInfo: function() {
return {
longname: 'Umbraco Macro Insertion Plugin',
author: 'Umbraco',
authorurl: 'http://umbraco.org',
infourl: 'http://umbraco.org/redir/tinymcePlugins',
version: "1.0"
};
}
});
// Register plugin
tinymce.PluginManager.add('umbracomacro', tinymce.plugins.umbracomacro);
})();
Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

@@ -1,19 +0,0 @@
tinyMCEPopup.requireLangPack();
var ExampleDialog = {
init : function() {
var f = document.forms[0];
// Get the selected contents as text and place it in the input
f.someval.value = tinyMCEPopup.editor.selection.getContent({format : 'text'});
f.somearg.value = tinyMCEPopup.getWindowArg('some_custom_arg');
},
insert : function() {
// Insert the contents from the input into the document
tinyMCEPopup.editor.execCommand('mceInsertContent', false, document.forms[0].someval.value);
tinyMCEPopup.close();
}
};
tinyMCEPopup.onInit.add(ExampleDialog.init, ExampleDialog);
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en.umbracomacro',{
desc : 'Insert macro'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en.example_dlg',{
title : 'This is just a example title'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en_us.umbracomacro',{
desc : 'Insert macro'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('en_us.example_dlg',{
title : 'This is just a example title'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('he.umbracomacro',{
desc : 'הוסף מאקרו'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('he.example_dlg',{
title : 'This is just a example title'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ja.umbracomacro',{
desc : 'マクロの挿入'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ja.example_dlg',{
title : 'これはタイトルの例です'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ru.umbracomacro',{
desc : 'Вставить макрос'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('ru.example_dlg',{
title : 'Это просто пример заголовка'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('sv.umbracomacro',{
desc : 'Infoga makro'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('sv.example_dlg',{
title : 'Detta är bar ett exempel på en titel'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('zh.umbracomacro',{
desc : '插入宏'
});
@@ -1,3 +0,0 @@
tinyMCE.addI18n('zh.example_dlg',{
title : '这是示例标题'
});
@@ -1,53 +0,0 @@
/**
* editor_plugin_src.js
*
* Copyright 2012, Umbraco
* Released under MIT License.
*
* License: http://opensource.org/licenses/mit-license.html
*/
(function () {
var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM;
/**
* This plugin modifies the standard TinyMCE paste, with umbraco specific changes.
*
* @class tinymce.plugins.umbContextMenu
*/
tinymce.create('tinymce.plugins.UmbracoPaste', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @method init
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init: function (ed) {
var t = this;
ed.plugins.paste.onPreProcess.add(function (pl, o) {
var ed = this.editor, h = o.content;
var umbracoAllowedStyles = ed.getParam('theme_umbraco_styles');
for (var i = 1; i < 7; i++) {
if (umbracoAllowedStyles.indexOf("h" + i) == -1) {
h = h.replace(new RegExp('<h' + i + '[^>]*', 'gi'), '<p><strong');
h = h.replace(new RegExp('</h' + i + '>', 'gi'), '</strong></p>');
}
}
o.content = h;
});
}
});
// Register plugin
tinymce.PluginManager.add('umbracopaste', tinymce.plugins.UmbracoPaste);
})();
@@ -1,43 +0,0 @@
(function () {
tinymce.create('tinymce.plugins.Umbracoshortcut', {
init: function (ed, url) {
var t = this;
var ctrlPressed = false;
t.editor = ed;
ed.onKeyDown.add(function (ed, e) {
if (e.keyCode == 17)
ctrlPressed = true;
if (ctrlPressed && e.keyCode == 83) {
jQuery(document).trigger("UMBRACO_TINYMCE_SAVE", e);
ctrlPressed = false;
tinymce.dom.Event.cancel(e);
return false;
}
});
ed.onKeyUp.add(function (ed, e) {
if (e.keyCode == 17)
ctrlPressed = false;
});
},
getInfo: function () {
return {
longname: 'Umbraco Save short cut key',
author: 'Umbraco HQ',
authorurl: 'http://umbraco.com',
infourl: 'http://our.umbraco.org',
version: "1.0"
};
}
// Private methods
});
// Register plugin
tinymce.PluginManager.add('umbracoshortcut', tinymce.plugins.Umbracoshortcut);
})();
@@ -358,7 +358,7 @@ angular.module("umbraco.directives")
var unsubscribe = scope.$on("formSubmitting", function () {
//TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer
// we do parse it out on the server side but would be nice to do that on the client side before as well.
scope.value = tinyMceEditor.getContent();
scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null;
});
//when the element is disposed we need to unsubscribe!
@@ -82,8 +82,10 @@
@param {boolean} sortable (<code>binding</code>): Will add a move cursor on the node preview. Can used in combination with ui-sortable.
@param {boolean} allowRemove (<code>binding</code>): Show/Hide the remove button.
@param {boolean} allowOpen (<code>binding</code>): Show/Hide the open button.
@param {boolean} allowEdit (<code>binding</code>): Show/Hide the edit button (Added in version 7.7.0).
@param {function} onRemove (<code>expression</code>): Callback function when the remove button is clicked.
@param {function} onOpen (<code>expression</code>): Callback function when the open button is clicked.
@param {function} onEdit (<code>expression</code>): Callback function when the edit button is clicked (Added in version 7.7.0).
**/
(function () {
@@ -108,8 +110,10 @@
sortable: "=?",
allowOpen: "=?",
allowRemove: "=?",
allowEdit: "=?",
onOpen: "&?",
onRemove: "&?"
onRemove: "&?",
onEdit: "&?"
},
link: link
};
@@ -1,8 +1,6 @@
.umb-node-preview {
padding: 7px 0;
border-radius: 3px;
display: flex;
align-items: center;
max-width: 66.6%;
box-sizing: border-box;
border-bottom: 1px solid @gray-9;
@@ -37,10 +35,12 @@
.umb-node-preview__content {
flex: 1 1 auto;
margin-right: 25px;
}
.umb-node-preview__name {
color: @black;
margin-top: 2px;
}
.umb-node-preview__description {
@@ -91,7 +91,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController",
userService.getCurrentUser().then(function (userData) {
$scope.mediaPickerOverlay = {
view: "mediapicker",
startNodeId: userData.startMediaIds.length == 0 ? -1 : userData.startMediaIds[0],
startNodeId: userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0],
show: true,
submit: function(model) {
var media = model.selectedImages[0];
@@ -16,6 +16,7 @@ angular.module("umbraco")
$scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1;
$scope.cropSize = dialogOptions.cropSize;
$scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId");
$scope.lockedFolder = true;
var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings;
var allowedUploadFiles = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles);
@@ -121,6 +122,8 @@ angular.module("umbraco")
$scope.path = [];
}
$scope.lockedFolder = folder.id === -1 && $scope.model.startNodeIsVirtual;
$scope.currentFolder = folder;
localStorageService.set("umbLastOpenedMediaNodeId", folder.id);
return getChildren(folder.id);
@@ -30,7 +30,7 @@
type="button"
label-key="general_upload"
action="upload()"
disabled="disabled">
disabled="lockedFolder">
</umb-button>
</div>
@@ -48,7 +48,7 @@
<span class="umb-breadcrumbs__seperator">&#47;</span>
</li>
<li class="umb-breadcrumbs__ancestor">
<li class="umb-breadcrumbs__ancestor" ng-if="!lockedFolder">
<a href ng-hide="showFolderInput" ng-click="showFolderInput = true">
<i class="icon icon-add small"></i>
</a>
@@ -67,7 +67,7 @@
</div>
<umb-file-dropzone
ng-if="acceptedMediatypes.length > 0 && !loading"
ng-if="acceptedMediatypes.length > 0 && !loading && !lockedFolder"
accepted-mediatypes="acceptedMediatypes"
parent-id="{{currentFolder.id}}"
files-uploaded="onUploadComplete"
@@ -1,10 +1,10 @@
<div class="umb-node-preview" ng-class="{'umb-node-preview--sortable': sortable, 'umb-node-preview--unpublished': published === false }">
<i ng-if="icon" class="umb-node-preview__icon {{ icon }}"></i>
<div class="umb-node-preview__content">
<div class="flex items-center">
<div class="umb-node-preview__name">{{ name }}</div>
<div ng-if="description" class="umb-node-preview__description">{{ description }}</div>
</div>
<div class="umb-node-preview__name">{{ name }}</div>
<div class="umb-node-preview__description" ng-if="description">{{ description }}</div>
<div class="umb-user-group-preview__permission" ng-if="permissions">
<span>
<span class="bold">Permissions:</span>
@@ -13,6 +13,7 @@
</div>
</div>
<div class="umb-node-preview__actions">
<a class="umb-node-preview__action" title="Open" href="" ng-if="allowEdit" ng-click="onEdit()"><localize key="general_edit">Edit</localize></a>
<a class="umb-node-preview__action" title="Open" href="" ng-if="allowOpen" ng-click="onOpen()"><localize key="general_open">Open</localize></a>
<a class="umb-node-preview__action umb-node-preview__action--red" title="Remove" href="" ng-if="allowRemove" ng-click="onRemove()"><localize key="general_remove">Remove</localize></i></a>
<div>
@@ -4,7 +4,8 @@ angular.module("umbraco")
if (!$scope.model.config.startNodeId) {
userService.getCurrentUser().then(function (userData) {
$scope.model.config.startNodeId = userData.startMediaIds.length === 0 ? -1 : userData.startMediaIds[0];
$scope.model.config.startNodeId = userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0];
$scope.model.config.startNodeIsVirtual = userData.startMediaIds.length !== 1;
});
}
@@ -12,6 +13,7 @@ angular.module("umbraco")
$scope.mediaPickerOverlay = {};
$scope.mediaPickerOverlay.view = "mediapicker";
$scope.mediaPickerOverlay.startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined;
$scope.mediaPickerOverlay.startNodeIsVirtual = $scope.mediaPickerOverlay.startNodeId ? $scope.model.config.startNodeIsVirtual : undefined;
$scope.mediaPickerOverlay.cropSize = $scope.control.editor.config && $scope.control.editor.config.size ? $scope.control.editor.config.size : undefined;
$scope.mediaPickerOverlay.showDetails = true;
$scope.mediaPickerOverlay.disableFolderSelect = true;
@@ -28,7 +28,7 @@
currentTarget: currentTarget,
onlyImages: true,
showDetails: true,
startNodeId: userData.startMediaIds.length === 0 ? -1 : userData.startMediaIds[0],
startNodeId: userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0],
view: "mediapicker",
show: true,
submit: function(model) {

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