Compare commits

..

128 Commits

Author SHA1 Message Date
Mads Rasmussen 244ee646b9 Revert "update content when changing variation"
This reverts commit b487436d93.
2016-04-07 12:45:33 +02:00
Mads Rasmussen b487436d93 update content when changing variation 2016-04-07 12:38:05 +02:00
Mads Rasmussen 321b1a3964 disable autocomplete on editor name input 2016-04-07 11:17:05 +02:00
Mads Rasmussen f6b1971243 disable name input for a marketing variation 2016-04-07 11:05:21 +02:00
Simon Busborg ab1e412b4b Active in quickswitcher 2016-04-07 10:51:39 +02:00
Mads Rasmussen 2c866e8326 add spanish 2016-04-07 10:24:52 +02:00
Mads Rasmussen 433563c10b select first variation 2016-04-06 20:03:49 +02:00
Mads Rasmussen 95b91cb55f a bit fine tuning of selected variation and language 2016-04-06 19:29:29 +02:00
Mads Rasmussen d070b869a3 fix error in css 2016-04-06 16:09:26 +02:00
Mads Rasmussen 82bcb8bb8a Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-04-06 16:07:49 +02:00
Mads Rasmussen 8cbd0281aa set limit on apps 2016-04-06 16:07:12 +02:00
Simon Busborg 148067f119 apps 2016-04-06 16:01:16 +02:00
Mads Rasmussen 9d79577833 add activity app 2016-04-06 15:05:16 +02:00
Simon Busborg c24918aeb7 standard width on apps 2016-04-06 14:15:10 +02:00
Simon Busborg f7a814714c even spacing between apps 2016-04-06 11:36:34 +02:00
Simon Busborg 3200a7fd1a Splitview close 2016-04-06 11:23:38 +02:00
Mads Rasmussen 7983aedf53 make tabs to apps 2016-04-06 11:22:18 +02:00
Mads Rasmussen c31efa3f54 only show variations for active language + add sortable on variations 2016-04-05 15:16:55 +02:00
Simon Busborg c98a98dd71 Tabs 2016-04-05 15:07:35 +02:00
Mads Rasmussen ee3965521d bring back old tabs markup to enable active state 2016-04-05 14:34:57 +02:00
Mads Rasmussen 3d90c0d3d7 add segments to create variation + fix edit variation 2016-04-05 12:31:00 +02:00
Mads Rasmussen bc60aa1688 remove analytics from content plugins 2016-04-05 11:46:08 +02:00
Mads Rasmussen 5c90043298 hide the split view divider when there is no split view open 2016-04-05 11:44:16 +02:00
Mads Rasmussen 0f784151cb close split view on route change 2016-04-05 09:47:58 +02:00
Mads Rasmussen 681512da8c Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-04-04 19:04:53 +02:00
Mads Rasmussen b17770d6c7 fake split views 2016-04-04 19:04:36 +02:00
Simon Busborg 745b536f63 Fixed divider 2016-04-04 12:55:08 +02:00
Mads Rasmussen 738289cd78 comment out sync switcher and property overlay 2016-04-01 11:19:13 +02:00
Simon Busborg 77d30e8484 fixed colors 2016-03-30 15:02:53 +02:00
Simon Busborg 347fb3a90d demoed version of splitview (not pretty) 2016-03-30 12:24:01 +02:00
Mads Rasmussen 39bdc1bc78 handle 1sites with 1 language 2016-03-30 09:04:26 +02:00
Simon Busborg a3dcdb159b Removed tags, added tags checkboxes, styling in general for variations 2016-03-29 15:38:50 +02:00
Simon Busborg 9656659ecd overview 2016-03-29 13:46:11 +02:00
Mads Rasmussen d679a4e697 make it possible to fake variation content 2016-03-29 12:18:47 +02:00
Mads Rasmussen c81a034c69 only show variations toggle if there are any variations 2016-03-23 14:23:02 +01:00
Mads Rasmussen a519d38b54 Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-03-23 14:13:10 +01:00
Mads Rasmussen cf4c09f41f When click on item in variation quick switcher - change context in header 2016-03-23 14:12:57 +01:00
Simon Busborg bd3096c3ec changed quick toggler 2016-03-23 13:49:07 +01:00
Simon Busborg 1bbf104b9f variations overview 2016-03-23 13:41:26 +01:00
Mads Rasmussen 4f1e44d42e get variations from helper service so they are in sync 2016-03-23 13:39:26 +01:00
Simon Busborg fa68a9472b quickswitcher update 2016-03-23 11:54:54 +01:00
Mads Rasmussen efb2b744fc Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-03-23 11:52:26 +01:00
Mads Rasmussen 9018c4ef79 add functionality to create, edit and delete variations - missing styling + segments 2016-03-23 11:52:04 +01:00
Simon Busborg dfce0aa0cb changed width of container 2016-03-23 08:59:52 +01:00
Mads Rasmussen 131c9a6fe1 move description inline 2016-03-22 16:24:18 +01:00
Mads Rasmussen 555589ef3b change colour on tags + bring back create variation link 2016-03-22 15:10:46 +01:00
Mads Rasmussen b099d35981 Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/components/umb-variations.less
#	src/Umbraco.Web.UI.Client/src/views/components/umb-variations.html
2016-03-22 14:24:03 +01:00
Mads Rasmussen e3bc3091f7 add dynamic data to variations overview + clean up UI + add segments to variations overview 2016-03-22 14:17:20 +01:00
Simon Busborg 320ed93b14 active quick switcher 2016-03-22 13:50:39 +01:00
Simon Busborg c71ce7ef2a changed lang options 2016-03-22 10:59:12 +01:00
Mads Rasmussen c0ea46c9f1 split languages and variations in dropdown. Show selected in header 2016-03-22 10:55:33 +01:00
Mads Rasmussen 533443fd25 remove sidebar on variations 2016-03-22 10:47:00 +01:00
Simon Busborg e76658373f Added lang groups for variations 2016-03-22 10:13:05 +01:00
Mads Rasmussen a77330a592 add a bit a variations toggle styling 2016-03-21 10:39:48 +01:00
Mads Rasmussen 2f5e9ee8c4 change sync off label + smaller font size 2016-03-21 10:01:36 +01:00
Mads Rasmussen f252590a1c Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-03-18 14:40:23 +01:00
Mads Rasmussen fa4bdac78a style editor overlay label 2016-03-18 14:39:18 +01:00
Simon Busborg e268945077 fixed animate bug 2016-03-18 14:38:04 +01:00
Simon Busborg b428fb2211 fixed search / scrollable area 2016-03-18 14:26:24 +01:00
Mads Rasmussen bfc098e5e0 make change variation work work editor view 2016-03-18 14:09:07 +01:00
Simon Busborg d9b58e80fe added search to variations 2016-03-18 12:40:16 +01:00
Simon Busborg a7a860bbcd fixed dropdown 2016-03-18 12:03:05 +01:00
Mads Rasmussen fa277a4a5d fix styling on dropdown 2016-03-18 11:58:57 +01:00
Mads Rasmussen 7e1df76db3 move dropdown logic 2016-03-18 11:26:46 +01:00
Simon Busborg 9c33e292ae moved component to label 2016-03-18 11:13:49 +01:00
Mads Rasmussen 75edd645c6 add basic functionality to edit content and change which variation to sync content from 2016-03-17 21:31:09 +01:00
Mads Rasmussen 6adfdbf7dd clear variations when a new master i set 2016-03-17 20:30:29 +01:00
Mads Rasmussen 5453d86a46 make sidebar title a little smaller 2016-03-17 20:09:58 +01:00
Mads Rasmussen 6d4146b9c6 add wrappers and title to sidebar 2016-03-17 20:07:57 +01:00
Simon Busborg a93d98933f fixed z-index on buttons 2016-03-17 15:20:34 +01:00
Mads Rasmussen cf28c0ca5e change text and icon on sync toggle 2016-03-17 15:12:56 +01:00
Mads Rasmussen 435434b859 position toggle top 0 and right 0 2016-03-17 15:10:07 +01:00
Mads Rasmussen e93b057a5f make sync button a bit smaller 2016-03-17 15:02:38 +01:00
Simon Busborg e8d167faf0 added get content 2016-03-17 14:42:26 +01:00
Mads Rasmussen ab1322f789 started on dropdown 2016-03-17 12:39:40 +01:00
Simon Busborg 36abb83ff2 moved psuedo element to the property editor markup 2016-03-17 11:54:01 +01:00
Simon Busborg 0d62e62fda changed inactive state 2016-03-17 11:41:38 +01:00
Simon Busborg d25a01d9c9 added overlay to variation picker 2016-03-17 11:22:52 +01:00
Simon Busborg 1da55e4dde Fixed subview editor header 2016-03-17 10:46:08 +01:00
Simon Busborg c346ec1282 search width 2016-03-14 11:06:03 +01:00
Simon Busborg 556d4b4c11 search 2016-03-11 14:07:05 +01:00
Mads Rasmussen 7d0d58f7c2 fix notifications width 2016-03-11 13:53:50 +01:00
Mads Rasmussen a0618f401f Merge remote-tracking branch 'origin/temp-maurice' into temp-maurice 2016-03-11 13:19:48 +01:00
Mads Rasmussen 34645460fb Set position relative to contain absolute elements 2016-03-11 13:19:15 +01:00
Simon Busborg 43b534c3b1 tabs activity 2016-03-11 10:57:44 +01:00
Mads Rasmussen bc29b2e235 copy search functionality to top bar 2016-03-11 10:52:45 +01:00
Simon Busborg d6c226d41a Added navigation to sidebars 2016-03-10 15:29:41 +01:00
Simon Busborg 14d8b634b5 Acitvity feed 2016-03-10 12:45:08 +01:00
Mads Rasmussen c4e41c1df6 add a content wrapper to add padding 2016-03-10 12:20:46 +01:00
Mads Rasmussen 788efeb098 remove horizontal scrollbar in media folders 2016-03-10 11:57:00 +01:00
Mads Rasmussen 71916af49c hide generic properties tab content 2016-03-10 11:56:31 +01:00
Mads Rasmussen 55e62c01e4 hide tab instead of removing it.. now we can save again 2016-03-10 11:43:53 +01:00
Mads Rasmussen fa8dc5ace4 remove console.logs 2016-03-10 11:22:08 +01:00
Simon Busborg 671d99f455 changed menu state 2016-03-10 11:09:51 +01:00
Mads Rasmussen d681a84800 Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-03-10 10:59:07 +01:00
Mads Rasmussen 440e2a7d56 bring back dashboards 2016-03-10 10:58:45 +01:00
Simon Busborg 2f8ec7bd29 Added more and added sidebar navigation status 2016-03-10 10:58:07 +01:00
Simon Busborg 5105cf890d displaying apps center 2016-03-10 10:04:32 +01:00
Mads Rasmussen 88a0f21328 align sub view header content left and right 2016-03-10 09:58:52 +01:00
Mads Rasmussen cd1ea78825 contain absolute positioned elements inside content 2016-03-10 09:33:57 +01:00
Simon Busborg ca4ff98c5f navigation fluf 2016-03-10 09:18:26 +01:00
Mads Rasmussen 339e1dc94e WIP bring in variation ideas + a couple of placeholder subviews 2016-03-10 09:16:37 +01:00
Mads Rasmussen a84c6e9dff remove generic properties tab 2016-03-10 09:15:29 +01:00
Simon Busborg ba927d1962 fixed tree navigation 2016-03-09 20:40:34 +01:00
Simon Busborg ee30f10357 Dropdown 2016-03-09 20:21:14 +01:00
Simon Busborg 478fe51651 Added tree toggler 2016-03-09 15:21:43 +01:00
Mads Rasmussen 5694beafef add subviews to content 2016-03-08 14:49:04 +01:00
Mads Rasmussen 2a1e9e30ae add generic properties icon 2016-03-07 10:01:33 +01:00
Mads Rasmussen ef5bf29b07 remove background color on footer - wireframe style 2016-03-07 09:58:42 +01:00
Mads Rasmussen 7b521e6857 um tree nav - set overflow to auto 2016-03-07 09:51:35 +01:00
Mads Rasmussen 4135e30834 add tabs to media 2016-03-05 14:03:16 +01:00
Mads Rasmussen 2b1bf0b966 add scroll to tree 2016-03-04 18:42:06 +01:00
Mads Rasmussen 6bc2ce19f5 hide search in tree 2016-03-04 18:13:21 +01:00
Mads Rasmussen 67efc1906a add editor toolbar directive - move tabs outside header for content section 2016-03-04 18:12:53 +01:00
Mads Rasmussen 8b62d09e64 remove background from editor header - wireframe look 2016-03-04 18:09:34 +01:00
Mads Rasmussen 5c6bbfb423 remove background + add border to navigation bar - wireframe look 2016-03-04 18:09:04 +01:00
Mads Rasmussen 97ff32245d fix navigation height 2016-03-04 14:43:56 +01:00
Simon Busborg b7549ad644 Fixed second header 🌮 2016-03-04 11:31:56 +01:00
Mads Rasmussen 802fe45614 Merge branch 'temp-maurice' of https://github.com/umbraco/Umbraco-CMS into temp-maurice 2016-03-04 11:05:06 +01:00
Mads Rasmussen 253a4520b0 tighten up tree a bit 2016-03-04 11:04:41 +01:00
Simon Busborg b6877dc4ce fixed header size 2016-03-04 11:03:50 +01:00
Simon Busborg 27a031ea12 Updated recess – fixed content scroll 2016-03-04 10:59:19 +01:00
Mads Rasmussen 0e2212bd40 less padding and smaller font size on top navigation 2016-03-04 10:34:18 +01:00
Simon Busborg 8ee414793f flex - content 2016-03-04 10:26:33 +01:00
Simon Busborg 1dddc06ae7 added tree 🌳 2016-03-03 16:12:07 +01:00
Simon Busborg 3d253b79e4 Added very slick navigation 🔥 2016-03-03 14:26:37 +01:00
Mads Rasmussen e7542bc455 add functionality to top bar navigation - needs styling 2016-03-03 12:56:38 +01:00
Simon Busborg 43ab5a8e2e Nuked interface 2016-03-03 10:38:01 +01:00
166 changed files with 4498 additions and 3345 deletions
+1
View File
@@ -72,6 +72,7 @@
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
<file src="tools\install.core.ps1" target="tools\install.ps1" />
<file src="tools\uninstall.core.ps1" target="tools\uninstall.ps1" />
<!-- Added to be able to produce a symbols package -->
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
+1
View File
@@ -33,6 +33,7 @@
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
<file src="tools\install.ps1" target="tools\install.ps1" />
<file src="tools\uninstall.ps1" target="tools\uninstall.ps1" />
<file src="tools\Readme.txt" target="tools\Readme.txt" />
<file src="tools\ReadmeUpgrade.txt" target="tools\ReadmeUpgrade.txt" />
<file src="tools\Web.config.install.xdt" target="Content\Web.config.install.xdt" />
@@ -21,8 +21,6 @@
<appSettings xdt:Transform="InsertIfMissing" />
<appSettings>
<add key="owin:appStartup" value="UmbracoDefaultOwinStartup" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
<add key="Umbraco.ModelsBuilder.Enable" value="false" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
<add key="Umbraco.ModelsBuilder.ModelsMode" value="Nothing" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
</appSettings>
<umbracoConfiguration xdt:Transform="InsertIfMissing">
+48
View File
@@ -0,0 +1,48 @@
param($installPath, $toolsPath, $package, $project)
Write-Host "installPath:" "${installPath}"
Write-Host "toolsPath:" "${toolsPath}"
Write-Host " "
if ($project) {
# Create paths and list them
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
Write-Host "projectPath:" "${projectPath}"
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup"
Write-Host "backupPath:" "${backupPath}"
$umbracoBinFolder = Join-Path $projectPath "bin"
Write-Host "umbracoBinFolder:" "${umbracoBinFolder}"
# Remove backups
Write-Host "removing backups:" "${backupPath}"
if(Test-Path $backupPath) { Remove-Item -Recurse -Force $backupPath -Confirm:$false }
# Delete files Umbraco ships with
Write-Host "removing dlls:" "${umbracoBinFolder}"
if(Test-Path $umbracoBinFolder\businesslogic.dll) { Remove-Item $umbracoBinFolder\businesslogic.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\cms.dll) { Remove-Item $umbracoBinFolder\cms.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\controls.dll) { Remove-Item $umbracoBinFolder\controls.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\interfaces.dll) { Remove-Item $umbracoBinFolder\interfaces.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\log4net.dll) { Remove-Item $umbracoBinFolder\log4net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\SQLCE4Umbraco.dll) { Remove-Item $umbracoBinFolder\SQLCE4Umbraco.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\TidyNet.dll) { Remove-Item $umbracoBinFolder\TidyNet.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.dll) { Remove-Item $umbracoBinFolder\umbraco.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Core.dll) { Remove-Item $umbracoBinFolder\Umbraco.Core.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.DataLayer.dll) { Remove-Item $umbracoBinFolder\umbraco.DataLayer.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.editorControls.dll) { Remove-Item $umbracoBinFolder\umbraco.editorControls.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.MacroEngines.dll) { Remove-Item $umbracoBinFolder\umbraco.MacroEngines.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\umbraco.providers.dll) { Remove-Item $umbracoBinFolder\umbraco.providers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\UmbracoExamine.dll) { Remove-Item $umbracoBinFolder\UmbracoExamine.dll -Force -Confirm:$false }
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
if(Test-Path $amd64Folder) { Remove-Item $amd64Folder -Force -Recurse -Confirm:$false }
$x86Folder = Join-Path $umbracoBinFolder "x86"
if(Test-Path $x86Folder) { Remove-Item $x86Folder -Force -Recurse -Confirm:$false }
}
+39
View File
@@ -0,0 +1,39 @@
param($installPath, $toolsPath, $package, $project)
Write-Host "installPath:" "${installPath}"
Write-Host "toolsPath:" "${toolsPath}"
Write-Host " "
if ($project) {
# Create paths and list them
$projectPath = (Get-Item $project.Properties.Item("FullPath").Value).FullName
Write-Host "projectPath:" "${projectPath}"
$backupPath = Join-Path $projectPath "App_Data\NuGetBackup"
Write-Host "backupPath:" "${backupPath}"
$appBrowsers = Join-Path $projectPath "App_Browsers"
Write-Host "appBrowsers:" "${appBrowsers}"
$appData = Join-Path $projectPath "App_Data"
Write-Host "appData:" "${appData}"
# Remove backups
Write-Host "removing backups:" "${backupPath}"
if(Test-Path $backupPath) { Remove-Item -Recurse -Force $backupPath -Confirm:$false }
# Remove app_data files
Write-Host "removing app_data files:" "${appData}"
if(Test-Path $appData\packages) { Remove-Item $appData\packages -Recurse -Force -Confirm:$false }
Write-Host "removing app_browsers:" "${appBrowsers}"
if(Test-Path $appBrowsers\Form.browser) { Remove-Item $appBrowsers\Form.browser -Force -Confirm:$false }
if(Test-Path $appBrowsers\w3cvalidator.browser) { Remove-Item $appBrowsers\w3cvalidator.browser -Force -Confirm:$false }
# Remove umbraco and umbraco_files
$umbracoFolder = Join-Path $projectPath "Umbraco"
Write-Host "removing umbraco folder:" "${umbracoFolder}"
if(Test-Path $umbracoFolder) { Remove-Item $umbracoFolder -Recurse -Force -Confirm:$false }
$umbracoClientFolder = Join-Path $projectPath "Umbraco_Client"
Write-Host "removing umbraco client folder:" "${umbracoClientFolder}"
if(Test-Path $umbracoClientFolder) { Remove-Item $umbracoClientFolder -Recurse -Force -Confirm:$false }
}
@@ -5,10 +5,8 @@ using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Linq.Expressions;
using System.Text;
using System.Web.Services.Description;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Dynamics
{
@@ -22,20 +20,6 @@ namespace Umbraco.Core.Dynamics
/// </summary>
private static readonly ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]> MethodCache = new ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]>();
private static IEnumerable<Type> GetTypes(Assembly a)
{
try
{
return TypeFinder.GetTypesWithFormattedException(a);
}
catch (ReflectionTypeLoadException ex)
{
// is this going to flood the log?
LogHelper.Error(typeof (ExtensionMethodFinder), "Failed to get types.", ex);
return Enumerable.Empty<Type>();
}
}
/// <summary>
/// Returns the enumerable of all extension method info's in the app domain = USE SPARINGLY!!!
/// </summary>
@@ -52,7 +36,7 @@ namespace Umbraco.Core.Dynamics
// assemblies that contain extension methods
.Where(a => a.IsDefined(typeof (ExtensionAttribute), false))
// types that contain extension methods
.SelectMany(a => GetTypes(a)
.SelectMany(a => a.GetTypes()
.Where(t => t.IsDefined(typeof (ExtensionAttribute), false) && t.IsSealed && t.IsGenericType == false && t.IsNested == false))
// actual extension methods
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public)
@@ -61,9 +45,9 @@ namespace Umbraco.Core.Dynamics
.Concat(typeof (Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public))
//If we don't do this then we'll be scanning all assemblies each time!
.ToArray(),
//only cache for 5 minutes
timeout: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromMinutes(5),
//each time this is accessed it will be for 5 minutes longer
isSliding:true);
@@ -73,7 +57,7 @@ namespace Umbraco.Core.Dynamics
/// Returns all extension methods found matching the definition
/// </summary>
/// <param name="runtimeCache">
/// The runtime cache is used to temporarily cache all extension methods found in the app domain so that
/// The runtime cache is used to temporarily cache all extension methods found in the app domain so that
/// while we search for individual extension methods, the process will be reasonably 'quick'. We then statically
/// cache the MethodInfo's that we are looking for and then the runtime cache will expire and give back all that memory.
/// </param>
@@ -94,7 +78,7 @@ namespace Umbraco.Core.Dynamics
{
var candidates = GetAllExtensionMethodsInAppDomain(runtimeCache);
// filter by name
// filter by name
var filtr1 = candidates.Where(m => m.Name == name);
// filter by args count
@@ -118,7 +102,7 @@ namespace Umbraco.Core.Dynamics
return filtr3.ToArray();
});
}
private static MethodInfo DetermineMethodFromParams(IEnumerable<MethodInfo> methods, Type genericType, IEnumerable<object> args)
@@ -139,12 +123,12 @@ namespace Umbraco.Core.Dynamics
types = method.GetParameters().Select(pi => pi.ParameterType).Skip(1)
});
//This type comparer will check
//This type comparer will check
var typeComparer = new DelegateEqualityComparer<Type>(
//Checks if the argument type passed in can be assigned from the parameter type in the method. For
//Checks if the argument type passed in can be assigned from the parameter type in the method. For
// example, if the argument type is HtmlHelper<MyModel> but the method parameter type is HtmlHelper then
// it will match because the argument is assignable to that parameter type and will be able to execute
TypeHelper.IsTypeAssignableFrom,
TypeHelper.IsTypeAssignableFrom,
//This will not ever execute but if it does we need to get the hash code of the string because the hash
// code of a type is random
type => type.FullName.GetHashCode());
@@ -175,7 +159,7 @@ namespace Umbraco.Core.Dynamics
.ToArray();
var methods = GetAllExtensionMethods(runtimeCache, thisType, name, args.Length).ToArray();
return DetermineMethodFromParams(methods, genericType, args);
}
}
+20 -59
View File
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using Semver;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.Migrations;
namespace Umbraco.Core.Events
@@ -14,50 +13,24 @@ namespace Umbraco.Core.Events
/// </summary>
/// <param name="eventObject"></param>
/// <param name="targetVersion"></param>
/// <param name="productName"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, string productName, bool canCancel)
: this(eventObject, null, configuredVersion, targetVersion, productName, canCancel)
{ }
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="targetVersion"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, bool canCancel)
: this(eventObject, null, configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName, canCancel)
{ }
[Obsolete("Use constructor accepting SemVersion instances and a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, Version configuredVersion, Version targetVersion, bool canCancel)
: this(eventObject, null, new SemVersion(configuredVersion), new SemVersion(targetVersion), GlobalSettings.UmbracoMigrationName, canCancel)
{ }
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="migrationContext"></param>
/// <param name="targetVersion"></param>
/// <param name="productName"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
internal MigrationEventArgs(IList<IMigration> eventObject, MigrationContext migrationContext, SemVersion configuredVersion, SemVersion targetVersion, string productName, bool canCancel)
: base(eventObject, canCancel)
{
MigrationContext = migrationContext;
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
ProductName = productName;
}
[Obsolete("Use constructor accepting UmbracoVersion instances instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, Version configuredVersion, Version targetVersion, bool canCancel)
: base(eventObject, canCancel)
{
ConfiguredSemVersion = new SemVersion(configuredVersion);
TargetSemVersion = new SemVersion(targetVersion);
}
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
@@ -66,15 +39,12 @@ namespace Umbraco.Core.Events
/// <param name="targetVersion"></param>
/// <param name="canCancel"></param>
/// <param name="configuredVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
internal MigrationEventArgs(IList<IMigration> eventObject, MigrationContext migrationContext, SemVersion configuredVersion, SemVersion targetVersion, bool canCancel)
: base(eventObject, canCancel)
{
MigrationContext = migrationContext;
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
ProductName = GlobalSettings.UmbracoMigrationName;
}
/// <summary>
@@ -83,28 +53,21 @@ namespace Umbraco.Core.Events
/// <param name="eventObject"></param>
/// <param name="configuredVersion"></param>
/// <param name="targetVersion"></param>
/// <param name="productName"></param>
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion, string productName)
: this(eventObject, null, configuredVersion, targetVersion, productName, false)
{ }
/// <summary>
/// Constructor accepting multiple migrations that are used in the migration runner
/// </summary>
/// <param name="eventObject"></param>
/// <param name="configuredVersion"></param>
/// <param name="targetVersion"></param>
[Obsolete("Use constructor accepting a product name instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, SemVersion configuredVersion, SemVersion targetVersion)
: this(eventObject, null, configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName, false)
{ }
: base(eventObject)
{
ConfiguredSemVersion = configuredVersion;
TargetSemVersion = targetVersion;
}
[Obsolete("Use constructor accepting SemVersion instances and a product name instead.")]
[Obsolete("Use constructor accepting UmbracoVersion instances instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationEventArgs(IList<IMigration> eventObject, Version configuredVersion, Version targetVersion)
: this(eventObject, null, new SemVersion(configuredVersion), new SemVersion(targetVersion), GlobalSettings.UmbracoMigrationName, false)
{ }
: base(eventObject)
{
ConfiguredSemVersion = new SemVersion(configuredVersion);
TargetSemVersion = new SemVersion(targetVersion);
}
/// <summary>
/// Returns all migrations that were used in the migration runner
@@ -132,8 +95,6 @@ namespace Umbraco.Core.Events
public SemVersion TargetSemVersion { get; private set; }
public string ProductName { get; private set; }
internal MigrationContext MigrationContext { get; private set; }
}
}
+1 -7
View File
@@ -7,12 +7,6 @@ namespace Umbraco.Core.Models
/// </summary
public interface IMediaType : IContentTypeComposition
{
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <param name="newAlias"></param>
/// <returns></returns>
IMediaType DeepCloneWithResetIdentities(string newAlias);
}
}
-25
View File
@@ -38,30 +38,5 @@ namespace Umbraco.Core.Models
: base(parent, alias)
{
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset
/// </summary>
/// <returns></returns>
public IMediaType DeepCloneWithResetIdentities(string alias)
{
var clone = (MediaType)DeepClone();
clone.Alias = alias;
clone.Key = Guid.Empty;
foreach (var propertyGroup in clone.PropertyGroups)
{
propertyGroup.ResetIdentity();
propertyGroup.ResetDirtyProperties(false);
}
foreach (var propertyType in clone.PropertyTypes)
{
propertyType.ResetIdentity();
propertyType.ResetDirtyProperties(false);
}
clone.ResetIdentity();
clone.ResetDirtyProperties(false);
return clone;
}
}
}
@@ -114,25 +114,10 @@ namespace Umbraco.Core.Models.PublishedContent
internal static void ClearContentType(int id)
{
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
// we don't support "get all" at the moment - so, cheating
var all = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItemsByKeySearch<PublishedContentType>("PublishedContentType_").ToArray();
// the one we want to clear
var clr = all.FirstOrDefault(x => x.Id == id);
if (clr == null) return;
// those that have that one in their composition aliases
// note: CompositionAliases contains all recursive aliases
var oth = all.Where(x => x.CompositionAliases.InvariantContains(clr.Alias)).Select(x => x.Id);
// merge ids
var ids = oth.Concat(new[] { clr.Id }).ToArray();
// clear them all at once
// we don't support "clear many at once" at the moment - so, cheating
// requires a predicate because the key does not contain the ID
// faster than key strings comparisons anyway
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
(key, value) => ids.Contains(value.Id));
(key, value) => value.Id == id);
}
internal static void ClearDataType(int id)
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
@@ -28,21 +27,18 @@ namespace Umbraco.Core.Persistence.Migrations
private readonly IMigration[] _migrations;
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(Version currentVersion, Version targetVersion, string productName)
: this(LoggerResolver.Current.Logger, currentVersion, targetVersion, productName)
{
}
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(ILogger logger, Version currentVersion, Version targetVersion, string productName)
: this(logger, currentVersion, targetVersion, productName, null)
{
}
[Obsolete("Use the ctor that specifies all dependencies instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public MigrationRunner(ILogger logger, Version currentVersion, Version targetVersion, string productName, params IMigration[] migrations)
: this(ApplicationContext.Current.Services.MigrationEntryService, logger, new SemVersion(currentVersion), new SemVersion(targetVersion), productName, migrations)
{
@@ -96,7 +92,7 @@ namespace Umbraco.Core.Persistence.Migrations
: OrderedDowngradeMigrations(foundMigrations).ToList();
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, _productName, true), this))
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this))
{
_logger.Warn<MigrationRunner>("Migration was cancelled by an event");
return false;
@@ -125,7 +121,7 @@ namespace Umbraco.Core.Persistence.Migrations
throw;
}
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, _productName, false), this);
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, false), this);
return true;
}
@@ -128,34 +128,6 @@ namespace Umbraco.Core.Persistence.Querying
right = Visit(b.Right);
}
}
else if (operand == "=")
{
// deal with (x == true|false) - most common
var constRight = b.Right as ConstantExpression;
if (constRight != null && constRight.Type == typeof (bool))
return ((bool) constRight.Value) ? VisitNotNot(b.Left) : VisitNot(b.Left);
right = Visit(b.Right);
// deal with (true|false == x) - why not
var constLeft = b.Left as ConstantExpression;
if (constLeft != null && constLeft.Type == typeof (bool))
return ((bool) constLeft.Value) ? VisitNotNot(b.Right) : VisitNot(b.Right);
left = Visit(b.Left);
}
else if (operand == "<>")
{
// deal with (x != true|false) - most common
var constRight = b.Right as ConstantExpression;
if (constRight != null && constRight.Type == typeof(bool))
return ((bool) constRight.Value) ? VisitNot(b.Left) : VisitNotNot(b.Left);
right = Visit(b.Right);
// deal with (true|false != x) - why not
var constLeft = b.Left as ConstantExpression;
if (constLeft != null && constLeft.Type == typeof(bool))
return ((bool) constLeft.Value) ? VisitNot(b.Right) : VisitNotNot(b.Right);
left = Visit(b.Left);
}
else
{
left = Visit(b.Left);
@@ -259,47 +231,25 @@ namespace Umbraco.Core.Persistence.Querying
switch (u.NodeType)
{
case ExpressionType.Not:
return VisitNot(u.Operand);
var o = Visit(u.Operand);
//use a Not equal operator instead of <> since we don't know that <> works in all sql servers
switch (u.Operand.NodeType)
{
case ExpressionType.MemberAccess:
//In this case it wil be a false property , i.e. x => !Trashed
SqlParameters.Add(true);
return string.Format("NOT ({0} = @0)", o);
default:
//In this case it could be anything else, such as: x => !x.Path.StartsWith("-20")
return string.Format("NOT ({0})", o);
}
default:
return Visit(u.Operand);
}
}
private string VisitNot(Expression exp)
{
var o = Visit(exp);
// use a "NOT (...)" syntax instead of "<>" since we don't know whether "<>" works in all sql servers
// also, x.StartsWith(...) translates to "x LIKE '...%'" which we cannot "<>" and have to "NOT (...")
switch (exp.NodeType)
{
case ExpressionType.MemberAccess:
// false property , i.e. x => !Trashed
SqlParameters.Add(true);
return "NOT (" + o + " = @0)";
default:
// could be anything else, such as: x => !x.Path.StartsWith("-20")
return "NOT (" + o + ")";
}
}
private string VisitNotNot(Expression exp)
{
var o = Visit(exp);
switch (exp.NodeType)
{
case ExpressionType.MemberAccess:
// true property, i.e. x => Trashed
SqlParameters.Add(true);
return o + " = @0";
default:
// could be anything else, such as: x => x.Path.StartsWith("-20")
return o;
}
}
protected virtual string VisitNewArray(NewArrayExpression na)
{
@@ -1212,19 +1212,5 @@ AND umbracoNode.id <> @id",
{
return PerformExists(id);
}
public string GetUniqueAlias(string alias)
{
// alias is unique accross ALL content types!
var aliasColumn = SqlSyntax.GetQuotedColumnName("alias");
var aliases = Database.Fetch<string>(@"SELECT cmsContentType." + aliasColumn + @" FROM cmsContentType
INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id
WHERE cmsContentType." + aliasColumn + @" LIKE @pattern",
new { pattern = alias + "%", objectType = NodeObjectTypeId });
var i = 1;
string test;
while (aliases.Contains(test = alias + i)) i++;
return test;
}
}
}
@@ -32,13 +32,5 @@ namespace Umbraco.Core.Persistence.Repositories
/// </param>
/// <returns></returns>
IEnumerable<string> GetAllContentTypeAliases(params Guid[] objectTypes);
/// <summary>
/// Derives a unique alias from an existing alias.
/// </summary>
/// <param name="alias">The original alias.</param>
/// <returns>The original alias with a number appended to it, so that it is unique.</returns>
/// /// <remarks>Unique accross all content, media and member types.</remarks>
string GetUniqueAlias(string alias);
}
}
@@ -15,13 +15,5 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable<IMediaType> GetByQuery(IQuery<PropertyType> query);
IEnumerable<MoveEventInfo<IMediaType>> Move(IMediaType toMove, EntityContainer container);
/// <summary>
/// Derives a unique alias from an existing alias.
/// </summary>
/// <param name="alias">The original alias.</param>
/// <returns>The original alias with a number appended to it, so that it is unique.</returns>
/// <remarks>Unique accross all content, media and member types.</remarks>
string GetUniqueAlias(string alias);
}
}
@@ -794,7 +794,7 @@ namespace Umbraco.Core.Services
//TODO: This needs to change, if we are deleting a content type, we should just delete the data,
// this method will recursively go lookup every content item, check if any of it's descendants are
// of a different type, move them to the recycle bin, then permanently delete the content items.
// of a different type, move them to the recycle bin, then permanently delete the content items.
// The main problem with this is that for every content item being deleted, events are raised...
// which we need for many things like keeping caches in sync, but we can surely do this MUCH better.
@@ -1067,92 +1067,6 @@ namespace Umbraco.Core.Services
new OperationStatus<MoveOperationStatusType>(MoveOperationStatusType.Success, evtMsgs));
}
public Attempt<OperationStatus<IMediaType, MoveOperationStatusType>> CopyMediaType(IMediaType toCopy, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
IMediaType copy;
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.MediaTypeContainerGuid))
using (var repository = RepositoryFactory.CreateMediaTypeRepository(uow))
{
try
{
if (containerId > 0)
{
var container = containerRepository.Get(containerId);
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
var alias = repository.GetUniqueAlias(toCopy.Alias);
copy = toCopy.DeepCloneWithResetIdentities(alias);
copy.Name = copy.Name + " (copy)"; // might not be unique
// if it has a parent, and the parent is a content type, unplug composition
// all other compositions remain in place in the copied content type
if (copy.ParentId > 0)
{
var parent = repository.Get(copy.ParentId);
if (parent != null)
copy.RemoveContentType(parent.Alias);
}
copy.ParentId = containerId;
repository.AddOrUpdate(copy);
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(new OperationStatus<IMediaType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
}
return Attempt.Succeed(new OperationStatus<IMediaType, MoveOperationStatusType>(copy, MoveOperationStatusType.Success, evtMsgs));
}
public Attempt<OperationStatus<IContentType, MoveOperationStatusType>> CopyContentType(IContentType toCopy, int containerId)
{
var evtMsgs = EventMessagesFactory.Get();
IContentType copy;
var uow = UowProvider.GetUnitOfWork();
using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow, Constants.ObjectTypes.DocumentTypeContainerGuid))
using (var repository = RepositoryFactory.CreateContentTypeRepository(uow))
{
try
{
if (containerId > 0)
{
var container = containerRepository.Get(containerId);
if (container == null)
throw new DataOperationException<MoveOperationStatusType>(MoveOperationStatusType.FailedParentNotFound);
}
var alias = repository.GetUniqueAlias(toCopy.Alias);
copy = toCopy.DeepCloneWithResetIdentities(alias);
copy.Name = copy.Name + " (copy)"; // might not be unique
// if it has a parent, and the parent is a content type, unplug composition
// all other compositions remain in place in the copied content type
if (copy.ParentId > 0)
{
var parent = repository.Get(copy.ParentId);
if (parent != null)
copy.RemoveContentType(parent.Alias);
}
copy.ParentId = containerId;
repository.AddOrUpdate(copy);
}
catch (DataOperationException<MoveOperationStatusType> ex)
{
return Attempt.Fail(new OperationStatus<IContentType, MoveOperationStatusType>(null, ex.Operation, evtMsgs));
}
uow.Commit();
}
return Attempt.Succeed(new OperationStatus<IContentType, MoveOperationStatusType>(copy, MoveOperationStatusType.Success, evtMsgs));
}
/// <summary>
/// Saves a single <see cref="IMediaType"/> object
/// </summary>
@@ -291,7 +291,5 @@ namespace Umbraco.Core.Services
Attempt<OperationStatus<MoveOperationStatusType>> MoveMediaType(IMediaType toMove, int containerId);
Attempt<OperationStatus<MoveOperationStatusType>> MoveContentType(IContentType toMove, int containerId);
Attempt<OperationStatus<IMediaType, MoveOperationStatusType>> CopyMediaType(IMediaType toCopy, int containerId);
Attempt<OperationStatus<IContentType, MoveOperationStatusType>> CopyContentType(IContentType toCopy, int containerId);
}
}
+28 -59
View File
@@ -22,7 +22,7 @@ namespace Umbraco.Core
/// <summary>
/// A utility class to find all classes of a certain type by reflection in the current bin folder
/// of the web application.
/// of the web application.
/// </summary>
public static class TypeFinder
{
@@ -34,7 +34,7 @@ namespace Umbraco.Core
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
/// </summary>
/// <remarks>
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// loaded in the CLR, not all assemblies.
/// See these threads:
/// http://issues.umbraco.org/issue/U5-198
@@ -136,7 +136,7 @@ namespace Umbraco.Core
});
/// <summary>
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
/// cached for perforance reasons.
/// </summary>
@@ -190,7 +190,6 @@ namespace Umbraco.Core
/// </summary>
/// <remarks>
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
/// NOTE this means that "foo." will NOT exclude "foo.dll" but only "foo.*.dll"
/// </remarks>
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
{
@@ -215,7 +214,7 @@ namespace Umbraco.Core
"RouteDebugger,",
"SqlCE4Umbraco,",
"umbraco.datalayer,",
"umbraco.interfaces,",
"umbraco.interfaces,",
//"umbraco.providers,",
//"Umbraco.Web.UI,",
"umbraco.webservices",
@@ -231,9 +230,9 @@ namespace Umbraco.Core
"AutoMapper,",
"AutoMapper.",
"AzureDirectory,",
"itextsharp,",
"itextsharp,",
"UrlRewritingNet.",
"HtmlAgilityPack,",
"HtmlAgilityPack,",
"MiniProfiler,",
"Moq,",
"nunit.framework,",
@@ -372,7 +371,7 @@ namespace Umbraco.Core
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the attribute type's assembly since we
//find all assembly references that are referencing the attribute type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain a class that has this attribute.
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
@@ -419,7 +418,7 @@ namespace Umbraco.Core
foreach (var subTypesInAssembly in allAttributeTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
// * We should not search for sub types if the type is static since you cannot inherit from them.
@@ -490,7 +489,7 @@ namespace Umbraco.Core
/// <summary>
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// deriving from the base type.
/// </summary>
/// <param name="assignTypeFrom"></param>
@@ -514,7 +513,7 @@ namespace Umbraco.Core
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the current type's assembly since we
//find all assembly references that are referencing the current type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain sub type's of the one we're currently looking for
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
@@ -561,7 +560,7 @@ namespace Umbraco.Core
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
// * We should not search for sub types if the type is static since you cannot inherit from them.
@@ -603,69 +602,39 @@ namespace Umbraco.Core
return foundAssignableTypes;
}
internal static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
{
//if the assembly is dynamic, do not try to scan it
if (a.IsDynamic)
return Enumerable.Empty<Type>();
var getAll = a.GetCustomAttribute<AllowPartiallyTrustedCallersAttribute>() == null;
try
{
//we need to detect if an assembly is partially trusted, if so we cannot go interrogating all of it's types
//only its exported types, otherwise we'll get exceptions.
return getAll ? a.GetTypes() : a.GetExportedTypes();
if (a.GetCustomAttribute<AllowPartiallyTrustedCallersAttribute>() == null)
{
return a.GetTypes();
}
else
{
return a.GetExportedTypes();
}
}
catch (TypeLoadException ex) // GetExportedTypes *can* throw TypeLoadException!
catch (ReflectionTypeLoadException ex)
{
var sb = new StringBuilder();
AppendCouldNotLoad(sb, a, getAll);
AppendLoaderException(sb, ex);
// rethrow as ReflectionTypeLoadException (for consistency) with new message
throw new ReflectionTypeLoadException(new Type[0], new Exception[] { ex }, sb.ToString());
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
{
sb.AppendLine("Exception: " + loaderException);
}
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
}
catch (ReflectionTypeLoadException rex) // GetTypes throws ReflectionTypeLoadException
{
var sb = new StringBuilder();
AppendCouldNotLoad(sb, a, getAll);
foreach (var loaderException in rex.LoaderExceptions.WhereNotNull())
AppendLoaderException(sb, loaderException);
// rethrow with new message
throw new ReflectionTypeLoadException(rex.Types, rex.LoaderExceptions, sb.ToString());
}
}
private static void AppendCouldNotLoad(StringBuilder sb, Assembly a, bool getAll)
{
sb.Append("Could not load ");
sb.Append(getAll ? "all" : "exported");
sb.Append(" types from \"");
sb.Append(a.FullName);
sb.AppendLine("\" due to LoaderExceptions, skipping:");
}
private static void AppendLoaderException(StringBuilder sb, Exception loaderException)
{
sb.Append(". ");
sb.Append(loaderException.GetType().FullName);
var tloadex = loaderException as TypeLoadException;
if (tloadex != null)
{
sb.Append(" on ");
sb.Append(tloadex.TypeName);
}
sb.Append(": ");
sb.Append(loaderException.Message);
sb.AppendLine();
}
#endregion
public static Type GetTypeByName(string typeName)
{
@@ -1,100 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using Semver;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
using Umbraco.Web.Strategies.Migrations;
namespace Umbraco.Tests.Persistence.Migrations
{
[TestFixture]
public class MigrationStartupHandlerTests
{
[Test]
public void Executes_For_Any_Product_Name_When_Not_Specified()
{
var changed1 = new Args { CountExecuted = 0 };
var testHandler1 = new TestMigrationHandler(changed1);
testHandler1.OnApplicationStarting(Mock.Of<UmbracoApplicationBase>(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
var conn = new Mock<IDbConnection>();
conn.Setup(x => x.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(Mock.Of<IDbTransaction>());
var db = new Mock<Database>(conn.Object);
var runner1 = new MigrationRunner(Mock.Of<IMigrationEntryService>(), Mock.Of<ILogger>(), new SemVersion(1), new SemVersion(2), "Test1",
new IMigration[] { Mock.Of<IMigration>() });
var result1 = runner1.Execute(db.Object, DatabaseProviders.SqlServerCE, false);
Assert.AreEqual(1, changed1.CountExecuted);
}
[Test]
public void Executes_Only_For_Specified_Product_Name()
{
var changed1 = new Args { CountExecuted = 0};
var testHandler1 = new TestMigrationHandler("Test1", changed1);
testHandler1.OnApplicationStarting(Mock.Of<UmbracoApplicationBase>(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
var changed2 = new Args { CountExecuted = 0 };
var testHandler2 = new TestMigrationHandler("Test2", changed2);
testHandler2.OnApplicationStarting(Mock.Of<UmbracoApplicationBase>(), new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>())));
var conn = new Mock<IDbConnection>();
conn.Setup(x => x.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(Mock.Of<IDbTransaction>());
var db = new Mock<Database>(conn.Object);
var runner1 = new MigrationRunner(Mock.Of<IMigrationEntryService>(), Mock.Of<ILogger>(), new SemVersion(1), new SemVersion(2), "Test1",
new IMigration[] { Mock.Of<IMigration>()});
var result1 = runner1.Execute(db.Object, DatabaseProviders.SqlServerCE, false);
Assert.AreEqual(1, changed1.CountExecuted);
Assert.AreEqual(0, changed2.CountExecuted);
var runner2 = new MigrationRunner(Mock.Of<IMigrationEntryService>(), Mock.Of<ILogger>(), new SemVersion(1), new SemVersion(2), "Test2",
new IMigration[] { Mock.Of<IMigration>() });
var result2 = runner2.Execute(db.Object, DatabaseProviders.SqlServerCE, false);
Assert.AreEqual(1, changed1.CountExecuted);
Assert.AreEqual(1, changed2.CountExecuted);
}
public class Args
{
public int CountExecuted { get; set; }
}
public class TestMigrationHandler : MigrationStartupHander
{
private readonly string _prodName;
private readonly Args _changed;
public TestMigrationHandler(Args changed)
{
_changed = changed;
}
public TestMigrationHandler(string prodName, Args changed)
{
_prodName = prodName;
_changed = changed;
}
protected override void AfterMigration(MigrationRunner sender, MigrationEventArgs e)
{
_changed.CountExecuted++;
}
public override string[] TargetProductNames
{
get { return _prodName.IsNullOrWhiteSpace() ? new string[] {} : new[] {_prodName}; }
}
}
}
}
@@ -51,18 +51,6 @@ namespace Umbraco.Tests.Persistence.Querying
Assert.AreEqual("-20%", sql.Arguments[1]);
}
[Test]
public void Where_Clause_With_EqualsFalse_Starts_With()
{
var level = 1;
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.Level == level && x.Path.StartsWith("-20") == false);
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[level] = @0 AND NOT (upper([umbracoNode].[path]) LIKE upper(@1)))", sql.SQL.Replace("\n", " "));
Assert.AreEqual(2, sql.Arguments.Length);
Assert.AreEqual(level, sql.Arguments[0]);
Assert.AreEqual("-20%", sql.Arguments[1]);
}
[Test]
public void Where_Clause_With_Equals_Clause()
{
@@ -83,16 +71,6 @@ namespace Umbraco.Tests.Persistence.Querying
Assert.AreEqual(true, sql.Arguments[0]);
}
[Test]
public void Where_Clause_With_EqualsFalse_Boolean()
{
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.Trashed == false);
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " "));
Assert.AreEqual(1, sql.Arguments.Length);
Assert.AreEqual(true, sql.Arguments[0]);
}
[Test]
public void Where_Clause_With_Boolean()
{
+2 -2
View File
@@ -79,8 +79,8 @@ namespace Umbraco.Tests.Plugins
var originalTypesFound = TypeFinderOriginal.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
Assert.AreEqual(originalTypesFound.Count(), typesFound.Count());
Assert.AreEqual(9, typesFound.Count());
Assert.AreEqual(9, originalTypesFound.Count());
Assert.AreEqual(8, typesFound.Count());
Assert.AreEqual(8, originalTypesFound.Count());
}
[Test]
-2
View File
@@ -175,7 +175,6 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Persistence\Migrations\MigrationStartupHandlerTests.cs" />
<Compile Include="Web\AngularIntegration\AngularAntiForgeryTests.cs" />
<Compile Include="Web\AngularIntegration\ContentModelSerializationTests.cs" />
<Compile Include="Web\AngularIntegration\JsInitializationTests.cs" />
@@ -245,7 +244,6 @@
<Compile Include="Models\UmbracoEntityTests.cs" />
<Compile Include="Models\UserTests.cs" />
<Compile Include="Models\UserTypeTests.cs" />
<Compile Include="Web\Mvc\RenderModelBinderTests.cs" />
<Compile Include="Web\Mvc\SurfaceControllerTests.cs" />
<Compile Include="Web\Mvc\UmbracoViewPageTests.cs" />
<Compile Include="BootManagers\CoreBootManagerTests.cs" />
@@ -1,157 +0,0 @@
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class RenderModelBinderTests
{
[Test]
public void Returns_Binder_For_IPublishedContent_And_IRenderModel()
{
var binder = new RenderModelBinder();
var found = binder.GetBinder(typeof (IPublishedContent));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(IRenderModel));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(RenderModel));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(DynamicPublishedContent));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(MyContent));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(MyOtherContent));
Assert.IsNull(found);
}
[Test]
public void BindModel_Null_Source_Returns_Null()
{
Assert.IsNull(RenderModelBinder.BindModel(null, typeof(MyContent), CultureInfo.CurrentCulture));
}
[Test]
public void BindModel_Returns_If_Same_Type()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = RenderModelBinder.BindModel(content, typeof (IPublishedContent), CultureInfo.CurrentCulture);
Assert.AreSame(content, bound);
}
[Test]
public void BindModel_RenderModel_To_IPublishedContent()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var renderModel = new RenderModel(content, CultureInfo.CurrentCulture);
var bound = RenderModelBinder.BindModel(renderModel, typeof(IPublishedContent), CultureInfo.CurrentCulture);
Assert.AreSame(content, bound);
}
[Test]
public void BindModel_IPublishedContent_To_RenderModel()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = (IRenderModel)RenderModelBinder.BindModel(content, typeof(RenderModel), CultureInfo.CurrentCulture);
Assert.AreSame(content, bound.Content);
}
[Test]
public void BindModel_IPublishedContent_To_Generic_RenderModel()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = (IRenderModel)RenderModelBinder.BindModel(content, typeof(RenderModel<MyContent>), CultureInfo.CurrentCulture);
Assert.AreSame(content, bound.Content);
}
[Test]
public void No_DataToken_Returns_Null()
{
var binder = new RenderModelBinder();
var routeData = new RouteData();
var result = binder.BindModel(new ControllerContext(Mock.Of<HttpContextBase>(), routeData, Mock.Of<ControllerBase>()),
new ModelBindingContext());
Assert.IsNull(result);
}
[Test]
public void Invalid_DataToken_Model_Type_Returns_Null()
{
var binder = new RenderModelBinder();
var routeData = new RouteData();
routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = "hello";
//the value provider is the default implementation
var valueProvider = new Mock<IValueProvider>();
//also IUnvalidatedValueProvider
var invalidatedValueProvider = valueProvider.As<IUnvalidatedValueProvider>();
invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny<string>(), It.IsAny<bool>())).Returns(() =>
new ValueProviderResult(null, "", CultureInfo.CurrentCulture));
var controllerCtx = new ControllerContext(
Mock.Of<HttpContextBase>(http => http.Items == new Dictionary<object, object>()),
routeData,
Mock.Of<ControllerBase>());
var result = binder.BindModel(controllerCtx,
new ModelBindingContext
{
ValueProvider = valueProvider.Object,
ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content")
});
Assert.IsNull(result);
}
[Test]
public void IPublishedContent_DataToken_Model_Type_Uses_DefaultImplementation()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var binder = new RenderModelBinder();
var routeData = new RouteData();
routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = content;
//the value provider is the default implementation
var valueProvider = new Mock<IValueProvider>();
//also IUnvalidatedValueProvider
var invalidatedValueProvider = valueProvider.As<IUnvalidatedValueProvider>();
invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny<string>(), It.IsAny<bool>())).Returns(() =>
new ValueProviderResult(content, "content", CultureInfo.CurrentCulture));
var controllerCtx = new ControllerContext(
Mock.Of<HttpContextBase>(http => http.Items == new Dictionary<object, object>()),
routeData,
Mock.Of<ControllerBase>());
var result = binder.BindModel(controllerCtx,
new ModelBindingContext
{
ValueProvider = valueProvider.Object,
ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content")
});
Assert.AreEqual(content, result);
}
public class MyOtherContent
{
}
public class MyContent : PublishedContentWrapped
{
public MyContent(IPublishedContent content) : base(content)
{
}
}
}
}
+7 -7
View File
@@ -1,5 +1,5 @@
{
"env": {
"env": {
"browser": true
},
@@ -8,7 +8,7 @@
],
"rules": {
"eqeqeq": 2,
"eqeqeq": 2,
"curly": 2,
"no-unused-vars": 1,
@@ -18,8 +18,8 @@
"dot-notation": 1,
"no-use-before-define": 0,
"angular/ng_controller_as": 1,
"angular/ng_controller_as_vm": 1,
"angular/ng_controller_as": 1,
"angular/ng_controller_as_vm": 1,
"strict": 0,
@@ -32,8 +32,8 @@
"comma-spacing": 0,
"no-trailing-spaces": 0,
"eol-last": 0,
"no-underscore-dangle": 0,
"camelcase": 0
"no-underscore-dangle": 0,
"camelcase": 0
},
"globals": {
@@ -50,4 +50,4 @@
"Bloodhound", false
}
}
}
@@ -210,7 +210,7 @@ function submit()
if (findDepth(curLineHTML, cc) !== 0) {
// Cursor is inside a <tag>, don't set cursor:
curLineHTML = curLineHTML.replace(cc, '');
doc.getLineHandle(pos.line).text = curLineHTML;
doc.setLine(pos.line, curLineHTML);
}
// Submit HTML to TinyMCE:
+1 -1
View File
@@ -37,7 +37,7 @@
"grunt-ngdocs": "~0.1.2",
"grunt-open": "~0.2.0",
"grunt-postcss": "~0.6.0",
"grunt-recess": "~0.3",
"grunt-recess": "~1.0.1",
"karma": "~0.9",
"karma-chrome-launcher": "0.0.2",
"karma-coffee-preprocessor": "0.0.1",
+7 -27
View File
@@ -22,35 +22,15 @@ var packages = angular.module("umbraco.packages", []);
//module is initilized.
angular.module("umbraco.views", ["umbraco.viewcache"]);
angular.module("umbraco.viewcache", [])
.run(function($rootScope, $templateCache) {
/** For debug mode, always clear template cache to cut down on
.run(function($rootScope, $templateCache){
/** For debug mode, always clear template cache to cut down on
dev frustration and chrome cache on templates */
if (Umbraco.Sys.ServerVariables.isDebuggingEnabled) {
$templateCache.removeAll();
if(Umbraco.Sys.ServerVariables.isDebuggingEnabled){
//$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
//});
}
})
.config([
//This ensures that all of our angular views are cache busted, if the path starts with views/ and ends with .html, then
// we will append the cache busting value to it. This way all upgraded sites will not have to worry about browser cache.
"$provide", function($provide) {
return $provide.decorator("$http", [
"$delegate", function($delegate) {
var get = $delegate.get;
$delegate.get = function (url, config) {
if (Umbraco.Sys.ServerVariables.application && url.startsWith("views/") && url.endsWith(".html")) {
var rnd = Umbraco.Sys.ServerVariables.application.version + "." + Umbraco.Sys.ServerVariables.application.cdf;
var _op = (url.indexOf("?") > 0) ? "&" : "?";
url += _op + "umb__rnd=" + rnd;
}
return get(url, config);
};
return $delegate;
}
]);
}
]);
})
//Call a document callback if defined, this is sort of a dodgy hack to
// be able to configure angular values in the Default.cshtml
@@ -17,7 +17,7 @@
if(convert){
element.html("<i class='icon-section " + convert + "'></i>");
}else{
element.html("<img class='icon-section' src='images/tray/" + icon + "'>");
element.html("<img src='images/tray/" + icon + "'>");
}
//it's a file, normally legacy so look in the icon tray images
}
@@ -3,11 +3,93 @@
* @name umbraco.directives.directive:umbNavigation
* @restrict E
**/
function umbNavigationDirective() {
function umbNavigationDirective(appState, $location) {
return {
restrict: "E", // restrict to an element
replace: true, // replace the html element with the template
templateUrl: 'views/components/application/umb-navigation.html'
templateUrl: 'views/components/application/umb-navigation.html',
link: function (scope, element, attr, ctrl) {
scope.showTreeNavigation = appState.getGlobalState("showNavigation");
scope.searchClick = function() {
scope.searchOverlay = {
view: "search",
show: true,
submit: function(model) {
$location.path(model.selectedItem.editorPath);
scope.searchOverlay.show = false;
scope.searchOverlay = null;
},
close: function(oldModel) {
scope.searchOverlay.show = false;
scope.searchOverlay = null;
}
};
};
scope.avatarClick = function(){
if(scope.helpDialog) {
closeHelpDialog();
}
if(!scope.userDialog) {
scope.userDialog = {
view: "user",
show: true,
close: function(oldModel) {
closeUserDialog();
}
};
} else {
closeUserDialog();
}
};
function closeUserDialog() {
scope.userDialog.show = false;
scope.userDialog = null;
}
scope.helpClick = function(){
if(scope.userDialog) {
closeUserDialog();
}
if(!scope.helpDialog) {
scope.helpDialog = {
view: "help",
show: true,
close: function(oldModel) {
closeHelpDialog();
}
};
} else {
closeHelpDialog();
}
};
function closeHelpDialog() {
scope.helpDialog.show = false;
scope.helpDialog = null;
}
scope.showTree = function () {
scope.showTreeNavigation = appState.getGlobalState("showNavigation");
if(scope.showTreeNavigation === true) {
appState.setGlobalState("showNavigation", false);
} else {
appState.setGlobalState("showNavigation", true);
}
};
}
};
}
@@ -11,7 +11,7 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
link: function (scope, element, attr, ctrl) {
//setup scope vars
scope.maxSections = 7;
scope.maxSections = 5;
scope.overflowingSections = 0;
scope.sections = [];
scope.currentSection = appState.getSectionState("currentSection");
@@ -34,16 +34,25 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
sectionResource.getSections()
.then(function (result) {
scope.sections = result;
calculateHeight();
// hide overflowing sections
scope.totalSections = scope.sections.length;
if(scope.totalSections > scope.maxSections){
scope.needTray = true;
scope.overflowingSections = scope.maxSections - scope.totalSections;
}
// calculateHeight();
});
}
function calculateHeight(){
$timeout(function(){
//total height minus room for avatar and help icon
var height = $(window).height()-200;
var height = $(window).width();
scope.totalSections = scope.sections.length;
scope.maxSections = Math.floor(height / 70);
scope.maxSections = Math.floor(width / 70);
scope.needTray = false;
if(scope.totalSections > scope.maxSections){
@@ -84,57 +93,7 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
});
//on page resize
window.onresize = calculateHeight;
scope.avatarClick = function(){
if(scope.helpDialog) {
closeHelpDialog();
}
if(!scope.userDialog) {
scope.userDialog = {
view: "user",
show: true,
close: function(oldModel) {
closeUserDialog();
}
};
} else {
closeUserDialog();
}
};
function closeUserDialog() {
scope.userDialog.show = false;
scope.userDialog = null;
}
scope.helpClick = function(){
if(scope.userDialog) {
closeUserDialog();
}
if(!scope.helpDialog) {
scope.helpDialog = {
view: "help",
show: true,
close: function(oldModel) {
closeHelpDialog();
}
};
} else {
closeHelpDialog();
}
};
function closeHelpDialog() {
scope.helpDialog.show = false;
scope.helpDialog = null;
}
// window.onresize = calculateHeight;
scope.sectionClick = function (event, section) {
@@ -0,0 +1,30 @@
(function() {
'use strict';
function TreeNavigation(appState) {
function link(scope, el, attr, ctrl) {
scope.showTreeNavigation = false;
scope.currentSection = appState.getSectionState("currentSection");
scope.$watch(function(){
return appState.getGlobalState("showNavigation");
}, function (newValue) {
scope.showTreeNavigation = newValue;
});
}
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/application/umb-tree-navigation.html',
link: link
};
return directive;
}
angular.module('umbraco.directives').directive('umbTreeNavigation', TreeNavigation);
})();
@@ -0,0 +1,18 @@
(function() {
'use strict';
function EditorSubView() {
var directive = {
transclude: true,
restrict: 'E',
replace: true,
templateUrl: 'views/components/editor/subview/umb-editor-sub-view.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorSubView', EditorSubView);
})();
@@ -0,0 +1,18 @@
(function() {
'use strict';
function EditorSubViewContainer() {
var directive = {
transclude: true,
restrict: 'E',
replace: true,
templateUrl: 'views/components/editor/subview/umb-editor-sub-view-container.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorSubViewContainer', EditorSubViewContainer);
})();
@@ -0,0 +1,18 @@
(function() {
'use strict';
function EditorSubViewContent() {
var directive = {
transclude: true,
restrict: 'E',
replace: true,
templateUrl: 'views/components/editor/subview/umb-editor-sub-view-content.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorSubViewContent', EditorSubViewContent);
})();
@@ -0,0 +1,18 @@
(function() {
'use strict';
function EditorSubViewHeader() {
var directive = {
transclude: true,
restrict: 'E',
replace: true,
templateUrl: 'views/components/editor/subview/umb-editor-sub-view-header.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorSubViewHeader', EditorSubViewHeader);
})();
@@ -0,0 +1,18 @@
(function() {
'use strict';
function EditorSubViewSidebar() {
var directive = {
transclude: true,
restrict: 'E',
replace: true,
templateUrl: 'views/components/editor/subview/umb-editor-sub-view-sidebar.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorSubViewSidebar', EditorSubViewSidebar);
})();
@@ -5,8 +5,20 @@
function link(scope, el, attr, ctrl) {
scope.showVariationsQuickSwitchToggle = false;
scope.showVariationsQuickSwitch = false;
scope.variations = variationsHelper.getVariations();
function activate() {
showVariationsQuickSwitch(scope.variations);
}
function showVariationsQuickSwitch(variations) {
if(variations && variations.length > 1 || variations && variations.length === 1 && variations[0].variations && variations[0].variations.length > 0) {
scope.showVariationsQuickSwitchToggle = true;
} else {
scope.showVariationsQuickSwitchToggle = false;
}
}
scope.openIconPicker = function() {
scope.dialogModel = {
@@ -31,6 +43,58 @@
scope.toggleVariationsQuickSwitch = function() {
scope.showVariationsQuickSwitch = !scope.showVariationsQuickSwitch;
};
scope.hideVariationsQuickSwitch = function() {
scope.showVariationsQuickSwitch = false;
};
scope.toggleSubItems = function(item, $event) {
item.showSubItems = !item.showSubItems;
$event.preventDefault();
$event.stopPropagation();
};
scope.selectItem = function(item) {
if(scope.onSelectItem) {
for(var i = 0; i < scope.variations.length; i++) {
var language = scope.variations[i];
language.active = false;
if(language.variations && language.variations.length > 0) {
for(var variationIndex = 0; variationIndex < language.variations.length; variationIndex++) {
var variation = language.variations[variationIndex];
variation.active = false;
}
}
}
// set selected item to active
item.active = true;
scope.onSelectItem(item);
scope.showVariationsQuickSwitch = false;
}
};
scope.openInSplitView = function(item, $event) {
if(scope.onOpenInSplitView) {
scope.onOpenInSplitView(item);
scope.showVariationsQuickSwitch = false;
$event.preventDefault();
$event.stopPropagation();
}
};
scope.$watch('variations', function(newValue, oldValue){
showVariationsQuickSwitch(newValue);
}, true);
activate();
}
var directive = {
@@ -44,6 +108,11 @@
actions: "=",
name: "=",
nameLocked: "=",
variation: "=",
language: "=",
variations: "=",
onSelectItem: "=",
onOpenInSplitView: "=",
menu: "=",
icon: "=",
hideIcon: "@",
@@ -6,10 +6,21 @@
function link(scope, el, attr, ctrl) {
scope.showNavigation = true;
scope.showDropdown = false;
scope.maxNavigationItems = 5;
scope.overflowingNavigationsItems = 0;
scope.needDropdown = false;
scope.clickNavigationItem = function(selectedItem) {
setItemToActive(selectedItem);
runItemAction(selectedItem);
if(scope.showDropdown) {
scope.closeDropdown();
}
};
function runItemAction(selectedItem) {
@@ -40,8 +51,29 @@
scope.showNavigation = false;
}
hideOverflowingNavigationItems();
}
function hideOverflowingNavigationItems() {
scope.totalNavigationItems = scope.navigation.length;
if(scope.totalNavigationItems > scope.maxNavigationItems){
scope.needDropdown = true;
scope.overflowingNavigationsItems = scope.maxNavigationItems - scope.totalNavigationItems;
}
}
scope.toggleDropdown = function() {
scope.showDropdown = !scope.showDropdown;
};
scope.closeDropdown = function() {
scope.showDropdown = false;
};
activate();
}
@@ -3,32 +3,6 @@
function EditorSubViewsDirective() {
function link(scope, el, attr, ctrl) {
scope.activeView = {};
// set toolbar from selected navigation item
function setActiveView(items) {
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.active && item.view) {
scope.activeView = item;
}
}
}
// watch for navigation changes
scope.$watch('subViews', function(newValue, oldValue) {
if (newValue) {
setActiveView(newValue);
}
}, true);
}
var directive = {
restrict: 'E',
replace: true,
@@ -36,8 +10,7 @@
scope: {
subViews: "=",
model: "="
},
link: link
}
};
return directive;
@@ -0,0 +1,19 @@
(function() {
'use strict';
function EditorToolbar() {
var directive = {
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'views/components/editor/umb-editor-toolbar.html'
};
return directive;
}
angular.module('umbraco.directives').directive('umbEditorToolbar', EditorToolbar);
})();
@@ -11,22 +11,88 @@ angular.module("umbraco.directives")
},
transclude: true,
restrict: 'E',
replace: true,
replace: true,
templateUrl: 'views/components/property/umb-property.html',
link: function(scope) {
scope.propertyAlias = Umbraco.Sys.ServerVariables.isDebuggingEnabled === true ? scope.property.alias : null;
scope.showDropdown = false;
scope.selectedVariation = {};
scope.variations = [
{
name: "Danish",
master: true,
selected: true
},
{
name: "German"
},
{
name: "Spanish"
},
{
name: "Finnish"
},
{
name: "Albanian"
},
{
name: "Russian"
},
{
name: "Norwegian"
},
{
name: "Swedish"
}
];
function activate() {
for(var i = 0; i < scope.variations.length; i++ ) {
var variation = scope.variations[i];
if(variation.selected) {
scope.property.variation = variation;
}
}
}
scope.toggleDropdown = function() {
scope.showDropdown = !scope.showDropdown;
};
scope.closeDropdown = function() {
scope.showDropdown = false;
};
scope.editContent = function() {
scope.property.variation = null;
scope.showDropdown = false;
};
scope.syncContent = function(selectedVariation) {
for(var i = 0; i < scope.variations.length; i++ ) {
var variation = scope.variations[i];
variation.selected = false;
}
selectedVariation.selected = true;
scope.property.variation = selectedVariation;
scope.showDropdown = false;
};
activate();
},
//Define a controller for this directive to expose APIs to other directives
controller: function ($scope, $timeout) {
var self = this;
//set the API properties/methods
self.property = $scope.property;
self.setPropertyError = function(errorMsg) {
$scope.property.propertyErrorMessage = errorMsg;
};
}
};
});
});
@@ -1,7 +1,7 @@
/**
* @ngdoc directive
* @function
* @name umbraco.directives.directive:umbPropertyEditor
* @name umbraco.directives.directive:umbPropertyEditor
* @requires formController
* @restrict E
**/
@@ -14,10 +14,10 @@ var _umbPropertyEditor = function (umbPropEditorHelper) {
isPreValue: "@",
preview: "@"
},
require: "^form",
restrict: 'E',
replace: true,
replace: true,
templateUrl: 'views/components/property/umb-property-editor.html',
link: function (scope, element, attrs, ctrl) {
@@ -33,6 +33,7 @@ var _umbPropertyEditor = function (umbPropEditorHelper) {
scope.$watch("model.view", function(val){
scope.propertyEditorView = umbPropEditorHelper.getViewPath(scope.model.view, scope.isPreValue);
});
}
};
};
@@ -13,7 +13,7 @@
el.find("a:first").tab('show');
//enable the tab drop
el.tabdrop();
//el.tabdrop();
});
@@ -29,7 +29,7 @@
scope.$on('$destroy', function () {
//ensure to destroy tabdrop (unbinds window resize listeners)
el.tabdrop("destroy");
//el.tabdrop("destroy");
unbindModelWatch();
@@ -0,0 +1,112 @@
(function() {
'use strict';
function Variations(iconHelper) {
function link(scope, el, attr, ctrl) {
scope.newVariation = {};
scope.segments = [
{
name: "Mobile",
id: 1
},
{
name: "Tablet",
id: 2
},
{
name: "Email Subscriber",
id: 3
},
{
name: "Email Campagin March 2016",
id: 4
},
{
name: "Codegarden Attendees",
id: 5
},
{
name: "Codegarden Attendees from abroad",
id: 6
}
];
scope.variationsSortableOptions = {
distance: 10,
tolerance: "pointer",
opacity: 0.7,
scroll: true,
cursor: "move",
zIndex: 6000
};
scope.showNewVariation = function(language) {
language.showNewVariation = true;
};
scope.hideNewVariation = function(language) {
language.showNewVariation = false;
};
scope.toggleEditVariation = function(selectedVariation) {
selectedVariation.editVariation = !selectedVariation.editVariation;
};
scope.createNewVariation = function(newVariation, language) {
var variation = angular.copy(language);
variation.variationName = newVariation.name;
variation.variationDescription = newVariation.description;
variation.segments = newVariation.segments;
variation.active = false;
language.variations.unshift(variation);
language.showNewVariation = false;
scope.newVariation = {
name: "",
description: "",
segments: []
};
};
scope.saveVariation = function(variation, language) {
variation.editVariation = false;
};
scope.deleteVariation = function(variation, language) {
var index = language.variations.indexOf(variation);
language.variations.splice(index, 1);
};
scope.hideEditVariation = function(variation) {
variation.editVariation = false;
};
}
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/umb-variations.html',
scope: {
variations: "=",
onClickVariation: "=",
onSaveVariation: "=",
onCloneVariation: "=",
onDeleteVariation: "="
},
link: link
};
return directive;
}
angular.module('umbraco.directives').directive('umbVariations', Variations);
})();
@@ -1,76 +0,0 @@
(function() {
'use strict';
function WebsiteSelector() {
function link(scope, el, attr, ctrl) {
scope.showWebsiteDropdown = false;
scope.selectedWebsite = {};
function activate() {
for(var i = 0; i < scope.websites.length; i++) {
var website = scope.websites[i];
if(website.selected) {
scope.selectedWebsite = website;
}
}
}
scope.toggleWebsiteDropDown = function() {
scope.showWebsiteDropdown = !scope.showWebsiteDropdown;
};
scope.closeWebsiteDropDown = function() {
scope.showWebsiteDropdown = false;
};
scope.createWebsite = function() {
if(scope.onCreateWebsite) {
scope.onCreateWebsite();
scope.closeWebsiteDropDown();
}
};
scope.clickWebsite = function(website) {
if(scope.onClickWebsite) {
scope.onClickWebsite(website);
setSelectedWebsite(website, scope.websites);
scope.closeWebsiteDropDown();
}
};
function setSelectedWebsite(selectedWebsite, websites) {
for(var i = 0; i < websites.length; i++) {
var website = websites[i];
website.selected = false;
}
selectedWebsite.selected = true;
scope.selectedWebsite = selectedWebsite;
}
scope.$watch('websites', function(newValue, oldValue){
activate();
}, true);
}
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/umb-website-selector.html',
link: link,
scope: {
websites: "=",
onCreateWebsite: "=",
onClickWebsite: "="
}
};
return directive;
}
angular.module('umbraco.directives').directive('umbWebsiteSelector', WebsiteSelector);
})();
@@ -509,16 +509,6 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
'Failed to check permission for item ' + id);
},
getPermissions: function (nodeIds) {
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"contentApiBaseUrl",
"GetPermissions"),
nodeIds),
'Failed to get permissions');
},
/**
* @ngdoc method
* @name umbraco.resources.contentResource#save
@@ -29,7 +29,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
filterContentTypes: filterContentTypes,
filterPropertyTypes: filterPropertyTypes
};
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
@@ -201,9 +201,9 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
* .then(function() {
* alert("node was moved");
* }, function(err){
* alert("node didnt move:" + err.data.Message);
* alert("node didnt move:" + err.data.Message);
* });
* </pre>
* </pre>
* @param {Object} args arguments object
* @param {Int} args.idd the ID of the node to move
* @param {Int} args.parentId the ID of the parent node to move to
@@ -230,26 +230,6 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
'Failed to move content');
},
copy: function(args) {
if (!args) {
throw "args cannot be null";
}
if (!args.parentId) {
throw "args.parentId cannot be null";
}
if (!args.id) {
throw "args.id cannot be null";
}
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCopy"),
{
parentId: args.parentId,
id: args.id
}),
'Failed to copy content');
},
createContainer: function(parentId, name) {
return umbRequestHelper.resourcePromise(
@@ -257,7 +237,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
'Failed to create a folder under parent id ' + parentId);
}
};
}
angular.module('umbraco.resources').factory('contentTypeResource', contentTypeResource);
@@ -53,7 +53,7 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
* .then(function(array) {
* $scope.type = type;
* });
* </pre>
* </pre>
* @param {Int} mediaId id of the media item to retrive allowed child types for
* @returns {Promise} resourcePromise object.
*
@@ -145,9 +145,9 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
* .then(function() {
* alert("node was moved");
* }, function(err){
* alert("node didnt move:" + err.data.Message);
* alert("node didnt move:" + err.data.Message);
* });
* </pre>
* </pre>
* @param {Object} args arguments object
* @param {Int} args.idd the ID of the node to move
* @param {Int} args.parentId the ID of the parent node to move to
@@ -174,26 +174,6 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
'Failed to move content');
},
copy: function (args) {
if (!args) {
throw "args cannot be null";
}
if (!args.parentId) {
throw "args.parentId cannot be null";
}
if (!args.id) {
throw "args.id cannot be null";
}
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostCopy"),
{
parentId: args.parentId,
id: args.id
}),
'Failed to copy content');
},
createContainer: function(parentId, name) {
return umbRequestHelper.resourcePromise(
@@ -16,7 +16,7 @@ function treeResource($q, $http, umbRequestHelper) {
/** internal method to get the tree menu url */
function getTreeMenuUrl(node) {
if (!node.menuUrl) {
return null;
throw "No menuUrl property found on the tree node, cannot load menu";
}
return node.menuUrl;
}
@@ -26,16 +26,10 @@ function treeResource($q, $http, umbRequestHelper) {
/** Loads in the data to display the nodes menu */
loadMenu: function (node) {
var treeMenuUrl = getTreeMenuUrl(node);
if (treeMenuUrl !== undefined && treeMenuUrl !== null && treeMenuUrl.length > 0) {
return umbRequestHelper.resourcePromise(
$http.get(getTreeMenuUrl(node)),
"Failed to retrieve data for a node's menu " + node.id);
} else {
return $q.reject({
errorMsg: "No tree menu url defined for node " + node.id
});
}
return umbRequestHelper.resourcePromise(
$http.get(getTreeMenuUrl(node)),
"Failed to retrieve data for a node's menu " + node.id);
},
/** Loads in the data to display the nodes for an application */
@@ -1,323 +1,270 @@
// This service was based on OpenJS library available in BSD License
// http://www.openjs.com/scripts/events/keyboard_shortcuts/index.php
angular.module('umbraco.services')
.factory('keyboardService', ['$window', '$timeout', function ($window, $timeout) {
var keyboardManagerService = {};
var defaultOpt = {
'type': 'keydown',
'propagate': false,
'inputDisabled': false,
'target': $window.document,
'keyCode': false
};
function keyboardService($window, $timeout) {
var keyboardManagerService = {};
var defaultOpt = {
'type': 'keydown',
'propagate': false,
'inputDisabled': false,
'target': $window.document,
'keyCode': false
};
var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
// Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
var shift_nums = {
"`": "~",
"1": "!",
"2": "@",
"3": "#",
"4": "$",
"5": "%",
"6": "^",
"7": "&",
"8": "*",
"9": "(",
"0": ")",
"-": "_",
"=": "+",
";": ":",
"'": "\"",
",": "<",
".": ">",
"/": "?",
"\\": "|"
};
// Store all keyboard combination shortcuts
keyboardManagerService.keyboardEvent = {};
// Special Keys - and their codes
var special_keys = {
'esc': 27,
'escape': 27,
'tab': 9,
'space': 32,
'return': 13,
'enter': 13,
'backspace': 8,
'scrolllock': 145,
'scroll_lock': 145,
'scroll': 145,
'capslock': 20,
'caps_lock': 20,
'caps': 20,
'numlock': 144,
'num_lock': 144,
'num': 144,
// Add a new keyboard combination shortcut
keyboardManagerService.bind = function (label, callback, opt) {
'pause': 19,
'break': 19,
//replace ctrl key with meta key
if(isMac && label !== "ctrl+space"){
label = label.replace("ctrl","meta");
}
'insert': 45,
'home': 36,
'delete': 46,
'end': 35,
var fct, elt, code, k;
// Initialize opt object
opt = angular.extend({}, defaultOpt, opt);
label = label.toLowerCase();
elt = opt.target;
if(typeof opt.target === 'string'){
elt = document.getElementById(opt.target);
}
'pageup': 33,
'page_up': 33,
'pu': 33,
'pagedown': 34,
'page_down': 34,
'pd': 34,
fct = function (e) {
e = e || $window.event;
'left': 37,
'up': 38,
'right': 39,
'down': 40,
// Disable event handler when focus input and textarea
if (opt['inputDisabled']) {
var elt;
if (e.target){
elt = e.target;
}else if (e.srcElement){
elt = e.srcElement;
}
'f1': 112,
'f2': 113,
'f3': 114,
'f4': 115,
'f5': 116,
'f6': 117,
'f7': 118,
'f8': 119,
'f9': 120,
'f10': 121,
'f11': 122,
'f12': 123
};
if (elt.nodeType === 3){elt = elt.parentNode;}
if (elt.tagName === 'INPUT' || elt.tagName === 'TEXTAREA'){return;}
}
var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
// Find out which key is pressed
if (e.keyCode){
code = e.keyCode;
}else if (e.which){
code = e.which;
}
// The event handler for bound element events
function eventHandler(e) {
e = e || $window.event;
var character = String.fromCharCode(code).toLowerCase();
var code, k;
if (code === 188){character = ",";} // If the user presses , when the type is onkeydown
if (code === 190){character = ".";} // If the user presses , when the type is onkeydown
// Find out which key is pressed
if (e.keyCode)
{
code = e.keyCode;
}
else if (e.which) {
code = e.which;
}
var keys = label.split("+");
// Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
var kp = 0;
// Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
var shift_nums = {
"`":"~",
"1":"!",
"2":"@",
"3":"#",
"4":"$",
"5":"%",
"6":"^",
"7":"&",
"8":"*",
"9":"(",
"0":")",
"-":"_",
"=":"+",
";":":",
"'":"\"",
",":"<",
".":">",
"/":"?",
"\\":"|"
};
// Special Keys - and their codes
var special_keys = {
'esc':27,
'escape':27,
'tab':9,
'space':32,
'return':13,
'enter':13,
'backspace':8,
var character = String.fromCharCode(code).toLowerCase();
'scrolllock':145,
'scroll_lock':145,
'scroll':145,
'capslock':20,
'caps_lock':20,
'caps':20,
'numlock':144,
'num_lock':144,
'num':144,
if (code === 188){character = ",";} // If the user presses , when the type is onkeydown
if (code === 190){character = ".";} // If the user presses , when the type is onkeydown
'pause':19,
'break':19,
var propagate = true;
'insert':45,
'home':36,
'delete':46,
'end':35,
//Now we need to determine which shortcut this event is for, we'll do this by iterating over each
//registered shortcut to find the match. We use Find here so that the loop exits as soon
//as we've found the one we're looking for
_.find(_.keys(keyboardManagerService.keyboardEvent), function(key) {
'pageup':33,
'page_up':33,
'pu':33,
var shortcutLabel = key;
var shortcutVal = keyboardManagerService.keyboardEvent[key];
'pagedown':34,
'page_down':34,
'pd':34,
// Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
var kp = 0;
'left':37,
'up':38,
'right':39,
'down':40,
// Some modifiers key
var modifiers = {
shift: {
wanted: false,
pressed: e.shiftKey ? true : false
},
ctrl: {
wanted: false,
pressed: e.ctrlKey ? true : false
},
alt: {
wanted: false,
pressed: e.altKey ? true : false
},
meta: { //Meta is Mac specific
wanted: false,
pressed: e.metaKey ? true : false
}
};
'f1':112,
'f2':113,
'f3':114,
'f4':115,
'f5':116,
'f6':117,
'f7':118,
'f8':119,
'f9':120,
'f10':121,
'f11':122,
'f12':123
};
// Some modifiers key
var modifiers = {
shift: {
wanted: false,
pressed: e.shiftKey ? true : false
},
ctrl : {
wanted: false,
pressed: e.ctrlKey ? true : false
},
alt : {
wanted: false,
pressed: e.altKey ? true : false
},
meta : { //Meta is Mac specific
wanted: false,
pressed: e.metaKey ? true : false
}
};
// Foreach keys in label (split on +)
var l = keys.length;
for (var i = 0; i < l; i++) {
var keys = shortcutLabel.split("+");
var opt = shortcutVal.opt;
var callback = shortcutVal.callback;
var k=keys[i];
switch (k) {
case 'ctrl':
case 'control':
kp++;
modifiers.ctrl.wanted = true;
break;
case 'shift':
case 'alt':
case 'meta':
kp++;
modifiers[k].wanted = true;
break;
}
// Foreach keys in label (split on +)
var l = keys.length;
for (var i = 0; i < l; i++) {
if (k.length > 1) { // If it is a special key
if(special_keys[k] === code){
kp++;
}
var k = keys[i];
switch (k) {
case 'ctrl':
case 'control':
kp++;
modifiers.ctrl.wanted = true;
break;
case 'shift':
case 'alt':
case 'meta':
kp++;
modifiers[k].wanted = true;
break;
}
} else if (opt['keyCode']) { // If a specific key is set into the config
if (opt['keyCode'] === code) {
kp++;
}
if (k.length > 1) { // If it is a special key
if (special_keys[k] === code) {
kp++;
}
}
else if (opt['keyCode']) { // If a specific key is set into the config
if (opt['keyCode'] === code) {
kp++;
}
}
else { // The special keys did not match
if (character === k) {
kp++;
}
else {
if (shift_nums[character] && e.shiftKey) { // Stupid Shift key bug created by using lowercase
character = shift_nums[character];
if (character === k) {
kp++;
}
}
}
}
} else { // The special keys did not match
if(character === k) {
kp++;
}else {
if(shift_nums[character] && e.shiftKey) { // Stupid Shift key bug created by using lowercase
character = shift_nums[character];
if(character === k){
kp++;
}
}
}
}
} //for end
} //for end
if (kp === keys.length &&
modifiers.ctrl.pressed === modifiers.ctrl.wanted &&
modifiers.shift.pressed === modifiers.shift.wanted &&
modifiers.alt.pressed === modifiers.alt.wanted &&
modifiers.meta.pressed === modifiers.meta.wanted) {
if(kp === keys.length &&
modifiers.ctrl.pressed === modifiers.ctrl.wanted &&
modifiers.shift.pressed === modifiers.shift.wanted &&
modifiers.alt.pressed === modifiers.alt.wanted &&
modifiers.meta.pressed === modifiers.meta.wanted) {
$timeout(function() {
callback(e);
}, 1);
//found the right callback!
if(!opt['propagate']) { // Stop the event
// e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = false;
// Disable event handler when focus input and textarea
if (opt['inputDisabled']) {
var elt;
if (e.target) {
elt = e.target;
} else if (e.srcElement) {
elt = e.srcElement;
}
// e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
}
};
// Store shortcut
keyboardManagerService.keyboardEvent[label] = {
'callback': fct,
'target': elt,
'event': opt['type']
};
if (elt.nodeType === 3) { elt = elt.parentNode; }
if (elt.tagName === 'INPUT' || elt.tagName === 'TEXTAREA') {
//This exits the Find loop
return true;
}
}
//Attach the function with the event
if(elt.addEventListener){
elt.addEventListener(opt['type'], fct, false);
}else if(elt.attachEvent){
elt.attachEvent('on' + opt['type'], fct);
}else{
elt['on' + opt['type']] = fct;
}
};
// Remove the shortcut - just specify the shortcut and I will remove the binding
keyboardManagerService.unbind = function (label) {
label = label.toLowerCase();
var binding = keyboardManagerService.keyboardEvent[label];
delete(keyboardManagerService.keyboardEvent[label]);
$timeout(function () {
callback(e);
}, 1);
if(!binding){return;}
if (!opt['propagate']) { // Stop the event
propagate = false;
}
//This exits the Find loop
return true;
}
//we haven't found one so continue looking
return false;
});
// Stop the event if required
if (!propagate) {
// e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = false;
// e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
}
// Store all keyboard combination shortcuts
keyboardManagerService.keyboardEvent = {};
// Add a new keyboard combination shortcut
keyboardManagerService.bind = function (label, callback, opt) {
//replace ctrl key with meta key
if(isMac && label !== "ctrl+space"){
label = label.replace("ctrl","meta");
}
var elt;
// Initialize opt object
opt = angular.extend({}, defaultOpt, opt);
label = label.toLowerCase();
elt = opt.target;
if(typeof opt.target === 'string'){
elt = document.getElementById(opt.target);
}
//Ensure we aren't double binding to the same element + type otherwise we'll end up multi-binding
// and raising events for now reason. So here we'll check if the event is already registered for the element
var boundValues = _.values(keyboardManagerService.keyboardEvent);
var found = _.find(boundValues, function (i) {
return i.target === elt && i.event === opt['type'];
});
// Store shortcut
keyboardManagerService.keyboardEvent[label] = {
'callback': callback,
'target': elt,
'opt': opt['type']
};
if (!found) {
//Attach the function with the event
if (elt.addEventListener) {
elt.addEventListener(opt['type'], eventHandler, false);
} else if (elt.attachEvent) {
elt.attachEvent('on' + opt['type'], eventHandler);
} else {
elt['on' + opt['type']] = eventHandler;
}
}
};
// Remove the shortcut - just specify the shortcut and I will remove the binding
keyboardManagerService.unbind = function (label) {
label = label.toLowerCase();
var binding = keyboardManagerService.keyboardEvent[label];
delete(keyboardManagerService.keyboardEvent[label]);
if(!binding){return;}
var type = binding['event'],
var type = binding['event'],
elt = binding['target'],
callback = binding['callback'];
if(elt.detachEvent){
elt.detachEvent('on' + type, callback);
}else if(elt.removeEventListener){
elt.removeEventListener(type, callback, false);
}else{
elt['on'+type] = false;
}
};
//
if(elt.detachEvent){
elt.detachEvent('on' + type, callback);
}else if(elt.removeEventListener){
elt.removeEventListener(type, callback, false);
}else{
elt['on'+type] = false;
}
};
//
return keyboardManagerService;
}
return keyboardManagerService;
}]);
@@ -1,319 +1,288 @@
(function () {
'use strict';
(function() {
'use strict';
function listViewHelper(localStorageService) {
function listViewHelper(localStorageService) {
var firstSelectedIndex = 0;
var localStorageKey = "umblistViewLayout";
var firstSelectedIndex = 0;
var localStorageKey = "umblistViewLayout";
function getLayout(nodeId, availableLayouts) {
function getLayout(nodeId, availableLayouts) {
var storedLayouts = [];
var storedLayouts = [];
if (localStorageService.get(localStorageKey)) {
storedLayouts = localStorageService.get(localStorageKey);
if(localStorageService.get(localStorageKey)) {
storedLayouts = localStorageService.get(localStorageKey);
}
if (storedLayouts && storedLayouts.length > 0) {
for (var i = 0; storedLayouts.length > i; i++) {
var layout = storedLayouts[i];
if (layout.nodeId === nodeId) {
return setLayout(nodeId, layout, availableLayouts);
}
}
}
return getFirstAllowedLayout(availableLayouts);
}
function setLayout(nodeId, selectedLayout, availableLayouts) {
var activeLayout = {};
var layoutFound = false;
for (var i = 0; availableLayouts.length > i; i++) {
var layout = availableLayouts[i];
if (layout.path === selectedLayout.path) {
activeLayout = layout;
layout.active = true;
layoutFound = true;
} else {
layout.active = false;
}
}
if(!layoutFound) {
activeLayout = getFirstAllowedLayout(availableLayouts);
}
saveLayoutInLocalStorage(nodeId, activeLayout);
return activeLayout;
}
function saveLayoutInLocalStorage(nodeId, selectedLayout) {
var layoutFound = false;
var storedLayouts = [];
if(localStorageService.get(localStorageKey)) {
storedLayouts = localStorageService.get(localStorageKey);
}
if(storedLayouts.length > 0) {
for(var i = 0; storedLayouts.length > i; i++) {
var layout = storedLayouts[i];
if(layout.nodeId === nodeId) {
layout.path = selectedLayout.path;
layoutFound = true;
}
}
}
if(!layoutFound) {
var storageObject = {
"nodeId": nodeId,
"path": selectedLayout.path
};
storedLayouts.push(storageObject);
}
localStorageService.set(localStorageKey, storedLayouts);
}
function getFirstAllowedLayout(layouts) {
var firstAllowedLayout = {};
for (var i = 0; layouts.length > i; i++) {
var layout = layouts[i];
if (layout.selected === true) {
firstAllowedLayout = layout;
break;
}
}
if (storedLayouts && storedLayouts.length > 0) {
for (var i = 0; storedLayouts.length > i; i++) {
var layout = storedLayouts[i];
if (layout.nodeId === nodeId) {
return setLayout(nodeId, layout, availableLayouts);
}
}
return firstAllowedLayout;
}
}
function selectHandler(selectedItem, selectedIndex, items, selection, $event) {
return getFirstAllowedLayout(availableLayouts);
var start = 0;
var end = 0;
var item = null;
}
if ($event.shiftKey === true) {
function setLayout(nodeId, selectedLayout, availableLayouts) {
if(selectedIndex > firstSelectedIndex) {
var activeLayout = {};
var layoutFound = false;
start = firstSelectedIndex;
end = selectedIndex;
for (var i = 0; availableLayouts.length > i; i++) {
var layout = availableLayouts[i];
if (layout.path === selectedLayout.path) {
activeLayout = layout;
layout.active = true;
layoutFound = true;
} else {
layout.active = false;
}
}
if (!layoutFound) {
activeLayout = getFirstAllowedLayout(availableLayouts);
}
saveLayoutInLocalStorage(nodeId, activeLayout);
return activeLayout;
}
function saveLayoutInLocalStorage(nodeId, selectedLayout) {
var layoutFound = false;
var storedLayouts = [];
if (localStorageService.get(localStorageKey)) {
storedLayouts = localStorageService.get(localStorageKey);
}
if (storedLayouts.length > 0) {
for (var i = 0; storedLayouts.length > i; i++) {
var layout = storedLayouts[i];
if (layout.nodeId === nodeId) {
layout.path = selectedLayout.path;
layoutFound = true;
}
}
}
if (!layoutFound) {
var storageObject = {
"nodeId": nodeId,
"path": selectedLayout.path
};
storedLayouts.push(storageObject);
}
localStorageService.set(localStorageKey, storedLayouts);
}
function getFirstAllowedLayout(layouts) {
var firstAllowedLayout = {};
for (var i = 0; layouts.length > i; i++) {
var layout = layouts[i];
if (layout.selected === true) {
firstAllowedLayout = layout;
break;
}
}
return firstAllowedLayout;
}
function selectHandler(selectedItem, selectedIndex, items, selection, $event) {
var start = 0;
var end = 0;
var item = null;
if ($event.shiftKey === true) {
if (selectedIndex > firstSelectedIndex) {
start = firstSelectedIndex;
end = selectedIndex;
for (; end >= start; start++) {
item = items[start];
selectItem(item, selection);
}
} else {
start = firstSelectedIndex;
end = selectedIndex;
for (; end <= start; start--) {
item = items[start];
selectItem(item, selection);
}
}
for (; end >= start; start++) {
item = items[start];
selectItem(item, selection);
}
} else {
if (selectedItem.selected) {
deselectItem(selectedItem, selection);
} else {
selectItem(selectedItem, selection);
}
start = firstSelectedIndex;
end = selectedIndex;
firstSelectedIndex = selectedIndex;
for (; end <= start; start--) {
item = items[start];
selectItem(item, selection);
}
}
}
} else {
function selectItem(item, selection) {
var isSelected = false;
for (var i = 0; selection.length > i; i++) {
var selectedItem = selection[i];
if (item.id === selectedItem.id) {
isSelected = true;
}
}
if (!isSelected) {
selection.push({ id: item.id });
item.selected = true;
}
}
function deselectItem(item, selection) {
for (var i = 0; selection.length > i; i++) {
var selectedItem = selection[i];
if (item.id === selectedItem.id) {
selection.splice(i, 1);
item.selected = false;
}
}
}
function clearSelection(items, folders, selection) {
var i = 0;
selection.length = 0;
if (angular.isArray(items)) {
for (i = 0; items.length > i; i++) {
var item = items[i];
item.selected = false;
}
if(selectedItem.selected) {
deselectItem(selectedItem, selection);
} else {
selectItem(selectedItem, selection);
}
if (angular.isArray(items)) {
for (i = 0; folders.length > i; i++) {
var folder = folders[i];
folder.selected = false;
}
firstSelectedIndex = selectedIndex;
}
}
function selectItem(item, selection) {
var isSelected = false;
for (var i = 0; selection.length > i; i++) {
var selectedItem = selection[i];
if (item.id === selectedItem.id) {
isSelected = true;
}
}
}
if(!isSelected) {
selection.push({id: item.id});
item.selected = true;
}
}
function selectAllItems(items, selection, $event) {
var checkbox = $event.target;
var clearSelection = false;
if (!angular.isArray(items)) {
return;
function deselectItem(item, selection) {
for (var i = 0; selection.length > i; i++) {
var selectedItem = selection[i];
if (item.id === selectedItem.id) {
selection.splice(i, 1);
item.selected = false;
}
}
}
selection.length = 0;
function clearSelection(items, folders, selection) {
for (var i = 0; i < items.length; i++) {
var i = 0;
var item = items[i];
if (checkbox.checked) {
selection.push({ id: item.id });
} else {
clearSelection = true;
}
item.selected = checkbox.checked;
selection.length = 0;
if(angular.isArray(items)) {
for(i = 0; items.length > i; i++) {
var item = items[i];
item.selected = false;
}
}
if (clearSelection) {
selection.length = 0;
if(angular.isArray(items)) {
for(i = 0; folders.length > i; i++) {
var folder = folders[i];
folder.selected = false;
}
}
}
}
function selectAllItems(items, selection, $event) {
function isSelectedAll(items, selection) {
var checkbox = $event.target;
var clearSelection = false;
var numberOfSelectedItem = 0;
if (!angular.isArray(items)) {
return;
}
for (var itemIndex = 0; items.length > itemIndex; itemIndex++) {
var item = items[itemIndex];
selection.length = 0;
for (var selectedIndex = 0; selection.length > selectedIndex; selectedIndex++) {
var selectedItem = selection[selectedIndex];
for (var i = 0; i < items.length; i++) {
if (item.id === selectedItem.id) {
numberOfSelectedItem++;
}
}
var item = items[i];
}
if (checkbox.checked) {
selection.push({id: item.id});
} else {
clearSelection = true;
}
if (numberOfSelectedItem === items.length) {
return true;
}
item.selected = checkbox.checked;
}
}
function setSortingDirection(col, direction, options) {
return options.orderBy.toUpperCase() === col.toUpperCase() && options.orderDirection === direction;
}
if (clearSelection) {
selection.length = 0;
}
function setSorting(field, allow, options) {
if (allow) {
options.orderBy = field;
}
if (options.orderDirection === "desc") {
options.orderDirection = "asc";
} else {
options.orderDirection = "desc";
}
}
}
//This takes in a dictionary of Ids with Permissions and determines
// the intersect of all permissions to return an object representing the
// listview button permissions
function getButtonPermissions(unmergedPermissions, currentIdsWithPermissions) {
if (currentIdsWithPermissions == null) {
currentIdsWithPermissions = {};
}
function isSelectedAll(items, selection) {
//merge the newly retrieved permissions to the main dictionary
_.each(unmergedPermissions, function (value, key, list) {
currentIdsWithPermissions[key] = value;
});
var numberOfSelectedItem = 0;
//get the intersect permissions
var arr = [];
_.each(currentIdsWithPermissions, function (value, key, list) {
arr.push(value);
});
for(var itemIndex = 0; items.length > itemIndex; itemIndex++) {
var item = items[itemIndex];
//we need to use 'apply' to call intersection with an array of arrays,
//see: http://stackoverflow.com/a/16229480/694494
var intersectPermissions = _.intersection.apply(_, arr);
for(var selectedIndex = 0; selection.length > selectedIndex; selectedIndex++) {
var selectedItem = selection[selectedIndex];
return {
canCopy: _.contains(intersectPermissions, 'O'), //Magic Char = O
canCreate: _.contains(intersectPermissions, 'C'), //Magic Char = C
canDelete: _.contains(intersectPermissions, 'D'), //Magic Char = D
canMove: _.contains(intersectPermissions, 'M'), //Magic Char = M
canPublish: _.contains(intersectPermissions, 'U'), //Magic Char = U
canUnpublish: _.contains(intersectPermissions, 'U'), //Magic Char = Z (however UI says it can't be set, so if we can publish 'U' we can unpublish)
};
}
if(item.id === selectedItem.id) {
numberOfSelectedItem++;
}
}
var service = {
getLayout: getLayout,
getFirstAllowedLayout: getFirstAllowedLayout,
setLayout: setLayout,
saveLayoutInLocalStorage: saveLayoutInLocalStorage,
selectHandler: selectHandler,
selectItem: selectItem,
deselectItem: deselectItem,
clearSelection: clearSelection,
selectAllItems: selectAllItems,
isSelectedAll: isSelectedAll,
setSortingDirection: setSortingDirection,
setSorting: setSorting,
getButtonPermissions: getButtonPermissions
};
}
return service;
if(numberOfSelectedItem === items.length) {
return true;
}
}
}
angular.module('umbraco.services').factory('listViewHelper', listViewHelper);
function setSortingDirection(col, direction, options) {
return options.orderBy.toUpperCase() === col.toUpperCase() && options.orderDirection === direction;
}
function setSorting(field, allow, options) {
if (allow) {
options.orderBy = field;
if (options.orderDirection === "desc") {
options.orderDirection = "asc";
} else {
options.orderDirection = "desc";
}
}
}
var service = {
getLayout: getLayout,
getFirstAllowedLayout: getFirstAllowedLayout,
setLayout: setLayout,
saveLayoutInLocalStorage: saveLayoutInLocalStorage,
selectHandler: selectHandler,
selectItem: selectItem,
deselectItem: deselectItem,
clearSelection: clearSelection,
selectAllItems: selectAllItems,
isSelectedAll: isSelectedAll,
setSortingDirection: setSortingDirection,
setSorting: setSorting
};
return service;
}
angular.module('umbraco.services').factory('listViewHelper', listViewHelper);
})();
@@ -21,7 +21,6 @@ function packageHelper(assetsService, treeService, eventsService, $templateCache
}
angular.module('umbraco.services').factory('packageHelper', packageHelper);
//TODO: I believe this is obsolete
function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, mediaHelper, umbRequestHelper) {
return {
/** sets the image's url, thumbnail and if its a folder */
@@ -320,6 +319,7 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, me
}
};
}
angular.module("umbraco.services").factory("umbPhotoFolderHelper", umbPhotoFolderHelper);
/**
@@ -5,7 +5,97 @@
var variations = [];
/*
var variations = [
{
language: "Danish",
master: true,
published: true,
variations: [
{
name: "Mobile",
description: "Danish content for mobile",
published: true,
segments: [
{
name: "Mobile"
}
]
}
]
},
{
language: "Dutch",
published: true,
variations: [
{
name: "Mobile",
description: "Dutch content for mobile",
segments: [
{
name: "Mobile"
}
]
}
]
},
{
language: "English (United States)",
published: true,
variations: [
{
name: "Mobile",
description: "English content for mobile",
published: true,
segments: [
{
name: "Mobile"
}
]
},
{
name: "Job campaign: Front-end developer",
description: "Landing page for job thing 1",
published: true,
segments: [
{
name: "Front-end developer"
}
]
},
{
name: "Job campaign: Back-end developer",
description: "Landing page for job thing 2",
published: true,
segments: [
{
name: "Back-end developer"
}
]
}
]
},
{
language: "German",
published: true
},
{
language: "Italian",
published: true
},
{
language: "Spanish",
published: false
},
{
language: "Swedish",
published: false
}
];
*/
function setMaster(master) {
variations = [];
master.master = true;
variations.push(master);
}
@@ -39,7 +129,6 @@
variationClone.master = false;
variationClone.published = false;
variations.push(variationClone);
console.log(variations);
}
function deleteVariation(variation, event, index) {
@@ -8,7 +8,7 @@
* The main application controller
*
*/
function MainController($scope, $rootScope, $location, $routeParams, $timeout, $http, $log, appState, treeService, notificationsService, userService, navigationService, historyService, updateChecker, assetsService, eventsService, umbRequestHelper, tmhDynamicLocale) {
function MainController($scope, $rootScope, $location, $routeParams, $timeout, $http, $log, appState, treeService, notificationsService, userService, navigationService, historyService, updateChecker, assetsService, eventsService, umbRequestHelper, tmhDynamicLocale, $templateCache) {
//the null is important because we do an explicit bool check on this in the view
//the avatar is by default the umbraco logo
@@ -19,7 +19,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
{ value: "assets/img/application/logo@3x.png" }
];
$scope.touchDevice = appState.getGlobalState("touchDevice");
$scope.splitView = {};
$scope.removeNotification = function (index) {
notificationsService.remove(index);
@@ -126,6 +126,28 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
};
}));
evts.push(eventsService.on("splitView.open", function(name, view) {
var updateTime = Date.now();
$scope.splitView = {
id: view.id,
view: view.view + "?updated=" + updateTime,
show: true
};
}));
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
$scope.closeSplitView();
});
$scope.closeSplitView = function() {
$scope.splitView.show = false;
$scope.splitView.id = null;
$scope.splitView.view = null;
};
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
@@ -141,4 +163,4 @@ angular.module('umbraco').controller("Umbraco.MainController", MainController).
config(function (tmhDynamicLocaleProvider) {
//Set url for locale files
tmhDynamicLocaleProvider.localeLocationPattern('lib/angular/1.1.5/i18n/angular-locale_{{locale}}.js');
});
});
@@ -155,53 +155,6 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
}
};
$scope.websites = [
{
name: "English",
language: "en-UK",
selected: true
},
{
name: "Dansk",
language: "da-DK",
selected: false
}
];
$scope.createWebsite = function() {
$scope.createWebsiteOverlay = {
view: "createwebsite",
title: "Create website",
submitButtonLabel: "Create website",
show: true,
submit: function(model) {
// deselct all current sites
for(var i = 0; i < $scope.websites.length; i++) {
var website = $scope.websites[i];
website.selected = false;
}
// set new site to selected and push to scope
model.website.selected = true;
$scope.websites.push(model.website);
// clsoe overlay
$scope.createWebsiteOverlay.show = false;
$scope.createWebsiteOverlay = null;
},
close: function() {
$scope.createWebsiteOverlay.show = false;
$scope.createWebsiteOverlay = null;
}
};
};
$scope.clickWebsite = function(website) {
};
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
@@ -41,14 +41,10 @@ body {
}
#contentwrapper, #contentcolumn {
position: absolute;
top: 0px; bottom: 0px; right: 0px; left: 80px;
z-index: 10;
margin: 0
}
#umb-notifications-wrapper {
left: 80px;
// position: absolute;
// top: 0px; bottom: 0px; right: 0px; left: 80px;
// z-index: 10;
// margin: 0
}
#contentcolumn {
@@ -63,24 +59,6 @@ body {
border: none;
}
#leftcolumn {
height: 100%;
z-index: 20;
width: 80px;
float: left;
position: absolute;
}
#applications {
z-index: 1000;
height: 100%;
left: 0px;
top: 0;
bottom: 0;
position: absolute;
text-align: center
}
#applications-tray {
z-index: 900;
left: 80px;
@@ -91,6 +69,7 @@ body {
text-align: center;
}
/*
#search-form {
display: block;
margin: 0;
@@ -102,21 +81,37 @@ body {
overflow: hidden;
.form-search {
display: -ms-flexbox;
display: -webkit-box;
display: -webkit-flex;
display: flex;
margin-top: 17px;
.umb-search-field {
width: auto;
min-width: 160px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
border-left: none;
border-right: none;
border-top: none;
}
}
}
*/
.form-search {
display: flex;
//margin-top: 17px;
.umb-search-field {
width: auto;
min-width: 160px;
flex: 1;
border-left: none;
border-right: none;
border-top: none;
height: 60px;
box-sizing: border-box;
padding-left: 40px !important;
}
}
#navigation {
left: 80px;
@@ -199,10 +194,10 @@ body {
z-index:9999 !important;
}
@media (min-width: 1101px) {
#contentwrapper, #umb-notifications-wrapper {left: 440px;}
#speechbubble {left: 360px;}
}
// @media (min-width: 1101px) {
// #contentwrapper, #umb-notifications-wrapper {left: 440px;}
// #speechbubble {left: 360px;}
// }
//empty section modification
.emptySection #contentwrapper, .emptySection #umb-notifications-wrapper {left: 80px;}
@@ -0,0 +1,228 @@
.umb-navigation {
display: flex;
flex: 0 0 @navigationBarHeight;
align-items: center;
border-bottom: 1px solid @grayLight;
box-sizing: border-box;
}
.umb-navigation-link {
display: flex;
align-items: center;
padding: 0 20px;
height: 49px;
font-size: 13px;
cursor: pointer;
&:hover {
text-decoration: none;
background: @grayLighter;
}
&:focus {
text-decoration: none;
}
}
.umb-navigation-link.-current {
color: @blue;
}
.umb-navigation-link.open {
background: @grayLighter;
}
.umb-navigation__right {
display: flex;
align-items: center;
margin-left: auto;
}
#avatar-img {
border-radius: 50%;
margin: 0 0 0 10px;
}
.umb-sections__tray {
display: flex;
flex-direction: column;
align-items: flex-start;
position: absolute;
z-index: 1;
width: 220px;
top: @navigationBarHeight;
background: white;
transform: translate(-42px, 0px);
}
.umb-sections__tray .umb-navigation-link {
width: 100%;
box-sizing: border-box;
}
.umb-sections__tray .umb-navigation-link:hover {
background: #ececec;
}
.umb-navigation-more {
width: 22px;
height: auto;
}
.umb-navigation-more__path {
fill: @black;
}
// Tree Doors Downu
#mainwrapper {
display: flex;
flex-direction: column;
}
#contentwrapper {
display: flex;
flex-direction: row;
flex: 1 1 auto;
}
#contentcolumn {
flex: 1 1 100%;
position: relative;
}
// Editor blocks
.umb-editor-wrapper {
display: flex;
flex-direction: column;
height: ~"(calc(~'100vh' - ~'@{navigationBarHeight}'))";
}
.umb-editor-header {
flex: 0 0 @editorHeaderHeight;
display: flex;
align-items: center;
box-sizing: border-box;
}
.umb-editor-container {
flex: 1 1 auto;
box-sizing: border-box;
overflow-y: auto;
//display: flex;
//flex-direction: row;
}
.umb-editor-content {
padding: 30px 20px;
}
.umb-editor-container-test {
flex: 1 1 auto;
padding: 30px 20px;
overflow-y: auto;
}
.umb-editor-container-sidebar {
flex: 0 0 400px;
padding: 30px 20px;
border-left: 1px solid @grayLight;
overflow-y: auto;
}
.umb-editor-drawer {
flex: 0 0 31px;
}
.umb-tree-navigation {
display: flex;
flex-direction: column;
flex: 0 0 300px;
border-right: 1px solid @grayLight;
overflow-y: auto;
padding-bottom: 20px;
}
.umb-panel-header-content-wrapper {
width: 100%;
}
.umb-toggle-tree {
display: flex;
align-items: center;
justify-content: center;
height: 49px;
width: 20px;
padding: 0 20px;
cursor: pointer;
transition: background-color 80ms ease;
}
.umb-toggle-icon {
margin: 0 auto 0 0;
width: 20px;
height: 2px;
background-color: @grayLight;
transition: all 80ms ease;
display: block;
}
.umb-toggle-icon:before,
.umb-toggle-icon:after {
content: '';
width: 20px;
height: 2px;
display: block;
background-color: @grayLight;
transition: all 80ms ease;
}
.umb-toggle-icon:before {
transform: translate(0, -5px);
width: 15px;
}
.umb-toggle-icon:after {
transform: translate(0, 3px);
width: 9px;
}
.umb-toggle-tree:hover,
.umb-toggle-tree.-open {
background: @grayLighter;
}
.umb-toggle-tree:hover .umb-toggle-icon,
.umb-toggle-tree:hover .umb-toggle-icon:before,
.umb-toggle-tree:hover .umb-toggle-icon:after {
background-color: @grayMed;
}
.umb-toggle-tree.-open .umb-toggle-icon,
.umb-toggle-tree.-open .umb-toggle-icon:before,
.umb-toggle-tree.-open .umb-toggle-icon:after {
width: 20px;
background-color: @grayMed;
}
@@ -59,6 +59,7 @@
@import "application/grid.less";
@import "application/shadows.less";
@import "application/animations.less";
@import "application/umb-navigation.less";
// Belle styles
@import "buttons.less";
@@ -84,6 +85,8 @@
@import "components/umb-sub-views.less";
@import "components/umb-editor-navigation.less";
@import "components/umb-editor-sub-views.less";
@import "components/editor/subviews/umb-editor-sub-view.less";
@import "components/editor/umb-editor-toolbar.less";
@import "components/editor/subheader/umb-editor-sub-header.less";
@import "components/umb-grid-selector.less";
@import "components/umb-child-selector.less";
@@ -108,8 +111,9 @@
@import "components/umb-empty-state.less";
@import "components/umb-property-editor.less";
@import "components/umb-iconpicker.less";
@import "components/umb-website-selector.less";
@import "components/umb-dots.less";
@import "components/umb-variations.less";
@import "components/umb-splitview.less";
@import "components/buttons/umb-button.less";
@import "components/buttons/umb-button-group.less";
@@ -4,30 +4,29 @@
.umb-editor-wrapper{
background: white;
position: absolute;
top: 0px; bottom: 0px; left: 0px; right: 0px;
// position: absolute;
// top: 0px; bottom: 0px; left: 0px; right: 0px;
}
.umb-editor-header{
background: @grayLighter;
.umb-editor-header {
//background: @grayLighter;
border-bottom: 1px solid @grayLight;
position: absolute;
height: 99px;
top: 0px;
right: 0px;
left: 0px;
//position: absolute;
// height: 99px;
//top: 0px;
//right: 0px;
//left: 0px;
}
.umb-editor-container {
top: 101px;
left: 0px;
right: 0px;
bottom: 52px;
position: absolute;
clear: both;
overflow: auto;
// top: 101px;
// left: 0px;
// right: 0px;
// bottom: 52px;
// position: absolute;
// clear: both;
// overflow: auto;
}
.umb-editor-wrapper.-no-footer .umb-editor-container {
@@ -39,17 +38,18 @@
}
.umb-editor-drawer{
margin: 0;
//margin: 0;
padding: 10px 20px;
z-index: 999;
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
height: 31px;
//z-index: 999;
//position: absolute;
//bottom: 0px;
//left: 0px;
//right: 0px;
background: @grayLighter;
//background: @grayLighter;
border-top: 1px solid @grayLight;
flex: 0 0 @editorFooterHeight;
box-sizing: border-box;
}
@@ -61,3 +61,187 @@
.umb-editor-actions li{
display: inline-block;
}
.umb-editor-header__published-state {
width: 10px;
height: 10px;
}
/* ----- LANGUAGE AND VARIATION */
.umb-editor-header__selected-variations {
display: flex;
flex-direction: row;
margin-top: 6px;
margin-bottom: -4px;
}
.umb-editor-header__selected-variation {
display: flex;
flex-direction: row;
font-size: 12px;
color: #9e9ea6;
}
.umb-editor-header__selected-variation:first-child {
margin-right: 10px;
}
.umb-editor-header__selected-variation-icon {
margin-right: 5px;
}
/* --- VARIATIONS --- */
.umb-variations-quick-switcher__toggle {
position: absolute;
top: 0;
right: 0;
display: flex;
align-items: center;
border: 1px solid #ECECEC;
padding-left: 20px;
padding-right: 20px;
height: 30px;
box-sizing: border-box;
}
.umb-variations-quick-switcher__toggle.-active,
.umb-variations-quick-switcher__toggle.-active:hover {
background: @blue;
border-color: @blue;
color: @white;
}
.umb-variations-quick-switcher__toggle:hover {
background-color: @grayLighter;
border-color: @grayLight;
}
.umb-variations-quick-switcher__toggle:hover,
.umb-variations-quick-switcher__toggle:focus {
text-decoration: none;
}
.umb-variations-quick-switcher__toggle-icon {
margin-right: 5px;
}
.umb-variations-quick-switcher__toggle-arrow {
}
.umb-variations-quick-switcher_variations {
position: absolute;
top: 30px;
left: 0;
right: 0;
z-index: 6200;
background-color: #ffffff;
max-height: 300px;
overflow-y: auto;
list-style: none;
margin-left: 0;
margin-bottom: 0;
}
.umb-variations-quick-switcher_variation > li {
border-left: 4px solid transparent;
box-sizing: border-box;
}
.umb-variations-quick-switcher_variation > li:hover {
border-color: @grayLighter;
}
.umb-variations-quick-switcher_variation > li.-active,
.umb-variations-quick-switcher_variation > li.-active:hover {
border-left-color: @blue;
}
.umb-variations-quick-switcher_variation li.-active,
.umb-variations-quick-switcher_variation li.-active:hover {
background-color: fade(@blueDark, 4%);
}
.umb-variations-quick-switcher__variation {
display: flex;
flex-direction: row;
align-items: center;
height: 60px;
padding: 0 15px;
}
.umb-variations-quick-switcher__variation-stroke {
border-left: 1px solid @grayLight;
padding-left: 10px;
}
.umb-variations-quick-switcher__subnav {
list-style: none;
margin-left: 0;
margin-bottom: 0;
}
.umb-variations-quick-switcher__variation:last-child {
border-bottom: none;
}
.umb-variations-quick-switcher__variation:hover,
.umb-variations-quick-switcher__variation:focus {
text-decoration: none;
outline: none;
}
.umb-variations-quick-switcher__variation:hover,
.umb-variations-quick-switcher__variation.-active {
background-color: @grayLighter;
}
.umb-variations-quick-switcher__variation.-active {
background-color: rgb(238, 246, 254);
}
.umb-variations-quick-switcher__variation-published-state {
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
background-color: @grayLight;
margin-right: 10px;
}
.umb-variations-quick-switcher__variation-toggle {
font-size: 13px;
margin-left: auto;
opacity: .5;
padding: 5px 10px;
}
.umb-variations-quick-switcher__variation-toggle:hover {
opacity: 1;
}
.umb-variations-quick-switcher__variation-published-state.-published {
background-color: @green;
}
.umb-variations-quick-switcher__variation-name {
font-size: 13px;
font-weight: bold;
}
.umb-variations-quick-switcher__variation-icon {
color: @grayLight;
margin-right: 5px;
}
.umb-variations-quick-switcher__variation-description {
font-size: 11px;
color: @gray;
margin-left: 5px;
}
@@ -0,0 +1,107 @@
.umb-editor-sub-view {
display: flex;
flex-direction: column;
height: ~"(calc(~'100vh' - ~'@{navigationBarHeight}' - ~'@{editorHeaderHeight}' - ~'@{editorFooterHeight}'))";
}
.umb-editor-sub-view-header {
display: flex;
flex-direction: row;
border-bottom: 1px solid rgba(217,217,217, .6);
flex: 0 0 @editorSubViewHeaderHeight;
padding: 0 20px;
align-items: center;
box-sizing: border-box;
background: @grayLighter;
}
.umb-editor-sub-view-header__content-left {
margin-right: auto;
}
.umb-editor-sub-view-header__content-right {
margin-left: auto;
}
.umb-editor-sub-view-container {
flex: 1 1 auto;
display: flex;
flex-direction: row;
background: #F9F9F9;
}
.umb-editor-sub-view-content {
flex: 1 1 auto;
padding: 30px 20px;
overflow-y: auto;
position: relative;
}
.umb-editor-sub-view-sidebar {
flex: 0 0 400px;
border-left: 1px solid @grayLight;
display: flex;
flex-direction: column;
background: @white;
}
.umb-editor-sub-view-sidebar-header {
flex: 0 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
padding: 20px 0;
}
.umb-editor-sub-view-sidebar-header i {
margin-left: auto;
cursor: pointer;
color: @grayMed;
}
.umb-editor-sub-view-sidebar-header i:hover {
color: @black;
}
.umb-editor-sub-view-sidebar-title {
font-size: 16px;
font-weight: bold;
color: @black;
display: flex;
width: 100%;
}
.umb-editor-sub-view-sidebar-container {
overflow-y: auto;
flex: 1 1 auto;
box-sizing: border-box;
padding-top: 20px;
padding-bottom: 20px;
}
.umb-editor-sub-view-sidebar-footer {
flex: 0 0 @editorFooterHeight;
background: @grayLighter;
display: flex;
align-items: center;
}
.umb-editor-sub-view-sidebar-header,
.umb-editor-sub-view-sidebar-container,
.umb-editor-sub-view-sidebar-footer {
padding-right: 20px;
padding-left: 20px;
}
@@ -0,0 +1,19 @@
.umb-editor-toolbar {
padding: 0 20px;
flex: 0 0 50px;
display: flex;
align-items: center;
border-bottom: 1px solid @grayLight;
justify-content: space-between;
}
.editor-toolbar-properties {
font-size: 20px;
color: @grayMed;
}
.editor-toolbar-properties:hover,
.editor-toolbar-properties:focus {
color: @grayDark !important;
text-decoration: none;
}
@@ -1,7 +1,7 @@
.umb-notifications {
z-index: 1000;
position: absolute;
bottom: 52px;
bottom: @editorFooterHeight;
left: 0;
right: 0;
border-bottom: none;
@@ -152,30 +152,19 @@
}
}
/* ---------- OVERLAY TREE ---------- */
.umb-overlay.umb-overlay-tree {
position: absolute;
width: 500px;
top: 0;
left: 100%;
/* ---------- OVERLAY FULL ---------- */
.umb-overlay.umb-overlay-full {
left: 0;
right: 0;
top: @navigationBarHeight;
bottom: 0;
border: none;
//box-shadow: 0 0 20px rgba(0,0,0,0.19), 0 0 6px rgba(0,0,0,0.23);
box-shadow: 3px 0 7px #dbdbdb;
display: inline-block;
}
.umb-overlay.umb-overlay-tree .umb-overlay-header {
flex-basis: 100px;
padding: 20px;
box-sizing: border-box;
.umb-overlay.umb-overlay-full .umb-overlay-header {
display: none;
}
.umb-overlay.umb-overlay-tree .umb-overlay-container {
padding: 20px;
}
/* ---------- OVERLAY ITEM DETAILS ---------- */
.umb-overlay__item-details {
position: absolute;
@@ -1,26 +0,0 @@
.umb-dots {
position: relative;
width: 5px;
height: 5px;
background-color: @gray;
border-radius: 50%;
}
.umb-dots:before,
.umb-dots:after {
display: block;
position: absolute;
content: '';
width: 5px;
height: 5px;
background-color: @gray;
border-radius: 50%;
}
.umb-dots:before {
transform: translateX(-8px);
}
.umb-dots:after {
transform: translateX(8px);
}
@@ -1,14 +1,41 @@
.umb-sub-views-nav {
list-style: none;
display: flex;
margin: 0;
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: flex-end;
}
.umb-sub-views-nav-items {
display: flex;
justify-content: center;
height: 61px;
}
.umb-sub-views-nav-items .umb-navigation-more {
height: 20px;
margin: 0;
}
.umb-sub-views-nav-item {
text-align: center;
margin-left: 20px;
padding: 10px;
cursor: pointer;
display: block;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
max-width: 100%;
text-overflow: ellipsis;
box-sizing: border-box;
}
.umb-sub-views-nav-item:focus {
@@ -35,5 +62,23 @@
}
.umb-sub-views-nav-item-text {
font-size: 11px;
font-size: 11px;
vertical-align: baseline;
margin: 10px 0 0 0;
line-height: 1;
white-space: nowrap;
}
// drop down
.umb-sub-views-nav__dropdown {
position: absolute;
right: 20px;
background: #fff;
margin-top: 10px;
z-index: 1;
padding: 10px 20px;
display: flex;
justify-content: flex-end;
width: auto;
}
@@ -4,9 +4,8 @@
// drop zone
// tall and small version - animate height
.dropzone {
height: 400px;
height: 500px;
width: 100%;
padding: 50px 0;
border: 1px dashed @grayLight;
text-align: center;
color: @gray;
@@ -15,11 +14,12 @@
-webkit-transition: height 0.8s;
-moz-transition: height 0.8s;
transition: height 0.8s;
box-sizing: border-box;
.illustration {
width: 300px;
}
&.is-small {
height: 100px;
height: 200px;
.illustration {
width: 200px;
}
@@ -1,3 +1,146 @@
.umb-property-editor.-not-clickable {
pointer-events: none;
}
.umb-property-editor {
position: relative;
}
.umb-property-editor__overlay {
background-color: rgba(255,255,255, .65);
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
}
.umb-property-editor__overlay-label {
font-size: 16px;
font-weight: bold;
color: #;
background: #ffffff;
padding: 10px 20px;
color: @grayLight;
}
.umb-property .control-label {
font-size: 14px;
}
.umb-property .control-label small {
font-size: 11px;
line-height: 17px;
margin-top: 5px;
margin-bottom: 10px;
}
.umb-property-editor__dropdown-toggling {
z-index: 1;
position: relative;
}
.umb-property-editor__dropdown-toggling.-active {
z-index: 10;
}
.umb-property-editor__dropdown-toggling.-active .umb-property-editor__dropdown-toggle {
color: @blue;
}
.umb-property-editor__dropdown-toggle {
display: inline-flex;
align-items: center;
width: auto;
box-sizing: border-box;
font-weight: bold;
font-size: 12px;
cursor: pointer;
margin-top: 5px;
}
.umb-property-editor__dropdown-toggle:hover {
color: @blue;
}
.umb-property-editor__dropdown-toggle i,
.umb-property-editor__dropdown-link i {
margin-right: 5px;
font-size: 12px;
}
.umb-property-editor__dropdown {
position: absolute;
z-index: 10;
min-width: 250px;
background: #ffffff;
margin-top: 5px;
}
.umb-property-editor__dropdown-items {
list-style: none;
margin-bottom: 0;
margin-left: 0;
font-size: 12px;
font-weight: normal;
max-height: 165px;
overflow-y: auto;
}
.umb-property-editor__dropdown-filter {
padding: 5px;
}
.umb-property-editor__dropdown-filter input[type="search"] {
font-size: 12px;
}
.umb-property-editor__dropdown-link.-sync-off {
border-bottom: 1px solid @grayLight;
padding: 10px;
font-size: 12px;
}
.umb-property-editor__dropdown-link.-sync-off:hover {
background: rgba(217,217,217, .35);
}
.umb-property-editor__dropdown-link {
padding: 5px 10px;
display: flex;
align-items: center;
box-sizing: border-box;
}
.umb-property-editor__dropdown-link:hover {
background-color: @grayLighter;
text-decoration: none;
}
@@ -0,0 +1,41 @@
/* split view */
.splitview--views {
display: flex;
}
.splitview--view {
position: relative;
flex: 1 1 100%;
}
.splitview--divider {
flex: 0 0 8px;
background: @white;
border-right: 1px solid @grayLight;
border-left: 1px solid @grayLight;
box-shadow: 0 0 4px rgba(0,0,0,0.1);
position: relative;
z-index: 1;
}
.splitview--close {
position: absolute;
bottom: 50px;
left: 50%;
transform: translate3d(-50%, -50%, 0);
z-index: 100;
font-size: 14px;
font-weight: bold;
padding: 8px 18px;
background: rgba(0,0,0,0.05);
border-radius: 6px;
cursor: pointer;
&:hover {
background: rgba(0,0,0,0.1);
}
}
@@ -1,15 +1,119 @@
.umb-nav-tabs {
position: absolute;
z-index: 10;
.umb-tabs-nav {
list-style: none;
margin: 0;
}
.umb-nav-tabs.-padding-left {
padding-left: 20px;
// Sub view header tabs
.umb-editor-sub-view-header .umb-tabs-nav {
display: flex;
flex-wrap: wrap;
}
.umb-tab-content {
padding-top: 20px;
position: relative;
top: 22px;
border-top: 1px solid @grayLight;
.umb-editor-sub-view-header .umb-tabs-nav__tab a {
padding: 4px 10px;
font-size: 12px;
font-weight: bold;
border-radius: 6px;
margin-right: 15px;
}
.umb-editor-sub-view-header .umb-tabs-nav__tab a:hover,
.umb-editor-sub-view-header .umb-tabs-nav__tab a:active,
.umb-editor-sub-view-header .umb-tabs-nav__tab a:focus {
text-decoration: none !important;
background: rgba(0,0,0,0.05);
}
.umb-editor-sub-view-header .umb-tabs-nav__tab.active a {
background: @blue;
color: white;
text-decoration: none;
}
// Sidebar tabs
.umb-editor-sub-view-sidebar .umb-tabs-nav {
display: flex;
width: 100%;
border-bottom: 1px solid @grayLight;
padding-top: 25px;
}
.umb-editor-sub-view-sidebar .umb-tabs-nav__tab {
border-bottom: 3px solid transparent;
padding-bottom: 8px;
margin-right: 0;
flex: 1 1 100%;
font-size: 14px;
color: @grayMed;
}
.umb-editor-sub-view-sidebar .umb-tabs-nav__tab:hover,
.umb-editor-sub-view-sidebar .umb-tabs-nav__tab.-active {
text-decoration: none !important;
border-color: @blue;
color: @black;
}
.umb-editor-sub-view-sidebar .umb-tabs-nav__tab:focus,
.umb-editor-sub-view-sidebar .umb-tabs-nav__tab:active {
text-decoration: none !important;
}
// Umb activity demo css
.umb-activity {
padding: 0;
margin: 0;
}
.umb-activity-item {
border: 1px solid transparent;
padding: 10px;
list-style: none;
font-weight: bold;
cursor: pointer;
}
.umb-activity-item:hover {
border-color: @grayLight;
}
.umb-activity-item:hover .umb-activity-item-rollback {
color: @blue;
text-decoration: none;
}
.umb-activity-item-name {
display: block;
width: 100%;
font-size: 15px;
margin-bottom: 5px;
}
.umb-activity-item-rollback {
font-size: 13px;
color: @grayMed;
font-weight: normal;
}
.umb-activity-item .umb-activity-item-rollback:hover {
color: @blueDark;
}
.umb-activity-item + .umb-activity-item {
margin-top: 5px;
}
@@ -0,0 +1,356 @@
.umb-variations {
max-width: 100%;
padding: 0 20px;
margin-right: auto;
margin-left: auto;
}
.umb-variations__title-wrapper {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 20px;
}
.umb-variations__title {
font-size: 16px;
font-weight: bold;
color: @black;
}
.umb-variations__help-text {
line-height: 1.6em;
display: block;
color: @grayMed;
margin-bottom: 20px;
}
.umb-variations__filter {
margin-bottom: 10px;
}
.umb-varations__published-state {
width: 6px;
height: 6px;
border-radius: 50%;
background-color: @grayLight;
margin-right: 10px;
}
.umb-varations__published-state.-published {
background-color: @green;
}
/* ---------- VARIATIONS LANG GROUP ---------- */
.umb-varations__lang-group {
background: @white;
border: 1px solid @grayLight;
margin-bottom: 30px;
}
.umb-varations__lang-group-info {
padding: 20px 15px;
display: flex;
}
.umb-varations__lang-group-info__name {
font-size: 15px;
font-weight: bold;
display: flex;
align-items: center;
flex-direction: row;
flex: 1 1 auto;
}
.umb-varations__lang-group-info__link:hover {
text-decoration: underline;
cursor: pointer;
}
.umb-varations__lang-group-info__name i {
margin-right: 5px;
}
.umb-varations__lang-group-info__name small {
margin-left: 5px;
color: @grayMed;
font-weight: normal;
font-size: 13px;
}
.umb-varations__lang-group .umb-variations__action span {
font-size: 13px;
margin-left: 5px;
font-weight: bold;
}
.umb-varations__lang-group-info .umb-variations__action {
color: @blue;
display: flex;
}
.umb-varations__lang-group-info .umb-variations__action:hover {
color: @blueDark;
}
.umb-variations__no-variations {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 20px 40px;
}
.umb-variations__no-variations-message {
display: block;
margin-bottom: 20px;
font-size: 14px;
line-height: 22px;
color: #999;
}
/* ---------- VARIATIONS LIST ---------- */
.umb-variations__list {
list-style: none;
margin: 0;
}
.umb-variations__list-item-wrapper {
display: flex;
flex-direction: column;
}
.umb-variations__list-item {
padding: 15px;
flex: 3 1 auto;
border-top: 1px solid @grayLight;
background: #ffffff;
}
.umb-variations__list-item.-edit-mode {
background: @grayLighter;
border-top-color: #e7e7e7;
}
.umb-variations__list-item.-edit-mode + .umb-variations__edit-list-item {
border-top-color: @grayLighter;
}
.umb-variations__list-item__edit {
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: bold;
background: rgba(0, 0, 0, 0.05);
}
.umb-variations__list-item__edit:hover {
background: rgba(0, 0, 0, 0.09);
cursor: pointer;
}
.umb-variations__variation-top-bar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
}
.umb-variations__published-state {
width: 10px;
height: 10px;
border-radius: 20px;
background-color: @grayLight;
margin-right: 10px;
}
.umb-variations__published-state.-published {
background-color: @green;
}
.umb-variations__name-wrapper {
display: flex;
align-items: center;
flex-direction: row;
flex: 1 1 auto;
}
.umb-variations__name {
font-size: 13px;
font-weight: bold;
color: @black;
}
.umb-variations__name:hover {
text-decoration: underline;
cursor: pointer;
}
.umb-variations__name-icon {
margin-right: 5px;
}
.umb-variations__edit-form {
width: 100%;
}
.umb-variations__name-input:focus,
.umb-variations__name-input:active {
outline: none;
}
.umb-variations__description {
margin-bottom: 0;
margin-left: 5px;
resize: none;
font-size: 12px;
color: @grayMed;
}
.umb-variations__description-input {
resize: none;
}
.umb-variations__actions {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.umb-variations__action {
font-size: 18px;
cursor: pointer;
display: flex;
align-items: center;
flex-direction: row;
}
.umb-variations__action + .umb-variations__action {
margin-left: 20px;
}
.umb-variations__action:hover {
color: @blue;
}
/* --- CREATE VARIATION --- */
.umb-variation__create-title {
color: @black;
font-weight: bold;
font-size: 24px;
margin-bottom: 10px;
}
.umb-variation__create-form-description {
resize: none;
min-height: 100px;
}
.umb-variation__create-form {
display: flex;
flex-direction: column;
}
.umb-variation__create-form label,
.umb-variations__edit-form label {
font-weight: bold;
}
.umb-variation__create-form-actions {
display: flex;
justify-content: flex-end;
}
.umb-variations__edit-form + .umb-variations__actions {
margin-top: 30px;
}
/* */
.form-group-actions {
margin-top: 10px;
margin-bottom: 0;
}
.umb-variations__edit-list-item {
display: flex;
flex-direction: column;
width: 100%;
padding: 20px 30px;
box-sizing: border-box;
background-color: @white;
border-top: 1px solid @grayLight;
}
/* MATCHES */
.umb-variations__matches {
list-style: none;
margin-bottom: 0;
margin-left: 0;
}
.umb-variations__match {
background: @grayLighter;
padding: 10px 15px;
cursor: grab;
border-left: 2px solid @blue;
margin-bottom: 5px;
}
/* TAGS */
.umb-variations__tags {
display: flex;
flex-wrap: wrap;
}
.umb-variations__tag {
display: flex;
flex: 0 0 100%;
overflow: hidden;
box-sizing: border-box;
text-overflow: ellipsis;
font-size: 13px;
}
.umb-variations__tag + .umb-variations__tag {
margin-top: 5px;
}
.umb-variations__tag .checkbox {
margin-right: 5px;
}
.umb-variations__tag .checkbox:checked + span {
font-weight: bold;
}
/* FORM */
.umb-variations__form-group {
margin-bottom: 10px;
}
.umb-variations__label {
font-weight: bold;
color: @black;
}
.umb-variations__label + .umb-variations__tags {
margin-top: 10px;
}
@@ -1,109 +0,0 @@
.umb-website-selector {
border-bottom: 1px solid #d9d9d9;
display: flex;
align-items: stretch;
height: 50px;
position: relative;
}
.umb-website-selector__create-website {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
color: @blue;
}
.umb-website-selector__dropdown-toggle {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
padding-left: 20px;
padding-right: 20px;
font-weight: bold;
}
.umb-website-selector__dropdown-toggle:hover,
.umb-website-selector__dropdown-toggle:focus {
text-decoration: none;
}
.umb-website-selector__dropdown-toggle-content {
display: flex;
align-items: center;
}
.umb-website-selector__dropdown-toggle-name {
margin-right: 5px;
}
.umb-website-selector__dropdown {
position: absolute;
top: 50px;
left: 0;
right: 0;
z-index: 1;
background: #ffffff;
}
.umb-website-selector__websites {
margin-left: 0;
margin-bottom: 0;
list-style: none;
max-height: 300px;
overflow-y: auto;
}
.umb-website-selector__website-link {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 38px;
}
.umb-website-selector__website-link:hover,
.umb-website-selector__website-link.-selected {
background-color: @grayLighter;
text-decoration: none;
}
.umb-website-selector__dropdown-action {
display: flex;
justify-content: center;
align-items: center;
padding-top: 10px;
padding-bottom: 10px;
color: @blue;
font-size: 12px;
}
.umb-website-selector__dropdown-arrow {
width: 0;
height: 0;
margin-right: 10px;
}
.umb-website-selector__dropdown-arrow.-down {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid @gray;
}
.umb-website-selector__dropdown-arrow.-up {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid @gray;
}
.umb-website-selector__dropdown-action:hover {
text-decoration: none;
background: @blue;
color: #ffffff;
}
+11 -5
View File
@@ -16,11 +16,11 @@ label small, .guiDialogTiny {
font-size: 11px
}
label.control-label, .control-label {
label.control-label {
padding: 0 10px 0 0 !important;
font-weight: bold;
}
}
.umb-status-label{
color: @gray !important;
@@ -49,6 +49,7 @@ label.control-label, .control-label {
.form-search {
position: relative;
padding: 0;
margin-bottom: 0;
}
.form-search a{
text-decoration:none;
@@ -65,8 +66,8 @@ label.control-label, .control-label {
}
.form-search .icon, .form-search .icon-search {
position: absolute;
top: 6px;
left: 4px;
top: 23px;
left: 20px;
color: @grayLight;
}
@@ -164,7 +165,7 @@ textarea {
// Identify controls by their labels
label {
display: inline-block;
display: block;
margin-bottom: 5px;
}
@@ -207,6 +208,11 @@ input.-full-width-input {
height: 30px;
}
textarea.-full-width-textarea {
width: 100%;
box-sizing: border-box;
}
// Reset appearance properties for textual inputs and textarea
// Declare width for legacy (can't be on input[type=*] selectors or it's too specific)
input,
+1 -1
View File
@@ -139,7 +139,7 @@ h5.-black {
}
/* LABELS*/
.umb-control-group label.control-label, .umb-control-group .control-label {
.umb-control-group label.control-label {
text-align: left;
}
.umb-control-group label.control-label > div > label {
+69 -61
View File
@@ -2,11 +2,11 @@
// -------------------------
.umb-panel {
background: white;
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
// position: absolute;
// top: 0px;
// bottom: 0px;
// left: 0px;
// right: 0px;
}
.umb-panel-nobody {
@@ -17,21 +17,21 @@
.umb-panel-header {
background: @grayLighter;
border-bottom: 1px solid @grayLight;
position: absolute;
height: 99px;
top: 0px;
right: 0px;
left: 0px;
// position: absolute;
// height: 99px;
// top: 0px;
// right: 0px;
// left: 0px;
}
.umb-panel-body {
top: 101px;
left: 0px;
right: 0px;
bottom: 0px;
position: absolute;
clear: both;
overflow: auto;
// top: 101px;
// left: 0px;
// right: 0px;
// bottom: 0px;
// position: absolute;
// clear: both;
// overflow: auto;
}
.umb-panel-body.no-header {
@@ -356,7 +356,7 @@
.umb-panel-header-content-wrapper {
display: flex;
flex-direction: column;
height: 100px;
// height: 100px;
padding: 0 20px;
}
@@ -366,15 +366,18 @@
flex: 1;
}
/*
.umb-panel-header-content.-top-position {
position: relative;
top: -12px;
}
*/
.umb-panel-header-left-side {
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
}
.umb-panel-header-icon {
@@ -496,63 +499,68 @@ input.umb-panel-header-description {
/* --- VARIATIONS --- */
.umb-variations-quick-switcher__toggle {
position: absolute;
top: 6px;
right: 10px;
font-size: 16px;
// Large Search
.large-search {
font-size: 18px;
padding-top: 20px;
padding-bottom: 10px;
border-bottom: 1px solid @grayLight;
display: flex;
flex-direction: row;
align-items: center;
}
.umb-variations-quick-switcher_variations {
position: absolute;
top: 40px;
left: 0;
right: 0;
z-index: 20;
background-color: #ffffff;
max-height: 200px;
overflow-y: scroll;
.large-search,
.umb-tree.large-search-results {
width: 100%;
max-width: 960px;
min-width: auto;
margin: 0 auto;
}
.umb-variations-quick-switcher__variation {
display: flex;
flex-direction: row;
align-items: center;
padding: 10px 15px;
.large-search .umb-search-field {
border-bottom: none;
font-size: 22px;
text-indent: 10px;
padding-left: 0 !important;
line-height: 60px;
}
.umb-variations-quick-switcher__variation:last-child {
border-bottom: none;
.large-search .icon-search {
color: @black;
position: static;
font-size: 22px;
}
.umb-variations-quick-switcher__variation:hover,
.umb-variations-quick-switcher__variation:focus {
background-color: @grayLighter;
text-decoration: none;
outline: none;
.umb-tree.large-search-results .umb-search-group-item-link {
padding: 10px 0;
display: flex;
flex-direction: row;
align-items: center;
min-height: 60px;
}
.umb-variations-quick-switcher__variation-published-state {
display: block;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: @grayLight;
margin-right: 10px;
.umb-tree.large-search-results .umb-search-group-item-info {
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
overflow: visible;
}
.umb-variations-quick-switcher__variation-published-state.-published {
background-color: @green;
.umb-tree.large-search-results .umb-search-group-item-link .icon {
font-size: 24px;
}
.umb-variations-quick-switcher__variation-name {
font-size: 12px;
font-weight: bold;
.umb-tree.large-search-results .umb-search-group-item-name {
font-size: 16px;
font-weight: bold;
}
.umb-variations-quick-switcher__variation-description {
font-size: 12px;
color: @gray;
margin-left: 10px;
.umb-tree.large-search-results .search-subtitle {
padding-left: 0;
}
@@ -81,9 +81,6 @@ div.umb-codeeditor .umb-btn-toolbar {
font-size:16px !important;
}
/* pre-value editor */
.rte-editor-preval .control-group .controls > div > label .mce-ico { line-height: 20px; }
//
// Color picker
@@ -199,7 +196,6 @@ ul.color-picker li a {
flex-wrap: wrap;
padding: 2px;
margin: 5px;
background: white;
border: 1px solid #f8f8f8;
}
@@ -1,26 +1,39 @@
// Sections
// -------------------------
ul.sections {
margin: 0;
display: block;
background: @blackLight;
height: 100%;
width: 80px;
border-right: 1px solid @grayDark;
.umb-sections {
//margin: 0;
//display: block;
//background: @blackLight;
display: flex;
flex-direction: row;
flex-wrap: wrap;
//height: 100%;
//width: 80px;
//border-right: 1px solid @grayDark;
}
ul.sections li {
display: block;
border-left: 4px @blackLight solid;
-webkit-transition: all .3s linear;
-moz-transition: all .3s linear;
transition: all .3s linear;
.umb-sections__section {
//border-left: 4px @blackLight solid;
//-webkit-transition: all .3s linear;
//-moz-transition: all .3s linear;
//transition: all .3s linear;
}
ul.sections li [class^="icon-"]:before,
ul.sections li [class*=" icon-"]:before,
ul.sections li img.icon-section {
.umb-sections__section:hover {
background: #E2E2E2;
text-decoration: none;
}
.umb-sections__section.-current,
.umb-sections__section:focus {
outline: none;
text-decoration: none;
color: @blue;
}
/*
ul.sections li [class^="icon-"]:before,
ul.sections li [class*=" icon-"]:before{
font-size: 30px;
margin: 1px 0 0 0;
opacity: 0.4;
@@ -28,13 +41,15 @@ ul.sections li img.icon-section {
-moz-transition: all .3s linear;
transition: all .3s linear;
}
*/
ul.sections:hover li [class^="icon-"]:before,
ul.sections:hover li [class*=" icon-"]:before,
ul.sections:hover li img.icon-section {
/*
ul.sections:hover li [class^="icon-"]:before,
ul.sections:hover li [class*=" icon-"]:before {
opacity: 1
}
*/
/*
ul.sections li a {
display: block;
text-decoration: none;
@@ -45,7 +60,7 @@ ul.sections li a {
width: 100%;
height: 100%;
margin: 0 0 0 -4px;
cursor: pointer; // make sure IE10 displays pointer cursor for expand and help sections.
cursor: pointer; // make sure IE10 displays pointer cursor for expand and help sections.
}
ul.sections a span {
@@ -61,11 +76,12 @@ ul.sections a span {
ul.sections:hover a span {
opacity: 1
}
*/
// Avatar, Section & Help icons
// -------------------------
/*
ul.sections li.avatar {
height: 75px;
padding: 22px 0 2px 0;
@@ -86,7 +102,8 @@ ul.sections li.avatar a img {
border-radius: 50%;
width: 30px;
}
*/
/*
.faded ul.sections li {
opacity: 0.4
}
@@ -103,7 +120,7 @@ ul.sections li.current a{
padding-left: 0px;
}
ul.sections li.help {
ul.sections li.help {
margin: 0;
position: absolute;
bottom: 0;
@@ -115,9 +132,11 @@ ul.sections li.help {
ul.sections li.help a {
border-bottom: none;
}
*/
// Section slide-out tray for additional apps
// -------------------------
li.expand a, li.expand{border: none !Important;}
li.expand {
@@ -127,7 +146,7 @@ li.expand {
-o-transition: all 1s !important;
-moz-transition: all 1s !important;
transition: all 1s !important;
&:before {
-ms-transform: rotate(180deg) !important; /* IE 9 */
-webkit-transform: rotate(180deg) !important; /* Chrome, Safari, Opera */
@@ -149,7 +168,7 @@ ul.sections-tray {
& > li {
// 5px (instead of 4px) because of vertical border
border-left-width: 5px;
&.current, &:hover {
border-left-width: 5px;
}
@@ -7,6 +7,15 @@
// --------------------------------------------------
//
// -------------------------
@navigationBarHeight: 50px;
@editorHeaderHeight: 80px;
@editorFooterHeight: 50px;
@editorSubViewHeaderHeight: 50px;
// Grays
// -------------------------
@black: #000;
@@ -20,28 +20,36 @@
hide-alias="true">
</umb-editor-header>
<umb-editor-toolbar umb-tabs>
<umb-tabs-nav ng-if="dashboard.tabs" model="dashboard.tabs"></umb-tabs-nav>
</umb-editor-toolbar>
<umb-editor-container>
<umb-tabs-content view="true">
<umb-tab id="tab{{tab.id}}" ng-repeat="tab in dashboard.tabs" rel="{{tab.id}}">
<div class="umb-editor-content">
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide">
<umb-tabs-content view="true">
<umb-tab id="tab{{tab.id}}" ng-repeat="tab in dashboard.tabs" rel="{{tab.id}}">
<div class="span12 clearfix" ng-switch-when="false">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<div ng-include="property.path"></div>
</div>
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide">
<div class="span12 umb-dashboard-control clearfix" ng-switch-when="true">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<div ng-switch-when="false">
<h3 ng-show="property.caption">{{property.caption}}</h3>
<div ng-include="property.path"></div>
</div>
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
</div>
<div class="span12 umb-dashboard-control clearfix" ng-switch-when="true">
<h3 ng-show="property.caption">{{property.caption}}</h3>
</div>
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
</div>
</umb-tab>
</umb-tabs-content>
</div>
</umb-tab>
</umb-tabs-content>
</div>
</umb-editor-container>
@@ -1,15 +0,0 @@
(function() {
"use strict";
function CreateWebsiteOverlay($scope) {
var vm = this;
$scope.model.website = {};
}
angular.module("umbraco").controller("Umbraco.Overlay.CreateWebsiteOverlay", CreateWebsiteOverlay);
})();
@@ -1,26 +0,0 @@
<div ng-controller="Umbraco.Overlay.CreateWebsiteOverlay as vm">
<div class="umb-control-group control-group">
<label>Website name</label>
<input type="text" ng-model="model.website.name" />
</div>
<div class="umb-control-group control-group">
<label>Website language</label>
<select ng-model="model.website.language">
<option value="aa-DJ">Afar (Djinouti) [aa-DJ]</option>
<option value="aa-ER">Afar (Eritrea) [aa-ER]</option>
<option value="aa-ET">Afar (Ethiopia) [aa-ET]</option>
</select>
</div>
<div class="umb-control-group control-group">
<label>Create blank</label>
<input type="checkbox" ng-model="model.website.blank" />
<label>Copy all</label>
<input type="checkbox" ng-model="model.website.copyAll" />
<label>Copy selected</label>
<input type="checkbox" ng-model="model.website.copySelected" />
</div>
</div>
@@ -0,0 +1,132 @@
(function() {
"use strict";
function SearchOverlay($scope, searchService, $log, $location, navigationService, $q) {
$scope.searchTerm = null;
$scope.searchResults = [];
$scope.isSearching = false;
$scope.selectedResult = -1;
$scope.navigateResults = function(ev) {
//38: up 40: down, 13: enter
switch (ev.keyCode) {
case 38:
iterateResults(true);
break;
case 40:
iterateResults(false);
break;
case 13:
if ($scope.model.selectedItem) {
$scope.selectItem($scope.model.selectedItem);
}
break;
}
};
$scope.selectItem = function(selectedItem) {
$scope.model.selectedItem = selectedItem;
$scope.model.submit($scope.model);
};
var group = undefined;
var groupIndex = -1;
var itemIndex = -1;
$scope.model.selectedItem = undefined;
function iterateResults(up) {
//default group
if (!group) {
group = $scope.groups[0];
groupIndex = 0;
}
if (up) {
if (itemIndex === 0) {
if (groupIndex === 0) {
gotoGroup($scope.groups.length - 1, true);
} else {
gotoGroup(groupIndex - 1, true);
}
} else {
gotoItem(itemIndex - 1);
}
} else {
if (itemIndex < group.results.length - 1) {
gotoItem(itemIndex + 1);
} else {
if (groupIndex === $scope.groups.length - 1) {
gotoGroup(0);
} else {
gotoGroup(groupIndex + 1);
}
}
}
}
function gotoGroup(index, up) {
groupIndex = index;
group = $scope.groups[groupIndex];
if (up) {
gotoItem(group.results.length - 1);
} else {
gotoItem(0);
}
}
function gotoItem(index) {
itemIndex = index;
$scope.model.selectedItem = group.results[itemIndex];
}
//used to cancel any request in progress if another one needs to take it's place
var canceler = null;
$scope.$watch("searchTerm", _.debounce(function(newVal, oldVal) {
$scope.$apply(function() {
if ($scope.searchTerm) {
if (newVal !== null && newVal !== undefined && newVal !== oldVal) {
$scope.isSearching = true;
//navigationService.showSearch();
$scope.model.selectedItem = undefined;
//a canceler exists, so perform the cancelation operation and reset
if (canceler) {
console.log("CANCELED!");
canceler.resolve();
canceler = $q.defer();
} else {
canceler = $q.defer();
}
searchService.searchAll({
term: $scope.searchTerm,
canceler: canceler
}).then(function(result) {
$scope.groups = _.filter(result, function(group) {
return group.results.length > 0;
});
//set back to null so it can be re-created
canceler = null;
});
}
} else {
$scope.isSearching = false;
//navigationService.hideSearch();
$scope.model.selectedItem = undefined;
}
});
}, 200));
}
angular.module("umbraco").controller("Umbraco.Overlays.SearchOverlay", SearchOverlay);
})();
@@ -0,0 +1,50 @@
<div ng-controller="Umbraco.Overlays.SearchOverlay">
<!-- Search form -->
<form class="form-search large-search" novalidate>
<i class="icon-search"></i>
<input type="text"
id="search-field"
ng-model="searchTerm"
class="umb-search-field search-query search-input"
localize="placeholder"
placeholder="@placeholders_search"
ng-keydown="navigateResults($event)"
umb-auto-focus
autocomplete="off" />
</form>
<!-- Search results --->
<ul class="umb-tree large-search-results">
<li class="root">
<div>
<h5 class="umb-tree-header"><localize key="general_searchResults">Search results</localize></h5>
</div>
<ul class="umb-search-group" ng-repeat="group in groups">
<li ng-repeat="result in group.results" ng-class="{'current':model.selectedItem == result}">
<div class="umb-search-group-item">
<a class="umb-search-group-item-link" ng-class="{'first':$first}" ng-click="selectItem(result)">
<i class="icon umb-tree-icon sprTree {{result.icon}}"></i>
<div class="umb-search-group-item-info">
<div class="umb-search-group-item-name">
{{result.name}}
</div>
<small class="search-subtitle" ng-show="result.subTitle">
{{result.subTitle}}
</small>
</div>
</a>
</div>
</li>
</ul>
</li>
</ul>
</div>
@@ -1,116 +1,66 @@
<div id="leftcolumn" ng-controller="Umbraco.NavigationController"
ng-mouseleave="leaveTree($event)" ng-mouseenter="enterTree($event)">
<div
class="umb-navigation"
ng-controller="Umbraco.NavigationController"
ng-mouseleave="leaveTree($event)"
ng-mouseenter="enterTree($event)">
<umb-sections sections="sections" ng-if="authenticated">
</umb-sections>
<div class="umb-toggle-tree"
ng-click="showTree()"
ng-class="{'-open':showTreeNavigation}">
<!-- navigation container -->
<div id="navigation" ng-show="showNavigation" class="fill umb-modalcolumn" ng-animate="'slide'" nav-resize>
<div ng-swipe-left="nav.hideNavigation()" class="navigation-inner-container span6">
<!-- the search -->
<div ng-controller="Umbraco.SearchController" ng-if="authenticated">
<!-- Search form -->
<div id="search-form">
<div class="umb-modalcolumn-header">
<form class="form-search" novalidate>
<i class="icon-search"></i>
<input type="text"
hotkey="ctrl+space"
id="search-field"
ng-model="searchTerm"
class="umb-search-field search-query search-input"
localize="placeholder"
placeholder="@placeholders_search"
ng-keydown="navigateResults($event)"/>
</form>
</div>
</div>
<!-- Search results -->
<div id="search-results" class="umb-modalcolumn-body" ng-show="showSearchResults">
<ul class="umb-tree">
<li class="root">
<div>
<h5 class="umb-tree-header"><localize key="general_searchResults">Search results</localize></h5>
</div>
<ul class="umb-search-group" ng-repeat="group in groups">
<li ng-repeat="result in group.results" ng-class="{'current':selectedItem == result}">
<div class="umb-search-group-item">
<a class="umb-search-group-item-link" ng-class="{'first':$first}" ng-click="searchHide()" ng-href="#/{{result.editorPath}}">
<div class="umb-search-group-item-name">
<i class="icon umb-tree-icon sprTree {{result.icon}}"></i>
{{result.name}}
</div>
<small class="search-subtitle" ng-show="result.subTitle">
{{result.subTitle}}
</small>
</a>
<a href ng-click="searchShowMenu($event, {node: result})" class="umb-options"><i></i><i></i><i></i></a>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
<umb-website-selector
websites="websites"
on-create-website="createWebsite"
on-click-website="clickWebsite">
</umb-website-selector>
<!-- the tree -->
<div id="tree" ng-if="authenticated && websites.length > 0">
<umb-tree
cachekey="_"
eventhandler="treeEventHandler"
section="{{currentSection}}" >
</umb-tree>
</div>
</div>
<div class="offset6" id="navOffset" style="z-index: 10">
<!-- The context menu -->
<div id='contextMenu' class="umb-modalcolumn fill shadow" ng-swipe-left="nav.hideMenu()" ng-show="showContextMenu" ng-animate="'slide'">
<umb-context-menu
menu-dialog-title="{{menuDialogTitle}}"
current-section="{{currentSection}}"
current-node="menuNode"
menu-actions="menuActions">
</umb-context-menu>
</div>
<umb-overlay
ng-if="createWebsiteOverlay.show"
model="createWebsiteOverlay"
view="createWebsiteOverlay.view"
position="tree">
</umb-overlay>
<!-- Tree dialogs -->
<div id="dialog" class='umb-modalcolumn fill shadow'
ng-swipe-left="nav.hideDialog()"
ng-show="showContextMenuDialog" ng-animate="'slide'">
<div class='umb-modalcolumn-header'>
<h1>{{menuDialogTitle}}</h1>
</div>
<div class='umb-modalcolumn-body'>
</div>
</div>
</div>
<div class="umb-toggle-icon"></div>
</div>
<umb-sections
ng-if="authenticated"
sections="sections">
</umb-sections>
<div class="umb-navigation__right">
<div class="search">
<a class="umb-navigation-link" href class="help" hotkey="ctrl+shift+s" ng-click="searchClick()" prevent-default>
<span>Search</span>
</a>
</div>
<div class="help">
<a class="umb-navigation-link" href class="help" hotkey="ctrl+shift+h" ng-click="helpClick()" prevent-default>
<span><localize key="sections_help">Help</localize></span>
</a>
</div>
<div>
<a class="umb-navigation-link" href="#" ng-click="avatarClick()" hotkey="ctrl+shift+u" title="{{user.name}}" prevent-default>
<span>{{user.name}}</span>
<img id="avatar-img" ng-src="{{avatar[0].value}}" ng-srcset="{{avatar[1].value}} 2x, {{avatar[2].value}} 3x" />
</a>
</div>
</div>
<!-- navigation container -->
<umb-overlay
ng-if="searchOverlay.show"
model="searchOverlay"
view="searchOverlay.view"
position="full">
</umb-overlay>
<umb-overlay
ng-if="helpDialog.show"
model="helpDialog"
view="helpDialog.view"
position="right">
</umb-overlay>
<umb-overlay
ng-if="userDialog.show"
model="userDialog"
view="userDialog.view"
position="right">
</umb-overlay>
</div>
@@ -1,62 +1,45 @@
<div>
<div id="applications" ng-class="{faded:stickyNavigation}">
<ul class="sections">
<li class="avatar">
<a href="#" ng-click="avatarClick()" hotkey="ctrl+shift+u" title="{{user.name}}" prevent-default>
<img id="avatar-img" ng-src="{{avatar[0].value}}" ng-srcset="{{avatar[1].value}} 2x, {{avatar[2].value}} 3x" />
</a>
</li>
<li ng-repeat="section in sections | limitTo: maxSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
<nav class="umb-sections">
<a
class="umb-navigation-link"
href="#/{{section.alias}}"
ng-repeat="section in sections | limitTo: maxSections"
ng-class="{'-current': section.alias == currentSection}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<span class="umb-sections__section-name">{{section.name}}</span>
</a>
<span class="umb-navigation-link expand"
ng-class="{ 'open': showTray === true }"
ng-show="needTray"
href ng-click="trayClick()">
<svg class="umb-navigation-more" viewBox="0 0 24 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path class="umb-navigation-more__path" d="M2.76923077,5.53846154 C4.29863469,5.53846154 5.53846154,4.29863469 5.53846154,2.76923077 C5.53846154,1.23982685 4.29863469,0 2.76923077,0 C1.23982685,0 0,1.23982685 0,2.76923077 C0,4.29863469 1.23982685,5.53846154 2.76923077,5.53846154 Z M12,5.53846154 C13.5294039,5.53846154 14.7692308,4.29863469 14.7692308,2.76923077 C14.7692308,1.23982685 13.5294039,0 12,0 C10.4705961,0 9.23076923,1.23982685 9.23076923,2.76923077 C9.23076923,4.29863469 10.4705961,5.53846154 12,5.53846154 Z M21.2307692,5.53846154 C22.7601732,5.53846154 24,4.29863469 24,2.76923077 C24,1.23982685 22.7601732,0 21.2307692,0 C19.7013653,0 18.4615385,1.23982685 18.4615385,2.76923077 C18.4615385,4.29863469 19.7013653,5.53846154 21.2307692,5.53846154 Z"></path>
</g>
</svg>
<div class="umb-sections__tray shadow-depth-2"
ng-show="showTray">
<a class="umb-navigation-link"
ng-repeat="section in sections | limitTo: overflowingSections"
ng-class="{'-current': section.alias == currentSection}"
href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
<li class="expand" ng-class="{ 'open': showTray === true }" ng-show="needTray">
<a href ng-click="trayClick()">
<i class="icon icon-arrow-right"></i>
</a>
</li>
<li class="help">
<a href class="help" hotkey="ctrl+shift+h" ng-click="helpClick()" prevent-default>
<i class="icon-help-alt"></i>
<span><localize key="sections_help">Help</localize></span>
</a>
</li>
</ul>
</div>
</div>
</span>
<div id="applications-tray" ng-show="showTray" ng-animate="trayAnimation()" style="display: none;">
<ul class="sections sections-tray">
<li ng-repeat="section in sections | limitTo: overflowingSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>
</ul>
</div>
<umb-overlay
ng-if="helpDialog.show"
model="helpDialog"
view="helpDialog.view"
position="left">
</umb-overlay>
<umb-overlay
ng-if="userDialog.show"
model="userDialog"
view="userDialog.view"
position="left">
</umb-overlay>
</nav>
</div>
@@ -0,0 +1,74 @@
<div class="umb-tree-navigation" ng-show="showTreeNavigation">
<!-- the search
<div ng-controller="Umbraco.SearchController" ng-if="authenticated">
-->
<!-- Search form
<form class="form-search" novalidate>
<i class="icon-search"></i>
<input type="text"
hotkey="ctrl+space"
id="search-field"
ng-model="searchTerm"
class="umb-search-field search-query search-input"
localize="placeholder"
placeholder="@placeholders_search"
ng-keydown="navigateResults($event)"/>
</form>
-->
<!-- Search results
<div ng-show="showSearchResults">
<ul class="umb-tree">
<li class="root">
<div>
<h5 class="umb-tree-header"><localize key="general_searchResults">Search results</localize></h5>
</div>
<ul class="umb-search-group" ng-repeat="group in groups">
<li ng-repeat="result in group.results" ng-class="{'current':selectedItem == result}">
<div class="umb-search-group-item">
<a class="umb-search-group-item-link" ng-class="{'first':$first}" ng-click="searchHide()" ng-href="#/{{result.editorPath}}">
<div class="umb-search-group-item-name">
<i class="icon umb-tree-icon sprTree {{result.icon}}"></i>
{{result.name}}
</div>
<small class="search-subtitle" ng-show="result.subTitle">
{{result.subTitle}}
</small>
</a>
<a href ng-click="searchShowMenu($event, {node: result})" class="umb-options"><i></i><i></i><i></i></a>
</div>
</li>
</ul>
</li>
</ul>
</div>
-->
<!--
</div>
--->
<!--
<div ng-show="!showSearchResults">
<umb-tree
cachekey="_"
eventhandler="treeEventHandler"
section="{{currentSection}}" >
</umb-tree>
</div>
--->
<umb-tree
cachekey="_"
eventhandler="treeEventHandler"
section="{{currentSection}}" >
</umb-tree>
</div>
@@ -0,0 +1 @@
<div class="umb-editor-sub-view-container" ng-transclude></div>
@@ -0,0 +1 @@
<div class="umb-editor-sub-view-content" ng-transclude></div>
@@ -0,0 +1 @@
<div class="umb-editor-sub-view-header" ng-transclude></div>
@@ -0,0 +1 @@
<div class="umb-editor-sub-view-sidebar" ng-transclude></div>
@@ -0,0 +1 @@
<div class="umb-editor-sub-view" ng-transclude></div>
@@ -1,6 +1,8 @@
<div class="umb-editor-container umb-panel-body umb-scrollable row-fluid" ng-class="{'-stop-scrolling': numberOfOverlays > 0}">
<umb-overlay-backdrop></umb-overlay-backdrop>
<div class="umb-pane">
<div ng-transclude></div>
</div>
</div>
<div
class="umb-editor-container"
ng-class="{'-stop-scrolling': numberOfOverlays > 0}"
ng-transclude>
<!--
<umb-overlay-backdrop></umb-overlay-backdrop>
-->
</div>
@@ -1,4 +1,4 @@
<div class="umb-panel-header">
<div class="umb-editor-header">
<div class="umb-panel-header-content-wrapper">
@@ -15,6 +15,10 @@
<div class="umb-panel-header-title-wrapper">
<!--
<div class="umb-editor-header__published-state"></div>
--->
<ng-form name="headerNameForm">
<input
type="text"
@@ -25,15 +29,69 @@
ng-show="!nameLocked"
ng-model="name"
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
ng-disabled="variation"
umb-auto-focus
autocomplete="off"
required />
<div class="umb-editor-header__selected-variations" ng-if="language || variation">
<div class="umb-editor-header__selected-variation" ng-if="language && variations.length > 1">
<i class="umb-editor-header__selected-variation-icon icon-umb-translation"></i>
<div>{{ language }}</div>
</div>
<div class="umb-editor-header__selected-variation" ng-if="variation">
<i class="umb-editor-header__selected-variation-icon icon-documents"></i>
<div>{{ variation }}</div>
</div>
</div>
</ng-form>
<div class="umb-panel-header-name" ng-if="nameLocked">{{ name }}</div>
<a class="umb-variations-quick-switcher__toggle" href="" ng-if="showVariationsQuickSwitchToggle" ng-click="toggleVariationsQuickSwitch()" ng-class="{'-active' : showVariationsQuickSwitch}">
<span class="umb-variations-quick-switcher__toggle-arrow">&dtrif;</span>
</a>
<a class="umb-variations-quick-switcher__toggle" href="" ng-click="toggleVariationsQuickSwitch()">
<i class="icon-documents"></i>
</a>
<ul class="umb-variations-quick-switcher_variations shadow-depth-2" ng-if="showVariationsQuickSwitch" on-outside-click="hideVariationsQuickSwitch()">
<!-- Multiple languages -->
<li ng-repeat="variation in variations" ng-class="{'-active' : variation.showSubItems}">
<a class="umb-variations-quick-switcher__variation" href ng-if="variations.length === 1" ng-click="selectItem(variation)" ng-class="{'-active': variation.active}">
<span class="umb-variations-quick-switcher__variation-published-state" ng-class="{'-published': variation.published}"></span>
<span class="umb-variations-quick-switcher__variation-name">{{variation.name}}</span>
<span class="umb-variations-quick-switcher__variation-description">(Original)</span>
</a>
<a class="umb-variations-quick-switcher__variation" href ng-if="variations.length > 1" ng-click="selectItem(variation)" ng-class="{'-active': variation.active}">
<span class="umb-variations-quick-switcher__variation-published-state" ng-class="{'-published': variation.published}"></span>
<i class="umb-variations-quick-switcher__variation-icon icon-umb-translation"></i>
<span class="umb-variations-quick-switcher__variation-name">{{variation.language}}</span>
<!--
<span class="umb-variations-quick-switcher__variation-toggle" ng-if="variation.variations" ng-click="toggleSubItems(variation, $event)">variations &dtrif;</span>
--->
<span class="umb-variations-quick-switcher__variation-toggle" ng-if="onOpenInSplitView && !variation.active" ng-click="openInSplitView(variation, $event)">Open in splitview</span>
</a>
<ul class="umb-variations-quick-switcher__subnav">
<li ng-repeat="test in variation.variations">
<a class="umb-variations-quick-switcher__variation" href ng-click="selectItem(test)" ng-class="{'-active': test.active}">
<span class="umb-variations-quick-switcher__variation-published-state" ng-class="{'-published': test.published}"></span>
<i class="umb-variations-quick-switcher__variation-icon icon-documents"></i>
<span class="umb-variations-quick-switcher__variation-name">{{ test.variationName }}</span>
<span class="umb-variations-quick-switcher__variation-description" ng-if="test.variationDescription">({{ test.variationDescription }})</span>
<span class="umb-variations-quick-switcher__variation-toggle" ng-if="onOpenInSplitView && !test.active" ng-click="openInSplitView(test, $event)">Open in splitview</span>
</a>
</li>
</ul>
</li>
</ul>
<div class="umb-panel-header-name" ng-if="nameLocked">{{ name }}</div>
<umb-generate-alias class="umb-panel-header-alias"
ng-if="!hideAlias"
@@ -59,7 +117,7 @@
</div>
<umb-tabs-nav ng-if="tabs" model="tabs"></umb-tabs-nav>
<!-- <umb-tabs-nav ng-if="tabs" model="tabs"></umb-tabs-nav> -->
</div>
@@ -1,15 +1,37 @@
<div>
<ul class="umb-sub-views-nav" ng-if="showNavigation">
<li ng-repeat="item in navigation">
<a tabindex="-1"
class="umb-sub-views-nav-item"
href=""
ng-click="clickNavigationItem(item)"
hotkey="{{$index+1}}"
ng-class="{'is-active': item.active, '-has-error': item.hasError}">
<i class="icon {{ item.icon }}"></i>
<span class="umb-sub-views-nav-item-text">{{ item.name }}</span>
</a>
</li>
</ul>
<ul class="umb-sub-views-nav" ng-if="showNavigation">
<li ng-repeat="item in navigation | limitTo: maxNavigationItems" class="umb-sub-views-nav-items">
<a tabindex="-1" class="umb-sub-views-nav-item" href="" ng-click="clickNavigationItem(item)" hotkey="{{$index+1}}" ng-class="{'is-active': item.active, '-has-error': item.hasError}">
<i class="icon {{ item.icon }}"></i>
<span class="umb-sub-views-nav-item-text">{{ item.name }}</span>
</a>
</li>
<li class="umb-sub-views-nav-items" ng-if="needDropdown" ng-click="toggleDropdown()">
<a href="" class="umb-sub-views-nav-item">
<svg class="umb-navigation-more" viewBox="0 0 24 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path class="umb-navigation-more__path" d="M2.76923077,5.53846154 C4.29863469,5.53846154 5.53846154,4.29863469 5.53846154,2.76923077 C5.53846154,1.23982685 4.29863469,0 2.76923077,0 C1.23982685,0 0,1.23982685 0,2.76923077 C0,4.29863469 1.23982685,5.53846154 2.76923077,5.53846154 Z M12,5.53846154 C13.5294039,5.53846154 14.7692308,4.29863469 14.7692308,2.76923077 C14.7692308,1.23982685 13.5294039,0 12,0 C10.4705961,0 9.23076923,1.23982685 9.23076923,2.76923077 C9.23076923,4.29863469 10.4705961,5.53846154 12,5.53846154 Z M21.2307692,5.53846154 C22.7601732,5.53846154 24,4.29863469 24,2.76923077 C24,1.23982685 22.7601732,0 21.2307692,0 C19.7013653,0 18.4615385,1.23982685 18.4615385,2.76923077 C18.4615385,4.29863469 19.7013653,5.53846154 21.2307692,5.53846154 Z"></path>
</g>
</svg>
<span class="umb-sub-views-nav-item-text">More</span>
</a>
</li>
</ul>
<div class="umb-sub-views-nav__dropdown shadow-depth-2" ng-if="showDropdown" on-outside-click="closeDropdown()">
<ul class="umb-sub-views-nav">
<li ng-repeat="item in navigation | limitTo: overflowingNavigationsItems" class="umb-sub-views-nav-items">
<a tabindex="-1" class="umb-sub-views-nav-item" href="" ng-click="clickNavigationItem(item)" hotkey="{{$index+1}}" ng-class="{'is-active': item.active, '-has-error': item.hasError}">
<i class="icon {{ item.icon }}"></i>
<span class="umb-sub-views-nav-item-text">{{ item.name }}</span>
</a>
</li>
</ul>
</div>
</div>
@@ -3,7 +3,7 @@
id="sub-view-{{$index}}"
ng-repeat="subView in subViews"
ng-include="subView.view"
ng-show="activeView.name == subView.name"
ng-show="subView.active"
ng-class="'sub-view-' + subView.name"
val-sub-view>
</div>
@@ -0,0 +1 @@
<div class="umb-editor-toolbar" ng-transclude></div>
@@ -1,4 +1,4 @@
<div class="umb-panel umb-editor-wrapper animated -half-second fadeIn"
<div class="umb-panel umb-editor-wrapper"
ng-class="{
'-no-footer': footer === 'false'
}"
@@ -1,3 +1,8 @@
<div class="umb-property-editor" ng-class="{'-not-clickable': preview}">
<!--
<div class="umb-property-editor__overlay" ng-if="model.variation">
<div class="umb-property-editor__overlay-label">Gets content from {{model.variation.name}}</div>
</div>
--->
<div ng-include="propertyEditorView"></div>
</div>
@@ -1,14 +1,46 @@
<div class="umb-property">
<ng-form name="propertyForm">
<div class="control-group umb-control-group" ng-class="{hidelabel:property.hideLabel}" >
<val-property-msg property="property"></val-property-msg>
<div class="umb-el-wrap">
<label class="control-label" ng-hide="property.hideLabel" for="{{property.alias}}" ng-attr-title="{{propertyAlias}}">
{{property.label}}
<small ng-bind-html="property.description"></small>
<small ng-if="property.description" ng-bind-html="property.description"></small>
<!--
<div class="umb-property-editor__dropdown-toggling" ng-class="{'-active' : showDropdown}">
<div class="umb-property-editor__dropdown-toggle" ng-click="toggleDropdown()">
<div ng-if="property.variation"><i class="icon-sync"></i>from {{ property.variation.name }} &dtrif;</div>
<div ng-if="!property.variation"><i class="icon-sync"></i>from &dtrif;</div>
</div>
<div class="umb-property-editor__dropdown shadow-depth-2" ng-if="showDropdown" on-outside-click="closeDropdown()">
<div class="umb-property-editor__dropdown-item">
<a class="umb-property-editor__dropdown-link -sync-off" ng-click="editContent()" href="">
<i class="icon-sync"></i>Off
</a>
</div>
<div class="umb-property-editor__dropdown-filter" ng-if="variations.length > 9">
<input type="search"class="-full-width-input" placeholder="Search for variants" ng-model="searchTerm" umb-auto-focus>
</div>
<ul class="umb-property-editor__dropdown-items">
<li class="umb-property-editor__dropdown-item" ng-repeat="variation in variations | filter:searchTerm">
<a class="umb-property-editor__dropdown-link" ng-click="syncContent(variation)" href="">{{ variation.name }}</a>
</li>
</ul>
</div>
</div>
--->
</label>
<div class="controls" ng-transclude>
@@ -16,4 +48,4 @@
</div>
</div>
</ng-form>
</div>
</div>
@@ -1,5 +1,5 @@
<ul class="nav nav-tabs umb-nav-tabs">
<li ng-class="{'tab-error': tabHasError}" ng-repeat="tab in model" val-tab>
<a data-toggle="tab" href="#tab{{tab.id}}">{{ tab.label }}</a>
</li>
<ul class="umb-tabs-nav">
<li class="umb-tabs-nav__tab" ng-class="{'tab-error': tabHasError}" ng-repeat="tab in model" val-tab>
<a data-toggle="tab" href="#tab{{tab.id}}">{{ tab.label }}</a>
</li>
</ul>
@@ -1,23 +1,19 @@
<ul class="umb-tree">
<li class="root">
<ul class="umb-search-group">
<li ng-repeat="result in results">
<div style="padding-left: 20px" ng-class="{'umb-tree-node-checked' : result.selected}">
<a class="umb-search-group-item-link" ng-class="{first:$first}" ng-click="selectResultCallback($event, result)">
<div class="umb-search-group-item-name">
<i class="icon umb-tree-icon sprTree {{result.icon}}"></i>
{{result.name}}
</div>
<small class="search-subtitle" ng-if="result.subTitle">{{result.subTitle}}</small>
</a>
</div>
</li>
</ul>
</li>
</ul>
<div>
<ul class="umb-tree">
<li class="root">
<ul class="umb-search-group">
<li ng-repeat="result in results">
<div style="padding-left: 20px">
<a class="umb-search-group-item-link" ng-class="{first:$first}" ng-click="selectResultCallback($event, result)">
<div class="umb-search-group-item-name">
<i class="icon umb-tree-icon sprTree {{result.icon}}"></i>
{{result.name}}
</div>
<small class="search-subtitle" ng-if="result.subTitle">{{result.subTitle}}</small>
</a>
</div>
</li>
</ul>
</li>
</ul>
</div>

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