diff --git a/.gitignore b/.gitignore index 8064045856..113b207285 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,12 @@ build/UmbracoCms.*/ src/.vs/ src/Umbraco.Web.UI/umbraco/js/install.loader.js src/Umbraco.Web.UI/js/* -src/Umbraco.Tests/media \ No newline at end of file +src/Umbraco.Tests/media +tools/docfx/* +apidocs/_site/* +src/*/project.lock.json + +apidocs/api/* +build/docs.zip +build/ui-docs.zip +build/csharp-docs.zip diff --git a/apidocs/docfx.filter.yml b/apidocs/docfx.filter.yml new file mode 100644 index 0000000000..e96fbaafff --- /dev/null +++ b/apidocs/docfx.filter.yml @@ -0,0 +1,18 @@ +apiRules: + - include: + uidRegex: ^Umbraco\.Core + - exclude: + uidRegex: ^umbraco\.Web\.org + - include: + uidRegex: ^Umbraco\.Web + - exclude: + hasAttribute: + uid: System.ComponentModel.EditorBrowsableAttribute + ctorArguments: + - System.ComponentModel.EditorBrowsableState.Never + - exclude: + uidRegex: ^umbraco\. + - exclude: + uidRegex: ^CookComputing\. + - exclude: + uidRegex: ^.*$ \ No newline at end of file diff --git a/apidocs/docfx.json b/apidocs/docfx.json new file mode 100644 index 0000000000..520622a0e0 --- /dev/null +++ b/apidocs/docfx.json @@ -0,0 +1,75 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "Umbraco.Core/Umbraco.Core.csproj", + "Umbraco.Web/Umbraco.Web.csproj" + ], + "exclude": [ + "**/obj/**", + "**/bin/**", + "_site/**" + ], + "cwd": "../src" + } + ], + "dest": "../apidocs/api", + "filter": "../apidocs/docfx.filter.yml" + } + ], + "build": { + "content": [ + { + "files": [ + "api/**.yml", + "api/index.md" + ] + }, + { + "files": [ + "articles/**.md", + "articles/**/toc.yml", + "toc.yml", + "*.md" + ], + "exclude": [ + "obj/**", + "_site/**" + ] + } + ], + "resource": [ + { + "files": [ + "images/**" + ], + "exclude": [ + "obj/**", + "_site/**" + ] + } + ], + "overwrite": [ + { + "files": [ + "**.md" + ], + "exclude": [ + "obj/**", + "_site/**" + ] + } + ], + "globalMetadata": { + "_appTitle": "Umbraco c# Api docs", + "_enableSearch": true, + "_disableContribution": false + }, + "dest": "_site", + "template": [ + "default", "umbracotemplate" + ] + } +} \ No newline at end of file diff --git a/apidocs/index.md b/apidocs/index.md new file mode 100644 index 0000000000..b90b816312 --- /dev/null +++ b/apidocs/index.md @@ -0,0 +1,7 @@ + +# Umbraco c# API reference + +## Quick Links: + +### [Umbraco.Core](api/Umbraco.Core.html) docs +### [Umbraco.Web](api/Umbraco.Web.html) docs diff --git a/apidocs/toc.yml b/apidocs/toc.yml new file mode 100644 index 0000000000..6817825066 --- /dev/null +++ b/apidocs/toc.yml @@ -0,0 +1,5 @@ + +- name: Umbraco.Core Documentation + href: https://our.umbraco.org/apidocs/csharp/api/Umbraco.Core.html +- name: Umbraco.Web Documentation + href: https://our.umbraco.org/apidocs/csharp/api/Umbraco.Web.html \ No newline at end of file diff --git a/apidocs/umbracotemplate/partials/class.tmpl.partial b/apidocs/umbracotemplate/partials/class.tmpl.partial new file mode 100644 index 0000000000..9153a863a4 --- /dev/null +++ b/apidocs/umbracotemplate/partials/class.tmpl.partial @@ -0,0 +1,257 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +{{^_disableContribution}} +{{#sourceurl}}{{__global.viewSource}}{{/sourceurl}} +{{/_disableContribution}} +

{{>partials/title}}

+
{{{summary}}}
+
{{{conceptual}}}
+{{#inheritance.0}} +
+
{{__global.inheritance}}
+{{#inheritance}} +
{{{specName.0.value}}}
+{{/inheritance}} +
{{item.name.0.value}}
+
+{{/inheritance.0}} +
{{__global.namespace}}:{{namespace}}
+
{{__global.assembly}}:{{assemblies.0}}.dll
+
{{__global.syntax}}
+
+
{{syntax.content.0.value}}
+
+{{#syntax.parameters.0}} +
{{__global.parameters}}
+ + + + + + + + + +{{/syntax.parameters.0}} +{{#syntax.parameters}} + + + + + +{{/syntax.parameters}} +{{#syntax.parameters.0}} + +
{{__global.type}}{{__global.name}}{{__global.description}}
{{{type.specName.0.value}}}{{{id}}}{{{description}}}
+{{/syntax.parameters.0}} +{{#syntax.return}} +
{{__global.returns}}
+ + + + + + + + + + + + + +
{{__global.type}}{{__global.description}}
{{{type.specName.0.value}}}{{{description}}}
+{{/syntax.return}} +{{#syntax.typeParameters.0}} +
{{__global.typeParameters}}
+ + + + + + + + +{{/syntax.typeParameters.0}} +{{#syntax.typeParameters}} + + + + +{{/syntax.typeParameters}} +{{#syntax.typeParameters.0}} + +
{{__global.name}}{{__global.description}}
{{{id}}}{{{description}}}
+{{/syntax.typeParameters.0}} +{{#remarks}} +
{{__global.remarks}}
+
{{{remarks}}}
+{{/remarks}} +{{#example.0}} +
{{__global.examples}}
+{{/example.0}} +{{#example}} +{{{.}}} +{{/example}} +{{#children}} +

{{>partials/classSubtitle}}

+{{#children}} +{{^_disableContribution}} +{{#sourceurl}} + + {{__global.viewSource}} +{{/sourceurl}} +{{/_disableContribution}} +

{{name.0.value}}

+
{{{summary}}}
+
{{{conceptual}}}
+
{{__global.declaration}}
+{{#syntax}} +
+
{{syntax.content.0.value}}
+
+{{#parameters.0}} +
{{__global.parameters}}
+ + + + + + + + + +{{/parameters.0}} +{{#parameters}} + + + + + +{{/parameters}} +{{#parameters.0}} + +
{{__global.type}}{{__global.name}}{{__global.description}}
{{{type.specName.0.value}}}{{{id}}}{{{description}}}
+{{/parameters.0}} +{{#return}} +
{{__global.returns}}
+ + + + + + + + + + + + + +
{{__global.type}}{{__global.description}}
{{{type.specName.0.value}}}{{{description}}}
+{{/return}} +{{#typeParameters.0}} +
{{__global.typeParameters}}
+ + + + + + + + +{{/typeParameters.0}} +{{#typeParameters}} + + + + +{{/typeParameters}} +{{#typeParameters.0}} + +
{{__global.name}}{{__global.description}}
{{{id}}}{{{description}}}
+{{/typeParameters.0}} +{{#fieldValue}} +
{{__global.fieldValue}}
+ + + + + + + + + + + + + +
{{__global.type}}{{__global.description}}
{{{type.specName.0.value}}}{{{description}}}
+{{/fieldValue}} +{{#propertyValue}} +
{{__global.propertyValue}}
+ + + + + + + + + + + + + +
{{__global.type}}{{__global.description}}
{{{type.specName.0.value}}}{{{description}}}
+{{/propertyValue}} +{{#eventType}} +
{{__global.eventType}}
+ + + + + + + + + + + + + +
{{__global.type}}{{__global.description}}
{{{type.specName.0.value}}}{{{description}}}
+{{/eventType}} +{{/syntax}} +{{#remarks}} +
{{__global.remarks}}
+
{{{remarks}}}
+{{/remarks}} +{{#example.0}} +
{{__global.examples}}
+{{/example.0}} +{{#example}} +{{{.}}} +{{/example}} +{{#exceptions.0}} +
{{__global.exceptions}}
+ + + + + + + + +{{/exceptions.0}} +{{#exceptions}} + + + + +{{/exceptions}} +{{#exceptions.0}} + +
{{__global.type}}{{__global.condition}}
{{{type.specName.0.value}}}{{{description}}}
+{{/exceptions.0}} +{{/children}} +{{/children}} diff --git a/apidocs/umbracotemplate/partials/footer.tmpl.partial b/apidocs/umbracotemplate/partials/footer.tmpl.partial new file mode 100644 index 0000000000..69f51a101f --- /dev/null +++ b/apidocs/umbracotemplate/partials/footer.tmpl.partial @@ -0,0 +1,13 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + diff --git a/apidocs/umbracotemplate/partials/head.tmpl.partial b/apidocs/umbracotemplate/partials/head.tmpl.partial new file mode 100644 index 0000000000..591e1c1885 --- /dev/null +++ b/apidocs/umbracotemplate/partials/head.tmpl.partial @@ -0,0 +1,18 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + + + {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} + + + + {{#_description}}{{/_description}} + + + + + + + {{#_enableSearch}}{{/_enableSearch}} + diff --git a/apidocs/umbracotemplate/partials/namespace.tmpl.partial b/apidocs/umbracotemplate/partials/namespace.tmpl.partial new file mode 100644 index 0000000000..80ca30799a --- /dev/null +++ b/apidocs/umbracotemplate/partials/namespace.tmpl.partial @@ -0,0 +1,18 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +{{^_disableContribution}} +{{#sourceurl}} +{{__global.viewSource}} +{{/sourceurl}} +{{/_disableContribution}} +

{{>partials/title}}

+
{{{summary}}}
+
{{{conceptual}}}
+
{{{remarks}}}
+{{#children}} +

{{>partials/namespaceSubtitle}}

+ {{#children}} +

{{{specName.0.value}}}

+
{{{summary}}}
+ {{/children}} +{{/children}} diff --git a/apidocs/umbracotemplate/partials/navbar.tmpl.partial b/apidocs/umbracotemplate/partials/navbar.tmpl.partial new file mode 100644 index 0000000000..e9ee0af1c7 --- /dev/null +++ b/apidocs/umbracotemplate/partials/navbar.tmpl.partial @@ -0,0 +1,22 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + diff --git a/apidocs/umbracotemplate/partials/rest.tmpl.partial b/apidocs/umbracotemplate/partials/rest.tmpl.partial new file mode 100644 index 0000000000..4306bf7db1 --- /dev/null +++ b/apidocs/umbracotemplate/partials/rest.tmpl.partial @@ -0,0 +1,101 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +{{^_disableContribution}} +{{#sourceurl}}View Source{{/sourceurl}} +{{/_disableContribution}} +

{{name}}

+{{#summary}} +
{{{summary}}}
+{{/summary}} +{{#description}} +
{{{description}}}
+{{/description}} +{{#conceptual}} +
{{{conceptual}}}
+{{/conceptual}} +{{#children}} +{{^_disableContribution}} +{{#sourceurl}} + + View Source +{{/sourceurl}} +{{/_disableContribution}} +

{{operationId}}

+{{#summary}} +
{{{summary}}}
+{{/summary}} +{{#description}} +
{{{description}}}
+{{/description}} +{{#conceptual}} +
{{{conceptual}}}
+{{/conceptual}} +
Request
+
+
{{operation}} {{path}}
+
+{{#parameters.0}} +
Parameters
+ + + + + + + + + + +{{/parameters.0}} +{{#parameters}} + + + + + + + {{/parameters}} + {{#parameters.0}} + +
NameTypeValueNotes
{{#required}}*{{/required}}{{name}}{{type}}{{default}}{{{description}}}
+{{/parameters.0}} +{{#responses.0}} +
+
Responses
+ + + + + + + + + +{{/responses.0}} +{{#responses}} + + + + + + {{/responses}} + {{#responses.0}} + +
Status CodeDescriptionSamples
{{statusCode}}{{{description}}} + {{#examples}} +
+ Mime type: {{mimeType}} +
+
{{content}}
+ {{/examples}} +
+
+{{/responses.0}} +{{#footer}} + +{{/footer}} +{{/children}} +{{#footer}} + +{{/footer}} + diff --git a/apidocs/umbracotemplate/styles/main.css b/apidocs/umbracotemplate/styles/main.css new file mode 100644 index 0000000000..7756b2f7d4 --- /dev/null +++ b/apidocs/umbracotemplate/styles/main.css @@ -0,0 +1,73 @@ +body { + color: rgba(0,0,0,.8); +} +.navbar-inverse { + background: #a3db78; +} +.navbar-inverse .navbar-nav>li>a, .navbar-inverse .navbar-text { + color: rgba(0,0,0,.8); +} + +.navbar-inverse { + border-color: transparent; +} + +.sidetoc { + background-color: #f5fbf1; +} +body .toc { + background-color: #f5fbf1; +} +.sidefilter { + background-color: #daf0c9; +} +.subnav { + background-color: #f5fbf1; +} + +.navbar-inverse .navbar-nav>.active>a { + color: rgba(0,0,0,.8); + background-color: #daf0c9; +} + +.navbar-inverse .navbar-nav>.active>a:focus, .navbar-inverse .navbar-nav>.active>a:hover { + color: rgba(0,0,0,.8); + background-color: #daf0c9; +} + +.btn-primary { + color: rgba(0,0,0,.8); + background-color: #fff; + border-color: rgba(0,0,0,.8); +} +.btn-primary:hover { + background-color: #daf0c9; + color: rgba(0,0,0,.8); + border-color: rgba(0,0,0,.8); +} + +.toc .nav > li > a { + color: rgba(0,0,0,.8); +} + +button, a { + color: #f36f21; +} + +button:hover, +button:focus, +a:hover, +a:focus { + color: #143653; + text-decoration: none; +} + +.navbar-header .navbar-brand { + background: url(https://our.umbraco.org/assets/images/logo.svg) left center no-repeat; + background-size: 40px auto; + width:50px; +} + +.toc .nav > li.active > a { + color: #f36f21; +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..b53eb55953 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,51 @@ +version: '{build}' +shallow_clone: true +build_script: +- cmd: >- + cd build + + SET "release=" + + FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i" + + SET nuGetFolder=C:\Users\appveyor\.nuget\packages + + ..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL + + ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Core\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet + + ..\src\.nuget\NuGet.exe restore ..\src\umbraco.datalayer\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet + + ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet + + ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet + + SET nuGetFolder=%CD%\..\src\packages\ + + ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Tests\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet + + ..\src\.nuget\NuGet.exe restore ..\src\umbraco.datalayer\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet + + ..\src\.nuget\NuGet.exe restore ..\src\umbraco.controls\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet + + ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER% + + SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe" + + %MSBUILD% "../src/Umbraco.Tests/Umbraco.Tests.csproj" /verbosity:minimal + + build.bat %release% build%APPVEYOR_BUILD_NUMBER% + + ECHO %PATH% +test: + assemblies: src\Umbraco.Tests\bin\Debug\Umbraco.Tests.dll +artifacts: +- path: build\UmbracoCms.* +notifications: +- provider: Slack + auth_token: + secure: v2csJi2V5ghR0rPdODK8GJdOGNCA+XaK84iQ9MdPOClqB+VU+40ybdKp6gPirGSH + channel: '#build-umbraco-core' + on_build_success: false + on_build_failure: true + on_build_status_changed: false \ No newline at end of file diff --git a/build/ApiDocs/TOC.css b/build/ApiDocs/TOC.css deleted file mode 100644 index 9c32aba214..0000000000 --- a/build/ApiDocs/TOC.css +++ /dev/null @@ -1,170 +0,0 @@ -/* File : TOC.css -// Author : Eric Woodruff (Eric@EWoodruff.us) -// Updated : 09/07/2007 -// -// Stylesheet for the table of content -*/ - -* -{ - margin: 0px 0px 0px 0px; - padding: 0px 0px 0px 0px; -} - -body -{ - font-family: Segoe UI, Arial, Verdana, Helvetica, sans-serif; - font-size: 0.9em; - background-color: white; - color: White; - overflow: hidden; -} - -input -{ - padding:5px; - margin: 3px 0px 3px 0px -} - -img -{ - border: 0; - margin-left: 5px; - margin-right: 2px; -} - -img.TreeNodeImg -{ - cursor: pointer; -} - -img.TOCLink -{ - cursor: pointer; - margin-left: 0; - margin-right: 0; -} - -a.SelectedNode, a.UnselectedNode -{ - color: #333; - text-decoration: none; - padding: 1px 3px 1px 3px; - white-space: nowrap; -} - -a.SelectedNode -{ - background-color: #ffffff; - border: solid 1px #999999; - padding: 0px 2px 0px 2px; -} - -a.UnselectedNode:hover, a.SelectedNode:hover -{ - background-color: #cccccc; - border: solid 1px #999999; - padding: 0px 2px 0px 2px; -} - -.Visible -{ - display: block; - margin-left: 2em; -} - -.Hidden -{ - display: none; -} - -.Tree -{ - background-color: #fff; - color: #333; - width: 300px; - overflow: auto; -} - -.TreeNode, .TreeItem -{ - white-space: nowrap; - margin: 2px 2px 2px 2px; -} - -.TOCDiv -{ - position: relative; - float: left; - width: 300px; - height: 100%; -} - -.TOCSizer -{ - clear: none; - float: left; - width: 10px; - height: 100%; - background-image: url("Splitter.gif"); - background-position:center center; - background-repeat:no-repeat; - position: relative; - cursor: w-resize; - border-left: solid 1px #CCC; -} - -.TopicContent -{ - position: relative; - float: right; - background-color: white; - height: 100%; -} - -.SearchOpts -{ - padding: 5px 5px 10px 5px; - color: black; - width: 300px; - border-bottom: solid lightgrey 1px; - height: 110px !important; -} - -.NavOpts -{ - padding: 5px 5px 6px 5px; - color: black; - width: 300px; - border-bottom: solid lightgrey 1px; -} - -.NavOpts img { - display:inline-block; - margin: 0px 5px 0px 5px; -} - -.IndexOpts -{ - padding: 5px 5px 6px 5px; - color: black; - width: 300px; - border-bottom: solid lightgrey 1px; -} - -.IndexItem -{ - white-space: nowrap; - margin: 2px 2px 2px 2px; -} - -.IndexSubItem -{ - white-space: nowrap; - margin: 2px 2px 2px 12px; -} - -.PaddedText -{ - margin: 10px 10px 10px 10px; -} diff --git a/build/ApiDocs/csharp-api-docs.shfbproj b/build/ApiDocs/csharp-api-docs.shfbproj deleted file mode 100644 index f635f2e2ee..0000000000 --- a/build/ApiDocs/csharp-api-docs.shfbproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - {cb4d85f1-7390-40ee-b41f-a724bb8fddea} - 1.9.5.0 - - Documentation - Documentation - Documentation - - .NET Framework 4.5 - .\Output\ - UmbracoClassLibrary - en-US - OnlyErrors - csharp-api-docs.log - Website - True - False - False - False - True - CSharp - Blank - False - VS2010 - False - Guid - Umbraco .Net Class Library - AboveNamespaces - Attributes, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected - - - - - - - None - None - False - True - Summary, AutoDocumentCtors, AutoDocumentDispose - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/Build.bat b/build/Build.bat index 2489c08f91..995cef6a48 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -15,11 +15,6 @@ IF [%1] NEQ [] (SET release=%1) IF [%2] NEQ [] (SET comment=%2) ELSE (IF [%1] NEQ [] (SET "comment=")) SET version=%release% - -REM SET MSBUILD="%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" -SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe" -SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% - IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%) ECHO Building Umbraco %version% @@ -39,7 +34,13 @@ DEL /F /Q webpihash.txt ECHO Making sure Git is in the path so that the build can succeed CALL InstallGit.cmd ECHO Performing MSBuild and producing Umbraco binaries zip files -%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /verbosity:minimal + +SET nuGetFolder=%CD%\..\src\packages\ +..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Core\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet +..\src\.nuget\NuGet.exe restore ..\src\umbraco.datalayer\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet +..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet +..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet +"%ProgramFiles(x86)%"\MSBuild\14.0\Bin\MSBuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /verbosity:minimal ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it while loading the websites project attrib +h ..\src\Umbraco.Web.UI.Client\node_modules diff --git a/build/Build.proj b/build/Build.proj index d3730d2b2b..0da79322c4 100644 --- a/build/Build.proj +++ b/build/Build.proj @@ -264,7 +264,7 @@ - + diff --git a/build/BuildDocs.bat b/build/BuildDocs.bat new file mode 100644 index 0000000000..9d0a04e1cd --- /dev/null +++ b/build/BuildDocs.bat @@ -0,0 +1,20 @@ +@ECHO OFF +SETLOCAL + +SET release=%1 +ECHO Installing Npm NuGet Package + +SET nuGetFolder=%CD%\..\src\packages\ +ECHO Configured packages folder: %nuGetFolder% +ECHO Current folder: %CD% + +%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet + +for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\" +for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\" + +ECHO Adding Npm and Node to path +REM SETLOCAL is on, so changes to the path not persist to the actual user's path +PATH=%npmPath%;%nodePath%;%PATH% + +Powershell.exe -ExecutionPolicy Unrestricted -File .\BuildDocs.ps1 \ No newline at end of file diff --git a/build/BuildDocs.ps1 b/build/BuildDocs.ps1 index 6f46a43fde..dcb3a85cc1 100644 --- a/build/BuildDocs.ps1 +++ b/build/BuildDocs.ps1 @@ -1,27 +1,100 @@ -##We cannot continue if sandcastle is not installed determined by env variable: SHFBROOT +$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path); +$RepoRoot = (get-item $PSScriptFilePath).Directory.Parent.FullName; +$SolutionRoot = Join-Path -Path $RepoRoot "src"; +$ToolsRoot = Join-Path -Path $RepoRoot "tools"; +$DocFx = Join-Path -Path $ToolsRoot "docfx\docfx.exe" +$DocFxFolder = (Join-Path -Path $ToolsRoot "docfx") +$DocFxJson = Join-Path -Path $RepoRoot "apidocs\docfx.json" +$7Zip = Join-Path -Path $ToolsRoot "7zip\7za.exe" +$DocFxSiteOutput = Join-Path -Path $RepoRoot "apidocs\_site\*.*" +$NgDocsSiteOutput = Join-Path -Path $RepoRoot "src\Umbraco.Web.UI.Client\docs\api\*.*" +$ProgFiles86 = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)"); +$MSBuild = "$ProgFiles86\MSBuild\14.0\Bin\MSBuild.exe" -if (-not (Test-Path Env:\SHFBROOT)) -{ - throw "The docs cannot be build, install Sandcastle help file builder" + +################ Do the UI docs + +"Changing to Umbraco.Web.UI.Client folder" +cd .. +cd src\Umbraco.Web.UI.Client +Write-Host $(Get-Location) + +"Creating build folder so MSBuild doesn't run the whole grunt build" +if (-Not (Test-Path "build")) { + md "build" } -$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path).FullName -$BuildRoot = Split-Path -Path $PSScriptFilePath -Parent -$OutputPath = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\Output" -$ProjFile = Join-Path -Path $BuildRoot -ChildPath "ApiDocs\csharp-api-docs.shfbproj" +"Installing node" +# Check if Install-Product exists, should only exist on the build server +if (Get-Command Install-Product -errorAction SilentlyContinue) +{ + Install-Product node '' +} -"Building docs with project file: $ProjFile" +"Installing node modules" +& npm install -$MSBuild = "$Env:SYSTEMROOT\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" +"Installing grunt" +& npm install -g grunt-cli -# build it! -& $MSBuild "$ProjFile" +"Moving back to build folder" +cd .. +cd .. +cd build +Write-Host $(Get-Location) -# remove files left over -Remove-Item $BuildRoot\* -include csharp-api-docs.shfbproj_* + & grunt --gruntfile ../src/umbraco.web.ui.client/gruntfile.js docs -# copy our custom styles in -Copy-Item $BuildRoot\ApiDocs\TOC.css $OutputPath\TOC.css +# change baseUrl +$BaseUrl = "https://our.umbraco.org/apidocs/ui/" +$IndexPath = "../src/umbraco.web.ui.client/docs/api/index.html" +(Get-Content $IndexPath).replace('location.href.replace(rUrl, indexFile)', "`'" + $BaseUrl + "`'") | Set-Content $IndexPath +# zip it -"" -"Done!" \ No newline at end of file +& $7Zip a -tzip ui-docs.zip $NgDocsSiteOutput -r + +################ Do the c# docs + +# Build the solution in debug mode +$SolutionPath = Join-Path -Path $SolutionRoot -ChildPath "umbraco.sln" +& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount /t:Clean +if (-not $?) +{ + throw "The MSBuild process returned an error code." +} +& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount +if (-not $?) +{ + throw "The MSBuild process returned an error code." +} + +# Go get docfx if we don't hae it +$FileExists = Test-Path $DocFx +If ($FileExists -eq $False) { + + If(!(Test-Path $DocFxFolder)) + { + New-Item $DocFxFolder -type directory + } + + $DocFxZip = Join-Path -Path $ToolsRoot "docfx\docfx.zip" + $DocFxSource = "https://github.com/dotnet/docfx/releases/download/v1.9.4/docfx.zip" + Invoke-WebRequest $DocFxSource -OutFile $DocFxZip + + #unzip it + & $7Zip e $DocFxZip "-o$DocFxFolder" +} + +#clear site +If(Test-Path(Join-Path -Path $RepoRoot "apidocs\_site")) +{ + Remove-Item $DocFxSiteOutput -recurse +} + +# run it! +& $DocFx metadata $DocFxJson +& $DocFx build $DocFxJson + +# zip it + +& $7Zip a -tzip csharp-docs.zip $DocFxSiteOutput -r diff --git a/build/NuSpecs/tools/install.ps1 b/build/NuSpecs/tools/install.ps1 index de7a6cc16e..5ebaa6d02a 100644 --- a/build/NuSpecs/tools/install.ps1 +++ b/build/NuSpecs/tools/install.ps1 @@ -77,8 +77,28 @@ if ($project) { { $packageWebConfigSource = Join-Path $installPath "UmbracoFiles\Web.config" Copy-Item $packageWebConfigSource $destinationWebConfig -Force - } + # Copy files that don't get automatically copied for Website projects + # We do this here, when copyWebconfig is true because we only want to do it for new installs + # If this is an upgrade then the files should already be there + $splashesSource = Join-Path $installPath "UmbracoFiles\Config\splashes\*.*" + $splashesDestination = Join-Path $projectPath "Config\splashes\" + New-Item $splashesDestination -Type directory + Copy-Item $splashesSource $splashesDestination -Force + + $sqlCe64Source = Join-Path $installPath "UmbracoFiles\bin\amd64\*" + $sqlCe64Destination = Join-Path $projectPath "bin\amd64\" + Copy-Item $sqlCe64Source $sqlCe64Destination -Force + + $sqlCex86Source = Join-Path $installPath "UmbracoFiles\bin\x86\*" + $sqlCex86Destination = Join-Path $projectPath "bin\x86\" + Copy-Item $sqlCex86source $sqlCex86Destination -Force + + $umbracoUIXMLSource = Join-Path $installPath "UmbracoFiles\Umbraco\Config\Create\UI.xml" + $umbracoUIXMLDestination = Join-Path $projectPath "Umbraco\Config\Create\UI.xml" + Copy-Item $umbracoUIXMLSource $umbracoUIXMLDestination -Force + } + $installFolder = Join-Path $projectPath "Install" if(Test-Path $installFolder) { Remove-Item $installFolder -Force -Recurse -Confirm:$false diff --git a/build/RevertToEmptyInstall.bat b/build/RevertToEmptyInstall.bat index b8abe4e64e..aeb0cdac72 100644 --- a/build/RevertToEmptyInstall.bat +++ b/build/RevertToEmptyInstall.bat @@ -22,7 +22,7 @@ echo Removing bin files del ..\src\Umbraco.Web.UI\bin\*.* echo Building solution -%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build +"%ProgramFiles(x86)%"\MSBuild\14.0\Bin\MSBuild.exe ..\src\umbraco.sln /t:Clean,Build echo Resetting installedPackages.config echo ^^^ >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config @@ -86,7 +86,7 @@ echo Removing bin files FOR %%A IN (..\src\Umbraco.Web.UI\bin\*.*) DO DEL %%A echo Building solution -%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build +"%ProgramFiles(x86)%"\MSBuild\14.0\Bin\MSBuild.exe ..\src\umbraco.sln /t:Clean,Build echo Resetting installedPackages.config echo ^^^ >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config diff --git a/src/.nuget/NuGet.exe b/src/.nuget/NuGet.exe index 9ca66594f9..31fc9885e4 100644 Binary files a/src/.nuget/NuGet.exe and b/src/.nuget/NuGet.exe differ diff --git a/src/.nuget/NuGet.targets b/src/.nuget/NuGet.targets deleted file mode 100644 index 6ff51f6e83..0000000000 --- a/src/.nuget/NuGet.targets +++ /dev/null @@ -1,138 +0,0 @@ - - - - $(MSBuildProjectDirectory)\..\ - - - false - - - false - - - true - - - false - - - - - - - - - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) - - - - - $(SolutionDir).nuget - packages.config - - - - - $(NuGetToolsPath)\NuGet.exe - @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 $(NuGetExePath) - - $(TargetDir.Trim('\\')) - - -RequireConsent - -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - - - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj b/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj index 216fa74a67..604cbd2592 100644 --- a/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj +++ b/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj @@ -95,7 +95,6 @@ - integer, the above tryparse will fail. So we'll try going + // via decimal too to return the integer value rather than zero. + decimal decimalForIntegerValue; + if (decimal.TryParse(stringValue, out decimalForIntegerValue)) + { + integerValue = (int)decimalForIntegerValue; + } + } + + value = integerValue; + break; + case DataTypeDatabaseType.Decimal: + decimal decimalValue; + decimal.TryParse(stringValue, out decimalValue); + value = decimalValue; + break; + case DataTypeDatabaseType.Date: + DateTime dateValue; + DateTime.TryParse(stringValue, out dateValue); + value = dateValue; + break; + } + } + else + { + throw new Exception( + string.Format( + "Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'", + value == null ? "null" : value.GetType().Name, Alias)); + } + } SetPropertyValueAndDetectChanges(o => { diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index 0649801a0c..846b907197 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Linq; using System.Reflection; using System.Runtime.Serialization; using System.Text.RegularExpressions; @@ -425,6 +426,19 @@ namespace Umbraco.Core.Models return false; } + /// + /// Checks the underlying property editor prevalues to see if the one that allows changing of the database field + /// to which data is saved (dataInt, dataVarchar etc.) is included. If so that means the field could be changed when the data + /// type is saved. + /// + /// + internal bool CanHaveDataValueTypeChanged() + { + var propertyEditor = PropertyEditorResolver.Current.GetByAlias(_propertyEditorAlias); + return propertyEditor.PreValueEditor.Fields + .SingleOrDefault(x => x.Key == Constants.PropertyEditors.PreValueKeys.DataValueType) != null; + } + /// /// Validates the Value from a Property according to the validation settings /// diff --git a/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs index a4382aa945..795cf62d20 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.ObjectResolution where TResolved : class where TResolver : ResolverBase { - private IServiceContainer _container; + protected IServiceContainer Container; private object _locker = new object(); private bool _isInitialized = false; @@ -24,10 +24,36 @@ namespace Umbraco.Core.ObjectResolution : base(logger, typeListProducerList, scope) { if (container == null) throw new ArgumentNullException("container"); - _container = container; + Container = container; //Register ourselves in the case that a resolver instance should be injected someplace - _container.Register(factory => (TResolver)(object)this); + Container.Register(factory => (TResolver)(object)this); + } + + /// + /// Ensures that the types are registered in the container before the values can be resolved + /// + /// + /// + /// A callback that executes after the types are registered, this allows for custom registrations for inheritors + /// + protected void EnsureTypesRegisterred(ObjectLifetimeScope scope, Action afterRegistered = null) + { + //Before we can do anything, the first time this happens we need to setup the container with the resolved types + LazyInitializer.EnsureInitialized(ref Container, ref _isInitialized, ref _locker, () => + { + foreach (var type in InstanceTypes) + { + Container.Register(type, GetLifetime(LifetimeScope)); + } + + if (afterRegistered != null) + { + afterRegistered(Container); + } + + return Container; + }); } /// @@ -36,19 +62,11 @@ namespace Umbraco.Core.ObjectResolution /// A list of objects of type . protected override IEnumerable CreateValues(ObjectLifetimeScope scope) { - //Before we can do anything, the first time this happens we need to setup the container with the resolved types - LazyInitializer.EnsureInitialized(ref _container, ref _isInitialized, ref _locker, () => - { - foreach (var type in InstanceTypes) - { - _container.Register(type, GetLifetime(LifetimeScope)); - } - return _container; - }); + EnsureTypesRegisterred(scope); //NOTE: we ignore scope because objects are registered under this scope and not build based on the scope. - return _container.GetAllInstances(); + return Container.GetAllInstances(); } /// @@ -56,7 +74,7 @@ namespace Umbraco.Core.ObjectResolution /// /// /// - private static ILifetime GetLifetime(ObjectLifetimeScope scope) + protected static ILifetime GetLifetime(ObjectLifetimeScope scope) { switch (scope) { diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs index abc31330f3..2e750b4108 100644 --- a/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Umbraco.Core.Logging; namespace Umbraco.Core.Persistence.Migrations { @@ -7,5 +8,7 @@ namespace Umbraco.Core.Persistence.Migrations UmbracoDatabase Database { get; } ICollection Expressions { get; set; } + + ILogger Logger { get; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationResolver.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationResolver.cs index 58c569490a..0f895a397b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/IMigrationResolver.cs +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationResolver.cs @@ -7,6 +7,6 @@ namespace Umbraco.Core.Persistence.Migrations /// /// Gets the migrations /// - IEnumerable Migrations { get; } + IEnumerable GetMigrations(IMigrationContext migrationContext); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 76f29f3350..dcf191e0dd 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -146,7 +146,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1039, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1039", SortOrder = 2, UniqueId = new Guid("06f349a9-c949-4b6a-8660-59c10451af42"), Text = "Ultimate Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1038, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1038", SortOrder = 2, UniqueId = new Guid("1251c96c-185c-4e9b-93f4-b48205573cbd"), Text = "Simple Editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); } private void CreateUmbracoLockData() @@ -257,8 +257,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 14, DataTypeId = -42, PropertyEditorAlias = Constants.PropertyEditors.DropDownListAlias, DbType = "Integer" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 15, DataTypeId = -43, PropertyEditorAlias = Constants.PropertyEditors.CheckBoxListAlias, DbType = "Nvarchar" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 16, DataTypeId = 1034, PropertyEditorAlias = Constants.PropertyEditors.ContentPickerAlias, DbType = "Integer" }); - _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, PropertyEditorAlias = Constants.PropertyEditors.MediaPickerAlias, DbType = "Integer" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 18, DataTypeId = 1036, PropertyEditorAlias = Constants.PropertyEditors.MemberPickerAlias, DbType = "Integer" }); + _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, PropertyEditorAlias = Constants.PropertyEditors.MultipleMediaPickerAlias, DbType = "Nvarchar" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 21, DataTypeId = 1040, PropertyEditorAlias = Constants.PropertyEditors.RelatedLinksAlias, DbType = "Ntext" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 22, DataTypeId = 1041, PropertyEditorAlias = Constants.PropertyEditors.TagsAlias, DbType = "Ntext" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 24, DataTypeId = 1043, PropertyEditorAlias = Constants.PropertyEditors.ImageCropperAlias, DbType = "Ntext" }); diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs index 801e05869c..44f4f38f43 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs @@ -19,29 +19,17 @@ namespace Umbraco.Core.Persistence.Migrations public DatabaseType DatabaseType => Context.Database.DatabaseType; - public ILogger Logger { get; private set; } + public ILogger Logger { get; } + protected IMigrationContext Context { get; } - protected MigrationBase(ILogger logger) + protected MigrationBase(IMigrationContext context) { - Logger = logger; + Logger = context.Logger; + Context = context; } - internal IMigrationContext Context; - public abstract void Up(); - public abstract void Down(); - - public virtual void GetUpExpressions(IMigrationContext context) - { - Context = context; - Up(); - } - - public virtual void GetDownExpressions(IMigrationContext context) - { - Context = context; - Down(); - } + public abstract void Down(); public IAlterSyntaxBuilder Alter => new AlterSyntaxBuilder(Context); diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs index d9de233436..e038129e46 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs @@ -5,6 +5,8 @@ using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.SqlSyntax; +using System.Threading; +using Umbraco.Core.DependencyInjection; namespace Umbraco.Core.Persistence.Migrations { @@ -13,18 +15,51 @@ namespace Umbraco.Core.Persistence.Migrations /// internal class MigrationResolver : ContainerLazyManyObjectsResolver, IMigrationResolver { - + public MigrationResolver(IServiceContainer container, ILogger logger, Func> migrations) : base(container, logger, migrations, ObjectLifetimeScope.Transient) { } + /// + /// This creates the instances in a child IoC container, everytime GetMigrations is called, a child container + /// is created, the types are added to it and resolved and the child container is diposed. + /// + /// + /// + /// + /// This doesn't need to be thread safe because Migration instances are transient anyways + /// + protected override IEnumerable CreateValues(ObjectLifetimeScope scope) + { + EnsureTypesRegisterred(scope, container => + { + // resolve ctor dependency from GetInstance() runtimeArguments, if possible - 'factory' is + // the container, 'info' describes the ctor argument, and 'args' contains the args that + // were passed to GetInstance() - use first arg if it is the right type, + // + // for IMigrationContext + container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IMigrationContext : null); + }); + + foreach (var type in InstanceTypes) + { + //create each instance with the provided constructor argument + yield return (IMigration)Container.GetInstance(type, new object[] {_migrationContext}); + } + } + + private IMigrationContext _migrationContext; + /// /// Gets the migrations /// - public IEnumerable Migrations + public IEnumerable GetMigrations(IMigrationContext migrationContext) { - get { return Values; } + //set the current context to use to create the values + _migrationContext = migrationContext; + + return Values; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index 12506b8f60..d60b5adeb6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -52,14 +52,14 @@ namespace Umbraco.Core.Persistence.Migrations /// /// Executes the migrations against the database. /// - /// The NPoco Database, which the migrations will be run against + /// The migration context to execute migrations with /// Boolean indicating whether this is an upgrade or downgrade /// True if migrations were applied, otherwise False - public virtual bool Execute(UmbracoDatabase database, bool isUpgrade = true) + public bool Execute(IMigrationContext migrationContext, bool isUpgrade = true) { _logger.Info("Initializing database migrations"); - - var foundMigrations = FindMigrations(); + + var foundMigrations = FindMigrations(migrationContext); //filter all non-schema migrations var migrations = isUpgrade @@ -74,18 +74,18 @@ namespace Umbraco.Core.Persistence.Migrations } //Loop through migrations to generate sql - var migrationContext = InitializeMigrations(migrations, database, isUpgrade); + InitializeMigrations(migrations, isUpgrade); try { - ExecuteMigrations(migrationContext, database); + ExecuteMigrations(migrationContext); } catch (Exception ex) { //if this fails then the transaction will be rolled back, BUT if we are using MySql this is not the case, //since it does not support schema changes in a transaction, see: http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html //so in that case we have to downgrade - if (database.DatabaseType is NPoco.DatabaseTypes.MySqlDatabaseType) + if (migrationContext.Database.DatabaseType is NPoco.DatabaseTypes.MySqlDatabaseType) { throw new DataLossException( "An error occurred running a schema migration but the changes could not be rolled back. Error: " + ex.Message + ". In some cases, it may be required that the database be restored to it's original state before running this upgrade process again.", @@ -156,64 +156,41 @@ namespace Umbraco.Core.Persistence.Migrations /// Find all migrations that are available through the /// /// An array of - protected virtual IMigration[] FindMigrations() + protected IMigration[] FindMigrations(IMigrationContext context) { //MCH NOTE: Consider adding the ProductName filter to the Resolver so we don't get a bunch of irrelevant migrations - return _migrations ?? _resolver.Migrations.ToArray(); + return _migrations ?? _resolver.GetMigrations(context).ToArray(); } - internal MigrationContext InitializeMigrations( + internal void InitializeMigrations( List migrations, - UmbracoDatabase database, bool isUpgrade = true) { - //Loop through migrations to generate sql - var context = new MigrationContext(database, _logger); - foreach (var migration in migrations) { - var baseMigration = migration as MigrationBase; - if (baseMigration != null) + if (isUpgrade) { - if (isUpgrade) - { - baseMigration.GetUpExpressions(context); - _logger.Info(string.Format("Added UPGRADE migration '{0}' to context", baseMigration.GetType().Name)); - } - else - { - baseMigration.GetDownExpressions(context); - _logger.Info(string.Format("Added DOWNGRADE migration '{0}' to context", baseMigration.GetType().Name)); - } + migration.Up(); + _logger.Info($"Added UPGRADE migration '{migration.GetType().Name}' to context"); } else { - //this is just a normal migration so we can only call Up/Down - if (isUpgrade) - { - migration.Up(); - _logger.Info(string.Format("Added UPGRADE migration '{0}' to context", migration.GetType().Name)); - } - else - { - migration.Down(); - _logger.Info(string.Format("Added DOWNGRADE migration '{0}' to context", migration.GetType().Name)); - } + migration.Down(); + _logger.Info($"Added DOWNGRADE migration '{migration.GetType().Name}' to context"); } } - - return context; + } - private void ExecuteMigrations(IMigrationContext context, Database database) + private void ExecuteMigrations(IMigrationContext context) { //Transactional execution of the sql that was generated from the found migrations - using (var transaction = database.GetTransaction()) + using (var transaction = context.Database.GetTransaction()) { int i = 1; foreach (var expression in context.Expressions) { - var sql = expression.Process(database); + var sql = expression.Process(context.Database); if (string.IsNullOrEmpty(sql)) { i++; @@ -238,7 +215,7 @@ namespace Umbraco.Core.Persistence.Migrations //Execute the SQL up to the point of a GO statement var exeSql = sb.ToString(); _logger.Info("Executing sql statement " + i + ": " + exeSql); - database.Execute(exeSql); + context.Database.Execute(exeSql); //restart the string builder sb.Remove(0, sb.Length); @@ -253,7 +230,7 @@ namespace Umbraco.Core.Persistence.Migrations { var exeSql = sb.ToString(); _logger.Info("Executing sql statement " + i + ": " + exeSql); - database.Execute(exeSql); + context.Database.Execute(exeSql); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockObjects.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockObjects.cs index 238196cc40..a82112561b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockObjects.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockObjects.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight [Migration("8.0.0", 101, GlobalSettings.UmbracoMigrationName)] public class AddLockObjects : MigrationBase { - public AddLockObjects(ILogger logger) - : base(logger) + public AddLockObjects(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockTable.cs index ceff5e3537..afb39f6936 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/AddLockTable.cs @@ -1,14 +1,13 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight { [Migration("8.0.0", 100, GlobalSettings.UmbracoMigrationName)] public class AddLockTable : MigrationBase { - public AddLockTable(ILogger logger) - : base(logger) + public AddLockTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/RefactorXmlColumns.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/RefactorXmlColumns.cs index a3f8fa63a3..55b1c9ac47 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/RefactorXmlColumns.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionEight/RefactorXmlColumns.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionEight [Migration("8.0.0", 100, GlobalSettings.UmbracoMigrationName)] public class RefactorXmlColumns : MigrationBase { - public RefactorXmlColumns(ILogger logger) - : base(logger) + public RefactorXmlColumns(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs index 6584e29ea3..c047c54d0d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs @@ -1,7 +1,6 @@ using System.Data; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero [MigrationAttribute("4.9.0", 0, GlobalSettings.UmbracoMigrationName)] public class RemoveUmbracoAppConstraints : MigrationBase { - public RemoveUmbracoAppConstraints(ILogger logger) - : base(logger) + public RemoveUmbracoAppConstraints(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs new file mode 100644 index 0000000000..b6ac23e26a --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs @@ -0,0 +1,31 @@ +using System.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourOneZero +{ + [Migration("4.1.0", 0, GlobalSettings.UmbracoMigrationName)] + public class AddPreviewXmlTable : MigrationBase + { + public AddPreviewXmlTable(IMigrationContext context) + : base(context) + { + } + + public override void Up() + { + var tableName = "cmsPreviewXml"; + var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray(); + if (tables.InvariantContains(tableName)) return; + + Create.Table(tableName) + .WithColumn("nodeId").AsInt32().NotNullable() + .WithColumn("versionId").AsGuid().NotNullable() + .WithColumn("timestamp").AsDateTime().NotNullable() + .WithColumn("xml").AsString(); + } + + public override void Down() + { } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroPropertyTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroPropertyTable.cs index 3e271d7a2e..e1f1f460a0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroPropertyTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroPropertyTable.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -15,14 +14,14 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven { private readonly bool _skipIndexCheck; - internal AddIndexToCmsMacroPropertyTable(bool skipIndexCheck, ILogger logger) - : base(logger) + internal AddIndexToCmsMacroPropertyTable(bool skipIndexCheck, IMigrationContext context) + : base(context) { _skipIndexCheck = skipIndexCheck; } - public AddIndexToCmsMacroPropertyTable(ILogger logger) - : base(logger) + public AddIndexToCmsMacroPropertyTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroTable.cs index 465c062bad..4bc54f47ad 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddIndexToCmsMacroTable.cs @@ -17,14 +17,14 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven { private readonly bool _forTesting; - internal AddIndexToCmsMacroTable(bool forTesting, ILogger logger) - : base(logger) + internal AddIndexToCmsMacroTable(bool forTesting, IMigrationContext context) + : base(context) { _forTesting = forTesting; } - public AddIndexToCmsMacroTable(ILogger logger) - : base(logger) + public AddIndexToCmsMacroTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddPropertyEditorAliasColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddPropertyEditorAliasColumn.cs index 5f53442bde..074d0d7c2f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddPropertyEditorAliasColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AddPropertyEditorAliasColumn.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 0, GlobalSettings.UmbracoMigrationName)] public class AddPropertyEditorAliasColumn : MigrationBase { - public AddPropertyEditorAliasColumn(ILogger logger) - : base(logger) + public AddPropertyEditorAliasColumn(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterCmsMacroPropertyTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterCmsMacroPropertyTable.cs index abe1c71be8..7f758c6c36 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterCmsMacroPropertyTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterCmsMacroPropertyTable.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Syntax.Delete.DefaultConstraint; using Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions; @@ -20,8 +19,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 6, GlobalSettings.UmbracoMigrationName)] public class AlterCmsMacroPropertyTable : MigrationBase { - public AlterCmsMacroPropertyTable(ILogger logger) - : base(logger) + public AlterCmsMacroPropertyTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs index 0666a28d52..2f61ae0f99 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs @@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 8, GlobalSettings.UmbracoMigrationName)] public class AlterTagRelationsTable : MigrationBase { - public AlterTagRelationsTable(ILogger logger) - : base(logger) + public AlterTagRelationsTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagsTable.cs index 4b543de4d6..1c61e91072 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagsTable.cs @@ -2,7 +2,6 @@ using System.Data; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -11,8 +10,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 9, GlobalSettings.UmbracoMigrationName)] public class AlterTagsTable : MigrationBase { - public AlterTagsTable(ILogger logger) - : base(logger) + public AlterTagsTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterUserTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterUserTable.cs index cd438d0876..c6c88cba09 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterUserTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterUserTable.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 3, GlobalSettings.UmbracoMigrationName)] public class AlterUserTable : MigrationBase { - public AlterUserTable(ILogger logger) - : base(logger) + public AlterUserTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs index 58ff6053af..6b9dd6f43b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs @@ -1,7 +1,6 @@ using System.Data; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -15,8 +14,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 0, GlobalSettings.UmbracoMigrationName)] public class AssignMissingKeysAndIndexes : MigrationBase { - public AssignMissingKeysAndIndexes(ILogger logger) - : base(logger) + public AssignMissingKeysAndIndexes(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/DropControlIdColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/DropControlIdColumn.cs index d661839af0..86269c2a82 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/DropControlIdColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/DropControlIdColumn.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 2, GlobalSettings.UmbracoMigrationName)] public class DropControlIdColumn : MigrationBase { - public DropControlIdColumn(ILogger logger) - : base(logger) + public DropControlIdColumn(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/RemoveCmsMacroPropertyTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/RemoveCmsMacroPropertyTypeTable.cs index b40327e9c1..3eba55b4e7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/RemoveCmsMacroPropertyTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/RemoveCmsMacroPropertyTypeTable.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 7, GlobalSettings.UmbracoMigrationName)] public class RemoveCmsMacroPropertyTypeTable : MigrationBase { - public RemoveCmsMacroPropertyTypeTable(ILogger logger) - : base(logger) + public RemoveCmsMacroPropertyTypeTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateControlIdToPropertyEditorAlias.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateControlIdToPropertyEditorAlias.cs index b7cb1ddb4a..94bca55e03 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateControlIdToPropertyEditorAlias.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateControlIdToPropertyEditorAlias.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.PropertyEditors; @@ -12,8 +11,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 1, GlobalSettings.UmbracoMigrationName)] public class UpdateControlIdToPropertyEditorAlias : MigrationBase { - public UpdateControlIdToPropertyEditorAlias(ILogger logger) - : base(logger) + public UpdateControlIdToPropertyEditorAlias(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs index 9179a8f5e6..b9e636bcf9 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/UpdateRelatedLinksData.cs @@ -20,8 +20,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven [Migration("7.0.0", 10, GlobalSettings.UmbracoMigrationName)] public class UpdateRelatedLinksData : MigrationBase { - public UpdateRelatedLinksData(ILogger logger) - : base(logger) + public UpdateRelatedLinksData(IMigrationContext context) + : base(context) { } @@ -40,12 +40,12 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven if (!dataTypeIds.Any()) return string.Empty; - // need to use dynamic, as PropertyDataDto has new properties + // need to use dynamic, as PropertyDataDto has new properties (eg decimal...) in further versions that don't exist yet var propertyData = database.Fetch("SELECT * FROM cmsPropertyData" - + " WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { dataTypeIds = dataTypeIds }); - if (!propertyData.Any()) return string.Empty; + + " WHERE propertyTypeId in (SELECT id from cmsPropertyType where dataTypeID IN (@dataTypeIds))", new { /*dataTypeIds =*/ dataTypeIds }); + if (propertyData.Any() == false) return string.Empty; - var nodesIdsWithProperty = propertyData.Select(x => x.NodeId).Distinct().ToArray(); + var nodesIdsWithProperty = propertyData.Select(x => (int) x.contentNodeId).Distinct().ToArray(); var cmsContentXmlEntries = new List(); //We're doing an "IN" query here but SQL server only supports 2100 query parameters so we're going to split on that @@ -57,32 +57,32 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven cmsContentXmlEntries.AddRange(database.Fetch("WHERE nodeId in (@nodeIds)", new { nodeIds = batch })); } - var propertyTypeIds = propertyData.Select(x => x.PropertyTypeId).Distinct(); + var propertyTypeIds = propertyData.Select(x => (int) x.propertytypeid).Distinct(); //NOTE: We are writing the full query because we've added a column to the PropertyTypeDto in later versions so one of the columns // won't exist yet var propertyTypes = database.Fetch("SELECT * FROM cmsPropertyType WHERE id in (@propertyTypeIds)", new { propertyTypeIds = propertyTypeIds }); - + foreach (var data in propertyData) { - if (string.IsNullOrEmpty(data.Text) == false) + if (string.IsNullOrEmpty(data.dataNtext) == false) { XmlDocument xml; //fetch the current data (that's in xml format) try { xml = new XmlDocument(); - xml.LoadXml(data.Text); + xml.LoadXml(data.dataNtext); } catch (Exception ex) { int dataId = data.id; - int dataNodeId = data.nodeId; - string dataText = data.dataNText; - Logger.Error("The data stored for property id " + dataId + " on document " + dataNodeId + + int dataNodeId = data.contentNodeId; + string dataText = data.dataNtext; + Logger.Error("The data stored for property id " + dataId + " on document " + dataNodeId + " is not valid XML, the data will be removed because it cannot be converted to the new format. The value was: " + dataText, ex); - data.dataNText = ""; + data.dataNtext = ""; database.Update("cmsPropertyData", "id", data, new[] { "dataNText" }); UpdateXmlTable(propertyTypes, data, cmsContentXmlEntries, database); @@ -116,7 +116,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven } //store the serialized data - data.dataNText = JsonConvert.SerializeObject(links); + data.dataNtext = JsonConvert.SerializeObject(links); database.Update("cmsPropertyData", "id", data, new[] { "dataNText" }); @@ -133,20 +133,20 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven throw new DataLossException("Cannot downgrade from a version 7 database to a prior version, the database schema has already been modified"); } - private static void UpdateXmlTable(List propertyTypes, PropertyDataDto data, List cmsContentXmlEntries, Database database) + private static void UpdateXmlTable(List propertyTypes, dynamic data, List cmsContentXmlEntries, Database database) { //now we need to update the cmsContentXml table - var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.PropertyTypeId); + var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.propertytypeid); if (propertyType != null) { - var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.NodeId); + var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.contentNodeId); if (xmlItem != null) { var x = XElement.Parse(xmlItem.Xml); var prop = x.Element(propertyType.Alias); if (prop != null) { - prop.ReplaceAll(new XCData(data.Text)); + prop.ReplaceAll(new XCData(data.dataNtext)); database.Update(xmlItem); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddDataDecimalColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddDataDecimalColumn.cs index 45ace41dd7..8098e44087 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddDataDecimalColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddDataDecimalColumn.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 1, GlobalSettings.UmbracoMigrationName)] public class AddDataDecimalColumn : MigrationBase { - public AddDataDecimalColumn(ILogger logger) - : base(logger) + public AddDataDecimalColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUmbracoDeployTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUmbracoDeployTables.cs index 8cb0d6aa51..c6186ce75a 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUmbracoDeployTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUmbracoDeployTables.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 5, GlobalSettings.UmbracoMigrationName)] public class AddUmbracoDeployTables : MigrationBase { - public AddUmbracoDeployTables(ILogger logger) - : base(logger) + public AddUmbracoDeployTables(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs index 4e52585847..97e1669f71 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/AddUniqueIdPropertyTypeGroupColumn.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -13,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 2, GlobalSettings.UmbracoMigrationName)] public class AddUniqueIdPropertyTypeGroupColumn : MigrationBase { - public AddUniqueIdPropertyTypeGroupColumn(ILogger logger) - : base(logger) + public AddUniqueIdPropertyTypeGroupColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs index 77cdd0c43b..30b981ae7b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/EnsureContentTypeUniqueIdsAreConsistent.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -16,8 +15,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 3, GlobalSettings.UmbracoMigrationName)] public class EnsureContentTypeUniqueIdsAreConsistent : MigrationBase { - public EnsureContentTypeUniqueIdsAreConsistent(ILogger logger) - : base(logger) + public EnsureContentTypeUniqueIdsAreConsistent(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs index c903ca17d1..36cd45b0a7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/FixListViewMediaSortOrder.cs @@ -1,7 +1,6 @@ using System.Linq; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -10,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 4, GlobalSettings.UmbracoMigrationName)] public class FixListViewMediaSortOrder : MigrationBase { - public FixListViewMediaSortOrder(ILogger logger) - : base(logger) + public FixListViewMediaSortOrder(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/RemoveParentIdPropertyTypeGroupColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/RemoveParentIdPropertyTypeGroupColumn.cs index fa1079b173..4d6fdfe479 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/RemoveParentIdPropertyTypeGroupColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFourZero/RemoveParentIdPropertyTypeGroupColumn.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFourZer [Migration("7.4.0", 4, GlobalSettings.UmbracoMigrationName)] public class RemoveParentIdPropertyTypeGroupColumn : MigrationBase { - public RemoveParentIdPropertyTypeGroupColumn(ILogger logger) - : base(logger) + public RemoveParentIdPropertyTypeGroupColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenOneZero/AssignMissingPrimaryForMySqlKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenOneZero/AssignMissingPrimaryForMySqlKeys.cs index 18b794c857..b9fbed209b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenOneZero/AssignMissingPrimaryForMySqlKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenOneZero/AssignMissingPrimaryForMySqlKeys.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenOneZero @@ -14,8 +13,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenOneZero [Migration("7.0.0", "7.1.0", 0, GlobalSettings.UmbracoMigrationName)] public class AssignMissingPrimaryForMySqlKeys : MigrationBase { - public AssignMissingPrimaryForMySqlKeys(ILogger logger) - : base(logger) + public AssignMissingPrimaryForMySqlKeys(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs index 3f7f33b055..c114501188 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeOne/UpdateUserLanguagesToIsoCode.cs @@ -1,7 +1,6 @@ using System.Linq; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -13,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeOn [Migration("7.3.1", 0, GlobalSettings.UmbracoMigrationName)] public class UpdateUserLanguagesToIsoCode : MigrationBase { - public UpdateUserLanguagesToIsoCode(ILogger logger) - : base(logger) + public UpdateUserLanguagesToIsoCode(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs index 51fb881728..a431bf4524 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeTwo/EnsureMigrationsTableIdentityIsCorrect.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -14,8 +13,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeTw [Migration("7.3.2", 0, GlobalSettings.UmbracoMigrationName)] public class EnsureMigrationsTableIdentityIsCorrect : MigrationBase { - public EnsureMigrationsTableIdentityIsCorrect(ILogger logger) - : base(logger) + public EnsureMigrationsTableIdentityIsCorrect(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddExternalLoginsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddExternalLoginsTable.cs index 0fcc9e8d6f..2249b5931f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddExternalLoginsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddExternalLoginsTable.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 9, GlobalSettings.UmbracoMigrationName)] public class AddExternalLoginsTable : MigrationBase { - public AddExternalLoginsTable(ILogger logger) - : base(logger) + public AddExternalLoginsTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs index 6816245169..1703c56fcd 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddForeignKeysForLanguageAndDictionaryTables.cs @@ -3,7 +3,6 @@ using System.Data; using System.Linq; using NPoco; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -13,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 14, GlobalSettings.UmbracoMigrationName)] public class AddForeignKeysForLanguageAndDictionaryTables : MigrationBase { - public AddForeignKeysForLanguageAndDictionaryTables(ILogger logger) - : base(logger) + public AddForeignKeysForLanguageAndDictionaryTables(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddMigrationTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddMigrationTable.cs index 9cb15ce56d..14d7964e49 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddMigrationTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddMigrationTable.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 11, GlobalSettings.UmbracoMigrationName)] public class AddMigrationTable : MigrationBase { - public AddMigrationTable(ILogger logger) - : base(logger) + public AddMigrationTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddPublicAccessTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddPublicAccessTables.cs index bbc2a74eec..fe353bf90e 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddPublicAccessTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddPublicAccessTables.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 6, GlobalSettings.UmbracoMigrationName)] public class AddPublicAccessTables : MigrationBase { - public AddPublicAccessTables(ILogger logger) - : base(logger) + public AddPublicAccessTables(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddRelationTypeForDocumentOnDelete.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddRelationTypeForDocumentOnDelete.cs index df37404f34..672db2e638 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddRelationTypeForDocumentOnDelete.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddRelationTypeForDocumentOnDelete.cs @@ -1,6 +1,5 @@ using System; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 0, GlobalSettings.UmbracoMigrationName)] public class AddRelationTypeForDocumentOnDelete : MigrationBase { - public AddRelationTypeForDocumentOnDelete(ILogger logger) - : base(logger) + public AddRelationTypeForDocumentOnDelete(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddServerRegistrationColumnsAndLock.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddServerRegistrationColumnsAndLock.cs index c73201850c..5e6a5e1c8c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddServerRegistrationColumnsAndLock.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddServerRegistrationColumnsAndLock.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; @@ -10,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 17, GlobalSettings.UmbracoMigrationName)] public class AddServerRegistrationColumnsAndLock : MigrationBase { - public AddServerRegistrationColumnsAndLock(ILogger logger) - : base(logger) + public AddServerRegistrationColumnsAndLock(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs index f40bfbe0d0..0e04b6ee9b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 13, GlobalSettings.UmbracoMigrationName)] public class AddUniqueIdPropertyTypeColumn : MigrationBase { - public AddUniqueIdPropertyTypeColumn(ILogger logger) - : base(logger) + public AddUniqueIdPropertyTypeColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUserColumns.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUserColumns.cs index c0d60254e1..797808eee7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUserColumns.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUserColumns.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 10, GlobalSettings.UmbracoMigrationName)] public class AddUserColumns : MigrationBase { - public AddUserColumns(ILogger logger) - : base(logger) + public AddUserColumns(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CleanUpCorruptedPublishedFlags.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CleanUpCorruptedPublishedFlags.cs index 3926d03a9b..18e2ea91f7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CleanUpCorruptedPublishedFlags.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CleanUpCorruptedPublishedFlags.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -14,8 +13,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 18, GlobalSettings.UmbracoMigrationName)] public class CleanUpCorruptedPublishedFlags : MigrationBase { - public CleanUpCorruptedPublishedFlags(ILogger logger) - : base(logger) + public CleanUpCorruptedPublishedFlags(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CreateCacheInstructionTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CreateCacheInstructionTable.cs index b3aa932ec3..d35136691d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CreateCacheInstructionTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/CreateCacheInstructionTable.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.SqlSyntax; @@ -13,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 1, GlobalSettings.UmbracoMigrationName)] public class CreateCacheInstructionTable : MigrationBase { - public CreateCacheInstructionTable(ILogger logger) - : base(logger) + public CreateCacheInstructionTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs index 2aa9671791..452c5a4ff9 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs @@ -16,8 +16,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe public class MigrateAndRemoveTemplateMasterColumn : MigrationBase { - public MigrateAndRemoveTemplateMasterColumn(ILogger logger) - : base(logger) + public MigrateAndRemoveTemplateMasterColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateStylesheetDataToFile.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateStylesheetDataToFile.cs index 23bc5fb0d4..d0195555b5 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateStylesheetDataToFile.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateStylesheetDataToFile.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Text; using Umbraco.Core.Configuration; using Umbraco.Core.IO; -using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Persistence.SqlSyntax; using File = System.IO.File; @@ -23,8 +22,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 2, GlobalSettings.UmbracoMigrationName)] public class MigrateStylesheetDataToFile : MigrationBase { - public MigrateStylesheetDataToFile(ILogger logger) - : base(logger) + public MigrateStylesheetDataToFile(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs index 05c8d10c05..fde161b014 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MovePublicAccessXmlDataToDb.cs @@ -14,8 +14,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 7, GlobalSettings.UmbracoMigrationName)] public class MovePublicAccessXmlDataToDb : MigrationBase { - public MovePublicAccessXmlDataToDb(ILogger logger) - : base(logger) + public MovePublicAccessXmlDataToDb(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveHelpTextColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveHelpTextColumn.cs index 6bffcc26c7..767622b076 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveHelpTextColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveHelpTextColumn.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 8, GlobalSettings.UmbracoMigrationName)] public class RemoveHelpTextColumn : MigrationBase { - public RemoveHelpTextColumn(ILogger logger) - : base(logger) + public RemoveHelpTextColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveLanguageLocaleColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveLanguageLocaleColumn.cs index 2acc354c23..d842c14324 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveLanguageLocaleColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveLanguageLocaleColumn.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 4, GlobalSettings.UmbracoMigrationName)] public class RemoveLanguageLocaleColumn : MigrationBase { - public RemoveLanguageLocaleColumn(ILogger logger) - : base(logger) + public RemoveLanguageLocaleColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveStylesheetDataAndTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveStylesheetDataAndTables.cs index 0a9a0b9c9c..517de15665 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveStylesheetDataAndTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveStylesheetDataAndTables.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero @@ -9,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 3, GlobalSettings.UmbracoMigrationName)] public class RemoveStylesheetDataAndTables : MigrationBase { - public RemoveStylesheetDataAndTables(ILogger logger) - : base(logger) + public RemoveStylesheetDataAndTables(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveUmbracoLoginsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveUmbracoLoginsTable.cs index 438be514b2..8142f81169 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveUmbracoLoginsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/RemoveUmbracoLoginsTable.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero @@ -8,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 15, GlobalSettings.UmbracoMigrationName)] public class RemoveUmbracoLoginsTable : MigrationBase { - public RemoveUmbracoLoginsTable(ILogger logger) - : base(logger) + public RemoveUmbracoLoginsTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs index 9267c12cf5..3729bd84a2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/UpdateUniqueIdToHaveCorrectIndexType.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -11,8 +10,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe [Migration("7.3.0", 5, GlobalSettings.UmbracoMigrationName)] public class UpdateUniqueIdToHaveCorrectIndexType : MigrationBase { - public UpdateUniqueIdToHaveCorrectIndexType(ILogger logger) - : base(logger) + public UpdateUniqueIdToHaveCorrectIndexType(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddIndexToUmbracoNodeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddIndexToUmbracoNodeTable.cs index 923d3e4bda..d794a2e606 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddIndexToUmbracoNodeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddIndexToUmbracoNodeTable.cs @@ -1,6 +1,5 @@ using System.Linq; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.SqlSyntax; @@ -11,14 +10,14 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero { private readonly bool _skipIndexCheck; - internal AddIndexToUmbracoNodeTable(ILogger logger, bool skipIndexCheck) - : base(logger) + internal AddIndexToUmbracoNodeTable(bool skipIndexCheck, IMigrationContext context) + : base(context) { _skipIndexCheck = skipIndexCheck; } - public AddIndexToUmbracoNodeTable(ILogger logger) - : base(logger) + public AddIndexToUmbracoNodeTable(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs index b9eff9df5e..9efd6d86e2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AddMissingForeignKeyForContentType.cs @@ -11,8 +11,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero [Migration("7.2.0", 1, GlobalSettings.UmbracoMigrationName)] public class AddMissingForeignKeyForContentType : MigrationBase { - public AddMissingForeignKeyForContentType(ILogger logger) - : base(logger) + public AddMissingForeignKeyForContentType(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AlterDataTypePreValueTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AlterDataTypePreValueTable.cs index 29be1b3aeb..1f3c0d64a1 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AlterDataTypePreValueTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/AlterDataTypePreValueTable.cs @@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero [Migration("7.2.0", 0, GlobalSettings.UmbracoMigrationName)] public class AlterDataTypePreValueTable : MigrationBase { - public AlterDataTypePreValueTable(ILogger logger) - : base(logger) + public AlterDataTypePreValueTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/RemoveCmsDocumentAliasColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/RemoveCmsDocumentAliasColumn.cs index 55f57801ae..3dd971c9c2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/RemoveCmsDocumentAliasColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwoZero/RemoveCmsDocumentAliasColumn.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero [Migration("7.2.0", 2, GlobalSettings.UmbracoMigrationName)] public class RemoveCmsDocumentAliasColumn : MigrationBase { - public RemoveCmsDocumentAliasColumn(ILogger logger) - : base(logger) + public RemoveCmsDocumentAliasColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/DeleteAppTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/DeleteAppTables.cs index 7344e75b9c..b0dd2416e2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/DeleteAppTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/DeleteAppTables.cs @@ -9,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 10, GlobalSettings.UmbracoMigrationName)] public class DeleteAppTables : MigrationBase { - public DeleteAppTables(ILogger logger) - : base(logger) + public DeleteAppTables(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/EnsureAppsTreesUpdated.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/EnsureAppsTreesUpdated.cs index d06402c87c..ba7afe9c75 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/EnsureAppsTreesUpdated.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/EnsureAppsTreesUpdated.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 9, GlobalSettings.UmbracoMigrationName)] public class EnsureAppsTreesUpdated : MigrationBase { - public EnsureAppsTreesUpdated(ILogger logger) - : base(logger) + public EnsureAppsTreesUpdated(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/MoveMasterContentTypeData.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/MoveMasterContentTypeData.cs index e4afc7be31..16c301df0a 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/MoveMasterContentTypeData.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/MoveMasterContentTypeData.cs @@ -7,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 5, GlobalSettings.UmbracoMigrationName)] public class MoveMasterContentTypeData : MigrationBase { - public MoveMasterContentTypeData(ILogger logger) - : base(logger) + public MoveMasterContentTypeData(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/NewCmsContentType2ContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/NewCmsContentType2ContentTypeTable.cs index 9bcff9464f..1ccc600a6c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/NewCmsContentType2ContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/NewCmsContentType2ContentTypeTable.cs @@ -7,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 4, GlobalSettings.UmbracoMigrationName)] public class NewCmsContentType2ContentTypeTable : MigrationBase { - public NewCmsContentType2ContentTypeTable(ILogger logger) - : base(logger) + public NewCmsContentType2ContentTypeTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs index e21cab814f..2634b64160 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RemoveMasterContentTypeColumn.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 6, GlobalSettings.UmbracoMigrationName)] public class RemoveMasterContentTypeColumn : MigrationBase { - public RemoveMasterContentTypeColumn(ILogger logger) - : base(logger) + public RemoveMasterContentTypeColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameCmsTabTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameCmsTabTable.cs index abba5a7540..ceab9faa18 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameCmsTabTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameCmsTabTable.cs @@ -7,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 0, GlobalSettings.UmbracoMigrationName)] public class RenameCmsTabTable : MigrationBase { - public RenameCmsTabTable(ILogger logger) - : base(logger) + public RenameCmsTabTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameTabIdColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameTabIdColumn.cs index ba108035d6..872a167682 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameTabIdColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/RenameTabIdColumn.cs @@ -9,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 7, GlobalSettings.UmbracoMigrationName)] public class RenameTabIdColumn : MigrationBase { - public RenameTabIdColumn(ILogger logger) - : base(logger) + public RenameTabIdColumn(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeAllowedContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeAllowedContentTypeTable.cs index 3afd8234bc..b4b48432d0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeAllowedContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeAllowedContentTypeTable.cs @@ -7,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 3, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentTypeAllowedContentTypeTable : MigrationBase { - public UpdateCmsContentTypeAllowedContentTypeTable(ILogger logger) - : base(logger) + public UpdateCmsContentTypeAllowedContentTypeTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeTable.cs index 4ecc7dd64c..5e66533af2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentTypeTable.cs @@ -9,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 2, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentTypeTable : MigrationBase { - public UpdateCmsContentTypeTable(ILogger logger) - : base(logger) + public UpdateCmsContentTypeTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentVersionTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentVersionTable.cs index 956b8c13e8..566c4f7891 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentVersionTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsContentVersionTable.cs @@ -7,8 +7,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 8, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentVersionTable : MigrationBase { - public UpdateCmsContentVersionTable(ILogger logger) - : base(logger) + public UpdateCmsContentVersionTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsPropertyTypeGroupTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsPropertyTypeGroupTable.cs index 41f542993b..ff7e9f43f0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsPropertyTypeGroupTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSix/UpdateCmsPropertyTypeGroupTable.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix [Migration("6.0.0", 1, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsPropertyTypeGroupTable : MigrationBase { - public UpdateCmsPropertyTypeGroupTable(ILogger logger) - : base(logger) + public UpdateCmsPropertyTypeGroupTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs index 27011d6ce4..6d517fcc98 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs @@ -13,8 +13,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixOneZero [Migration("6.1.0", 0, GlobalSettings.UmbracoMigrationName)] public class CreateServerRegistryTable : MigrationBase { - public CreateServerRegistryTable(ILogger logger) - : base(logger) + public CreateServerRegistryTable(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs index a445585c03..7a3d67ce1d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AddChangeDocumentTypePermission.cs @@ -11,8 +11,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.2.0", 3, GlobalSettings.UmbracoMigrationName)] public class AddChangeDocumentTypePermission : MigrationBase { - public AddChangeDocumentTypePermission(ILogger logger) - : base(logger) + public AddChangeDocumentTypePermission(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs index d566bdd5c8..9781bada36 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs @@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.2.0", 1, GlobalSettings.UmbracoMigrationName)] public class AdditionalIndexesAndKeys : MigrationBase { - public AdditionalIndexesAndKeys(ILogger logger) - : base(logger) + public AdditionalIndexesAndKeys(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs index 614be4d3cc..9d34281f50 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys.cs @@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.2.0", 0, GlobalSettings.UmbracoMigrationName)] public class AssignMissingPrimaryForMySqlKeys : MigrationBase { - public AssignMissingPrimaryForMySqlKeys(ILogger logger) - : base(logger) + public AssignMissingPrimaryForMySqlKeys(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys2.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys2.cs index 42b59d1326..b1beca51d6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys2.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AssignMissingPrimaryForMySqlKeys2.cs @@ -11,8 +11,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.0.0", "6.2.0", 0, GlobalSettings.UmbracoMigrationName)] public class AssignMissingPrimaryForMySqlKeys2 : MigrationBase { - public AssignMissingPrimaryForMySqlKeys2(ILogger logger) - : base(logger) + public AssignMissingPrimaryForMySqlKeys2(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/ChangePasswordColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/ChangePasswordColumn.cs index b32250dee5..83ec557e8b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/ChangePasswordColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/ChangePasswordColumn.cs @@ -9,8 +9,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.2.0", 2, GlobalSettings.UmbracoMigrationName)] public class ChangePasswordColumn : MigrationBase { - public ChangePasswordColumn(ILogger logger) - : base(logger) + public ChangePasswordColumn(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs index 30bd923fca..88cbfb59af 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/UpdateToNewMemberPropertyAliases.cs @@ -12,8 +12,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero [Migration("6.2.0", 4, GlobalSettings.UmbracoMigrationName)] public class UpdateToNewMemberPropertyAliases : MigrationBase { - public UpdateToNewMemberPropertyAliases(ILogger logger) - : base(logger) + public UpdateToNewMemberPropertyAliases(IMigrationContext context) + : base(context) { } public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs index d9f1c6cdc2..1dd428f922 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixZeroOne/UpdatePropertyTypesAndGroups.cs @@ -11,8 +11,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne [Migration("6.0.2", 0, GlobalSettings.UmbracoMigrationName)] public class UpdatePropertyTypesAndGroups : MigrationBase { - public UpdatePropertyTypesAndGroups(ILogger logger) - : base(logger) + public UpdatePropertyTypesAndGroups(IMigrationContext context) + : base(context) { } diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorAttribute.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorAttribute.cs index 2f225f1764..d120753185 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditorAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorAttribute.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.PropertyEditors EditorView = editorView; //defaults - ValueType = "string"; + ValueType = PropertyEditorValueTypes.String; Icon = Constants.Icons.PropertyEditor; Group = "common"; } @@ -33,7 +33,7 @@ namespace Umbraco.Core.PropertyEditors Name = name; //defaults - ValueType = "string"; + ValueType = PropertyEditorValueTypes.String; Icon = Constants.Icons.PropertyEditor; Group = "common"; } diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorValueTypes.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorValueTypes.cs new file mode 100644 index 0000000000..0ece42d82b --- /dev/null +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorValueTypes.cs @@ -0,0 +1,34 @@ +using System; + +namespace Umbraco.Core.PropertyEditors +{ + public static class PropertyEditorValueTypes + { + // mapped to DataTypeDatabaseType in DataTypeService.OverrideDatabaseTypeIfProvidedInPreValues + // BUT what about those that are not mapped? + // + // also mapped to DataTypeDatabaseType in PropertyValueEditor + // and this time the "+" are mapped + + public const string Date = "DATE"; // +Date + + public const string DateTime = "DATETIME"; // Date + + public const string Decimal = "DECIMAL"; // Decimal + + public const string Integer = "INT"; // Integer + + [Obsolete("Use Integer.", false)] + public const string IntegerAlternative = "INTEGER"; // +Integer + + public const string Json = "JSON"; // +NText + + public const string Text = "TEXT"; // NText + + public const string Time = "TIME"; // +Date + + public const string String = "STRING"; // NVarchar + + public const string Xml = "XML"; // +NText + } +} diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs index af3a560837..0b083025f7 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs @@ -25,7 +25,7 @@ namespace Umbraco.Core.PropertyEditors /// public PropertyValueEditor() { - ValueType = "string"; + ValueType = PropertyEditorValueTypes.String; //set a default for validators Validators = new List(); } @@ -123,30 +123,35 @@ namespace Umbraco.Core.PropertyEditors } /// - /// Returns the true DataTypeDatabaseType from the string representation ValueType + /// Returns the true DataTypeDatabaseType from the string representation ValueType. /// /// public DataTypeDatabaseType GetDatabaseType() { - switch (ValueType.ToUpper(CultureInfo.InvariantCulture)) + return GetDatabaseType(ValueType); + } + + public static DataTypeDatabaseType GetDatabaseType(string valueType) + { + switch (valueType.ToUpperInvariant()) { - case "INT": - case "INTEGER": + case PropertyEditorValueTypes.Integer: + case PropertyEditorValueTypes.IntegerAlternative: return DataTypeDatabaseType.Integer; - case "DECIMAL": + case PropertyEditorValueTypes.Decimal: return DataTypeDatabaseType.Decimal; - case "STRING": + case PropertyEditorValueTypes.String: return DataTypeDatabaseType.Nvarchar; - case "TEXT": - case "JSON": - case "XML": + case PropertyEditorValueTypes.Text: + case PropertyEditorValueTypes.Json: + case PropertyEditorValueTypes.Xml: return DataTypeDatabaseType.Ntext; - case "DATETIME": - case "DATE": - case "TIME": + case PropertyEditorValueTypes.DateTime: + case PropertyEditorValueTypes.Date: + case PropertyEditorValueTypes.Time: return DataTypeDatabaseType.Date; default: - throw new FormatException("The ValueType does not match a known value type"); + throw new ArgumentException("Not a valid value type.", "valueType"); } } @@ -238,7 +243,7 @@ namespace Umbraco.Core.PropertyEditors public virtual object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue) { //if it's json but it's empty json, then return null - if (ValueType.InvariantEquals("JSON") && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson()) + if (ValueType.InvariantEquals(PropertyEditorValueTypes.Json) && editorValue.Value != null && editorValue.Value.ToString().DetectIsEmptyJson()) { return null; } diff --git a/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs b/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs index 33c2c02cb6..b3e8ff1f6f 100644 --- a/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.PropertyEditors { var asString = value.ToString(); - if (editor.ValueEditor.ValueType.InvariantEquals("JSON")) + if (editor.ValueEditor.ValueType.InvariantEquals(PropertyEditorValueTypes.Json)) { if (asString.DetectIsEmptyJson()) { diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs index 32fe356764..e32ff7af02 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/DecimalValueConverter.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.Models.PublishedContent; +using System.Globalization; +using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Core.PropertyEditors.ValueConverters { @@ -20,7 +21,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters if (sourceString != null) { decimal d; - return (decimal.TryParse(sourceString, out d)) ? d : 0M; + return (decimal.TryParse(sourceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out d)) ? d : 0M; } // in the database an a decimal is an a decimal diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs index e5ed8b8b94..c5f0236a1a 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -26,7 +26,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters { var propertyEditor = PropertyEditorResolver.Current.GetByAlias(propertyType.PropertyEditorAlias); if (propertyEditor == null) return false; - return propertyEditor.ValueEditor.ValueType.InvariantEquals("json"); + return propertyEditor.ValueEditor.ValueType.InvariantEquals(PropertyEditorValueTypes.Json); } public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs index 6725257888..39bcf85b12 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultipleTextStringValueConverter.cs @@ -35,6 +35,9 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters // as xml in the database, it's always been new line delimited. Will ask Stephen about this. // In the meantime, we'll do this xml check, see if it parses and if not just continue with // splitting by newline + // + // RS: SD/Stephan Please consider post before deciding to remove + //// https://our.umbraco.org/forum/contributing-to-umbraco-cms/76989-keep-the-xml-values-in-the-multipletextstringvalueconverter var values = new List(); var pos = sourceString.IndexOf("", StringComparison.Ordinal); while (pos >= 0) diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index 754f26762e..e0ee0c2eef 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -500,6 +500,10 @@ namespace Umbraco.Core.Services if (Saving.IsRaisedEventCancelled(new SaveEventArgs(dataTypeDefinition), this)) return; + // if preValues contain the data type, override the data type definition accordingly + if (values != null && values.ContainsKey(Constants.PropertyEditors.PreValueKeys.DataValueType)) + dataTypeDefinition.DatabaseType = PropertyValueEditor.GetDatabaseType(values[Constants.PropertyEditors.PreValueKeys.DataValueType].Value); + dataTypeDefinition.CreatorId = userId; using (var uow = UowProvider.CreateUnitOfWork()) @@ -514,7 +518,6 @@ namespace Umbraco.Core.Services Audit(AuditType.Save, "Save DataTypeDefinition performed by user", userId, dataTypeDefinition.Id); } - /// /// Deletes an /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index e8d704e686..cc774f94a2 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -250,8 +250,7 @@ namespace Umbraco.Core.Services /// Field to order by /// Direction to order by /// Flag to indicate when ordering by system field - /// Search text filter - /// + /// /// An Enumerable list of objects IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, bool orderBySystemField, IQuery filter); diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 74543e2cb7..f582117284 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -856,7 +856,7 @@ namespace Umbraco.Core.Services var c = stack.Peek(); IMedia[] cc; if (c.Level == level) - while ((cc = c.Children().ToArray()).Length > 0) + while ((cc = c.Children(this).ToArray()).Length > 0) { foreach (var ci in cc) stack.Push(ci); diff --git a/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs b/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs index 260e8e5159..58dddb5712 100644 --- a/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs +++ b/src/Umbraco.Core/Strings/Css/StylesheetHelper.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.Strings.Css { internal class StylesheetHelper { - private const string RuleRegexFormat = @"/\*\*\s*umb_name:\s*(?{0}?)\s*\*/\s*(?[^\s,{{]*?)\s*{{\s*(?.*?)\s*}}"; + private const string RuleRegexFormat = @"/\*\*\s*umb_name:\s*(?{0}?)\s*\*/\s*(?[^,{{]*?)\s*{{\s*(?.*?)\s*}}"; public static IEnumerable ParseRules(string input) { diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7c5f4e4800..fb20626a5a 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -37,132 +37,10 @@ false - - ..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll - True - - - False - ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll - - - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - - - ..\packages\LightInject.4.0.9\lib\net46\LightInject.dll - True - - - ..\packages\LightInject.Annotation.1.0.0.4\lib\net45\LightInject.Annotation.dll - True - - - ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll - True - - - ..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Analyzers.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Core.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.FastVectorHighlighter.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Highlighter.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Memory.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Queries.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Regex.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SimpleFacetedSearch.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Snowball.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SpellChecker.dll - True - - - False - ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - False - ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll - - - False - ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - ..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll - True - - - False - ..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - False - ..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - ..\packages\MiniProfiler.3.2.0.157\lib\net40\MiniProfiler.dll - True - - - False - ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll - - - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll - True - - - ..\packages\NPoco.3.3.0-beta3\lib\net45\NPoco.dll - True - - - ..\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\packages\semver.1.1.2\lib\net451\Semver.dll - True - - - False - ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll - - - False - ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll - @@ -469,6 +347,7 @@ + @@ -542,6 +421,7 @@ + @@ -1442,9 +1322,7 @@ - - Designer - + @@ -1457,7 +1335,6 @@ - - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - zone : function (input, keepLocalTime) { - var offset = this._offset || 0, - localAdjust; - if (input != null) { - if (typeof input === 'string') { - input = timezoneMinutesFromString(input); - } - if (Math.abs(input) < 16) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = this._dateTzOffset(); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.subtract(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addOrSubtractDurationFromMoment(this, - moment.duration(offset - input, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - moment.updateOffset(this, true); - this._changeInProgress = null; - } - } - } else { - return this._isUTC ? offset : this._dateTzOffset(); - } - return this; - }, - - zoneAbbr : function () { - return this._isUTC ? 'UTC' : ''; - }, - - zoneName : function () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - }, - - parseZone : function () { - if (this._tzm) { - this.zone(this._tzm); - } else if (typeof this._i === 'string') { - this.zone(this._i); - } - return this; - }, - - hasAlignedHourOffset : function (input) { - if (!input) { - input = 0; - } - else { - input = moment(input).zone(); - } - - return (this.zone() - input) % 60 === 0; - }, - - daysInMonth : function () { - return daysInMonth(this.year(), this.month()); - }, - - dayOfYear : function (input) { - var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - }, - - quarter : function (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - }, - - weekYear : function (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); - }, - - isoWeekYear : function (input) { - var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); - }, - - week : function (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - }, - - isoWeek : function (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - }, - - weekday : function (input) { - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - }, - - isoWeekday : function (input) { - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); - }, - - isoWeeksInYear : function () { - return weeksInYear(this.year(), 1, 4); - }, - - weeksInYear : function () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units](); - }, - - set : function (units, value) { - units = normalizeUnits(units); - if (typeof this[units] === 'function') { - this[units](value); - } - return this; - }, - - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - locale : function (key) { - var newLocaleData; - - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = moment.localeData(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - }, - - lang : deprecate( - 'moment().lang() is deprecated. Use moment().localeData() instead.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ), - - localeData : function () { - return this._locale; - }, - - _dateTzOffset : function () { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return Math.round(this._d.getTimezoneOffset() / 15) * 15; - } - }); - - function rawMonthSetter(mom, value) { - var dayOfMonth; - - // TODO: Move this out of here! - if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; - } - } - - dayOfMonth = Math.min(mom.date(), - daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function rawGetter(mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); - } - - function rawSetter(mom, unit, value) { - if (unit === 'Month') { - return rawMonthSetter(mom, value); - } else { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - - function makeAccessor(unit, keepTime) { - return function (value) { - if (value != null) { - rawSetter(this, unit, value); - moment.updateOffset(this, keepTime); - return this; - } else { - return rawGetter(this, unit); - } - }; - } - - moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); - moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); - moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); - // Setting the hour should keep the time, because the user explicitly - // specified which hour he wants. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); - // moment.fn.month is defined separately - moment.fn.date = makeAccessor('Date', true); - moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); - moment.fn.year = makeAccessor('FullYear', true); - moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); - - // add plural methods - moment.fn.days = moment.fn.day; - moment.fn.months = moment.fn.month; - moment.fn.weeks = moment.fn.week; - moment.fn.isoWeeks = moment.fn.isoWeek; - moment.fn.quarters = moment.fn.quarter; - - // add aliased format methods - moment.fn.toJSON = moment.fn.toISOString; - - /************************************ - Duration Prototype - ************************************/ - - - function daysToYears (days) { - // 400 years have 146097 days (taking into account leap year rules) - return days * 400 / 146097; - } - - function yearsToDays (years) { - // years * 365 + absRound(years / 4) - - // absRound(years / 100) + absRound(years / 400); - return years * 146097 / 400; - } - - extend(moment.duration.fn = Duration.prototype, { - - _bubble : function () { - var milliseconds = this._milliseconds, - days = this._days, - months = this._months, - data = this._data, - seconds, minutes, hours, years = 0; - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absRound(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absRound(seconds / 60); - data.minutes = minutes % 60; - - hours = absRound(minutes / 60); - data.hours = hours % 24; - - days += absRound(hours / 24); - - // Accurately convert days to years, assume start from year 0. - years = absRound(daysToYears(days)); - days -= absRound(yearsToDays(years)); - - // 30 days to a month - // TODO (iskren): Use anchor date (like 1st Jan) to compute this. - months += absRound(days / 30); - days %= 30; - - // 12 months -> 1 year - years += absRound(months / 12); - months %= 12; - - data.days = days; - data.months = months; - data.years = years; - }, - - abs : function () { - this._milliseconds = Math.abs(this._milliseconds); - this._days = Math.abs(this._days); - this._months = Math.abs(this._months); - - this._data.milliseconds = Math.abs(this._data.milliseconds); - this._data.seconds = Math.abs(this._data.seconds); - this._data.minutes = Math.abs(this._data.minutes); - this._data.hours = Math.abs(this._data.hours); - this._data.months = Math.abs(this._data.months); - this._data.years = Math.abs(this._data.years); - - return this; - }, - - weeks : function () { - return absRound(this.days() / 7); - }, - - valueOf : function () { - return this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6; - }, - - humanize : function (withSuffix) { - var output = relativeTime(this, !withSuffix, this.localeData()); - - if (withSuffix) { - output = this.localeData().pastFuture(+this, output); - } - - return this.localeData().postformat(output); - }, - - add : function (input, val) { - // supports only 2.0-style add(1, 's') or add(moment) - var dur = moment.duration(input, val); - - this._milliseconds += dur._milliseconds; - this._days += dur._days; - this._months += dur._months; - - this._bubble(); - - return this; - }, - - subtract : function (input, val) { - var dur = moment.duration(input, val); - - this._milliseconds -= dur._milliseconds; - this._days -= dur._days; - this._months -= dur._months; - - this._bubble(); - - return this; - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units.toLowerCase() + 's'](); - }, - - as : function (units) { - var days, months; - units = normalizeUnits(units); - - if (units === 'month' || units === 'year') { - days = this._days + this._milliseconds / 864e5; - months = this._months + daysToYears(days) * 12; - return units === 'month' ? months : months / 12; - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + yearsToDays(this._months / 12); - switch (units) { - case 'week': return days / 7 + this._milliseconds / 6048e5; - case 'day': return days + this._milliseconds / 864e5; - case 'hour': return days * 24 + this._milliseconds / 36e5; - case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; - case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - }, - - lang : moment.fn.lang, - locale : moment.fn.locale, - - toIsoString : deprecate( - 'toIsoString() is deprecated. Please use toISOString() instead ' + - '(notice the capitals)', - function () { - return this.toISOString(); - } - ), - - toISOString : function () { - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var years = Math.abs(this.years()), - months = Math.abs(this.months()), - days = Math.abs(this.days()), - hours = Math.abs(this.hours()), - minutes = Math.abs(this.minutes()), - seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); - - if (!this.asSeconds()) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - return (this.asSeconds() < 0 ? '-' : '') + - 'P' + - (years ? years + 'Y' : '') + - (months ? months + 'M' : '') + - (days ? days + 'D' : '') + - ((hours || minutes || seconds) ? 'T' : '') + - (hours ? hours + 'H' : '') + - (minutes ? minutes + 'M' : '') + - (seconds ? seconds + 'S' : ''); - }, - - localeData : function () { - return this._locale; - } - }); - - moment.duration.fn.toString = moment.duration.fn.toISOString; - - function makeDurationGetter(name) { - moment.duration.fn[name] = function () { - return this._data[name]; - }; - } - - for (i in unitMillisecondFactors) { - if (hasOwnProp(unitMillisecondFactors, i)) { - makeDurationGetter(i.toLowerCase()); - } - } - - moment.duration.fn.asMilliseconds = function () { - return this.as('ms'); - }; - moment.duration.fn.asSeconds = function () { - return this.as('s'); - }; - moment.duration.fn.asMinutes = function () { - return this.as('m'); - }; - moment.duration.fn.asHours = function () { - return this.as('h'); - }; - moment.duration.fn.asDays = function () { - return this.as('d'); - }; - moment.duration.fn.asWeeks = function () { - return this.as('weeks'); - }; - moment.duration.fn.asMonths = function () { - return this.as('M'); - }; - moment.duration.fn.asYears = function () { - return this.as('y'); - }; - - /************************************ - Default Locale - ************************************/ - - - // Set default locale, other locale will inherit from English. - moment.locale('en', { - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - // moment.js locale configuration -// locale : afrikaans (af) -// author : Werner Mollentze : https://github.com/wernerm - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('af', { - months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), - weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), - weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower ? 'vm' : 'VM'; - } else { - return isLower ? 'nm' : 'NM'; - } - }, - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Vandag om] LT', - nextDay : '[Môre om] LT', - nextWeek : 'dddd [om] LT', - lastDay : '[Gister om] LT', - lastWeek : '[Laas] dddd [om] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'oor %s', - past : '%s gelede', - s : '\'n paar sekondes', - m : '\'n minuut', - mm : '%d minute', - h : '\'n uur', - hh : '%d ure', - d : '\'n dag', - dd : '%d dae', - M : '\'n maand', - MM : '%d maande', - y : '\'n jaar', - yy : '%d jaar' - }, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter - }, - week : { - dow : 1, // Maandag is die eerste dag van die week. - doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. - } - }); -})); -// moment.js locale configuration -// locale : Moroccan Arabic (ar-ma) -// author : ElFadili Yassine : https://github.com/ElFadiliY -// author : Abdel Said : https://github.com/abdelsaid - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ar-ma', { - months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Arabic Saudi Arabia (ar-sa) -// author : Suhail Alkowaileet : https://github.com/xsoh - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }; - - return moment.defineLocale('ar-sa', { - months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// Locale: Arabic (ar) -// Author: Abdel Said: https://github.com/abdelsaid -// Changes in months, weekdays: Ahmed Elkhatib -// Native plural forms: forabi https://github.com/forabi - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }, pluralForm = function (n) { - return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; - }, plurals = { - s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], - m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], - h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], - d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], - M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], - y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] - }, pluralize = function (u) { - return function (number, withoutSuffix, string, isFuture) { - var f = pluralForm(number), - str = plurals[u][pluralForm(number)]; - if (f === 2) { - str = str[withoutSuffix ? 0 : 1]; - } - return str.replace(/%d/i, number); - }; - }, months = [ - 'كانون الثاني يناير', - 'شباط فبراير', - 'آذار مارس', - 'نيسان أبريل', - 'أيار مايو', - 'حزيران يونيو', - 'تموز يوليو', - 'آب أغسطس', - 'أيلول سبتمبر', - 'تشرين الأول أكتوبر', - 'تشرين الثاني نوفمبر', - 'كانون الأول ديسمبر' - ]; - - return moment.defineLocale('ar', { - months : months, - monthsShort : months, - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } - }, - calendar : { - sameDay: '[اليوم عند الساعة] LT', - nextDay: '[غدًا عند الساعة] LT', - nextWeek: 'dddd [عند الساعة] LT', - lastDay: '[أمس عند الساعة] LT', - lastWeek: 'dddd [عند الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'بعد %s', - past : 'منذ %s', - s : pluralize('s'), - m : pluralize('m'), - mm : pluralize('m'), - h : pluralize('h'), - hh : pluralize('h'), - d : pluralize('d'), - dd : pluralize('d'), - M : pluralize('M'), - MM : pluralize('M'), - y : pluralize('y'), - yy : pluralize('y') - }, - preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : azerbaijani (az) -// author : topchiyev : https://github.com/topchiyev - -(function (factory) { - factory(moment); -}(function (moment) { - var suffixes = { - 1: '-inci', - 5: '-inci', - 8: '-inci', - 70: '-inci', - 80: '-inci', - - 2: '-nci', - 7: '-nci', - 20: '-nci', - 50: '-nci', - - 3: '-üncü', - 4: '-üncü', - 100: '-üncü', - - 6: '-ncı', - - 9: '-uncu', - 10: '-uncu', - 30: '-uncu', - - 60: '-ıncı', - 90: '-ıncı' - }; - return moment.defineLocale('az', { - months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), - monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), - weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), - weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), - weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[sabah saat] LT', - nextWeek : '[gələn həftə] dddd [saat] LT', - lastDay : '[dünən] LT', - lastWeek : '[keçən həftə] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s sonra', - past : '%s əvvəl', - s : 'birneçə saniyyə', - m : 'bir dəqiqə', - mm : '%d dəqiqə', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir il', - yy : '%d il' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'gecə'; - } else if (hour < 12) { - return 'səhər'; - } else if (hour < 17) { - return 'gündüz'; - } else { - return 'axşam'; - } - }, - ordinal : function (number) { - if (number === 0) { // special case for zero - return number + '-ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - - return number + (suffixes[a] || suffixes[b] || suffixes[c]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : belarusian (be) -// author : Dmitry Demidov : https://github.com/demidov91 -// author: Praleska: http://praleska.pro/ -// Author : Menelion Elensúle : https://github.com/Oire - -(function (factory) { - factory(moment); -}(function (moment) { - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', - 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', - 'dd': 'дзень_дні_дзён', - 'MM': 'месяц_месяцы_месяцаў', - 'yy': 'год_гады_гадоў' - }; - if (key === 'm') { - return withoutSuffix ? 'хвіліна' : 'хвіліну'; - } - else if (key === 'h') { - return withoutSuffix ? 'гадзіна' : 'гадзіну'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'), - 'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_') - }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - 'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_') - }, - - nounCase = (/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('be', { - months : monthsCaseReplace, - monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., LT', - LLLL : 'dddd, D MMMM YYYY г., LT' - }, - calendar : { - sameDay: '[Сёння ў] LT', - nextDay: '[Заўтра ў] LT', - lastDay: '[Учора ў] LT', - nextWeek: function () { - return '[У] dddd [ў] LT'; - }, - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return '[У мінулую] dddd [ў] LT'; - case 1: - case 2: - case 4: - return '[У мінулы] dddd [ў] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'праз %s', - past : '%s таму', - s : 'некалькі секунд', - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : relativeTimeWithPlural, - hh : relativeTimeWithPlural, - d : 'дзень', - dd : relativeTimeWithPlural, - M : 'месяц', - MM : relativeTimeWithPlural, - y : 'год', - yy : relativeTimeWithPlural - }, - - - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночы'; - } else if (hour < 12) { - return 'раніцы'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечара'; - } - }, - - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - case 'w': - case 'W': - return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; - case 'D': - return number + '-га'; - default: - return number; - } - }, - - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : bulgarian (bg) -// author : Krasen Borisov : https://github.com/kraz - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('bg', { - months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), - weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Днес в] LT', - nextDay : '[Утре в] LT', - nextWeek : 'dddd [в] LT', - lastDay : '[Вчера в] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[В изминалата] dddd [в] LT'; - case 1: - case 2: - case 4: - case 5: - return '[В изминалия] dddd [в] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'след %s', - past : 'преди %s', - s : 'няколко секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дни', - M : 'месец', - MM : '%d месеца', - y : 'година', - yy : '%d години' - }, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; - } else { - return number + '-ти'; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Bengali (bn) -// author : Kaushik Gandhi : https://github.com/kaushikgandhi - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '১', - '2': '২', - '3': '৩', - '4': '৪', - '5': '৫', - '6': '৬', - '7': '৭', - '8': '৮', - '9': '৯', - '0': '০' - }, - numberMap = { - '১': '1', - '২': '2', - '৩': '3', - '৪': '4', - '৫': '5', - '৬': '6', - '৭': '7', - '৮': '8', - '৯': '9', - '০': '0' - }; - - return moment.defineLocale('bn', { - months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), - monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'), - weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'), - weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'), - weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'), - longDateFormat : { - LT : 'A h:mm সময়', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[আজ] LT', - nextDay : '[আগামীকাল] LT', - nextWeek : 'dddd, LT', - lastDay : '[গতকাল] LT', - lastWeek : '[গত] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s পরে', - past : '%s আগে', - s : 'কএক সেকেন্ড', - m : 'এক মিনিট', - mm : '%d মিনিট', - h : 'এক ঘন্টা', - hh : '%d ঘন্টা', - d : 'এক দিন', - dd : '%d দিন', - M : 'এক মাস', - MM : '%d মাস', - y : 'এক বছর', - yy : '%d বছর' - }, - preparse: function (string) { - return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - //Bengali is a vast language its spoken - //in different forms in various parts of the world. - //I have just generalized with most common one used - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'রাত'; - } else if (hour < 10) { - return 'শকাল'; - } else if (hour < 17) { - return 'দুপুর'; - } else if (hour < 20) { - return 'বিকেল'; - } else { - return 'রাত'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : tibetan (bo) -// author : Thupten N. Chakrishar : https://github.com/vajradog - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '༡', - '2': '༢', - '3': '༣', - '4': '༤', - '5': '༥', - '6': '༦', - '7': '༧', - '8': '༨', - '9': '༩', - '0': '༠' - }, - numberMap = { - '༡': '1', - '༢': '2', - '༣': '3', - '༤': '4', - '༥': '5', - '༦': '6', - '༧': '7', - '༨': '8', - '༩': '9', - '༠': '0' - }; - - return moment.defineLocale('bo', { - months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), - weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), - weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), - longDateFormat : { - LT : 'A h:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[དི་རིང] LT', - nextDay : '[སང་ཉིན] LT', - nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', - lastDay : '[ཁ་སང] LT', - lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ལ་', - past : '%s སྔན་ལ', - s : 'ལམ་སང', - m : 'སྐར་མ་གཅིག', - mm : '%d སྐར་མ', - h : 'ཆུ་ཚོད་གཅིག', - hh : '%d ཆུ་ཚོད', - d : 'ཉིན་གཅིག', - dd : '%d ཉིན་', - M : 'ཟླ་བ་གཅིག', - MM : '%d ཟླ་བ', - y : 'ལོ་གཅིག', - yy : '%d ལོ' - }, - preparse: function (string) { - return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'མཚན་མོ'; - } else if (hour < 10) { - return 'ཞོགས་ཀས'; - } else if (hour < 17) { - return 'ཉིན་གུང'; - } else if (hour < 20) { - return 'དགོང་དག'; - } else { - return 'མཚན་མོ'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : breton (br) -// author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou - -(function (factory) { - factory(moment); -}(function (moment) { - function relativeTimeWithMutation(number, withoutSuffix, key) { - var format = { - 'mm': 'munutenn', - 'MM': 'miz', - 'dd': 'devezh' - }; - return number + ' ' + mutation(format[key], number); - } - - function specialMutationForYears(number) { - switch (lastNumber(number)) { - case 1: - case 3: - case 4: - case 5: - case 9: - return number + ' bloaz'; - default: - return number + ' vloaz'; - } - } - - function lastNumber(number) { - if (number > 9) { - return lastNumber(number % 10); - } - return number; - } - - function mutation(text, number) { - if (number === 2) { - return softMutation(text); - } - return text; - } - - function softMutation(text) { - var mutationTable = { - 'm': 'v', - 'b': 'v', - 'd': 'z' - }; - if (mutationTable[text.charAt(0)] === undefined) { - return text; - } - return mutationTable[text.charAt(0)] + text.substring(1); - } - - return moment.defineLocale('br', { - months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), - monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), - weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), - weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), - weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), - longDateFormat : { - LT : 'h[e]mm A', - L : 'DD/MM/YYYY', - LL : 'D [a viz] MMMM YYYY', - LLL : 'D [a viz] MMMM YYYY LT', - LLLL : 'dddd, D [a viz] MMMM YYYY LT' - }, - calendar : { - sameDay : '[Hiziv da] LT', - nextDay : '[Warc\'hoazh da] LT', - nextWeek : 'dddd [da] LT', - lastDay : '[Dec\'h da] LT', - lastWeek : 'dddd [paset da] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'a-benn %s', - past : '%s \'zo', - s : 'un nebeud segondennoù', - m : 'ur vunutenn', - mm : relativeTimeWithMutation, - h : 'un eur', - hh : '%d eur', - d : 'un devezh', - dd : relativeTimeWithMutation, - M : 'ur miz', - MM : relativeTimeWithMutation, - y : 'ur bloaz', - yy : specialMutationForYears - }, - ordinal : function (number) { - var output = (number === 1) ? 'añ' : 'vet'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : bosnian (bs) -// author : Nedim Cholich : https://github.com/frontyard -// based on (hr) translation by Bojan Marković - -(function (factory) { - factory(moment); -}(function (moment) { - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; - } - } - - return moment.defineLocale('bs', { - months : 'januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD. MM. YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - - nextWeek : function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[jučer u] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'par sekundi', - m : translate, - mm : translate, - h : translate, - hh : translate, - d : 'dan', - dd : translate, - M : 'mjesec', - MM : translate, - y : 'godinu', - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : catalan (ca) -// author : Juan G. Hurtado : https://github.com/juanghurtado - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ca', { - months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), - monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'), - weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), - weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), - weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay : function () { - return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextDay : function () { - return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastDay : function () { - return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'en %s', - past : 'fa %s', - s : 'uns segons', - m : 'un minut', - mm : '%d minuts', - h : 'una hora', - hh : '%d hores', - d : 'un dia', - dd : '%d dies', - M : 'un mes', - MM : '%d mesos', - y : 'un any', - yy : '%d anys' - }, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : czech (cs) -// author : petrbela : https://github.com/petrbela - -(function (factory) { - factory(moment); -}(function (moment) { - var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), - monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); - - function plural(n) { - return (n > 1) && (n < 5) && (~~(n / 10) !== 1); - } - - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'minuty' : 'minut'); - } else { - return result + 'minutami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'hodiny' : 'hodin'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'den' : 'dnem'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'dny' : 'dní'); - } else { - return result + 'dny'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'měsíce' : 'měsíců'); - } else { - return result + 'měsíci'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'roky' : 'let'); - } else { - return result + 'lety'; - } - break; - } - } - - return moment.defineLocale('cs', { - months : months, - monthsShort : monthsShort, - monthsParse : (function (months, monthsShort) { - var i, _monthsParse = []; - for (i = 0; i < 12; i++) { - // use custom parser to solve problem with July (červenec) - _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); - } - return _monthsParse; - }(months, monthsShort)), - weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), - weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), - weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), - longDateFormat : { - LT: 'H:mm', - L : 'DD. MM. YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd D. MMMM YYYY LT' - }, - calendar : { - sameDay: '[dnes v] LT', - nextDay: '[zítra v] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[v neděli v] LT'; - case 1: - case 2: - return '[v] dddd [v] LT'; - case 3: - return '[ve středu v] LT'; - case 4: - return '[ve čtvrtek v] LT'; - case 5: - return '[v pátek v] LT'; - case 6: - return '[v sobotu v] LT'; - } - }, - lastDay: '[včera v] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulou neděli v] LT'; - case 1: - case 2: - return '[minulé] dddd [v] LT'; - case 3: - return '[minulou středu v] LT'; - case 4: - case 5: - return '[minulý] dddd [v] LT'; - case 6: - return '[minulou sobotu v] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : 'před %s', - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : chuvash (cv) -// author : Anatoly Mironov : https://github.com/mirontoli - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('cv', { - months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'), - monthsShort : 'кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш'.split('_'), - weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун'.split('_'), - weekdaysShort : 'выр_тун_ытл_юн_кĕç_эрн_шăм'.split('_'), - weekdaysMin : 'вр_тн_ыт_юн_кç_эр_шм'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD-MM-YYYY', - LL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]', - LLL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT', - LLLL : 'dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT' - }, - calendar : { - sameDay: '[Паян] LT [сехетре]', - nextDay: '[Ыран] LT [сехетре]', - lastDay: '[Ĕнер] LT [сехетре]', - nextWeek: '[Çитес] dddd LT [сехетре]', - lastWeek: '[Иртнĕ] dddd LT [сехетре]', - sameElse: 'L' - }, - relativeTime : { - future : function (output) { - var affix = /сехет$/i.exec(output) ? 'рен' : /çул$/i.exec(output) ? 'тан' : 'ран'; - return output + affix; - }, - past : '%s каялла', - s : 'пĕр-ик çеккунт', - m : 'пĕр минут', - mm : '%d минут', - h : 'пĕр сехет', - hh : '%d сехет', - d : 'пĕр кун', - dd : '%d кун', - M : 'пĕр уйăх', - MM : '%d уйăх', - y : 'пĕр çул', - yy : '%d çул' - }, - ordinal : '%d-мĕш', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Welsh (cy) -// author : Robert Allen - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('cy', { - months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), - monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), - weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), - weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), - weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), - // time formats are the same as en-gb - longDateFormat: { - LT: 'HH:mm', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY LT', - LLLL: 'dddd, D MMMM YYYY LT' - }, - calendar: { - sameDay: '[Heddiw am] LT', - nextDay: '[Yfory am] LT', - nextWeek: 'dddd [am] LT', - lastDay: '[Ddoe am] LT', - lastWeek: 'dddd [diwethaf am] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'mewn %s', - past: '%s yn ôl', - s: 'ychydig eiliadau', - m: 'munud', - mm: '%d munud', - h: 'awr', - hh: '%d awr', - d: 'diwrnod', - dd: '%d diwrnod', - M: 'mis', - MM: '%d mis', - y: 'blwyddyn', - yy: '%d flynedd' - }, - // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh - ordinal: function (number) { - var b = number, - output = '', - lookup = [ - '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed - 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed - ]; - - if (b > 20) { - if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { - output = 'fed'; // not 30ain, 70ain or 90ain - } else { - output = 'ain'; - } - } else if (b > 0) { - output = lookup[b]; - } - - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : danish (da) -// author : Ulrik Nielsen : https://github.com/mrbase - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('da', { - months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd [d.] D. MMMM YYYY LT' - }, - calendar : { - sameDay : '[I dag kl.] LT', - nextDay : '[I morgen kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[I går kl.] LT', - lastWeek : '[sidste] dddd [kl] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s siden', - s : 'få sekunder', - m : 'et minut', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dage', - M : 'en måned', - MM : '%d måneder', - y : 'et år', - yy : '%d år' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : austrian german (de-at) -// author : lluchs : https://github.com/lluchs -// author: Menelion Elensúle: https://github.com/Oire -// author : Martin Groller : https://github.com/MadMG - -(function (factory) { - factory(moment); -}(function (moment) { - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - return moment.defineLocale('de-at', { - months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - longDateFormat : { - LT: 'HH:mm [Uhr]', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay: '[Heute um] LT', - sameElse: 'L', - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' - }, - relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : german (de) -// author : lluchs : https://github.com/lluchs -// author: Menelion Elensúle: https://github.com/Oire - -(function (factory) { - factory(moment); -}(function (moment) { - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - return moment.defineLocale('de', { - months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - longDateFormat : { - LT: 'HH:mm [Uhr]', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay: '[Heute um] LT', - sameElse: 'L', - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' - }, - relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : modern greek (el) -// author : Aggelos Karalias : https://github.com/mehiel - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('el', { - monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), - monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), - months : function (momentToFormat, format) { - if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' - return this._monthsGenitiveEl[momentToFormat.month()]; - } else { - return this._monthsNominativeEl[momentToFormat.month()]; - } - }, - monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), - weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), - weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), - weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'μμ' : 'ΜΜ'; - } else { - return isLower ? 'πμ' : 'ΠΜ'; - } - }, - isPM : function (input) { - return ((input + '').toLowerCase()[0] === 'μ'); - }, - meridiemParse : /[ΠΜ]\.?Μ?\.?/i, - longDateFormat : { - LT : 'h:mm A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendarEl : { - sameDay : '[Σήμερα {}] LT', - nextDay : '[Αύριο {}] LT', - nextWeek : 'dddd [{}] LT', - lastDay : '[Χθες {}] LT', - lastWeek : function () { - switch (this.day()) { - case 6: - return '[το προηγούμενο] dddd [{}] LT'; - default: - return '[την προηγούμενη] dddd [{}] LT'; - } - }, - sameElse : 'L' - }, - calendar : function (key, mom) { - var output = this._calendarEl[key], - hours = mom && mom.hours(); - - if (typeof output === 'function') { - output = output.apply(mom); - } - - return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); - }, - relativeTime : { - future : 'σε %s', - past : '%s πριν', - s : 'δευτερόλεπτα', - m : 'ένα λεπτό', - mm : '%d λεπτά', - h : 'μία ώρα', - hh : '%d ώρες', - d : 'μία μέρα', - dd : '%d μέρες', - M : 'ένας μήνας', - MM : '%d μήνες', - y : 'ένας χρόνος', - yy : '%d χρόνια' - }, - ordinal : function (number) { - return number + 'η'; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : australian english (en-au) - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('en-au', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : canadian english (en-ca) -// author : Jonathan Abourbih : https://github.com/jonbca - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('en-ca', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - L : 'YYYY-MM-DD', - LL : 'D MMMM, YYYY', - LLL : 'D MMMM, YYYY LT', - LLLL : 'dddd, D MMMM, YYYY LT' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); -})); -// moment.js locale configuration -// locale : great britain english (en-gb) -// author : Chris Gedrim : https://github.com/chrisgedrim - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('en-gb', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : esperanto (eo) -// author : Colin Dean : https://github.com/colindean -// komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko. -// Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni! - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('eo', { - months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), - weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'), - weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'), - weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'YYYY-MM-DD', - LL : 'D[-an de] MMMM, YYYY', - LLL : 'D[-an de] MMMM, YYYY LT', - LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT' - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'p.t.m.' : 'P.T.M.'; - } else { - return isLower ? 'a.t.m.' : 'A.T.M.'; - } - }, - calendar : { - sameDay : '[Hodiaŭ je] LT', - nextDay : '[Morgaŭ je] LT', - nextWeek : 'dddd [je] LT', - lastDay : '[Hieraŭ je] LT', - lastWeek : '[pasinta] dddd [je] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'je %s', - past : 'antaŭ %s', - s : 'sekundoj', - m : 'minuto', - mm : '%d minutoj', - h : 'horo', - hh : '%d horoj', - d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo - dd : '%d tagoj', - M : 'monato', - MM : '%d monatoj', - y : 'jaro', - yy : '%d jaroj' - }, - ordinal : '%da', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : spanish (es) -// author : Julio Napurí : https://github.com/julionc - -(function (factory) { - factory(moment); -}(function (moment) { - var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - return moment.defineLocale('es', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (/-MMM-/.test(format)) { - return monthsShort[m.month()]; - } else { - return monthsShortDot[m.month()]; - } - }, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY LT', - LLLL : 'dddd, D [de] MMMM [de] YYYY LT' - }, - calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'una hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un año', - yy : '%d años' - }, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : estonian (et) -// author : Henry Kehlmann : https://github.com/madhenry -// improvements : Illimar Tambek : https://github.com/ragulka - -(function (factory) { - factory(moment); -}(function (moment) { - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], - 'm' : ['ühe minuti', 'üks minut'], - 'mm': [number + ' minuti', number + ' minutit'], - 'h' : ['ühe tunni', 'tund aega', 'üks tund'], - 'hh': [number + ' tunni', number + ' tundi'], - 'd' : ['ühe päeva', 'üks päev'], - 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], - 'MM': [number + ' kuu', number + ' kuud'], - 'y' : ['ühe aasta', 'aasta', 'üks aasta'], - 'yy': [number + ' aasta', number + ' aastat'] - }; - if (withoutSuffix) { - return format[key][2] ? format[key][2] : format[key][1]; - } - return isFuture ? format[key][0] : format[key][1]; - } - - return moment.defineLocale('et', { - months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), - monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), - weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), - weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), - weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay : '[Täna,] LT', - nextDay : '[Homme,] LT', - nextWeek : '[Järgmine] dddd LT', - lastDay : '[Eile,] LT', - lastWeek : '[Eelmine] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s pärast', - past : '%s tagasi', - s : processRelativeTime, - m : processRelativeTime, - mm : processRelativeTime, - h : processRelativeTime, - hh : processRelativeTime, - d : processRelativeTime, - dd : '%d päeva', - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : euskara (eu) -// author : Eneko Illarramendi : https://github.com/eillarra - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('eu', { - months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), - monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), - weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), - weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), - weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'YYYY-MM-DD', - LL : 'YYYY[ko] MMMM[ren] D[a]', - LLL : 'YYYY[ko] MMMM[ren] D[a] LT', - LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT', - l : 'YYYY-M-D', - ll : 'YYYY[ko] MMM D[a]', - lll : 'YYYY[ko] MMM D[a] LT', - llll : 'ddd, YYYY[ko] MMM D[a] LT' - }, - calendar : { - sameDay : '[gaur] LT[etan]', - nextDay : '[bihar] LT[etan]', - nextWeek : 'dddd LT[etan]', - lastDay : '[atzo] LT[etan]', - lastWeek : '[aurreko] dddd LT[etan]', - sameElse : 'L' - }, - relativeTime : { - future : '%s barru', - past : 'duela %s', - s : 'segundo batzuk', - m : 'minutu bat', - mm : '%d minutu', - h : 'ordu bat', - hh : '%d ordu', - d : 'egun bat', - dd : '%d egun', - M : 'hilabete bat', - MM : '%d hilabete', - y : 'urte bat', - yy : '%d urte' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Persian (fa) -// author : Ebrahim Byagowi : https://github.com/ebraminio - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '۱', - '2': '۲', - '3': '۳', - '4': '۴', - '5': '۵', - '6': '۶', - '7': '۷', - '8': '۸', - '9': '۹', - '0': '۰' - }, numberMap = { - '۱': '1', - '۲': '2', - '۳': '3', - '۴': '4', - '۵': '5', - '۶': '6', - '۷': '7', - '۸': '8', - '۹': '9', - '۰': '0' - }; - - return moment.defineLocale('fa', { - months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'قبل از ظهر'; - } else { - return 'بعد از ظهر'; - } - }, - calendar : { - sameDay : '[امروز ساعت] LT', - nextDay : '[فردا ساعت] LT', - nextWeek : 'dddd [ساعت] LT', - lastDay : '[دیروز ساعت] LT', - lastWeek : 'dddd [پیش] [ساعت] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'در %s', - past : '%s پیش', - s : 'چندین ثانیه', - m : 'یک دقیقه', - mm : '%d دقیقه', - h : 'یک ساعت', - hh : '%d ساعت', - d : 'یک روز', - dd : '%d روز', - M : 'یک ماه', - MM : '%d ماه', - y : 'یک سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); - }, - ordinal : '%dم', - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : finnish (fi) -// author : Tarmo Aidantausta : https://github.com/bleadof - -(function (factory) { - factory(moment); -}(function (moment) { - var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), - numbersFuture = [ - 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', - numbersPast[7], numbersPast[8], numbersPast[9] - ]; - - function translate(number, withoutSuffix, key, isFuture) { - var result = ''; - switch (key) { - case 's': - return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; - case 'm': - return isFuture ? 'minuutin' : 'minuutti'; - case 'mm': - result = isFuture ? 'minuutin' : 'minuuttia'; - break; - case 'h': - return isFuture ? 'tunnin' : 'tunti'; - case 'hh': - result = isFuture ? 'tunnin' : 'tuntia'; - break; - case 'd': - return isFuture ? 'päivän' : 'päivä'; - case 'dd': - result = isFuture ? 'päivän' : 'päivää'; - break; - case 'M': - return isFuture ? 'kuukauden' : 'kuukausi'; - case 'MM': - result = isFuture ? 'kuukauden' : 'kuukautta'; - break; - case 'y': - return isFuture ? 'vuoden' : 'vuosi'; - case 'yy': - result = isFuture ? 'vuoden' : 'vuotta'; - break; - } - result = verbalNumber(number, isFuture) + ' ' + result; - return result; - } - - function verbalNumber(number, isFuture) { - return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; - } - - return moment.defineLocale('fi', { - months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), - monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), - weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), - weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), - weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), - longDateFormat : { - LT : 'HH.mm', - L : 'DD.MM.YYYY', - LL : 'Do MMMM[ta] YYYY', - LLL : 'Do MMMM[ta] YYYY, [klo] LT', - LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT', - l : 'D.M.YYYY', - ll : 'Do MMM YYYY', - lll : 'Do MMM YYYY, [klo] LT', - llll : 'ddd, Do MMM YYYY, [klo] LT' - }, - calendar : { - sameDay : '[tänään] [klo] LT', - nextDay : '[huomenna] [klo] LT', - nextWeek : 'dddd [klo] LT', - lastDay : '[eilen] [klo] LT', - lastWeek : '[viime] dddd[na] [klo] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s päästä', - past : '%s sitten', - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : faroese (fo) -// author : Ragnar Johannesen : https://github.com/ragnar123 - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('fo', { - months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), - weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), - weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D. MMMM, YYYY LT' - }, - calendar : { - sameDay : '[Í dag kl.] LT', - nextDay : '[Í morgin kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[Í gjár kl.] LT', - lastWeek : '[síðstu] dddd [kl] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'um %s', - past : '%s síðani', - s : 'fá sekund', - m : 'ein minutt', - mm : '%d minuttir', - h : 'ein tími', - hh : '%d tímar', - d : 'ein dagur', - dd : '%d dagar', - M : 'ein mánaði', - MM : '%d mánaðir', - y : 'eitt ár', - yy : '%d ár' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : canadian french (fr-ca) -// author : Jonathan Abourbih : https://github.com/jonbca - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('fr-ca', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[Aujourd\'hui à] LT', - nextDay: '[Demain à] LT', - nextWeek: 'dddd [à] LT', - lastDay: '[Hier à] LT', - lastWeek: 'dddd [dernier à] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - ordinal : function (number) { - return number + (number === 1 ? 'er' : ''); - } - }); -})); -// moment.js locale configuration -// locale : french (fr) -// author : John Fischer : https://github.com/jfroffice - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('fr', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[Aujourd\'hui à] LT', - nextDay: '[Demain à] LT', - nextWeek: 'dddd [à] LT', - lastDay: '[Hier à] LT', - lastWeek: 'dddd [dernier à] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - ordinal : function (number) { - return number + (number === 1 ? 'er' : ''); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : galician (gl) -// author : Juan G. Hurtado : https://github.com/juanghurtado - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('gl', { - months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'), - monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'), - weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'), - weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'), - weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay : function () { - return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextDay : function () { - return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextWeek : function () { - return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - lastDay : function () { - return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; - }, - lastWeek : function () { - return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : function (str) { - if (str === 'uns segundos') { - return 'nuns segundos'; - } - return 'en ' + str; - }, - past : 'hai %s', - s : 'uns segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'unha hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un ano', - yy : '%d anos' - }, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Hebrew (he) -// author : Tomer Cohen : https://github.com/tomer -// author : Moshe Simantov : https://github.com/DevelopmentIL -// author : Tal Ater : https://github.com/TalAter - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('he', { - months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), - monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), - weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), - weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), - weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D [ב]MMMM YYYY', - LLL : 'D [ב]MMMM YYYY LT', - LLLL : 'dddd, D [ב]MMMM YYYY LT', - l : 'D/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY LT', - llll : 'ddd, D MMM YYYY LT' - }, - calendar : { - sameDay : '[היום ב־]LT', - nextDay : '[מחר ב־]LT', - nextWeek : 'dddd [בשעה] LT', - lastDay : '[אתמול ב־]LT', - lastWeek : '[ביום] dddd [האחרון בשעה] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'בעוד %s', - past : 'לפני %s', - s : 'מספר שניות', - m : 'דקה', - mm : '%d דקות', - h : 'שעה', - hh : function (number) { - if (number === 2) { - return 'שעתיים'; - } - return number + ' שעות'; - }, - d : 'יום', - dd : function (number) { - if (number === 2) { - return 'יומיים'; - } - return number + ' ימים'; - }, - M : 'חודש', - MM : function (number) { - if (number === 2) { - return 'חודשיים'; - } - return number + ' חודשים'; - }, - y : 'שנה', - yy : function (number) { - if (number === 2) { - return 'שנתיים'; - } - return number + ' שנים'; - } - } - }); -})); -// moment.js locale configuration -// locale : hindi (hi) -// author : Mayank Singhal : https://github.com/mayanksinghal - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - return moment.defineLocale('hi', { - months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), - monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), - weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), - longDateFormat : { - LT : 'A h:mm बजे', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[कल] LT', - nextWeek : 'dddd, LT', - lastDay : '[कल] LT', - lastWeek : '[पिछले] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s में', - past : '%s पहले', - s : 'कुछ ही क्षण', - m : 'एक मिनट', - mm : '%d मिनट', - h : 'एक घंटा', - hh : '%d घंटे', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महीने', - MM : '%d महीने', - y : 'एक वर्ष', - yy : '%d वर्ष' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - // Hindi notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'रात'; - } else if (hour < 10) { - return 'सुबह'; - } else if (hour < 17) { - return 'दोपहर'; - } else if (hour < 20) { - return 'शाम'; - } else { - return 'रात'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : hrvatski (hr) -// author : Bojan Marković : https://github.com/bmarkovic - -// based on (sl) translation by Robert Sedovšek - -(function (factory) { - factory(moment); -}(function (moment) { - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; - } - } - - return moment.defineLocale('hr', { - months : 'sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'), - monthsShort : 'sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD. MM. YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - - nextWeek : function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[jučer u] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'par sekundi', - m : translate, - mm : translate, - h : translate, - hh : translate, - d : 'dan', - dd : translate, - M : 'mjesec', - MM : translate, - y : 'godinu', - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : hungarian (hu) -// author : Adam Brunner : https://github.com/adambrunner - -(function (factory) { - factory(moment); -}(function (moment) { - var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); - - function translate(number, withoutSuffix, key, isFuture) { - var num = number, - suffix; - - switch (key) { - case 's': - return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; - case 'm': - return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'mm': - return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'h': - return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'hh': - return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'd': - return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'dd': - return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'M': - return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'MM': - return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'y': - return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); - case 'yy': - return num + (isFuture || withoutSuffix ? ' év' : ' éve'); - } - - return ''; - } - - function week(isFuture) { - return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; - } - - return moment.defineLocale('hu', { - months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), - monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), - weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), - weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), - weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'YYYY.MM.DD.', - LL : 'YYYY. MMMM D.', - LLL : 'YYYY. MMMM D., LT', - LLLL : 'YYYY. MMMM D., dddd LT' - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower === true ? 'de' : 'DE'; - } else { - return isLower === true ? 'du' : 'DU'; - } - }, - calendar : { - sameDay : '[ma] LT[-kor]', - nextDay : '[holnap] LT[-kor]', - nextWeek : function () { - return week.call(this, true); - }, - lastDay : '[tegnap] LT[-kor]', - lastWeek : function () { - return week.call(this, false); - }, - sameElse : 'L' - }, - relativeTime : { - future : '%s múlva', - past : '%s', - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Armenian (hy-am) -// author : Armendarabyan : https://github.com/armendarabyan - -(function (factory) { - factory(moment); -}(function (moment) { - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'), - 'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_') - }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function monthsShortCaseReplace(m, format) { - var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'); - - return monthsShort[m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'); - - return weekdays[m.day()]; - } - - return moment.defineLocale('hy-am', { - months : monthsCaseReplace, - monthsShort : monthsShortCaseReplace, - weekdays : weekdaysCaseReplace, - weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), - weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY թ.', - LLL : 'D MMMM YYYY թ., LT', - LLLL : 'dddd, D MMMM YYYY թ., LT' - }, - calendar : { - sameDay: '[այսօր] LT', - nextDay: '[վաղը] LT', - lastDay: '[երեկ] LT', - nextWeek: function () { - return 'dddd [օրը ժամը] LT'; - }, - lastWeek: function () { - return '[անցած] dddd [օրը ժամը] LT'; - }, - sameElse: 'L' - }, - relativeTime : { - future : '%s հետո', - past : '%s առաջ', - s : 'մի քանի վայրկյան', - m : 'րոպե', - mm : '%d րոպե', - h : 'ժամ', - hh : '%d ժամ', - d : 'օր', - dd : '%d օր', - M : 'ամիս', - MM : '%d ամիս', - y : 'տարի', - yy : '%d տարի' - }, - - meridiem : function (hour) { - if (hour < 4) { - return 'գիշերվա'; - } else if (hour < 12) { - return 'առավոտվա'; - } else if (hour < 17) { - return 'ցերեկվա'; - } else { - return 'երեկոյան'; - } - }, - - ordinal: function (number, period) { - switch (period) { - case 'DDD': - case 'w': - case 'W': - case 'DDDo': - if (number === 1) { - return number + '-ին'; - } - return number + '-րդ'; - default: - return number; - } - }, - - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Bahasa Indonesia (id) -// author : Mohammad Satrio Utomo : https://github.com/tyok -// reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('id', { - months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), - weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), - weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] LT', - LLLL : 'dddd, D MMMM YYYY [pukul] LT' - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'siang'; - } else if (hours < 19) { - return 'sore'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Besok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kemarin pukul] LT', - lastWeek : 'dddd [lalu pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lalu', - s : 'beberapa detik', - m : 'semenit', - mm : '%d menit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : icelandic (is) -// author : Hinrik Örn Sigurðsson : https://github.com/hinrik - -(function (factory) { - factory(moment); -}(function (moment) { - function plural(n) { - if (n % 100 === 11) { - return true; - } else if (n % 10 === 1) { - return false; - } - return true; - } - - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; - case 'm': - return withoutSuffix ? 'mínúta' : 'mínútu'; - case 'mm': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); - } else if (withoutSuffix) { - return result + 'mínúta'; - } - return result + 'mínútu'; - case 'hh': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); - } - return result + 'klukkustund'; - case 'd': - if (withoutSuffix) { - return 'dagur'; - } - return isFuture ? 'dag' : 'degi'; - case 'dd': - if (plural(number)) { - if (withoutSuffix) { - return result + 'dagar'; - } - return result + (isFuture ? 'daga' : 'dögum'); - } else if (withoutSuffix) { - return result + 'dagur'; - } - return result + (isFuture ? 'dag' : 'degi'); - case 'M': - if (withoutSuffix) { - return 'mánuður'; - } - return isFuture ? 'mánuð' : 'mánuði'; - case 'MM': - if (plural(number)) { - if (withoutSuffix) { - return result + 'mánuðir'; - } - return result + (isFuture ? 'mánuði' : 'mánuðum'); - } else if (withoutSuffix) { - return result + 'mánuður'; - } - return result + (isFuture ? 'mánuð' : 'mánuði'); - case 'y': - return withoutSuffix || isFuture ? 'ár' : 'ári'; - case 'yy': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); - } - return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); - } - } - - return moment.defineLocale('is', { - months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), - weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), - weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), - weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD/MM/YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] LT', - LLLL : 'dddd, D. MMMM YYYY [kl.] LT' - }, - calendar : { - sameDay : '[í dag kl.] LT', - nextDay : '[á morgun kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[í gær kl.] LT', - lastWeek : '[síðasta] dddd [kl.] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'eftir %s', - past : 'fyrir %s síðan', - s : translate, - m : translate, - mm : translate, - h : 'klukkustund', - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : italian (it) -// author : Lorenzo : https://github.com/aliem -// author: Mattia Larentis: https://github.com/nostalgiaz - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('it', { - months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), - monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), - weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'), - weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'), - weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay: '[Oggi alle] LT', - nextDay: '[Domani alle] LT', - nextWeek: 'dddd [alle] LT', - lastDay: '[Ieri alle] LT', - lastWeek: '[lo scorso] dddd [alle] LT', - sameElse: 'L' - }, - relativeTime : { - future : function (s) { - return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; - }, - past : '%s fa', - s : 'alcuni secondi', - m : 'un minuto', - mm : '%d minuti', - h : 'un\'ora', - hh : '%d ore', - d : 'un giorno', - dd : '%d giorni', - M : 'un mese', - MM : '%d mesi', - y : 'un anno', - yy : '%d anni' - }, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : japanese (ja) -// author : LI Long : https://github.com/baryon - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ja', { - months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), - weekdaysShort : '日_月_火_水_木_金_土'.split('_'), - weekdaysMin : '日_月_火_水_木_金_土'.split('_'), - longDateFormat : { - LT : 'Ah時m分', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日LT', - LLLL : 'YYYY年M月D日LT dddd' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return '午前'; - } else { - return '午後'; - } - }, - calendar : { - sameDay : '[今日] LT', - nextDay : '[明日] LT', - nextWeek : '[来週]dddd LT', - lastDay : '[昨日] LT', - lastWeek : '[前週]dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s後', - past : '%s前', - s : '数秒', - m : '1分', - mm : '%d分', - h : '1時間', - hh : '%d時間', - d : '1日', - dd : '%d日', - M : '1ヶ月', - MM : '%dヶ月', - y : '1年', - yy : '%d年' - } - }); -})); -// moment.js locale configuration -// locale : Georgian (ka) -// author : Irakli Janiashvili : https://github.com/irakli-janiashvili - -(function (factory) { - factory(moment); -}(function (moment) { - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), - 'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') - }, - - nounCase = (/D[oD] *MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), - 'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_') - }, - - nounCase = (/(წინა|შემდეგ)/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('ka', { - months : monthsCaseReplace, - monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), - weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), - longDateFormat : { - LT : 'h:mm A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[დღეს] LT[-ზე]', - nextDay : '[ხვალ] LT[-ზე]', - lastDay : '[გუშინ] LT[-ზე]', - nextWeek : '[შემდეგ] dddd LT[-ზე]', - lastWeek : '[წინა] dddd LT-ზე', - sameElse : 'L' - }, - relativeTime : { - future : function (s) { - return (/(წამი|წუთი|საათი|წელი)/).test(s) ? - s.replace(/ი$/, 'ში') : - s + 'ში'; - }, - past : function (s) { - if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { - return s.replace(/(ი|ე)$/, 'ის წინ'); - } - if ((/წელი/).test(s)) { - return s.replace(/წელი$/, 'წლის წინ'); - } - }, - s : 'რამდენიმე წამი', - m : 'წუთი', - mm : '%d წუთი', - h : 'საათი', - hh : '%d საათი', - d : 'დღე', - dd : '%d დღე', - M : 'თვე', - MM : '%d თვე', - y : 'წელი', - yy : '%d წელი' - }, - ordinal : function (number) { - if (number === 0) { - return number; - } - - if (number === 1) { - return number + '-ლი'; - } - - if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { - return 'მე-' + number; - } - - return number + '-ე'; - }, - week : { - dow : 1, - doy : 7 - } - }); -})); -// moment.js locale configuration -// locale : khmer (km) -// author : Kruy Vanna : https://github.com/kruyvanna - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('km', { - months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), - monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), - weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), - weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), - weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), - longDateFormat: { - LT: 'HH:mm', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY LT', - LLLL: 'dddd, D MMMM YYYY LT' - }, - calendar: { - sameDay: '[ថ្ងៃនៈ ម៉ោង] LT', - nextDay: '[ស្អែក ម៉ោង] LT', - nextWeek: 'dddd [ម៉ោង] LT', - lastDay: '[ម្សិលមិញ ម៉ោង] LT', - lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', - sameElse: 'L' - }, - relativeTime: { - future: '%sទៀត', - past: '%sមុន', - s: 'ប៉ុន្មានវិនាទី', - m: 'មួយនាទី', - mm: '%d នាទី', - h: 'មួយម៉ោង', - hh: '%d ម៉ោង', - d: 'មួយថ្ងៃ', - dd: '%d ថ្ងៃ', - M: 'មួយខែ', - MM: '%d ខែ', - y: 'មួយឆ្នាំ', - yy: '%d ឆ្នាំ' - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : korean (ko) -// -// authors -// -// - Kyungwook, Park : https://github.com/kyungw00k -// - Jeeeyul Lee -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ko', { - months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), - weekdaysShort : '일_월_화_수_목_금_토'.split('_'), - weekdaysMin : '일_월_화_수_목_금_토'.split('_'), - longDateFormat : { - LT : 'A h시 m분', - L : 'YYYY.MM.DD', - LL : 'YYYY년 MMMM D일', - LLL : 'YYYY년 MMMM D일 LT', - LLLL : 'YYYY년 MMMM D일 dddd LT' - }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; - }, - calendar : { - sameDay : '오늘 LT', - nextDay : '내일 LT', - nextWeek : 'dddd LT', - lastDay : '어제 LT', - lastWeek : '지난주 dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s 후', - past : '%s 전', - s : '몇초', - ss : '%d초', - m : '일분', - mm : '%d분', - h : '한시간', - hh : '%d시간', - d : '하루', - dd : '%d일', - M : '한달', - MM : '%d달', - y : '일년', - yy : '%d년' - }, - ordinal : '%d일', - meridiemParse : /(오전|오후)/, - isPM : function (token) { - return token === '오후'; - } - }); -})); -// moment.js locale configuration -// locale : Luxembourgish (lb) -// author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz - -// Note: Luxembourgish has a very particular phonological rule ('Eifeler Regel') that causes the -// deletion of the final 'n' in certain contexts. That's what the 'eifelerRegelAppliesToWeekday' -// and 'eifelerRegelAppliesToNumber' methods are meant for - -(function (factory) { - factory(moment); -}(function (moment) { - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eng Minutt', 'enger Minutt'], - 'h': ['eng Stonn', 'enger Stonn'], - 'd': ['een Dag', 'engem Dag'], - 'M': ['ee Mount', 'engem Mount'], - 'y': ['ee Joer', 'engem Joer'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - function processFutureTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'a ' + string; - } - return 'an ' + string; - } - - function processPastTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'viru ' + string; - } - return 'virun ' + string; - } - - /** - * Returns true if the word before the given number loses the '-n' ending. - * e.g. 'an 10 Deeg' but 'a 5 Deeg' - * - * @param number {integer} - * @returns {boolean} - */ - function eifelerRegelAppliesToNumber(number) { - number = parseInt(number, 10); - if (isNaN(number)) { - return false; - } - if (number < 0) { - // Negative Number --> always true - return true; - } else if (number < 10) { - // Only 1 digit - if (4 <= number && number <= 7) { - return true; - } - return false; - } else if (number < 100) { - // 2 digits - var lastDigit = number % 10, firstDigit = number / 10; - if (lastDigit === 0) { - return eifelerRegelAppliesToNumber(firstDigit); - } - return eifelerRegelAppliesToNumber(lastDigit); - } else if (number < 10000) { - // 3 or 4 digits --> recursively check first digit - while (number >= 10) { - number = number / 10; - } - return eifelerRegelAppliesToNumber(number); - } else { - // Anything larger than 4 digits: recursively check first n-3 digits - number = number / 1000; - return eifelerRegelAppliesToNumber(number); - } - } - - return moment.defineLocale('lb', { - months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), - weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), - weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), - weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), - longDateFormat: { - LT: 'H:mm [Auer]', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY LT', - LLLL: 'dddd, D. MMMM YYYY LT' - }, - calendar: { - sameDay: '[Haut um] LT', - sameElse: 'L', - nextDay: '[Muer um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gëschter um] LT', - lastWeek: function () { - // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule - switch (this.day()) { - case 2: - case 4: - return '[Leschten] dddd [um] LT'; - default: - return '[Leschte] dddd [um] LT'; - } - } - }, - relativeTime : { - future : processFutureTime, - past : processPastTime, - s : 'e puer Sekonnen', - m : processRelativeTime, - mm : '%d Minutten', - h : processRelativeTime, - hh : '%d Stonnen', - d : processRelativeTime, - dd : '%d Deeg', - M : processRelativeTime, - MM : '%d Méint', - y : processRelativeTime, - yy : '%d Joer' - }, - ordinal: '%d.', - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Lithuanian (lt) -// author : Mindaugas Mozūras : https://github.com/mmozuras - -(function (factory) { - factory(moment); -}(function (moment) { - var units = { - 'm' : 'minutė_minutės_minutę', - 'mm': 'minutės_minučių_minutes', - 'h' : 'valanda_valandos_valandą', - 'hh': 'valandos_valandų_valandas', - 'd' : 'diena_dienos_dieną', - 'dd': 'dienos_dienų_dienas', - 'M' : 'mėnuo_mėnesio_mėnesį', - 'MM': 'mėnesiai_mėnesių_mėnesius', - 'y' : 'metai_metų_metus', - 'yy': 'metai_metų_metus' - }, - weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'); - - function translateSeconds(number, withoutSuffix, key, isFuture) { - if (withoutSuffix) { - return 'kelios sekundės'; - } else { - return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; - } - } - - function translateSingular(number, withoutSuffix, key, isFuture) { - return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); - } - - function special(number) { - return number % 10 === 0 || (number > 10 && number < 20); - } - - function forms(key) { - return units[key].split('_'); - } - - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - if (number === 1) { - return result + translateSingular(number, withoutSuffix, key[0], isFuture); - } else if (withoutSuffix) { - return result + (special(number) ? forms(key)[1] : forms(key)[0]); - } else { - if (isFuture) { - return result + forms(key)[1]; - } else { - return result + (special(number) ? forms(key)[1] : forms(key)[2]); - } - } - } - - function relativeWeekDay(moment, format) { - var nominative = format.indexOf('dddd HH:mm') === -1, - weekDay = weekDays[moment.day()]; - - return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į'; - } - - return moment.defineLocale('lt', { - months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), - monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), - weekdays : relativeWeekDay, - weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), - weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'YYYY-MM-DD', - LL : 'YYYY [m.] MMMM D [d.]', - LLL : 'YYYY [m.] MMMM D [d.], LT [val.]', - LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]', - l : 'YYYY-MM-DD', - ll : 'YYYY [m.] MMMM D [d.]', - lll : 'YYYY [m.] MMMM D [d.], LT [val.]', - llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]' - }, - calendar : { - sameDay : '[Šiandien] LT', - nextDay : '[Rytoj] LT', - nextWeek : 'dddd LT', - lastDay : '[Vakar] LT', - lastWeek : '[Praėjusį] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : 'po %s', - past : 'prieš %s', - s : translateSeconds, - m : translateSingular, - mm : translate, - h : translateSingular, - hh : translate, - d : translateSingular, - dd : translate, - M : translateSingular, - MM : translate, - y : translateSingular, - yy : translate - }, - ordinal : function (number) { - return number + '-oji'; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : latvian (lv) -// author : Kristaps Karlsons : https://github.com/skakri - -(function (factory) { - factory(moment); -}(function (moment) { - var units = { - 'mm': 'minūti_minūtes_minūte_minūtes', - 'hh': 'stundu_stundas_stunda_stundas', - 'dd': 'dienu_dienas_diena_dienas', - 'MM': 'mēnesi_mēnešus_mēnesis_mēneši', - 'yy': 'gadu_gadus_gads_gadi' - }; - - function format(word, number, withoutSuffix) { - var forms = word.split('_'); - if (withoutSuffix) { - return number % 10 === 1 && number !== 11 ? forms[2] : forms[3]; - } else { - return number % 10 === 1 && number !== 11 ? forms[0] : forms[1]; - } - } - - function relativeTimeWithPlural(number, withoutSuffix, key) { - return number + ' ' + format(units[key], number, withoutSuffix); - } - - return moment.defineLocale('lv', { - months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), - weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), - weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'YYYY. [gada] D. MMMM', - LLL : 'YYYY. [gada] D. MMMM, LT', - LLLL : 'YYYY. [gada] D. MMMM, dddd, LT' - }, - calendar : { - sameDay : '[Šodien pulksten] LT', - nextDay : '[Rīt pulksten] LT', - nextWeek : 'dddd [pulksten] LT', - lastDay : '[Vakar pulksten] LT', - lastWeek : '[Pagājušā] dddd [pulksten] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s vēlāk', - past : '%s agrāk', - s : 'dažas sekundes', - m : 'minūti', - mm : relativeTimeWithPlural, - h : 'stundu', - hh : relativeTimeWithPlural, - d : 'dienu', - dd : relativeTimeWithPlural, - M : 'mēnesi', - MM : relativeTimeWithPlural, - y : 'gadu', - yy : relativeTimeWithPlural - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : macedonian (mk) -// author : Borislav Mickov : https://github.com/B0k0 - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('mk', { - months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), - weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), - weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Денес во] LT', - nextDay : '[Утре во] LT', - nextWeek : 'dddd [во] LT', - lastDay : '[Вчера во] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[Во изминатата] dddd [во] LT'; - case 1: - case 2: - case 4: - case 5: - return '[Во изминатиот] dddd [во] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'после %s', - past : 'пред %s', - s : 'неколку секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дена', - M : 'месец', - MM : '%d месеци', - y : 'година', - yy : '%d години' - }, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; - } else { - return number + '-ти'; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : malayalam (ml) -// author : Floyd Pink : https://github.com/floydpink - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ml', { - months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), - monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), - weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), - weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), - weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), - longDateFormat : { - LT : 'A h:mm -നു', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[ഇന്ന്] LT', - nextDay : '[നാളെ] LT', - nextWeek : 'dddd, LT', - lastDay : '[ഇന്നലെ] LT', - lastWeek : '[കഴിഞ്ഞ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s കഴിഞ്ഞ്', - past : '%s മുൻപ്', - s : 'അൽപ നിമിഷങ്ങൾ', - m : 'ഒരു മിനിറ്റ്', - mm : '%d മിനിറ്റ്', - h : 'ഒരു മണിക്കൂർ', - hh : '%d മണിക്കൂർ', - d : 'ഒരു ദിവസം', - dd : '%d ദിവസം', - M : 'ഒരു മാസം', - MM : '%d മാസം', - y : 'ഒരു വർഷം', - yy : '%d വർഷം' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'രാത്രി'; - } else if (hour < 12) { - return 'രാവിലെ'; - } else if (hour < 17) { - return 'ഉച്ച കഴിഞ്ഞ്'; - } else if (hour < 20) { - return 'വൈകുന്നേരം'; - } else { - return 'രാത്രി'; - } - } - }); -})); -// moment.js locale configuration -// locale : Marathi (mr) -// author : Harshad Kale : https://github.com/kalehv - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - return moment.defineLocale('mr', { - months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), - monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), - weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), - longDateFormat : { - LT : 'A h:mm वाजता', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[उद्या] LT', - nextWeek : 'dddd, LT', - lastDay : '[काल] LT', - lastWeek: '[मागील] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s नंतर', - past : '%s पूर्वी', - s : 'सेकंद', - m: 'एक मिनिट', - mm: '%d मिनिटे', - h : 'एक तास', - hh : '%d तास', - d : 'एक दिवस', - dd : '%d दिवस', - M : 'एक महिना', - MM : '%d महिने', - y : 'एक वर्ष', - yy : '%d वर्षे' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiem: function (hour, minute, isLower) - { - if (hour < 4) { - return 'रात्री'; - } else if (hour < 10) { - return 'सकाळी'; - } else if (hour < 17) { - return 'दुपारी'; - } else if (hour < 20) { - return 'सायंकाळी'; - } else { - return 'रात्री'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Bahasa Malaysia (ms-MY) -// author : Weldan Jamili : https://github.com/weldan - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('ms-my', { - months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), - weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), - weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), - weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] LT', - LLLL : 'dddd, D MMMM YYYY [pukul] LT' - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'tengahari'; - } else if (hours < 19) { - return 'petang'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Esok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kelmarin pukul] LT', - lastWeek : 'dddd [lepas pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lepas', - s : 'beberapa saat', - m : 'seminit', - mm : '%d minit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Burmese (my) -// author : Squar team, mysquar.com - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '၁', - '2': '၂', - '3': '၃', - '4': '၄', - '5': '၅', - '6': '၆', - '7': '၇', - '8': '၈', - '9': '၉', - '0': '၀' - }, numberMap = { - '၁': '1', - '၂': '2', - '၃': '3', - '၄': '4', - '၅': '5', - '၆': '6', - '၇': '7', - '၈': '8', - '၉': '9', - '၀': '0' - }; - return moment.defineLocale('my', { - months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), - monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), - weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), - weekdaysShort: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - weekdaysMin: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - longDateFormat: { - LT: 'HH:mm', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY LT', - LLLL: 'dddd D MMMM YYYY LT' - }, - calendar: { - sameDay: '[ယနေ.] LT [မှာ]', - nextDay: '[မနက်ဖြန်] LT [မှာ]', - nextWeek: 'dddd LT [မှာ]', - lastDay: '[မနေ.က] LT [မှာ]', - lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', - sameElse: 'L' - }, - relativeTime: { - future: 'လာမည့် %s မှာ', - past: 'လွန်ခဲ့သော %s က', - s: 'စက္ကန်.အနည်းငယ်', - m: 'တစ်မိနစ်', - mm: '%d မိနစ်', - h: 'တစ်နာရီ', - hh: '%d နာရီ', - d: 'တစ်ရက်', - dd: '%d ရက်', - M: 'တစ်လ', - MM: '%d လ', - y: 'တစ်နှစ်', - yy: '%d နှစ်' - }, - preparse: function (string) { - return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : norwegian bokmål (nb) -// authors : Espen Hovlandsdal : https://github.com/rexxars -// Sigurd Gartmann : https://github.com/sigurdga - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('nb', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'H.mm', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] LT', - LLLL : 'dddd D. MMMM YYYY [kl.] LT' - }, - calendar : { - sameDay: '[i dag kl.] LT', - nextDay: '[i morgen kl.] LT', - nextWeek: 'dddd [kl.] LT', - lastDay: '[i går kl.] LT', - lastWeek: '[forrige] dddd [kl.] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : 'for %s siden', - s : 'noen sekunder', - m : 'ett minutt', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dager', - M : 'en måned', - MM : '%d måneder', - y : 'ett år', - yy : '%d år' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : nepali/nepalese -// author : suvash : https://github.com/suvash - -(function (factory) { - factory(moment); -}(function (moment) { - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - return moment.defineLocale('ne', { - months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), - monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), - weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), - weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), - weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'), - longDateFormat : { - LT : 'Aको h:mm बजे', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 3) { - return 'राती'; - } else if (hour < 10) { - return 'बिहान'; - } else if (hour < 15) { - return 'दिउँसो'; - } else if (hour < 18) { - return 'बेलुका'; - } else if (hour < 20) { - return 'साँझ'; - } else { - return 'राती'; - } - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[भोली] LT', - nextWeek : '[आउँदो] dddd[,] LT', - lastDay : '[हिजो] LT', - lastWeek : '[गएको] dddd[,] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%sमा', - past : '%s अगाडी', - s : 'केही समय', - m : 'एक मिनेट', - mm : '%d मिनेट', - h : 'एक घण्टा', - hh : '%d घण्टा', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महिना', - MM : '%d महिना', - y : 'एक बर्ष', - yy : '%d बर्ष' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : dutch (nl) -// author : Joris Röling : https://github.com/jjupiter - -(function (factory) { - factory(moment); -}(function (moment) { - var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); - - return moment.defineLocale('nl', { - months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), - monthsShort : function (m, format) { - if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), - weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), - weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[vandaag om] LT', - nextDay: '[morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'over %s', - past : '%s geleden', - s : 'een paar seconden', - m : 'één minuut', - mm : '%d minuten', - h : 'één uur', - hh : '%d uur', - d : 'één dag', - dd : '%d dagen', - M : 'één maand', - MM : '%d maanden', - y : 'één jaar', - yy : '%d jaar' - }, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : norwegian nynorsk (nn) -// author : https://github.com/mechuwind - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('nn', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), - weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), - weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[I dag klokka] LT', - nextDay: '[I morgon klokka] LT', - nextWeek: 'dddd [klokka] LT', - lastDay: '[I går klokka] LT', - lastWeek: '[Føregåande] dddd [klokka] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : 'for %s sidan', - s : 'nokre sekund', - m : 'eit minutt', - mm : '%d minutt', - h : 'ein time', - hh : '%d timar', - d : 'ein dag', - dd : '%d dagar', - M : 'ein månad', - MM : '%d månader', - y : 'eit år', - yy : '%d år' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : polish (pl) -// author : Rafal Hirsz : https://github.com/evoL - -(function (factory) { - factory(moment); -}(function (moment) { - var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), - monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); - - function plural(n) { - return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); - } - - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'm': - return withoutSuffix ? 'minuta' : 'minutę'; - case 'mm': - return result + (plural(number) ? 'minuty' : 'minut'); - case 'h': - return withoutSuffix ? 'godzina' : 'godzinę'; - case 'hh': - return result + (plural(number) ? 'godziny' : 'godzin'); - case 'MM': - return result + (plural(number) ? 'miesiące' : 'miesięcy'); - case 'yy': - return result + (plural(number) ? 'lata' : 'lat'); - } - } - - return moment.defineLocale('pl', { - months : function (momentToFormat, format) { - if (/D MMMM/.test(format)) { - return monthsSubjective[momentToFormat.month()]; - } else { - return monthsNominative[momentToFormat.month()]; - } - }, - monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), - weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), - weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'), - weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay: '[Dziś o] LT', - nextDay: '[Jutro o] LT', - nextWeek: '[W] dddd [o] LT', - lastDay: '[Wczoraj o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[W zeszłą niedzielę o] LT'; - case 3: - return '[W zeszłą środę o] LT'; - case 6: - return '[W zeszłą sobotę o] LT'; - default: - return '[W zeszły] dddd [o] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : '%s temu', - s : 'kilka sekund', - m : translate, - mm : translate, - h : translate, - hh : translate, - d : '1 dzień', - dd : '%d dni', - M : 'miesiąc', - MM : translate, - y : 'rok', - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : brazilian portuguese (pt-br) -// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('pt-br', { - months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), - monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), - weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'), - weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'), - weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY [às] LT', - LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : '%s atrás', - s : 'segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - ordinal : '%dº' - }); -})); -// moment.js locale configuration -// locale : portuguese (pt) -// author : Jefferson : https://github.com/jalex79 - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('pt', { - months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), - monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), - weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'), - weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'), - weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY LT', - LLLL : 'dddd, D [de] MMMM [de] YYYY LT' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : 'há %s', - s : 'segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : romanian (ro) -// author : Vlad Gurdiga : https://github.com/gurdiga -// author : Valentin Agachi : https://github.com/avaly - -(function (factory) { - factory(moment); -}(function (moment) { - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'mm': 'minute', - 'hh': 'ore', - 'dd': 'zile', - 'MM': 'luni', - 'yy': 'ani' - }, - separator = ' '; - if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { - separator = ' de '; - } - - return number + separator + format[key]; - } - - return moment.defineLocale('ro', { - months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), - monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), - weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), - weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), - weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay: '[azi la] LT', - nextDay: '[mâine la] LT', - nextWeek: 'dddd [la] LT', - lastDay: '[ieri la] LT', - lastWeek: '[fosta] dddd [la] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'peste %s', - past : '%s în urmă', - s : 'câteva secunde', - m : 'un minut', - mm : relativeTimeWithPlural, - h : 'o oră', - hh : relativeTimeWithPlural, - d : 'o zi', - dd : relativeTimeWithPlural, - M : 'o lună', - MM : relativeTimeWithPlural, - y : 'un an', - yy : relativeTimeWithPlural - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : russian (ru) -// author : Viktorminator : https://github.com/Viktorminator -// Author : Menelion Elensúle : https://github.com/Oire - -(function (factory) { - factory(moment); -}(function (moment) { - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', - 'hh': 'час_часа_часов', - 'dd': 'день_дня_дней', - 'MM': 'месяц_месяца_месяцев', - 'yy': 'год_года_лет' - }; - if (key === 'm') { - return withoutSuffix ? 'минута' : 'минуту'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), - 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_') - }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function monthsShortCaseReplace(m, format) { - var monthsShort = { - 'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), - 'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_') - }, - - nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return monthsShort[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), - 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_') - }, - - nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - } - - return moment.defineLocale('ru', { - months : monthsCaseReplace, - monthsShort : monthsShortCaseReplace, - weekdays : weekdaysCaseReplace, - weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i], - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., LT', - LLLL : 'dddd, D MMMM YYYY г., LT' - }, - calendar : { - sameDay: '[Сегодня в] LT', - nextDay: '[Завтра в] LT', - lastDay: '[Вчера в] LT', - nextWeek: function () { - return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT'; - }, - lastWeek: function () { - switch (this.day()) { - case 0: - return '[В прошлое] dddd [в] LT'; - case 1: - case 2: - case 4: - return '[В прошлый] dddd [в] LT'; - case 3: - case 5: - case 6: - return '[В прошлую] dddd [в] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'через %s', - past : '%s назад', - s : 'несколько секунд', - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : 'час', - hh : relativeTimeWithPlural, - d : 'день', - dd : relativeTimeWithPlural, - M : 'месяц', - MM : relativeTimeWithPlural, - y : 'год', - yy : relativeTimeWithPlural - }, - - meridiemParse: /ночи|утра|дня|вечера/i, - isPM : function (input) { - return /^(дня|вечера)$/.test(input); - }, - - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночи'; - } else if (hour < 12) { - return 'утра'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечера'; - } - }, - - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - return number + '-й'; - case 'D': - return number + '-го'; - case 'w': - case 'W': - return number + '-я'; - default: - return number; - } - }, - - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : slovak (sk) -// author : Martin Minka : https://github.com/k2s -// based on work of petrbela : https://github.com/petrbela - -(function (factory) { - factory(moment); -}(function (moment) { - var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), - monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); - - function plural(n) { - return (n > 1) && (n < 5); - } - - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'minúty' : 'minút'); - } else { - return result + 'minútami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'hodiny' : 'hodín'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'dni' : 'dní'); - } else { - return result + 'dňami'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'mesiace' : 'mesiacov'); - } else { - return result + 'mesiacmi'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'roky' : 'rokov'); - } else { - return result + 'rokmi'; - } - break; - } - } - - return moment.defineLocale('sk', { - months : months, - monthsShort : monthsShort, - monthsParse : (function (months, monthsShort) { - var i, _monthsParse = []; - for (i = 0; i < 12; i++) { - // use custom parser to solve problem with July (červenec) - _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); - } - return _monthsParse; - }(months, monthsShort)), - weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), - weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), - weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), - longDateFormat : { - LT: 'H:mm', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd D. MMMM YYYY LT' - }, - calendar : { - sameDay: '[dnes o] LT', - nextDay: '[zajtra o] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[v nedeľu o] LT'; - case 1: - case 2: - return '[v] dddd [o] LT'; - case 3: - return '[v stredu o] LT'; - case 4: - return '[vo štvrtok o] LT'; - case 5: - return '[v piatok o] LT'; - case 6: - return '[v sobotu o] LT'; - } - }, - lastDay: '[včera o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulú nedeľu o] LT'; - case 1: - case 2: - return '[minulý] dddd [o] LT'; - case 3: - return '[minulú stredu o] LT'; - case 4: - case 5: - return '[minulý] dddd [o] LT'; - case 6: - return '[minulú sobotu o] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pred %s', - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : slovenian (sl) -// author : Robert Sedovšek : https://github.com/sedovsek - -(function (factory) { - factory(moment); -}(function (moment) { - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'm': - return withoutSuffix ? 'ena minuta' : 'eno minuto'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2) { - result += 'minuti'; - } else if (number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minut'; - } - return result; - case 'h': - return withoutSuffix ? 'ena ura' : 'eno uro'; - case 'hh': - if (number === 1) { - result += 'ura'; - } else if (number === 2) { - result += 'uri'; - } else if (number === 3 || number === 4) { - result += 'ure'; - } else { - result += 'ur'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dni'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mesec'; - } else if (number === 2) { - result += 'meseca'; - } else if (number === 3 || number === 4) { - result += 'mesece'; - } else { - result += 'mesecev'; - } - return result; - case 'yy': - if (number === 1) { - result += 'leto'; - } else if (number === 2) { - result += 'leti'; - } else if (number === 3 || number === 4) { - result += 'leta'; - } else { - result += 'let'; - } - return result; - } - } - - return moment.defineLocale('sl', { - months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), - weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), - weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), - weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), - longDateFormat : { - LT : 'H:mm', - L : 'DD. MM. YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY LT', - LLLL : 'dddd, D. MMMM YYYY LT' - }, - calendar : { - sameDay : '[danes ob] LT', - nextDay : '[jutri ob] LT', - - nextWeek : function () { - switch (this.day()) { - case 0: - return '[v] [nedeljo] [ob] LT'; - case 3: - return '[v] [sredo] [ob] LT'; - case 6: - return '[v] [soboto] [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[v] dddd [ob] LT'; - } - }, - lastDay : '[včeraj ob] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[prejšnja] dddd [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prejšnji] dddd [ob] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'čez %s', - past : '%s nazaj', - s : 'nekaj sekund', - m : translate, - mm : translate, - h : translate, - hh : translate, - d : 'en dan', - dd : translate, - M : 'en mesec', - MM : translate, - y : 'eno leto', - yy : translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Albanian (sq) -// author : Flakërim Ismani : https://github.com/flakerimi -// author: Menelion Elensúle: https://github.com/Oire (tests) -// author : Oerd Cukalla : https://github.com/oerd (fixes) - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('sq', { - months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), - monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), - weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), - weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), - weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), - meridiem : function (hours, minutes, isLower) { - return hours < 12 ? 'PD' : 'MD'; - }, - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[Sot në] LT', - nextDay : '[Nesër në] LT', - nextWeek : 'dddd [në] LT', - lastDay : '[Dje në] LT', - lastWeek : 'dddd [e kaluar në] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'në %s', - past : '%s më parë', - s : 'disa sekonda', - m : 'një minutë', - mm : '%d minuta', - h : 'një orë', - hh : '%d orë', - d : 'një ditë', - dd : '%d ditë', - M : 'një muaj', - MM : '%d muaj', - y : 'një vit', - yy : '%d vite' - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Serbian-cyrillic (sr-cyrl) -// author : Milan Janačković : https://github.com/milan-j - -(function (factory) { - factory(moment); -}(function (moment) { - var translator = { - words: { //Different grammatical cases - m: ['један минут', 'једне минуте'], - mm: ['минут', 'минуте', 'минута'], - h: ['један сат', 'једног сата'], - hh: ['сат', 'сата', 'сати'], - dd: ['дан', 'дана', 'дана'], - MM: ['месец', 'месеца', 'месеци'], - yy: ['година', 'године', 'година'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } - } - }; - - return moment.defineLocale('sr-cyrl', { - months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'], - monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'], - weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'], - weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'], - weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'], - longDateFormat: { - LT: 'H:mm', - L: 'DD. MM. YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY LT', - LLLL: 'dddd, D. MMMM YYYY LT' - }, - calendar: { - sameDay: '[данас у] LT', - nextDay: '[сутра у] LT', - - nextWeek: function () { - switch (this.day()) { - case 0: - return '[у] [недељу] [у] LT'; - case 3: - return '[у] [среду] [у] LT'; - case 6: - return '[у] [суботу] [у] LT'; - case 1: - case 2: - case 4: - case 5: - return '[у] dddd [у] LT'; - } - }, - lastDay : '[јуче у] LT', - lastWeek : function () { - var lastWeekDays = [ - '[прошле] [недеље] [у] LT', - '[прошлог] [понедељка] [у] LT', - '[прошлог] [уторка] [у] LT', - '[прошле] [среде] [у] LT', - '[прошлог] [четвртка] [у] LT', - '[прошлог] [петка] [у] LT', - '[прошле] [суботе] [у] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'за %s', - past : 'пре %s', - s : 'неколико секунди', - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'дан', - dd : translator.translate, - M : 'месец', - MM : translator.translate, - y : 'годину', - yy : translator.translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Serbian-latin (sr) -// author : Milan Janačković : https://github.com/milan-j - -(function (factory) { - factory(moment); -}(function (moment) { - var translator = { - words: { //Different grammatical cases - m: ['jedan minut', 'jedne minute'], - mm: ['minut', 'minute', 'minuta'], - h: ['jedan sat', 'jednog sata'], - hh: ['sat', 'sata', 'sati'], - dd: ['dan', 'dana', 'dana'], - MM: ['mesec', 'meseca', 'meseci'], - yy: ['godina', 'godine', 'godina'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } - } - }; - - return moment.defineLocale('sr', { - months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], - monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], - weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'], - weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'], - weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], - longDateFormat: { - LT: 'H:mm', - L: 'DD. MM. YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY LT', - LLLL: 'dddd, D. MMMM YYYY LT' - }, - calendar: { - sameDay: '[danas u] LT', - nextDay: '[sutra u] LT', - - nextWeek: function () { - switch (this.day()) { - case 0: - return '[u] [nedelju] [u] LT'; - case 3: - return '[u] [sredu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[juče u] LT', - lastWeek : function () { - var lastWeekDays = [ - '[prošle] [nedelje] [u] LT', - '[prošlog] [ponedeljka] [u] LT', - '[prošlog] [utorka] [u] LT', - '[prošle] [srede] [u] LT', - '[prošlog] [četvrtka] [u] LT', - '[prošlog] [petka] [u] LT', - '[prošle] [subote] [u] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pre %s', - s : 'nekoliko sekundi', - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'dan', - dd : translator.translate, - M : 'mesec', - MM : translator.translate, - y : 'godinu', - yy : translator.translate - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : swedish (sv) -// author : Jens Alm : https://github.com/ulmus - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('sv', { - months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), - weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), - weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[Idag] LT', - nextDay: '[Imorgon] LT', - lastDay: '[Igår] LT', - nextWeek: 'dddd LT', - lastWeek: '[Förra] dddd[en] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : 'för %s sedan', - s : 'några sekunder', - m : 'en minut', - mm : '%d minuter', - h : 'en timme', - hh : '%d timmar', - d : 'en dag', - dd : '%d dagar', - M : 'en månad', - MM : '%d månader', - y : 'ett år', - yy : '%d år' - }, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'e' : - (b === 1) ? 'a' : - (b === 2) ? 'a' : - (b === 3) ? 'e' : 'e'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : tamil (ta) -// author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 - -(function (factory) { - factory(moment); -}(function (moment) { - /*var symbolMap = { - '1': '௧', - '2': '௨', - '3': '௩', - '4': '௪', - '5': '௫', - '6': '௬', - '7': '௭', - '8': '௮', - '9': '௯', - '0': '௦' - }, - numberMap = { - '௧': '1', - '௨': '2', - '௩': '3', - '௪': '4', - '௫': '5', - '௬': '6', - '௭': '7', - '௮': '8', - '௯': '9', - '௦': '0' - }; */ - - return moment.defineLocale('ta', { - months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), - weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), - weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, LT', - LLLL : 'dddd, D MMMM YYYY, LT' - }, - calendar : { - sameDay : '[இன்று] LT', - nextDay : '[நாளை] LT', - nextWeek : 'dddd, LT', - lastDay : '[நேற்று] LT', - lastWeek : '[கடந்த வாரம்] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s இல்', - past : '%s முன்', - s : 'ஒரு சில விநாடிகள்', - m : 'ஒரு நிமிடம்', - mm : '%d நிமிடங்கள்', - h : 'ஒரு மணி நேரம்', - hh : '%d மணி நேரம்', - d : 'ஒரு நாள்', - dd : '%d நாட்கள்', - M : 'ஒரு மாதம்', - MM : '%d மாதங்கள்', - y : 'ஒரு வருடம்', - yy : '%d ஆண்டுகள்' - }, -/* preparse: function (string) { - return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - },*/ - ordinal : function (number) { - return number + 'வது'; - }, - - - // refer http://ta.wikipedia.org/s/1er1 - - meridiem : function (hour, minute, isLower) { - if (hour >= 6 && hour <= 10) { - return ' காலை'; - } else if (hour >= 10 && hour <= 14) { - return ' நண்பகல்'; - } else if (hour >= 14 && hour <= 18) { - return ' எற்பாடு'; - } else if (hour >= 18 && hour <= 20) { - return ' மாலை'; - } else if (hour >= 20 && hour <= 24) { - return ' இரவு'; - } else if (hour >= 0 && hour <= 6) { - return ' வைகறை'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : thai (th) -// author : Kridsada Thanabulpong : https://github.com/sirn - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('th', { - months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), - monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'), - weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), - weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference - weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), - longDateFormat : { - LT : 'H นาฬิกา m นาที', - L : 'YYYY/MM/DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY เวลา LT', - LLLL : 'วันddddที่ D MMMM YYYY เวลา LT' - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ก่อนเที่ยง'; - } else { - return 'หลังเที่ยง'; - } - }, - calendar : { - sameDay : '[วันนี้ เวลา] LT', - nextDay : '[พรุ่งนี้ เวลา] LT', - nextWeek : 'dddd[หน้า เวลา] LT', - lastDay : '[เมื่อวานนี้ เวลา] LT', - lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'อีก %s', - past : '%sที่แล้ว', - s : 'ไม่กี่วินาที', - m : '1 นาที', - mm : '%d นาที', - h : '1 ชั่วโมง', - hh : '%d ชั่วโมง', - d : '1 วัน', - dd : '%d วัน', - M : '1 เดือน', - MM : '%d เดือน', - y : '1 ปี', - yy : '%d ปี' - } - }); -})); -// moment.js locale configuration -// locale : Tagalog/Filipino (tl-ph) -// author : Dan Hagman - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('tl-ph', { - months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), - monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), - weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), - weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), - weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'MM/D/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY LT', - LLLL : 'dddd, MMMM DD, YYYY LT' - }, - calendar : { - sameDay: '[Ngayon sa] LT', - nextDay: '[Bukas sa] LT', - nextWeek: 'dddd [sa] LT', - lastDay: '[Kahapon sa] LT', - lastWeek: 'dddd [huling linggo] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'sa loob ng %s', - past : '%s ang nakalipas', - s : 'ilang segundo', - m : 'isang minuto', - mm : '%d minuto', - h : 'isang oras', - hh : '%d oras', - d : 'isang araw', - dd : '%d araw', - M : 'isang buwan', - MM : '%d buwan', - y : 'isang taon', - yy : '%d taon' - }, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : turkish (tr) -// authors : Erhan Gundogan : https://github.com/erhangundogan, -// Burak Yiğit Kaya: https://github.com/BYK - -(function (factory) { - factory(moment); -}(function (moment) { - var suffixes = { - 1: '\'inci', - 5: '\'inci', - 8: '\'inci', - 70: '\'inci', - 80: '\'inci', - - 2: '\'nci', - 7: '\'nci', - 20: '\'nci', - 50: '\'nci', - - 3: '\'üncü', - 4: '\'üncü', - 100: '\'üncü', - - 6: '\'ncı', - - 9: '\'uncu', - 10: '\'uncu', - 30: '\'uncu', - - 60: '\'ıncı', - 90: '\'ıncı' - }; - - return moment.defineLocale('tr', { - months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), - monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), - weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), - weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), - weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd, D MMMM YYYY LT' - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[yarın saat] LT', - nextWeek : '[haftaya] dddd [saat] LT', - lastDay : '[dün] LT', - lastWeek : '[geçen hafta] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s sonra', - past : '%s önce', - s : 'birkaç saniye', - m : 'bir dakika', - mm : '%d dakika', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir yıl', - yy : '%d yıl' - }, - ordinal : function (number) { - if (number === 0) { // special case for zero - return number + '\'ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - - return number + (suffixes[a] || suffixes[b] || suffixes[c]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn) -// author : Abdel Said : https://github.com/abdelsaid - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('tzm-latn', { - months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[asdkh g] LT', - nextDay: '[aska g] LT', - nextWeek: 'dddd [g] LT', - lastDay: '[assant g] LT', - lastWeek: 'dddd [g] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'dadkh s yan %s', - past : 'yan %s', - s : 'imik', - m : 'minuḍ', - mm : '%d minuḍ', - h : 'saɛa', - hh : '%d tassaɛin', - d : 'ass', - dd : '%d ossan', - M : 'ayowr', - MM : '%d iyyirn', - y : 'asgas', - yy : '%d isgasn' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : Morocco Central Atlas Tamaziɣt (tzm) -// author : Abdel Said : https://github.com/abdelsaid - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('tzm', { - months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'dddd D MMMM YYYY LT' - }, - calendar : { - sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', - nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', - nextWeek: 'dddd [ⴴ] LT', - lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', - lastWeek: 'dddd [ⴴ] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', - past : 'ⵢⴰⵏ %s', - s : 'ⵉⵎⵉⴽ', - m : 'ⵎⵉⵏⵓⴺ', - mm : '%d ⵎⵉⵏⵓⴺ', - h : 'ⵙⴰⵄⴰ', - hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', - d : 'ⴰⵙⵙ', - dd : '%d oⵙⵙⴰⵏ', - M : 'ⴰⵢoⵓⵔ', - MM : '%d ⵉⵢⵢⵉⵔⵏ', - y : 'ⴰⵙⴳⴰⵙ', - yy : '%d ⵉⵙⴳⴰⵙⵏ' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : ukrainian (uk) -// author : zemlanin : https://github.com/zemlanin -// Author : Menelion Elensúle : https://github.com/Oire - -(function (factory) { - factory(moment); -}(function (moment) { - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'mm': 'хвилина_хвилини_хвилин', - 'hh': 'година_години_годин', - 'dd': 'день_дні_днів', - 'MM': 'місяць_місяці_місяців', - 'yy': 'рік_роки_років' - }; - if (key === 'm') { - return withoutSuffix ? 'хвилина' : 'хвилину'; - } - else if (key === 'h') { - return withoutSuffix ? 'година' : 'годину'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - - function monthsCaseReplace(m, format) { - var months = { - 'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'), - 'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_') - }, - - nounCase = (/D[oD]? *MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - } - - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), - 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), - 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') - }, - - nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? - 'accusative' : - ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? - 'genitive' : - 'nominative'); - - return weekdays[nounCase][m.day()]; - } - - function processHoursFunction(str) { - return function () { - return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; - }; - } - - return moment.defineLocale('uk', { - months : monthsCaseReplace, - monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY р.', - LLL : 'D MMMM YYYY р., LT', - LLLL : 'dddd, D MMMM YYYY р., LT' - }, - calendar : { - sameDay: processHoursFunction('[Сьогодні '), - nextDay: processHoursFunction('[Завтра '), - lastDay: processHoursFunction('[Вчора '), - nextWeek: processHoursFunction('[У] dddd ['), - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return processHoursFunction('[Минулої] dddd [').call(this); - case 1: - case 2: - case 4: - return processHoursFunction('[Минулого] dddd [').call(this); - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'за %s', - past : '%s тому', - s : 'декілька секунд', - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : 'годину', - hh : relativeTimeWithPlural, - d : 'день', - dd : relativeTimeWithPlural, - M : 'місяць', - MM : relativeTimeWithPlural, - y : 'рік', - yy : relativeTimeWithPlural - }, - - // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason - - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночі'; - } else if (hour < 12) { - return 'ранку'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечора'; - } - }, - - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - case 'w': - case 'W': - return number + '-й'; - case 'D': - return number + '-го'; - default: - return number; - } - }, - - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1st is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : uzbek (uz) -// author : Sardor Muminov : https://github.com/muminoff - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('uz', { - months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), - monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), - weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), - weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY LT', - LLLL : 'D MMMM YYYY, dddd LT' - }, - calendar : { - sameDay : '[Бугун соат] LT [да]', - nextDay : '[Эртага] LT [да]', - nextWeek : 'dddd [куни соат] LT [да]', - lastDay : '[Кеча соат] LT [да]', - lastWeek : '[Утган] dddd [куни соат] LT [да]', - sameElse : 'L' - }, - relativeTime : { - future : 'Якин %s ичида', - past : 'Бир неча %s олдин', - s : 'фурсат', - m : 'бир дакика', - mm : '%d дакика', - h : 'бир соат', - hh : '%d соат', - d : 'бир кун', - dd : '%d кун', - M : 'бир ой', - MM : '%d ой', - y : 'бир йил', - yy : '%d йил' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : vietnamese (vi) -// author : Bang Nguyen : https://github.com/bangnk - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('vi', { - months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), - monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), - weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), - weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM [năm] YYYY', - LLL : 'D MMMM [năm] YYYY LT', - LLLL : 'dddd, D MMMM [năm] YYYY LT', - l : 'DD/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY LT', - llll : 'ddd, D MMM YYYY LT' - }, - calendar : { - sameDay: '[Hôm nay lúc] LT', - nextDay: '[Ngày mai lúc] LT', - nextWeek: 'dddd [tuần tới lúc] LT', - lastDay: '[Hôm qua lúc] LT', - lastWeek: 'dddd [tuần rồi lúc] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s tới', - past : '%s trước', - s : 'vài giây', - m : 'một phút', - mm : '%d phút', - h : 'một giờ', - hh : '%d giờ', - d : 'một ngày', - dd : '%d ngày', - M : 'một tháng', - MM : '%d tháng', - y : 'một năm', - yy : '%d năm' - }, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : chinese (zh-cn) -// author : suupic : https://github.com/suupic -// author : Zeno Zeng : https://github.com/zenozeng - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('zh-cn', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'Ah点mm', - L : 'YYYY-MM-DD', - LL : 'YYYY年MMMD日', - LLL : 'YYYY年MMMD日LT', - LLLL : 'YYYY年MMMD日ddddLT', - l : 'YYYY-MM-DD', - ll : 'YYYY年MMMD日', - lll : 'YYYY年MMMD日LT', - llll : 'YYYY年MMMD日ddddLT' - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : function () { - return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT'; - }, - nextDay : function () { - return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT'; - }, - lastDay : function () { - return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT'; - }, - nextWeek : function () { - var startOfWeek, prefix; - startOfWeek = moment().startOf('week'); - prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]'; - return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; - }, - lastWeek : function () { - var startOfWeek, prefix; - startOfWeek = moment().startOf('week'); - prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]'; - return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; - }, - sameElse : 'LL' - }, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '日'; - case 'M': - return number + '月'; - case 'w': - case 'W': - return number + '周'; - default: - return number; - } - }, - relativeTime : { - future : '%s内', - past : '%s前', - s : '几秒', - m : '1分钟', - mm : '%d分钟', - h : '1小时', - hh : '%d小时', - d : '1天', - dd : '%d天', - M : '1个月', - MM : '%d个月', - y : '1年', - yy : '%d年' - }, - week : { - // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -// moment.js locale configuration -// locale : traditional chinese (zh-tw) -// author : Ben : https://github.com/ben-lin - -(function (factory) { - factory(moment); -}(function (moment) { - return moment.defineLocale('zh-tw', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'Ah點mm', - L : 'YYYY年MMMD日', - LL : 'YYYY年MMMD日', - LLL : 'YYYY年MMMD日LT', - LLLL : 'YYYY年MMMD日ddddLT', - l : 'YYYY年MMMD日', - ll : 'YYYY年MMMD日', - lll : 'YYYY年MMMD日LT', - llll : 'YYYY年MMMD日ddddLT' - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - ordinal : function (number, period) { - switch (period) { - case 'd' : - case 'D' : - case 'DDD' : - return number + '日'; - case 'M' : - return number + '月'; - case 'w' : - case 'W' : - return number + '週'; - default : - return number; - } - }, - relativeTime : { - future : '%s內', - past : '%s前', - s : '幾秒', - m : '一分鐘', - mm : '%d分鐘', - h : '一小時', - hh : '%d小時', - d : '一天', - dd : '%d天', - M : '一個月', - MM : '%d個月', - y : '一年', - yy : '%d年' - } - }); -})); - - moment.locale('en'); - - - /************************************ - Exposing Moment - ************************************/ - - function makeGlobal(shouldDeprecate) { - /*global ender:false */ - if (typeof ender !== 'undefined') { - return; - } - oldGlobalMoment = globalScope.moment; - if (shouldDeprecate) { - globalScope.moment = deprecate( - 'Accessing Moment through the global scope is ' + - 'deprecated, and will be removed in an upcoming ' + - 'release.', - moment); - } else { - globalScope.moment = moment; - } - } - - // CommonJS module is defined - if (hasModule) { - module.exports = moment; - } else if (typeof define === 'function' && define.amd) { - define('moment', function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal === true) { - // release the global variable - globalScope.moment = oldGlobalMoment; - } - - return moment; - }); - makeGlobal(true); - } else { - makeGlobal(); - } -}).call(this); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index 1f12164b18..cc57eb6e74 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -212,15 +212,22 @@ Use this directive to construct a header inside the main editor window. scope.dialogModel = { view: "iconpicker", show: true, - submit: function(model) { - if (model.color) { - scope.icon = model.icon + " " + model.color; - } else { - scope.icon = model.icon; - } + submit: function (model) { - // set form to dirty - ctrl.$setDirty(); + /* ensure an icon is selected, because on focus on close button + or an element in background no icon is submitted. So don't clear/update existing icon/preview. + */ + if (model.icon) { + + if (model.color) { + scope.icon = model.icon + " " + model.color; + } else { + scope.icon = model.icon; + } + + // set form to dirty + ctrl.$setDirty(); + } scope.dialogModel.show = false; scope.dialogModel = null; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index 20fdc6e332..f4fe0db4e6 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -34,7 +34,7 @@ angular.module("umbraco.directives") //TODO: Remove more of the binding from this template and move the DOM manipulation to be manually done in the link function, // this will greatly improve performance since there's potentially a lot of nodes being rendered = a LOT of watches! - template: '
  • ' + + template: '
  • ' + '
    ' + //NOTE: This ins element is used to display the search icon if the node is a container/listview and the tree is currently in dialog //'' + @@ -72,14 +72,13 @@ angular.module("umbraco.directives") //set the padding .css("padding-left", (node.level * 20) + "px"); - //remove first 'ins' if there is no children - //show/hide last 'ins' depending on children + //toggle visibility of last 'ins' depending on children + //visibility still ensure the space is "reserved", so both nodes with and without children are aligned. if (!node.hasChildren) { - element.find("ins:first").remove(); - element.find("ins").last().hide(); + element.find("ins").last().css("visibility", "hidden"); } else { - element.find("ins").last().show(); + element.find("ins").last().css("visibility", "visible"); } var icon = element.find("i:first"); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/nodirtycheck.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/nodirtycheck.directive.js similarity index 100% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/nodirtycheck.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/nodirtycheck.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/umbsetdirtyonchange.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js similarity index 100% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/umbsetdirtyonchange.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valCustom.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valCustom.directive.js similarity index 100% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valCustom.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valCustom.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valHighlight.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valHighlight.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valHighlight.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valHighlight.directive.js index 2afd75eb29..9182441f8b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valHighlight.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valHighlight.directive.js @@ -1,28 +1,28 @@ -/** -* @ngdoc directive -* @name umbraco.directives.directive:valHighlight -* @restrict A -* @description Used on input fields when you want to signal that they are in error, this will highlight the item for 1 second -**/ -function valHighlight($timeout) { - return { - restrict: "A", - link: function (scope, element, attrs, ctrl) { - - attrs.$observe("valHighlight", function (newVal) { - if (newVal === "true") { - element.addClass("highlight-error"); - $timeout(function () { - //set the bound scope property to false - scope[attrs.valHighlight] = false; - }, 1000); - } - else { - element.removeClass("highlight-error"); - } - }); - - } - }; -} -angular.module('umbraco.directives.validation').directive("valHighlight", valHighlight); +/** +* @ngdoc directive +* @name umbraco.directives.directive:valHighlight +* @restrict A +* @description Used on input fields when you want to signal that they are in error, this will highlight the item for 1 second +**/ +function valHighlight($timeout) { + return { + restrict: "A", + link: function (scope, element, attrs, ctrl) { + + attrs.$observe("valHighlight", function (newVal) { + if (newVal === "true") { + element.addClass("highlight-error"); + $timeout(function () { + //set the bound scope property to false + scope[attrs.valHighlight] = false; + }, 1000); + } + else { + element.removeClass("highlight-error"); + } + }); + + } + }; +} +angular.module('umbraco.directives.validation').directive("valHighlight", valHighlight); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valcompare.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valcompare.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valcompare.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valcompare.directive.js index 31595273de..1a36dcc24f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valcompare.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valcompare.directive.js @@ -1,24 +1,24 @@ -angular.module('umbraco.directives.validation') - .directive('valCompare',function () { - return { - require: "ngModel", - link: function (scope, elem, attrs, ctrl) { - - //TODO: Pretty sure this should be done using a requires ^form in the directive declaration - var otherInput = elem.inheritedData("$formController")[attrs.valCompare]; - - ctrl.$parsers.push(function(value) { - if(value === otherInput.$viewValue) { - ctrl.$setValidity("valCompare", true); - return value; - } - ctrl.$setValidity("valCompare", false); - }); - - otherInput.$parsers.push(function(value) { - ctrl.$setValidity("valCompare", value === ctrl.$viewValue); - return value; - }); - } - }; +angular.module('umbraco.directives.validation') + .directive('valCompare',function () { + return { + require: "ngModel", + link: function (scope, elem, attrs, ctrl) { + + //TODO: Pretty sure this should be done using a requires ^form in the directive declaration + var otherInput = elem.inheritedData("$formController")[attrs.valCompare]; + + ctrl.$parsers.push(function(value) { + if(value === otherInput.$viewValue) { + ctrl.$setValidity("valCompare", true); + return value; + } + ctrl.$setValidity("valCompare", false); + }); + + otherInput.$parsers.push(function(value) { + ctrl.$setValidity("valCompare", value === ctrl.$viewValue); + return value; + }); + } + }; }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valemail.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valemail.directive.js similarity index 66% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valemail.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valemail.directive.js index 1e81d8edec..8574d01f5a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valemail.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valemail.directive.js @@ -29,6 +29,16 @@ function valEmail(valEmailExpression) { } }; + //if there is an attribute: type="email" then we need to remove those formatters and parsers + if (attrs.type === "email") { + //we need to remove the existing parsers = the default angular one which is created by + // type="email", but this has a regex issue, so we'll remove that and add our custom one + ctrl.$parsers.pop(); + //we also need to remove the existing formatter - the default angular one will not render + // what it thinks is an invalid email address, so it will just be blank + ctrl.$formatters.pop(); + } + ctrl.$parsers.push(patternValidator); } }; @@ -36,7 +46,8 @@ function valEmail(valEmailExpression) { angular.module('umbraco.directives.validation') .directive("valEmail", valEmail) - .factory('valEmailExpression', function() { + .factory('valEmailExpression', function () { + //NOTE: This is the fixed regex which is part of the newer angular return { EMAIL_REGEXP: /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valformmanager.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valformmanager.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js index 37c0313c45..9a00d5718c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valformmanager.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js @@ -1,133 +1,133 @@ -/** -* @ngdoc directive -* @name umbraco.directives.directive:valFormManager -* @restrict A -* @require formController -* @description Used to broadcast an event to all elements inside this one to notify that form validation has -* changed. If we don't use this that means you have to put a watch for each directive on a form's validation -* changing which would result in much higher processing. We need to actually watch the whole $error collection of a form -* because just watching $valid or $invalid doesn't acurrately trigger form validation changing. -* This also sets the show-validation (or a custom) css class on the element when the form is invalid - this lets -* us css target elements to be displayed when the form is submitting/submitted. -* Another thing this directive does is to ensure that any .control-group that contains form elements that are invalid will -* be marked with the 'error' css class. This ensures that labels included in that control group are styled correctly. -**/ -function valFormManager(serverValidationManager, $rootScope, $log, $timeout, notificationsService, eventsService, $routeParams) { - return { - require: "form", - restrict: "A", - controller: function($scope) { - //This exposes an API for direct use with this directive - - var unsubscribe = []; - var self = this; - - //This is basically the same as a directive subscribing to an event but maybe a little - // nicer since the other directive can use this directive's API instead of a magical event - this.onValidationStatusChanged = function (cb) { - unsubscribe.push($scope.$on("valStatusChanged", function(evt, args) { - cb.apply(self, [evt, args]); - })); - }; - - //Ensure to remove the event handlers when this instance is destroyted - $scope.$on('$destroy', function () { - for (var u in unsubscribe) { - unsubscribe[u](); - } - }); - }, - link: function (scope, element, attr, formCtrl) { - - scope.$watch(function () { - return formCtrl.$error; - }, function (e) { - scope.$broadcast("valStatusChanged", { form: formCtrl }); - - //find all invalid elements' .control-group's and apply the error class - var inError = element.find(".control-group .ng-invalid").closest(".control-group"); - inError.addClass("error"); - - //find all control group's that have no error and ensure the class is removed - var noInError = element.find(".control-group .ng-valid").closest(".control-group").not(inError); - noInError.removeClass("error"); - - }, true); - - var className = attr.valShowValidation ? attr.valShowValidation : "show-validation"; - var savingEventName = attr.savingEvent ? attr.savingEvent : "formSubmitting"; - var savedEvent = attr.savedEvent ? attr.savingEvent : "formSubmitted"; - - //This tracks if the user is currently saving a new item, we use this to determine - // if we should display the warning dialog that they are leaving the page - if a new item - // is being saved we never want to display that dialog, this will also cause problems when there - // are server side validation issues. - var isSavingNewItem = false; - - //we should show validation if there are any msgs in the server validation collection - if (serverValidationManager.items.length > 0) { - element.addClass(className); - } - - var unsubscribe = []; - - //listen for the forms saving event - unsubscribe.push(scope.$on(savingEventName, function(ev, args) { - element.addClass(className); - - //set the flag so we can check to see if we should display the error. - isSavingNewItem = $routeParams.create; - })); - - //listen for the forms saved event - unsubscribe.push(scope.$on(savedEvent, function(ev, args) { - //remove validation class - element.removeClass(className); - - //clear form state as at this point we retrieve new data from the server - //and all validation will have cleared at this point - formCtrl.$setPristine(); - })); - - //This handles the 'unsaved changes' dialog which is triggered when a route is attempting to be changed but - // the form has pending changes - var locationEvent = $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { - if (!formCtrl.$dirty || isSavingNewItem) { - return; - } - - var path = nextLocation.split("#")[1]; - if (path) { - if (path.indexOf("%253") || path.indexOf("%252")) { - path = decodeURIComponent(path); - } - - if (!notificationsService.hasView()) { - var msg = { view: "confirmroutechange", args: { path: path, listener: locationEvent } }; - notificationsService.add(msg); - } - - //prevent the route! - event.preventDefault(); - - //raise an event - eventsService.emit("valFormManager.pendingChanges", true); - } - - }); - unsubscribe.push(locationEvent); - - //Ensure to remove the event handler when this instance is destroyted - scope.$on('$destroy', function() { - for (var u in unsubscribe) { - unsubscribe[u](); - } - }); - - $timeout(function(){ - formCtrl.$setPristine(); - }, 1000); - } - }; -} +/** +* @ngdoc directive +* @name umbraco.directives.directive:valFormManager +* @restrict A +* @require formController +* @description Used to broadcast an event to all elements inside this one to notify that form validation has +* changed. If we don't use this that means you have to put a watch for each directive on a form's validation +* changing which would result in much higher processing. We need to actually watch the whole $error collection of a form +* because just watching $valid or $invalid doesn't acurrately trigger form validation changing. +* This also sets the show-validation (or a custom) css class on the element when the form is invalid - this lets +* us css target elements to be displayed when the form is submitting/submitted. +* Another thing this directive does is to ensure that any .control-group that contains form elements that are invalid will +* be marked with the 'error' css class. This ensures that labels included in that control group are styled correctly. +**/ +function valFormManager(serverValidationManager, $rootScope, $log, $timeout, notificationsService, eventsService, $routeParams) { + return { + require: "form", + restrict: "A", + controller: function($scope) { + //This exposes an API for direct use with this directive + + var unsubscribe = []; + var self = this; + + //This is basically the same as a directive subscribing to an event but maybe a little + // nicer since the other directive can use this directive's API instead of a magical event + this.onValidationStatusChanged = function (cb) { + unsubscribe.push($scope.$on("valStatusChanged", function(evt, args) { + cb.apply(self, [evt, args]); + })); + }; + + //Ensure to remove the event handlers when this instance is destroyted + $scope.$on('$destroy', function () { + for (var u in unsubscribe) { + unsubscribe[u](); + } + }); + }, + link: function (scope, element, attr, formCtrl) { + + scope.$watch(function () { + return formCtrl.$error; + }, function (e) { + scope.$broadcast("valStatusChanged", { form: formCtrl }); + + //find all invalid elements' .control-group's and apply the error class + var inError = element.find(".control-group .ng-invalid").closest(".control-group"); + inError.addClass("error"); + + //find all control group's that have no error and ensure the class is removed + var noInError = element.find(".control-group .ng-valid").closest(".control-group").not(inError); + noInError.removeClass("error"); + + }, true); + + var className = attr.valShowValidation ? attr.valShowValidation : "show-validation"; + var savingEventName = attr.savingEvent ? attr.savingEvent : "formSubmitting"; + var savedEvent = attr.savedEvent ? attr.savingEvent : "formSubmitted"; + + //This tracks if the user is currently saving a new item, we use this to determine + // if we should display the warning dialog that they are leaving the page - if a new item + // is being saved we never want to display that dialog, this will also cause problems when there + // are server side validation issues. + var isSavingNewItem = false; + + //we should show validation if there are any msgs in the server validation collection + if (serverValidationManager.items.length > 0) { + element.addClass(className); + } + + var unsubscribe = []; + + //listen for the forms saving event + unsubscribe.push(scope.$on(savingEventName, function(ev, args) { + element.addClass(className); + + //set the flag so we can check to see if we should display the error. + isSavingNewItem = $routeParams.create; + })); + + //listen for the forms saved event + unsubscribe.push(scope.$on(savedEvent, function(ev, args) { + //remove validation class + element.removeClass(className); + + //clear form state as at this point we retrieve new data from the server + //and all validation will have cleared at this point + formCtrl.$setPristine(); + })); + + //This handles the 'unsaved changes' dialog which is triggered when a route is attempting to be changed but + // the form has pending changes + var locationEvent = $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { + if (!formCtrl.$dirty || isSavingNewItem) { + return; + } + + var path = nextLocation.split("#")[1]; + if (path) { + if (path.indexOf("%253") || path.indexOf("%252")) { + path = decodeURIComponent(path); + } + + if (!notificationsService.hasView()) { + var msg = { view: "confirmroutechange", args: { path: path, listener: locationEvent } }; + notificationsService.add(msg); + } + + //prevent the route! + event.preventDefault(); + + //raise an event + eventsService.emit("valFormManager.pendingChanges", true); + } + + }); + unsubscribe.push(locationEvent); + + //Ensure to remove the event handler when this instance is destroyted + scope.$on('$destroy', function() { + for (var u in unsubscribe) { + unsubscribe[u](); + } + }); + + $timeout(function(){ + formCtrl.$setPristine(); + }, 1000); + } + }; +} angular.module('umbraco.directives.validation').directive("valFormManager", valFormManager); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valpropertymsg.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js index eba308d830..be5da51702 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valpropertymsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js @@ -1,196 +1,196 @@ -/** -* @ngdoc directive -* @name umbraco.directives.directive:valPropertyMsg -* @restrict A -* @element textarea -* @requires formController -* @description This directive is used to control the display of the property level validation message. -* We will listen for server side validation changes -* and when an error is detected for this property we'll show the error message. -* In order for this directive to work, the valStatusChanged directive must be placed on the containing form. -**/ -function valPropertyMsg(serverValidationManager) { - - return { - scope: { - property: "=" - }, - require: "^form", //require that this directive is contained within an ngForm - replace: true, //replace the element with the template - restrict: "E", //restrict to element - template: "
    {{errorMsg}}
    ", - - /** - Our directive requries a reference to a form controller - which gets passed in to this parameter - */ - link: function (scope, element, attrs, formCtrl) { - - var watcher = null; - - // Gets the error message to display - function getErrorMsg() { - //this can be null if no property was assigned - if (scope.property) { - //first try to get the error msg from the server collection - var err = serverValidationManager.getPropertyError(scope.property.alias, ""); - //if there's an error message use it - if (err && err.errorMsg) { - return err.errorMsg; - } - else { - return scope.property.propertyErrorMessage ? scope.property.propertyErrorMessage : "Property has errors"; - } - - } - return "Property has errors"; - } - - // We need to subscribe to any changes to our model (based on user input) - // This is required because when we have a server error we actually invalidate - // the form which means it cannot be resubmitted. - // So once a field is changed that has a server error assigned to it - // we need to re-validate it for the server side validator so the user can resubmit - // the form. Of course normal client-side validators will continue to execute. - function startWatch() { - //if there's not already a watch - if (!watcher) { - watcher = scope.$watch("property.value", function (newValue, oldValue) { - - if (!newValue || angular.equals(newValue, oldValue)) { - return; - } - - var errCount = 0; - for (var e in formCtrl.$error) { - if (angular.isArray(formCtrl.$error[e])) { - errCount++; - } - } - - //we are explicitly checking for valServer errors here, since we shouldn't auto clear - // based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg - // is the only one, then we'll clear. - - if ((errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) { - scope.errorMsg = ""; - formCtrl.$setValidity('valPropertyMsg', true); - stopWatch(); - } - }, true); - } - } - - //clear the watch when the property validator is valid again - function stopWatch() { - if (watcher) { - watcher(); - watcher = null; - } - } - - //if there's any remaining errors in the server validation service then we should show them. - var showValidation = serverValidationManager.items.length > 0; - var hasError = false; - - //create properties on our custom scope so we can use it in our template - scope.errorMsg = ""; - - var unsubscribe = []; - - //listen for form error changes - unsubscribe.push(scope.$on("valStatusChanged", function(evt, args) { - if (args.form.$invalid) { - - //first we need to check if the valPropertyMsg validity is invalid - if (formCtrl.$error.valPropertyMsg && formCtrl.$error.valPropertyMsg.length > 0) { - //since we already have an error we'll just return since this means we've already set the - // hasError and errorMsg properties which occurs below in the serverValidationManager.subscribe - return; - } - else if (element.closest(".umb-control-group").find(".ng-invalid").length > 0) { - //check if it's one of the properties that is invalid in the current content property - hasError = true; - //update the validation message if we don't already have one assigned. - if (showValidation && scope.errorMsg === "") { - scope.errorMsg = getErrorMsg(); - } - } - else { - hasError = false; - scope.errorMsg = ""; - } - } - else { - hasError = false; - scope.errorMsg = ""; - } - }, true)); - - //listen for the forms saving event - unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { - showValidation = true; - if (hasError && scope.errorMsg === "") { - scope.errorMsg = getErrorMsg(); - } - else if (!hasError) { - scope.errorMsg = ""; - stopWatch(); - } - })); - - //listen for the forms saved event - unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { - showValidation = false; - scope.errorMsg = ""; - formCtrl.$setValidity('valPropertyMsg', true); - stopWatch(); - })); - - //listen for server validation changes - // NOTE: we pass in "" in order to listen for all validation changes to the content property, not for - // validation changes to fields in the property this is because some server side validators may not - // return the field name for which the error belongs too, just the property for which it belongs. - // It's important to note that we need to subscribe to server validation changes here because we always must - // indicate that a content property is invalid at the property level since developers may not actually implement - // the correct field validation in their property editors. - - if (scope.property) { //this can be null if no property was assigned - serverValidationManager.subscribe(scope.property.alias, "", function (isValid, propertyErrors, allErrors) { - hasError = !isValid; - if (hasError) { - //set the error message to the server message - scope.errorMsg = propertyErrors[0].errorMsg; - //flag that the current validator is invalid - formCtrl.$setValidity('valPropertyMsg', false); - startWatch(); - } - else { - scope.errorMsg = ""; - //flag that the current validator is valid - formCtrl.$setValidity('valPropertyMsg', true); - stopWatch(); - } - }); - - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain - // but they are a different callback instance than the above. - element.bind('$destroy', function () { - stopWatch(); - serverValidationManager.unsubscribe(scope.property.alias, ""); - }); - } - - //when the scope is disposed we need to unsubscribe - scope.$on('$destroy', function () { - for (var u in unsubscribe) { - unsubscribe[u](); - } - }); - } - - - }; -} +/** +* @ngdoc directive +* @name umbraco.directives.directive:valPropertyMsg +* @restrict A +* @element textarea +* @requires formController +* @description This directive is used to control the display of the property level validation message. +* We will listen for server side validation changes +* and when an error is detected for this property we'll show the error message. +* In order for this directive to work, the valStatusChanged directive must be placed on the containing form. +**/ +function valPropertyMsg(serverValidationManager) { + + return { + scope: { + property: "=" + }, + require: "^form", //require that this directive is contained within an ngForm + replace: true, //replace the element with the template + restrict: "E", //restrict to element + template: "
    {{errorMsg}}
    ", + + /** + Our directive requries a reference to a form controller + which gets passed in to this parameter + */ + link: function (scope, element, attrs, formCtrl) { + + var watcher = null; + + // Gets the error message to display + function getErrorMsg() { + //this can be null if no property was assigned + if (scope.property) { + //first try to get the error msg from the server collection + var err = serverValidationManager.getPropertyError(scope.property.alias, ""); + //if there's an error message use it + if (err && err.errorMsg) { + return err.errorMsg; + } + else { + return scope.property.propertyErrorMessage ? scope.property.propertyErrorMessage : "Property has errors"; + } + + } + return "Property has errors"; + } + + // We need to subscribe to any changes to our model (based on user input) + // This is required because when we have a server error we actually invalidate + // the form which means it cannot be resubmitted. + // So once a field is changed that has a server error assigned to it + // we need to re-validate it for the server side validator so the user can resubmit + // the form. Of course normal client-side validators will continue to execute. + function startWatch() { + //if there's not already a watch + if (!watcher) { + watcher = scope.$watch("property.value", function (newValue, oldValue) { + + if (!newValue || angular.equals(newValue, oldValue)) { + return; + } + + var errCount = 0; + for (var e in formCtrl.$error) { + if (angular.isArray(formCtrl.$error[e])) { + errCount++; + } + } + + //we are explicitly checking for valServer errors here, since we shouldn't auto clear + // based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg + // is the only one, then we'll clear. + + if ((errCount === 1 && angular.isArray(formCtrl.$error.valPropertyMsg)) || (formCtrl.$invalid && angular.isArray(formCtrl.$error.valServer))) { + scope.errorMsg = ""; + formCtrl.$setValidity('valPropertyMsg', true); + stopWatch(); + } + }, true); + } + } + + //clear the watch when the property validator is valid again + function stopWatch() { + if (watcher) { + watcher(); + watcher = null; + } + } + + //if there's any remaining errors in the server validation service then we should show them. + var showValidation = serverValidationManager.items.length > 0; + var hasError = false; + + //create properties on our custom scope so we can use it in our template + scope.errorMsg = ""; + + var unsubscribe = []; + + //listen for form error changes + unsubscribe.push(scope.$on("valStatusChanged", function(evt, args) { + if (args.form.$invalid) { + + //first we need to check if the valPropertyMsg validity is invalid + if (formCtrl.$error.valPropertyMsg && formCtrl.$error.valPropertyMsg.length > 0) { + //since we already have an error we'll just return since this means we've already set the + // hasError and errorMsg properties which occurs below in the serverValidationManager.subscribe + return; + } + else if (element.closest(".umb-control-group").find(".ng-invalid").length > 0) { + //check if it's one of the properties that is invalid in the current content property + hasError = true; + //update the validation message if we don't already have one assigned. + if (showValidation && scope.errorMsg === "") { + scope.errorMsg = getErrorMsg(); + } + } + else { + hasError = false; + scope.errorMsg = ""; + } + } + else { + hasError = false; + scope.errorMsg = ""; + } + }, true)); + + //listen for the forms saving event + unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { + showValidation = true; + if (hasError && scope.errorMsg === "") { + scope.errorMsg = getErrorMsg(); + } + else if (!hasError) { + scope.errorMsg = ""; + stopWatch(); + } + })); + + //listen for the forms saved event + unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { + showValidation = false; + scope.errorMsg = ""; + formCtrl.$setValidity('valPropertyMsg', true); + stopWatch(); + })); + + //listen for server validation changes + // NOTE: we pass in "" in order to listen for all validation changes to the content property, not for + // validation changes to fields in the property this is because some server side validators may not + // return the field name for which the error belongs too, just the property for which it belongs. + // It's important to note that we need to subscribe to server validation changes here because we always must + // indicate that a content property is invalid at the property level since developers may not actually implement + // the correct field validation in their property editors. + + if (scope.property) { //this can be null if no property was assigned + serverValidationManager.subscribe(scope.property.alias, "", function (isValid, propertyErrors, allErrors) { + hasError = !isValid; + if (hasError) { + //set the error message to the server message + scope.errorMsg = propertyErrors[0].errorMsg; + //flag that the current validator is invalid + formCtrl.$setValidity('valPropertyMsg', false); + startWatch(); + } + else { + scope.errorMsg = ""; + //flag that the current validator is valid + formCtrl.$setValidity('valPropertyMsg', true); + stopWatch(); + } + }); + + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain + // but they are a different callback instance than the above. + element.bind('$destroy', function () { + stopWatch(); + serverValidationManager.unsubscribe(scope.property.alias, ""); + }); + } + + //when the scope is disposed we need to unsubscribe + scope.$on('$destroy', function () { + for (var u in unsubscribe) { + unsubscribe[u](); + } + }); + } + + + }; +} angular.module('umbraco.directives.validation').directive("valPropertyMsg", valPropertyMsg); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valpropertyvalidator.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertyvalidator.directive.js similarity index 100% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valpropertyvalidator.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertyvalidator.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valregex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valregex.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valregex.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valregex.directive.js index 7bc3c6b877..6406583e77 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valregex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valregex.directive.js @@ -1,78 +1,78 @@ -/** - * @ngdoc directive - * @name umbraco.directives.directive:valRegex - * @restrict A - * @description A custom directive to allow for matching a value against a regex string. - * NOTE: there's already an ng-pattern but this requires that a regex expression is set, not a regex string - **/ -function valRegex() { - - return { - require: 'ngModel', - restrict: "A", - link: function (scope, elm, attrs, ctrl) { - - var flags = ""; - var regex; - var eventBindings = []; - - attrs.$observe("valRegexFlags", function (newVal) { - if (newVal) { - flags = newVal; - } - }); - - attrs.$observe("valRegex", function (newVal) { - if (newVal) { - try { - var resolved = newVal; - if (resolved) { - regex = new RegExp(resolved, flags); - } - else { - regex = new RegExp(attrs.valRegex, flags); - } - } - catch (e) { - regex = new RegExp(attrs.valRegex, flags); - } - } - }); - - eventBindings.push(scope.$watch('ngModel', function(newValue, oldValue){ - if(newValue && newValue !== oldValue) { - patternValidator(newValue); - } - })); - - var patternValidator = function (viewValue) { - if (regex) { - //NOTE: we don't validate on empty values, use required validator for that - if (!viewValue || regex.test(viewValue.toString())) { - // it is valid - ctrl.$setValidity('valRegex', true); - //assign a message to the validator - ctrl.errorMsg = ""; - return viewValue; - } - else { - // it is invalid, return undefined (no model update) - ctrl.$setValidity('valRegex', false); - //assign a message to the validator - ctrl.errorMsg = "Value is invalid, it does not match the correct pattern"; - return undefined; - } - } - }; - - scope.$on('$destroy', function(){ - // unbind watchers - for(var e in eventBindings) { - eventBindings[e](); - } - }); - - } - }; -} -angular.module('umbraco.directives.validation').directive("valRegex", valRegex); +/** + * @ngdoc directive + * @name umbraco.directives.directive:valRegex + * @restrict A + * @description A custom directive to allow for matching a value against a regex string. + * NOTE: there's already an ng-pattern but this requires that a regex expression is set, not a regex string + **/ +function valRegex() { + + return { + require: 'ngModel', + restrict: "A", + link: function (scope, elm, attrs, ctrl) { + + var flags = ""; + var regex; + var eventBindings = []; + + attrs.$observe("valRegexFlags", function (newVal) { + if (newVal) { + flags = newVal; + } + }); + + attrs.$observe("valRegex", function (newVal) { + if (newVal) { + try { + var resolved = newVal; + if (resolved) { + regex = new RegExp(resolved, flags); + } + else { + regex = new RegExp(attrs.valRegex, flags); + } + } + catch (e) { + regex = new RegExp(attrs.valRegex, flags); + } + } + }); + + eventBindings.push(scope.$watch('ngModel', function(newValue, oldValue){ + if(newValue && newValue !== oldValue) { + patternValidator(newValue); + } + })); + + var patternValidator = function (viewValue) { + if (regex) { + //NOTE: we don't validate on empty values, use required validator for that + if (!viewValue || regex.test(viewValue.toString())) { + // it is valid + ctrl.$setValidity('valRegex', true); + //assign a message to the validator + ctrl.errorMsg = ""; + return viewValue; + } + else { + // it is invalid, return undefined (no model update) + ctrl.$setValidity('valRegex', false); + //assign a message to the validator + ctrl.errorMsg = "Value is invalid, it does not match the correct pattern"; + return undefined; + } + } + }; + + scope.$on('$destroy', function(){ + // unbind watchers + for(var e in eventBindings) { + eventBindings[e](); + } + }); + + } + }; +} +angular.module('umbraco.directives.validation').directive("valRegex", valRegex); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserver.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserver.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js index 6225485073..1432a713c0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserver.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js @@ -1,94 +1,94 @@ -/** - * @ngdoc directive - * @name umbraco.directives.directive:valServer - * @restrict A - * @description This directive is used to associate a content property with a server-side validation response - * so that the validators in angular are updated based on server-side feedback. - **/ -function valServer(serverValidationManager) { - return { - require: ['ngModel', '?^umbProperty'], - restrict: "A", - link: function (scope, element, attr, ctrls) { - - var modelCtrl = ctrls[0]; - var umbPropCtrl = ctrls.length > 1 ? ctrls[1] : null; - if (!umbPropCtrl) { - //we cannot proceed, this validator will be disabled - return; - } - - var watcher = null; - - //Need to watch the value model for it to change, previously we had subscribed to - //modelCtrl.$viewChangeListeners but this is not good enough if you have an editor that - // doesn't specifically have a 2 way ng binding. This is required because when we - // have a server error we actually invalidate the form which means it cannot be - // resubmitted. So once a field is changed that has a server error assigned to it - // we need to re-validate it for the server side validator so the user can resubmit - // the form. Of course normal client-side validators will continue to execute. - function startWatch() { - //if there's not already a watch - if (!watcher) { - watcher = scope.$watch(function () { - return modelCtrl.$modelValue; - }, function (newValue, oldValue) { - - if (!newValue || angular.equals(newValue, oldValue)) { - return; - } - - if (modelCtrl.$invalid) { - modelCtrl.$setValidity('valServer', true); - stopWatch(); - } - }, true); - } - } - - function stopWatch() { - if (watcher) { - watcher(); - watcher = null; - } - } - - var currentProperty = umbPropCtrl.property; - - //default to 'value' if nothing is set - var fieldName = "value"; - if (attr.valServer) { - fieldName = scope.$eval(attr.valServer); - if (!fieldName) { - //eval returned nothing so just use the string - fieldName = attr.valServer; - } - } - - //subscribe to the server validation changes - serverValidationManager.subscribe(currentProperty.alias, fieldName, function (isValid, propertyErrors, allErrors) { - if (!isValid) { - modelCtrl.$setValidity('valServer', false); - //assign an error msg property to the current validator - modelCtrl.errorMsg = propertyErrors[0].errorMsg; - startWatch(); - } - else { - modelCtrl.$setValidity('valServer', true); - //reset the error message - modelCtrl.errorMsg = ""; - stopWatch(); - } - }); - - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain - // but they are a different callback instance than the above. - element.bind('$destroy', function () { - stopWatch(); - serverValidationManager.unsubscribe(currentProperty.alias, fieldName); - }); - } - }; -} +/** + * @ngdoc directive + * @name umbraco.directives.directive:valServer + * @restrict A + * @description This directive is used to associate a content property with a server-side validation response + * so that the validators in angular are updated based on server-side feedback. + **/ +function valServer(serverValidationManager) { + return { + require: ['ngModel', '?^umbProperty'], + restrict: "A", + link: function (scope, element, attr, ctrls) { + + var modelCtrl = ctrls[0]; + var umbPropCtrl = ctrls.length > 1 ? ctrls[1] : null; + if (!umbPropCtrl) { + //we cannot proceed, this validator will be disabled + return; + } + + var watcher = null; + + //Need to watch the value model for it to change, previously we had subscribed to + //modelCtrl.$viewChangeListeners but this is not good enough if you have an editor that + // doesn't specifically have a 2 way ng binding. This is required because when we + // have a server error we actually invalidate the form which means it cannot be + // resubmitted. So once a field is changed that has a server error assigned to it + // we need to re-validate it for the server side validator so the user can resubmit + // the form. Of course normal client-side validators will continue to execute. + function startWatch() { + //if there's not already a watch + if (!watcher) { + watcher = scope.$watch(function () { + return modelCtrl.$modelValue; + }, function (newValue, oldValue) { + + if (!newValue || angular.equals(newValue, oldValue)) { + return; + } + + if (modelCtrl.$invalid) { + modelCtrl.$setValidity('valServer', true); + stopWatch(); + } + }, true); + } + } + + function stopWatch() { + if (watcher) { + watcher(); + watcher = null; + } + } + + var currentProperty = umbPropCtrl.property; + + //default to 'value' if nothing is set + var fieldName = "value"; + if (attr.valServer) { + fieldName = scope.$eval(attr.valServer); + if (!fieldName) { + //eval returned nothing so just use the string + fieldName = attr.valServer; + } + } + + //subscribe to the server validation changes + serverValidationManager.subscribe(currentProperty.alias, fieldName, function (isValid, propertyErrors, allErrors) { + if (!isValid) { + modelCtrl.$setValidity('valServer', false); + //assign an error msg property to the current validator + modelCtrl.errorMsg = propertyErrors[0].errorMsg; + startWatch(); + } + else { + modelCtrl.$setValidity('valServer', true); + //reset the error message + modelCtrl.errorMsg = ""; + stopWatch(); + } + }); + + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain + // but they are a different callback instance than the above. + element.bind('$destroy', function () { + stopWatch(); + serverValidationManager.unsubscribe(currentProperty.alias, fieldName); + }); + } + }; +} angular.module('umbraco.directives.validation').directive("valServer", valServer); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserverfield.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserverfield.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js index 46fbaf93dd..1e0d2d8ba5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valserverfield.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js @@ -1,65 +1,65 @@ -/** - * @ngdoc directive - * @name umbraco.directives.directive:valServerField - * @restrict A - * @description This directive is used to associate a content field (not user defined) with a server-side validation response - * so that the validators in angular are updated based on server-side feedback. - **/ -function valServerField(serverValidationManager) { - return { - require: 'ngModel', - restrict: "A", - link: function (scope, element, attr, ctrl) { - - var fieldName = null; - var eventBindings = []; - - attr.$observe("valServerField", function (newVal) { - if (newVal && fieldName === null) { - fieldName = newVal; - - //subscribe to the changed event of the view model. This is required because when we - // have a server error we actually invalidate the form which means it cannot be - // resubmitted. So once a field is changed that has a server error assigned to it - // we need to re-validate it for the server side validator so the user can resubmit - // the form. Of course normal client-side validators will continue to execute. - eventBindings.push(scope.$watch('ngModel', function(newValue){ - if (ctrl.$invalid) { - ctrl.$setValidity('valServerField', true); - } - })); - - //subscribe to the server validation changes - serverValidationManager.subscribe(null, fieldName, function (isValid, fieldErrors, allErrors) { - if (!isValid) { - ctrl.$setValidity('valServerField', false); - //assign an error msg property to the current validator - ctrl.errorMsg = fieldErrors[0].errorMsg; - } - else { - ctrl.$setValidity('valServerField', true); - //reset the error message - ctrl.errorMsg = ""; - } - }); - - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain - // but they are a different callback instance than the above. - element.bind('$destroy', function () { - serverValidationManager.unsubscribe(null, fieldName); - }); - } - }); - - scope.$on('$destroy', function(){ - // unbind watchers - for(var e in eventBindings) { - eventBindings[e](); - } - }); - - } - }; -} -angular.module('umbraco.directives.validation').directive("valServerField", valServerField); +/** + * @ngdoc directive + * @name umbraco.directives.directive:valServerField + * @restrict A + * @description This directive is used to associate a content field (not user defined) with a server-side validation response + * so that the validators in angular are updated based on server-side feedback. + **/ +function valServerField(serverValidationManager) { + return { + require: 'ngModel', + restrict: "A", + link: function (scope, element, attr, ctrl) { + + var fieldName = null; + var eventBindings = []; + + attr.$observe("valServerField", function (newVal) { + if (newVal && fieldName === null) { + fieldName = newVal; + + //subscribe to the changed event of the view model. This is required because when we + // have a server error we actually invalidate the form which means it cannot be + // resubmitted. So once a field is changed that has a server error assigned to it + // we need to re-validate it for the server side validator so the user can resubmit + // the form. Of course normal client-side validators will continue to execute. + eventBindings.push(scope.$watch('ngModel', function(newValue){ + if (ctrl.$invalid) { + ctrl.$setValidity('valServerField', true); + } + })); + + //subscribe to the server validation changes + serverValidationManager.subscribe(null, fieldName, function (isValid, fieldErrors, allErrors) { + if (!isValid) { + ctrl.$setValidity('valServerField', false); + //assign an error msg property to the current validator + ctrl.errorMsg = fieldErrors[0].errorMsg; + } + else { + ctrl.$setValidity('valServerField', true); + //reset the error message + ctrl.errorMsg = ""; + } + }); + + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain + // but they are a different callback instance than the above. + element.bind('$destroy', function () { + serverValidationManager.unsubscribe(null, fieldName); + }); + } + }); + + scope.$on('$destroy', function(){ + // unbind watchers + for(var e in eventBindings) { + eventBindings[e](); + } + }); + + } + }; +} +angular.module('umbraco.directives.validation').directive("valServerField", valServerField); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtab.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtab.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js index fbca0cd233..8d1fc60083 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtab.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js @@ -1,38 +1,38 @@ - -/** -* @ngdoc directive -* @name umbraco.directives.directive:valTab -* @restrict A -* @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data. -* In order for this directive to work, the valFormManager directive must be placed on the containing form. -**/ -function valTab() { - return { - require: ['^form', '^valFormManager'], - restrict: "A", - link: function (scope, element, attr, ctrs) { - - var valFormManager = ctrs[1]; - var tabId = "tab" + scope.tab.id; - scope.tabHasError = false; - - //listen for form validation changes - valFormManager.onValidationStatusChanged(function (evt, args) { - if (!args.form.$valid) { - var tabContent = element.closest(".umb-panel").find("#" + tabId); - //check if the validation messages are contained inside of this tabs - if (tabContent.find(".ng-invalid").length > 0) { - scope.tabHasError = true; - } else { - scope.tabHasError = false; - } - } - else { - scope.tabHasError = false; - } - }); - - } - }; -} + +/** +* @ngdoc directive +* @name umbraco.directives.directive:valTab +* @restrict A +* @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data. +* In order for this directive to work, the valFormManager directive must be placed on the containing form. +**/ +function valTab() { + return { + require: ['^form', '^valFormManager'], + restrict: "A", + link: function (scope, element, attr, ctrs) { + + var valFormManager = ctrs[1]; + var tabId = "tab" + scope.tab.id; + scope.tabHasError = false; + + //listen for form validation changes + valFormManager.onValidationStatusChanged(function (evt, args) { + if (!args.form.$valid) { + var tabContent = element.closest(".umb-panel").find("#" + tabId); + //check if the validation messages are contained inside of this tabs + if (tabContent.find(".ng-invalid").length > 0) { + scope.tabHasError = true; + } else { + scope.tabHasError = false; + } + } + else { + scope.tabHasError = false; + } + }); + + } + }; +} angular.module('umbraco.directives.validation').directive("valTab", valTab); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtogglemsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js similarity index 97% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtogglemsg.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js index 43792a708a..304f151274 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtogglemsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js @@ -1,90 +1,90 @@ -function valToggleMsg(serverValidationManager) { - return { - require: "^form", - restrict: "A", - - /** - Our directive requries a reference to a form controller which gets passed in to this parameter - */ - link: function (scope, element, attr, formCtrl) { - - if (!attr.valToggleMsg){ - throw "valToggleMsg requires that a reference to a validator is specified"; - } - if (!attr.valMsgFor){ - throw "valToggleMsg requires that the attribute valMsgFor exists on the element"; - } - if (!formCtrl[attr.valMsgFor]) { - throw "valToggleMsg cannot find field " + attr.valMsgFor + " on form " + formCtrl.$name; - } - - //if there's any remaining errors in the server validation service then we should show them. - var showValidation = serverValidationManager.items.length > 0; - var hasCustomMsg = element.contents().length > 0; - - //add a watch to the validator for the value (i.e. myForm.value.$error.required ) - scope.$watch(function () { - //sometimes if a dialog closes in the middle of digest we can get null references here - - return (formCtrl && formCtrl[attr.valMsgFor]) ? formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] : null; - }, function () { - //sometimes if a dialog closes in the middle of digest we can get null references here - if ((formCtrl && formCtrl[attr.valMsgFor])) { - if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] && showValidation) { - element.show(); - //display the error message if this element has no contents - if (!hasCustomMsg) { - element.html(formCtrl[attr.valMsgFor].errorMsg); - } - } - else { - element.hide(); - } - } - }); - - var unsubscribe = []; - - //listen for the saving event (the result is a callback method which is called to unsubscribe) - unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { - showValidation = true; - if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) { - element.show(); - //display the error message if this element has no contents - if (!hasCustomMsg) { - element.html(formCtrl[attr.valMsgFor].errorMsg); - } - } - else { - element.hide(); - } - })); - - //listen for the saved event (the result is a callback method which is called to unsubscribe) - unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { - showValidation = false; - element.hide(); - })); - - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise if this directive is part of a modal, the listener still exists because the dom - // element might still be there even after the modal has been hidden. - element.bind('$destroy', function () { - for (var u in unsubscribe) { - unsubscribe[u](); - } - }); - - } - }; -} - -/** -* @ngdoc directive -* @name umbraco.directives.directive:valToggleMsg -* @restrict A -* @element input -* @requires formController -* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ? -**/ +function valToggleMsg(serverValidationManager) { + return { + require: "^form", + restrict: "A", + + /** + Our directive requries a reference to a form controller which gets passed in to this parameter + */ + link: function (scope, element, attr, formCtrl) { + + if (!attr.valToggleMsg){ + throw "valToggleMsg requires that a reference to a validator is specified"; + } + if (!attr.valMsgFor){ + throw "valToggleMsg requires that the attribute valMsgFor exists on the element"; + } + if (!formCtrl[attr.valMsgFor]) { + throw "valToggleMsg cannot find field " + attr.valMsgFor + " on form " + formCtrl.$name; + } + + //if there's any remaining errors in the server validation service then we should show them. + var showValidation = serverValidationManager.items.length > 0; + var hasCustomMsg = element.contents().length > 0; + + //add a watch to the validator for the value (i.e. myForm.value.$error.required ) + scope.$watch(function () { + //sometimes if a dialog closes in the middle of digest we can get null references here + + return (formCtrl && formCtrl[attr.valMsgFor]) ? formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] : null; + }, function () { + //sometimes if a dialog closes in the middle of digest we can get null references here + if ((formCtrl && formCtrl[attr.valMsgFor])) { + if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg] && showValidation) { + element.show(); + //display the error message if this element has no contents + if (!hasCustomMsg) { + element.html(formCtrl[attr.valMsgFor].errorMsg); + } + } + else { + element.hide(); + } + } + }); + + var unsubscribe = []; + + //listen for the saving event (the result is a callback method which is called to unsubscribe) + unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { + showValidation = true; + if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) { + element.show(); + //display the error message if this element has no contents + if (!hasCustomMsg) { + element.html(formCtrl[attr.valMsgFor].errorMsg); + } + } + else { + element.hide(); + } + })); + + //listen for the saved event (the result is a callback method which is called to unsubscribe) + unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { + showValidation = false; + element.hide(); + })); + + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise if this directive is part of a modal, the listener still exists because the dom + // element might still be there even after the modal has been hidden. + element.bind('$destroy', function () { + for (var u in unsubscribe) { + unsubscribe[u](); + } + }); + + } + }; +} + +/** +* @ngdoc directive +* @name umbraco.directives.directive:valToggleMsg +* @restrict A +* @element input +* @requires formController +* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ? +**/ angular.module('umbraco.directives.validation').directive("valToggleMsg", valToggleMsg); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtriggerchange.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js similarity index 100% rename from src/Umbraco.Web.UI.Client/src/common/directives/components/validation/valtriggerchange.directive.js rename to src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js index 6d83c1b907..04194838ab 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js @@ -109,11 +109,16 @@ function iconHelper($q, $timeout) { }, formatContentTypeIcons: function (contentTypes) { for (var i = 0; i < contentTypes.length; i++) { - contentTypes[i].icon = this.convertFromLegacyIcon(contentTypes[i].icon); + if (!contentTypes[i].icon) { + //just to be safe (e.g. when focus was on close link and hitting save) + contentTypes[i].icon = "icon-document"; // default icon + } else { + contentTypes[i].icon = this.convertFromLegacyIcon(contentTypes[i].icon); + } //couldnt find replacement if(contentTypes[i].icon.indexOf(".") > 0){ - contentTypes[i].icon = "icon-document-dashed-line"; + contentTypes[i].icon = "icon-document-dashed-line"; } } return contentTypes; @@ -128,6 +133,10 @@ function iconHelper($q, $timeout) { }, /** If the icon is legacy */ isLegacyIcon: function (icon) { + if(!icon) { + return false; + } + if(icon.startsWith('..')){ return false; } diff --git a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js index 42d50b1ce7..0d3b56991e 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js @@ -19,7 +19,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ { value: "assets/img/application/logo@3x.png" } ]; $scope.touchDevice = appState.getGlobalState("touchDevice"); - + $scope.removeNotification = function (index) { notificationsService.remove(index); @@ -28,12 +28,12 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ $scope.closeDialogs = function (event) { //only close dialogs if non-link and non-buttons are clicked var el = event.target.nodeName; - var els = ["INPUT","A","BUTTON"]; + var els = ["INPUT", "A", "BUTTON"]; - if(els.indexOf(el) >= 0){return;} + if (els.indexOf(el) >= 0) { return; } var parents = $(event.target).parents("a,button"); - if(parents.length > 0){ + if (parents.length > 0) { return; } @@ -49,31 +49,31 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ var evts = []; //when a user logs out or timesout - evts.push(eventsService.on("app.notAuthenticated", function() { + evts.push(eventsService.on("app.notAuthenticated", function () { $scope.authenticated = null; $scope.user = null; })); - + //when the app is read/user is logged in, setup the data evts.push(eventsService.on("app.ready", function (evt, data) { - + $scope.authenticated = data.authenticated; $scope.user = data.user; - updateChecker.check().then(function(update){ - if(update && update !== "null"){ - if(update.type !== "None"){ + updateChecker.check().then(function(update) { + if (update && update !== "null") { + if (update.type !== "None") { var notification = { - headline: "Update available", - message: "Click to download", - sticky: true, - type: "info", - url: update.url + headline: "Update available", + message: "Click to download", + sticky: true, + type: "info", + url: update.url }; notificationsService.add(notification); } } - }) + }); //if the user has changed we need to redirect to the root so they don't try to continue editing the //last item in the URL (NOTE: the user id can equal zero, so we cannot just do !data.lastUserId since that will resolve to true) @@ -91,38 +91,40 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ if ($scope.user.emailHash) { //let's attempt to load the avatar, it might not exist or we might not have - // internet access so we'll detect it first - $http.get("https://www.gravatar.com/avatar/" + $scope.user.emailHash + ".jpg?s=64&d=404") + // internet access, well get an empty string back + $http.get(umbRequestHelper.getApiUrl("gravatarApiBaseUrl", "GetCurrentUserGravatarUrl")) .then( - function successCallback(response) { - $("#avatar-img").fadeTo(1000, 0, function () { - $scope.$apply(function () { - //this can be null if they time out - if ($scope.user && $scope.user.emailHash) { - var avatarBaseUrl = "https://www.gravatar.com/avatar/", - hash = $scope.user.emailHash; + function successCallback(response) { + // if we can't download the gravatar for some reason, an null gets returned, we cannot do anything + if (response.data !== "null") { + $("#avatar-img").fadeTo(1000, 0, function () { + $scope.$apply(function () { + //this can be null if they time out + if ($scope.user && $scope.user.emailHash) { + var avatarBaseUrl = "https://www.gravatar.com/avatar/", + hash = $scope.user.emailHash; - $scope.avatar = [ - { value: avatarBaseUrl + hash + ".jpg?s=30&d=mm" }, - { value: avatarBaseUrl + hash + ".jpg?s=60&d=mm" }, - { value: avatarBaseUrl + hash + ".jpg?s=90&d=mm" } - ]; - } + $scope.avatar = [ + { value: avatarBaseUrl + hash + ".jpg?s=30&d=mm" }, + { value: avatarBaseUrl + hash + ".jpg?s=60&d=mm" }, + { value: avatarBaseUrl + hash + ".jpg?s=90&d=mm" } + ]; + } + }); + $("#avatar-img").fadeTo(1000, 1); }); - $("#avatar-img").fadeTo(1000, 1); - }); + } }, function errorCallback(response) { //cannot load it from the server so we cannot do anything }); } - })); - evts.push(eventsService.on("app.ysod", function(name, error) { + evts.push(eventsService.on("app.ysod", function (name, error) { $scope.ysodOverlay = { view: "ysod", error: error, - show: true + show: true }; })); diff --git a/src/Umbraco.Web.UI.Client/src/less/hacks.less b/src/Umbraco.Web.UI.Client/src/less/hacks.less index 0d41eed050..fb809af015 100644 --- a/src/Umbraco.Web.UI.Client/src/less/hacks.less +++ b/src/Umbraco.Web.UI.Client/src/less/hacks.less @@ -63,9 +63,13 @@ iframe, .content-column-body { /*tree legacy icon*/ -.legacy-custom-file{ - width: 16px; height: 16px; margin-right: 11px; display: inline-block; +.legacy-custom-file { + width: 16px; + height: 16px; + min-width: 20px; /* this ensure the icon takes up same space as font-icon (20px) */ + display: inline-block; background-position: center center; + background-repeat: no-repeat; } /* diff --git a/src/Umbraco.Web.UI.Client/src/less/pages/login.less b/src/Umbraco.Web.UI.Client/src/less/pages/login.less index 6805783a86..892977180e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/pages/login.less +++ b/src/Umbraco.Web.UI.Client/src/less/pages/login.less @@ -13,7 +13,9 @@ left: 0; margin: 0 !important; padding: 0; + border: none; border-radius: 0; + overflow-y: auto; } @@ -50,7 +52,7 @@ } .login-overlay .form { - position:fixed; + position:relative; display: block; top: 100px; left: 165px; @@ -78,11 +80,30 @@ margin-top: 10px; } +@media (max-width: 767px) and (max-height: 420px) and (orientation: landscape) { + // Move form closer to top on narrow screen sizes + .login-overlay .form { + top: 50px; + } +} + @media (max-width: 565px) { // Remove padding on login-form on smaller devices .login-overlay .form { + top: 60px; + right: 25px; left: inherit; - right:25px; + padding-left: 25px; + padding-right:25px; + width: auto; + } +} + +@media (max-width: 339px) { + .login-overlay .form { + input[type="text"], input[type="password"] { + width: 250px; + } } } diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index a06484b8a0..85a1d9e36c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -201,6 +201,15 @@ ul.color-picker li a { margin: 5px; background: white; border: 1px solid #f8f8f8; + + max-width: 100%; +} + + +.umb-mediapicker .umb-sortable-thumbnails li { + flex-direction: column; + margin: 0; + padding: 5px; } @@ -289,7 +298,7 @@ ul.color-picker li a { } .umb-cropper img { - max-width: initial; + max-width: none; } .umb-cropper .overlay, .umb-cropper-gravity .overlay { @@ -384,6 +393,7 @@ ul.color-picker li a { } .umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder { display: inline-block; + max-width: 100%; } .umb-cropper-imageholder { diff --git a/src/Umbraco.Web.UI.Client/src/less/sections.less b/src/Umbraco.Web.UI.Client/src/less/sections.less index c2db58a99e..c89be83a10 100644 --- a/src/Umbraco.Web.UI.Client/src/less/sections.less +++ b/src/Umbraco.Web.UI.Client/src/less/sections.less @@ -22,6 +22,8 @@ ul.sections li [class^="icon-"]:before, ul.sections li [class*=" icon-"]:before, ul.sections li img.icon-section { font-size: 30px; + line-height: 20px; /* set line-height to ensure all icons use same line-height */ + display: inline-block; margin: 1px 0 0 0; opacity: 0.4; -webkit-transition: all .3s linear; diff --git a/src/Umbraco.Web.UI.Client/src/less/tree.less b/src/Umbraco.Web.UI.Client/src/less/tree.less index 35de441137..d809418f2c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/tree.less +++ b/src/Umbraco.Web.UI.Client/src/less/tree.less @@ -155,6 +155,11 @@ display: flex; } +.umb-tree li > div:hover a:not(.umb-options) { + overflow: hidden; + margin-right: 6px; +} + .umb-tree .icon { vertical-align: middle; margin: 0 13px 0 0; @@ -203,7 +208,9 @@ content: "\e165"; } -.umb-tree .umb-tree-node-checked i { +.umb-tree .umb-tree-node-checked i[class^="icon-"], +.umb-tree .umb-tree-node-checked i[class*=" icon-"] { + font-family: 'icomoon' !important; color:@blue !important; } .umb-tree .umb-tree-node-checked i:before { @@ -480,7 +487,6 @@ div.locked:before{ width:100%; height:1px; overflow:hidden; - position: absolute; left: 0; bottom: 0; @@ -498,15 +504,18 @@ div.locked:before{ /*body.touch .umb-tree .icon{font-size: 19px;}*/ body.touch .umb-tree ins{font-size: 14px; visibility: visible; padding: 7px;} -body.touch .umb-tree li div { +body.touch .umb-tree li > div { padding-top: 8px; padding-bottom: 8px; font-size: 110%; } -body.touch .umb-actions a{ - padding: 7px 25px 7px 20px; - font-size: 110%; +// change height of this if touch devices should have a different height of preloader. +body.touch .umb-tree li div.l div { + padding: 0; } -body.touch a.umb-options i {margin-top: 20px;} +body.touch .umb-actions a { + padding: 7px 25px 7px 20px; + font-size: 110%; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.controller.js index de71977ebe..ec1ad6e663 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.controller.js @@ -7,13 +7,14 @@ angular.module("umbraco") $scope.icons = icons; }); - $scope.submitClass = function(icon){ - if($scope.color) - { + $scope.submitClass = function (icon) { + if($scope.color) { $scope.submit(icon + " " + $scope.color); - }else{ - $scope.submit(icon); + } + else { + $scope.submit(icon); } }; + } ); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.html index 260d8ff85c..96ab990447 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/iconpicker.html @@ -4,10 +4,11 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/common/notifications/confirmroutechange.html b/src/Umbraco.Web.UI.Client/src/views/common/notifications/confirmroutechange.html index 80942baaeb..0b2926307c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/notifications/confirmroutechange.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/notifications/confirmroutechange.html @@ -1,7 +1,7 @@
    -

    You have unsaved changes

    -

    Are you sure you want to navigate away from this page? - you have unsaved changes

    +

    You have unsaved changes

    +

    Are you sure you want to navigate away from this page? - you have unsaved changes

    - - -
    + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html index 83a02a4504..0091289e6e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html @@ -9,7 +9,8 @@ class="umb-search-field search-query input-block-level" localize="placeholder" placeholder="@placeholders_filter" - umb-auto-focus> + umb-auto-focus + no-dirty-check> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html index 9bc0839122..472408468b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/overlays/umb-overlay.html @@ -66,6 +66,7 @@ label="{{model.submitButtonLabel}}" ng-if="model.submit && model.hideSubmitButton !== true" type="button" + disabled="model.disableSubmitButton" action="submitForm(model)"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html index 567d00c871..3533255288 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html @@ -49,7 +49,7 @@
    -
    +
    + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html index 3061f01c29..9d9626694a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html @@ -1,5 +1,5 @@
    -
    +

    diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 518c27d110..594475a7d2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -1,4 +1,4 @@ -function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService) { +function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService, navigationService, treeService) { //this is a quick check to see if we're in create mode, if so just exit - we cannot show children for content // that isn't created yet, if we continue this will use the parent id in the route params which isn't what @@ -357,7 +357,7 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie $scope.actionInProgress = true; $scope.bulkStatus = getStatusMsg(0, selected.length); - serial(selected, fn, getStatusMsg, 0).then(function (result) { + return serial(selected, fn, getStatusMsg, 0).then(function (result) { // executes once the whole selection has been processed // in case of an error (caught by serial), result will be the error if (!(result.data && angular.isArray(result.data.notifications))) @@ -366,11 +366,24 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie } $scope.delete = function () { - applySelected( - function (selected, index) { return deleteItemCallback(getIdCallback(selected[index])); }, - function (count, total) { return "Deleted " + count + " out of " + total + " item" + (total > 1 ? "s" : ""); }, - function (total) { return "Deleted " + total + " item" + (total > 1 ? "s" : ""); }, - "Sure you want to delete?"); + + var attempt = + applySelected( + function(selected, index) { return deleteItemCallback(getIdCallback(selected[index])); }, + function(count, total) { + return "Deleted " + count + " out of " + total + " item" + (total > 1 ? "s" : ""); + }, + function(total) { return "Deleted " + total + " item" + (total > 1 ? "s" : ""); }, + "Sure you want to delete?"); + if (attempt) { + attempt.then(function () { + //executes if all is successful, let's sync the tree + var activeNode = appState.getTreeState("selectedNode"); + if (activeNode) { + navigationService.reloadNode(activeNode); + } + }); + } }; $scope.publish = function () { @@ -412,12 +425,37 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie }; + function performMove(target) { - applySelected( - function (selected, index) { return contentResource.move({ parentId: target.id, id: getIdCallback(selected[index]) }); }, - function (count, total) { return "Moved " + count + " out of " + total + " item" + (total > 1 ? "s" : ""); }, - function (total) { return "Moved " + total + " item" + (total > 1 ? "s" : ""); }); + //NOTE: With the way this applySelected/serial works, I'm not sure there's a better way currently to return + // a specific value from one of the methods, so we'll have to try this way. Even though the first method + // will fire once per every node moved, the destination path will be the same and we need to use that to sync. + var newPath = null; + applySelected( + function(selected, index) { + return contentResource.move({ parentId: target.id, id: getIdCallback(selected[index]) }).then(function(path) { + newPath = path; + return path; + }); + }, + function(count, total) {return "Moved " + count + " out of " + total + " item" + (total > 1 ? "s" : "");}, + function(total) { return "Moved " + total + " item" + (total > 1 ? "s" : ""); }) + .then(function() { + //executes if all is successful, let's sync the tree + if (newPath) { + + //we need to do a double sync here: first refresh the node where the content was moved, + // then refresh the node where the content was moved from + navigationService.syncTree({ tree: target.nodeType, path: newPath, forceReload: true, activate: false }).then(function (args) { + //get the currently edited node (if any) + var activeNode = appState.getTreeState("selectedNode"); + if (activeNode) { + navigationService.reloadNode(activeNode); + } + }); + } + }); } $scope.copy = function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index 904939b75f..742d1251cb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -11,7 +11,7 @@ -
  • + - {{ selectedItemsCount() }} of {{ listViewResultSet.items.length }} selected + {{ selectedItemsCount() }} of {{ listViewResultSet.items.length }} selected
    @@ -86,7 +93,7 @@ type="button" button-style="link" label="Publish" - key="actions_publish" + label-key="actions_publish" icon="icon-globe" action="publish()" disabled="actionInProgress"> @@ -97,7 +104,7 @@ type="button" button-style="link" label="Unpublish" - key="actions_unpublish" + label-key="actions_unpublish" icon="icon-block" action="unpublish()" disabled="actionInProgress"> @@ -108,7 +115,7 @@ type="button" button-style="link" label="Copy" - key="actions_copy" + label-key="actions_copy" icon="icon-documents" action="copy()" disabled="actionInProgress"> @@ -119,7 +126,7 @@ type="button" button-style="link" label="Move" - key="actions_move" + label-key="actions_move" icon="icon-enter" action="move()" disabled="actionInProgress"> @@ -129,8 +136,8 @@ ng-if="options.allowBulkDelete && (buttonPermissions == null || buttonPermissions.canDelete)" type="button" button-style="link" - label="Delete" - key="actions_delete" + label="Delete" + label-key="actions_delete" icon="icon-trash" action="delete()" disabled="actionInProgress"> diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index 9969af937d..bbf61a32d3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -6,6 +6,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl //check the pre-values for multi-picker var multiPicker = $scope.model.config.multiPicker && $scope.model.config.multiPicker !== '0' ? true : false; var onlyImages = $scope.model.config.onlyImages && $scope.model.config.onlyImages !== '0' ? true : false; + var disableFolderSelect = $scope.model.config.disableFolderSelect && $scope.model.config.disableFolderSelect !== '0' ? true : false; if (!$scope.model.config.startNodeId) { userService.getCurrentUser().then(function (userData) { @@ -68,6 +69,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl startNodeId: $scope.model.config.startNodeId, multiPicker: multiPicker, onlyImages: onlyImages, + disableFolderSelect: disableFolderSelect, show: true, submit: function(model) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/handle.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/handle.prevalues.html index e12cb2a869..ae5deb099c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/handle.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/handle.prevalues.html @@ -1,5 +1,5 @@ 
    - diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 145503e3f8..cc804e8036 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -1,5 +1,7 @@  + + 9.0.30729 @@ -49,6 +51,8 @@ true true + + bin\ @@ -200,6 +204,10 @@ ..\packages\Microsoft.CodeAnalysis.CSharp.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll True + + ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + True + ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll @@ -1024,13 +1032,12 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" - + - @@ -1051,4 +1058,11 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml index 20e252c431..0bdb4a8453 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml @@ -179,6 +179,12 @@ Navštívit Vítejte + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Název Spravovat názvy hostitelů diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml index 12031dc0e0..3d422d0a9b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml @@ -186,6 +186,12 @@ Besøk Velkommen + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Navn på lokal link Rediger domener diff --git a/src/Umbraco.Web.UI/config/ExamineIndex.config b/src/Umbraco.Web.UI/config/ExamineIndex.config index 7212053ca0..a853847ecb 100644 --- a/src/Umbraco.Web.UI/config/ExamineIndex.config +++ b/src/Umbraco.Web.UI/config/ExamineIndex.config @@ -9,10 +9,10 @@ More information and documentation can be found on CodePlex: http://umbracoexami - + - + @@ -25,6 +25,6 @@ More information and documentation can be found on CodePlex: http://umbracoexami - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 200c30648c..8794ad6d48 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -37,6 +37,8 @@ --> 1 + 1079 + 1080 diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index c71c7d3d75..be5c82d0e4 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -21,6 +21,8 @@ + + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index df4318ec2a..3cbed82354 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -60,6 +60,7 @@ For + Ryd valg Vælg Vælg nuværende mappe Gør noget andet @@ -165,6 +166,10 @@ Klik for at uploade Slip filerne her... + Link til medie + eller klik her for at vælge filer + Tilladte filtyper er kun + Maks filstørrelse er Opret et nyt medlem @@ -187,6 +192,12 @@ Besøg Velkommen + + Bliv + Kassér ændringer + Du har ikke-gemte ændringer + Er du sikker på du vil navigere væk fra denne side? - du har ikke-gemte ændringer + Navn på lokalt link Rediger domæner @@ -197,7 +208,7 @@ Er du sikker på at du vil forlade Umbraco? Er du sikker? Klip - Rediger ordbogs nøgle + Rediger ordbogsnøgle Rediger sprog Indsæt lokalt link Indsæt tegn @@ -421,8 +432,8 @@ Listevisning Gemmer... nuværende - Flyt Indlejring + valgt @@ -985,7 +996,7 @@ Mange hilsner fra Umbraco robotten Roller Medlemstype Dokumenttyper - Dokumenttyper + Relationstyper Pakker Pakker Python diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/de.xml b/src/Umbraco.Web.UI/umbraco/config/lang/de.xml index 4bb906f983..3428323a71 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/de.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/de.xml @@ -186,6 +186,12 @@ Besuchen Willkommen + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Name Hostnamen verwalten diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index e3ea6f3120..ebd1b19df6 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -65,6 +65,7 @@ Viewing for + Clear selection Select Select current folder Do something else @@ -147,6 +148,7 @@ Properties This document is published but is not visible because the parent '%0%' is unpublished Oops: this document is published but is not in the cache (internal error) + Oops: this document is published but its url would collide with content %0% Publish Publication Status Publish at @@ -171,7 +173,7 @@ Click to upload Drop your files here... - Link to media + Link to media or click here to choose files Only allowed file types are Max file size is @@ -198,6 +200,12 @@ Visit Welcome + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Name Manage hostnames @@ -482,8 +490,8 @@ List view Saving... current - Move Embed + selected @@ -813,14 +821,14 @@ To manage your website, simply open the Umbraco back office and start adding con - Include unpublished child pages + Include unpublished subpages Publishing in progress - please wait... %0% out of %1% pages have been published... %0% has been published %0% and subpages have been published Publish %0% and all its subpages - ok to publish %0% and thereby making its content publicly available.

    - You can publish this page and all it's sub-pages by checking publish all children below. + Publish to publish %0% and thereby making its content publicly available.

    + You can publish this page and all its subpages by checking Include unpublished subpages below. ]]>
    @@ -1161,6 +1169,7 @@ To manage your website, simply open the Umbraco back office and start adding con To close a translation task, please go to the Details view and click the "Close" button. ]]>
    The page '%0%' has been send to translation + Please select the language that the content should be translated into Send the page '%0%' to translation Assigned by Task opened diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index d8d78a70ab..9505312459 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -65,6 +65,7 @@ Viewing for + Clear selection Select Select current folder Do something else @@ -148,6 +149,7 @@ Properties This document is published but is not visible because the parent '%0%' is unpublished Oops: this document is published but is not in the cache (internal error) + Oops: this document is published but its url would collide with content %0% Publish Publication Status Publish at @@ -200,6 +202,12 @@ Visit Welcome + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Name Manage hostnames @@ -486,8 +494,8 @@ List view Saving... current - Move Embed + selected Black @@ -671,7 +679,7 @@ To manage your website, simply open the Umbraco back office and start adding con Umbraco: Reset Password Your username to login to the Umbraco back-office is: %0%

    Click here to reset your password or copy/paste this URL into your browser:

    %1%

    ]]> -
    + Dashboard @@ -812,14 +820,14 @@ To manage your website, simply open the Umbraco back office and start adding con - Include unpublished child pages + Include unpublished subpages Publishing in progress - please wait... %0% out of %1% pages have been published... %0% has been published %0% and subpages have been published Publish %0% and all its subpages - ok to publish %0% and thereby making its content publicly available.

    - You can publish this page and all it's sub-pages by checking publish all children below. + Publish to publish %0% and thereby making its content publicly available.

    + You can publish this page and all its subpages by checking Include unpublished subpages below. ]]>
    @@ -1166,6 +1174,7 @@ To manage your website, simply open the Umbraco back office and start adding con To close a translation task, please go to the Details view and click the "Close" button. ]]>
    The page '%0%' has been send to translation + Please select the language that the content should be translated into Send the page '%0%' to translation Assigned by Task opened diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/es.xml b/src/Umbraco.Web.UI/umbraco/config/lang/es.xml index 097c028d2b..931d18c41d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/es.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/es.xml @@ -185,6 +185,12 @@ Visita Bienvenido + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Nombre Administrar dominios diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml index 853f1b11f1..55d25b4eff 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml @@ -181,6 +181,12 @@ Visiter Bienvenue + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Name Gérer les noms d'hôtes diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml index e42c382b20..f1a2ed358f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml @@ -131,6 +131,12 @@ בקר ברוכים הבאים + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + שם ניהול שם מתחם diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/it.xml b/src/Umbraco.Web.UI/umbraco/config/lang/it.xml index 039d727044..fa125dc842 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/it.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/it.xml @@ -127,6 +127,12 @@ Visita Benvenuto + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Nome Gestione alias Hostnames diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml index bbe3152464..21d85268fa 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml @@ -194,6 +194,12 @@ 訪れる ようこそ + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + 名前 ドメインの割り当て diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml index 8435cb9c48..58d5778892 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml @@ -125,6 +125,12 @@ 방문 환영합니다 + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + 이름 호스트네임 관리 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml index d69d5954dd..5bbe4f634c 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml @@ -188,6 +188,12 @@ Bezoek Welkom + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Naam Beheer domeinnamen diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml index dbdefcb6c2..db911b07b7 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml @@ -125,6 +125,12 @@ Odwiedź Witaj + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Nazwa Zarządzaj nazwami hostów diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml index 86887b00df..15ca527821 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml @@ -125,6 +125,12 @@ Visitar Bem Vindo(a) + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Nome Gerenciar hostnames diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml index 09edfdeb6a..216de9f9ab 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml @@ -254,6 +254,12 @@ Посетить Рады приветствовать + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Название Управление доменами diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml index ae7e8a479e..5ed13a0bf4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml @@ -181,6 +181,12 @@ Välkommen Besök + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Namn Hantera domännamn diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml index 4e25e92ef2..d703dee135 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml @@ -166,6 +166,12 @@ 访问 欢迎 + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + 锚点名称 管理主机名 diff --git a/src/Umbraco.Web.UI/umbraco/developer/Packages/editPackage.aspx b/src/Umbraco.Web.UI/umbraco/developer/Packages/editPackage.aspx index 82746bb7c2..edea60c62b 100644 --- a/src/Umbraco.Web.UI/umbraco/developer/Packages/editPackage.aspx +++ b/src/Umbraco.Web.UI/umbraco/developer/Packages/editPackage.aspx @@ -75,7 +75,7 @@
    - Include all child nodes + diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js index b8c1a203d6..e3a3ee4bf2 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js +++ b/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js @@ -7,9 +7,9 @@ _opts: null, _openMacroModal: function(alias) { - + var self = this; - + UmbClientMgr.openAngularModalWindow({ template: "views/common/dialogs/insertmacro.html", dialogData: { @@ -66,7 +66,7 @@ constructor: function(opts) { // Merge options with default this._opts = $.extend({ - + // Default options go here }, opts); @@ -82,7 +82,7 @@ event.preventDefault(); self.doSubmit(); }); - + $("#sb").click(function() { self._insertCodeBlock(); }); @@ -112,7 +112,7 @@ }); }, - doSubmit: function() { + doSubmit: function() { this.save(jQuery('#' + this._opts.templateNameClientId).val(), jQuery('#' + this._opts.templateAliasClientId).val(), UmbEditor.GetCode()); }, @@ -134,7 +134,7 @@ self.submitFailure(e.message, e.header); } }); - + }, submitSuccess: function (args) { @@ -151,7 +151,10 @@ if (args.contents) { UmbEditor.SetCode(args.contents); } - + + var alias = args.alias; + this._opts.aliasTxtBox.val(alias); + top.UmbSpeechBubble.ShowMessage('save', header, msg); UmbClientMgr.mainTree().setActiveTreeType('templates'); if (pathChanged) { @@ -167,7 +170,7 @@ top.UmbSpeechBubble.ShowMessage('error', header, err); } }); - + //Set defaults for jQuery ajax calls. $.ajaxSetup({ dataType: 'json', diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js index 87b180ce2d..a93f4cf815 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js +++ b/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js @@ -33,19 +33,19 @@ insertMacroMarkup: function(alias) { /// callback used to insert the markup for a macro with no parameters - + UmbEditor.Insert("@Umbraco.RenderMacro(\"" + alias + "\")", "", this._opts.codeEditorElementId); }, insertRenderBody: function() { UmbEditor.Insert("@RenderBody()", "", this._opts.codeEditorElementId); }, - + openMacroModal: function (alias) { /// callback used to display the modal dialog to insert a macro with parameters - + var self = this; - + UmbClientMgr.openAngularModalWindow({ template: "views/common/dialogs/insertmacro.html", dialogData: { @@ -141,7 +141,7 @@ }); } else { - //saving a partial view + //saving a partial view var actionName = this._opts.editorType === "PartialViewMacro" ? "SavePartialViewMacro" : "SavePartialView"; $.post(self._opts.restServiceLocation + actionName, @@ -159,9 +159,9 @@ }); } }, - + submitSuccess: function (args) { - + var msg = args.message; var header = args.header; var path = this._opts.treeSyncPath; @@ -183,6 +183,9 @@ if (this._opts.editorType == "Template") { + var alias = args.alias; + this._opts.aliasTxtBox.val(alias); + top.UmbSpeechBubble.ShowMessage('save', header, msg); //templates are different because they are ID based, whereas view files are file based without a static id @@ -194,12 +197,12 @@ else { UmbClientMgr.mainTree().syncTree(path, true); } - + } else { var newFilePath = this._opts.nameTxtBox.val(); - + function trimStart(str, trim) { if (str.startsWith(trim)) { return str.substring(trim.length); @@ -219,12 +222,12 @@ var newLocation = window.location.pathname + "?" + notFileParts.join("&") + "&file=" + newFilePath; UmbClientMgr.contentFrame(newLocation); - + //we need to do this after we navigate otherwise the navigation will wait unti lthe message timeout is done! top.UmbSpeechBubble.ShowMessage('save', header, msg); } else { - + top.UmbSpeechBubble.ShowMessage('save', header, msg); if (args && args.name) { @@ -235,15 +238,15 @@ } UmbClientMgr.mainTree().syncTree(path, true, null, newFilePath.split("/")[1]); - } + } } - + }, - + submitFailure: function (err, header) { - top.UmbSpeechBubble.ShowMessage('error', header, err); + top.UmbSpeechBubble.ShowMessage('error', header, err); }, - + changeMasterPageFile: function ( ) { //var editor = document.getElementById(this._opts.sourceEditorId); var templateDropDown = this._opts.masterPageDropDown.get(0); @@ -279,7 +282,7 @@ $.ajaxSetup({ dataType: 'json', cache: false, - contentType: 'application/json; charset=utf-8' + contentType: 'application/json; charset=utf-8' }); })(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web/ApplicationContextExtensions.cs b/src/Umbraco.Web/ApplicationContextExtensions.cs index fcbcab1628..b91e73df0d 100644 --- a/src/Umbraco.Web/ApplicationContextExtensions.cs +++ b/src/Umbraco.Web/ApplicationContextExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.Threading; using System.Web; using Umbraco.Core; @@ -7,24 +6,25 @@ namespace Umbraco.Web { public static class ApplicationContextExtensions { - /// - /// This will restart the application pool - /// - /// - /// - public static void RestartApplicationPool(this ApplicationContext appContext, HttpContextBase http) - { + /// + /// Restarts the application pool by unloading the application domain. + /// + /// + /// + public static void RestartApplicationPool(this ApplicationContext appContext, HttpContextBase http) + { + // we're going to put an application wide flag to show that the application is about to restart. + // we're doing this because if there is a script checking if the app pool is fully restarted, then + // it can check if this flag exists... if it does it means the app pool isn't restarted yet. + http.Application.Add("AppPoolRestarting", true); - //we're going to put an application wide flag to show that the application is about to restart. - //we're doing this because if there is a script checking if the app pool is fully restarted, then - //it can check if this flag exists... if it does it means the app pool isn't restarted yet. - http.Application.Add("AppPoolRestarting", true); - - //NOTE: this real way only works in full trust :( - //HttpRuntime.UnloadAppDomain(); - //so we'll do the dodgy hack instead - var configPath = http.Request.PhysicalApplicationPath + "\\web.config"; - File.SetLastWriteTimeUtc(configPath, DateTime.UtcNow); + // unload app domain - we must null out all identities otherwise we get serialization errors + // http://www.zpqrtbnk.net/posts/custom-iidentity-serialization-issue + http.User = null; + if (HttpContext.Current != null) + HttpContext.Current.User = null; + Thread.CurrentPrincipal = null; + HttpRuntime.UnloadAppDomain(); } } } diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 99bceffdc7..8fe00c6061 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -295,6 +295,10 @@ namespace Umbraco.Web.Editors "logApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetEntityLog(0)) }, + { + "gravatarApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( + controller => controller.GetCurrentUserGravatarUrl()) + }, { "memberApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetByKey(Guid.Empty)) diff --git a/src/Umbraco.Web/Editors/GravatarController.cs b/src/Umbraco.Web/Editors/GravatarController.cs new file mode 100644 index 0000000000..f1e184dce7 --- /dev/null +++ b/src/Umbraco.Web/Editors/GravatarController.cs @@ -0,0 +1,38 @@ +using System; +using System.Net; +using Umbraco.Core; +using Umbraco.Web.Mvc; + +namespace Umbraco.Web.Editors +{ + /// + /// API controller used for getting Gravatar urls + /// + [PluginController("UmbracoApi")] + public class GravatarController : UmbracoAuthorizedJsonController + { + public string GetCurrentUserGravatarUrl() + { + var userService = Services.UserService; + var user = userService.GetUserById(UmbracoContext.Security.CurrentUser.Id); + var gravatarHash = user.Email.ToMd5(); + var gravatarUrl = "https://www.gravatar.com/avatar/" + gravatarHash; + + // Test if we can reach this URL, will fail when there's network or firewall errors + var request = (HttpWebRequest)WebRequest.Create(gravatarUrl); + // Require response within 10 seconds + request.Timeout = 10000; + try + { + using ((HttpWebResponse)request.GetResponse()) { } + } + catch (Exception) + { + // There was an HTTP or other error, return an null instead + return null; + } + + return gravatarUrl; + } + } +} diff --git a/src/Umbraco.Web/Install/InstallHelper.cs b/src/Umbraco.Web/Install/InstallHelper.cs index 7d663bbc03..f0e0ed5d2e 100644 --- a/src/Umbraco.Web/Install/InstallHelper.cs +++ b/src/Umbraco.Web/Install/InstallHelper.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.Install { return new List { - new NewInstallStep(_umbContext.Application), + new NewInstallStep(_umbContext.HttpContext, _umbContext.Application), new UpgradeStep(), new FilePermissionsStep(), new MajorVersion7UpgradeReport(_umbContext.Application), diff --git a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs index baa94c304e..4d8e9c5a4b 100644 --- a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; +using System.Web; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Configuration; @@ -22,10 +23,12 @@ namespace Umbraco.Web.Install.InstallSteps "User", 20, "")] internal class NewInstallStep : InstallSetupStep { + private readonly HttpContextBase _http; private readonly ApplicationContext _applicationContext; - public NewInstallStep(ApplicationContext applicationContext) + public NewInstallStep(HttpContextBase http, ApplicationContext applicationContext) { + _http = http; _applicationContext = applicationContext; } @@ -111,7 +114,7 @@ namespace Umbraco.Web.Install.InstallSteps //the continue install UI : "continueinstall"; } } - + public override bool RequiresExecution(UserModel model) { //now we have to check if this is really a new install, the db might be configured and might contain data @@ -136,6 +139,10 @@ namespace Umbraco.Web.Install.InstallSteps } else { + // In this one case when it's a brand new install and nothing has been configured, make sure the + // back office cookie is cleared so there's no old cookies lying around causing problems + _http.ExpireCookie(UmbracoConfig.For.UmbracoSettings().Security.AuthCookieName); + return true; } } diff --git a/src/Umbraco.Web/LightInjectExtensions.cs b/src/Umbraco.Web/LightInjectExtensions.cs index 23fa1dbc81..247afe0926 100644 --- a/src/Umbraco.Web/LightInjectExtensions.cs +++ b/src/Umbraco.Web/LightInjectExtensions.cs @@ -16,6 +16,10 @@ namespace Umbraco.Web /// public static void RegisterMvcControllers(this IServiceRegistry container, PluginManager pluginManager) { + //TODO: We've already scanned for UmbracoApiControllers and SurfaceControllers - should we scan again + // for all controllers? Seems like we should just do this once and then filter. That said here we are + // only scanning our own single assembly. Hrm. + var types = pluginManager.ResolveTypes(specificAssemblies: new[] { Assembly.GetCallingAssembly() }); foreach (var type in types) { @@ -30,6 +34,10 @@ namespace Umbraco.Web /// public static void RegisterApiControllers(this IServiceRegistry container, PluginManager pluginManager) { + //TODO: We've already scanned for UmbracoApiControllers and SurfaceControllers - should we scan again + // for all controllers? Seems like we should just do this once and then filter. That said here we are + // only scanning our own single assembly. Hrm. + var types = pluginManager.ResolveTypes(specificAssemblies: new[] { Assembly.GetCallingAssembly() }); foreach (var type in types) { diff --git a/src/Umbraco.Web/Models/ContentExtensions.cs b/src/Umbraco.Web/Models/ContentExtensions.cs index b8ce099122..6f7aeb8070 100644 --- a/src/Umbraco.Web/Models/ContentExtensions.cs +++ b/src/Umbraco.Web/Models/ContentExtensions.cs @@ -49,6 +49,8 @@ namespace Umbraco.Web.Models ? null // for tests only : umbracoContext.ContentCache.GetRouteById(contentId); // cached + if (route != null && route.StartsWith("err/")) route = null; + var domainCache = umbracoContext == null ? new PublishedCache.XmlPublishedCache.DomainCache(domainService) // for tests only : umbracoContext.Facade.DomainCache; // default diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs index 37c0f025f3..b3e851a25e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs @@ -15,6 +15,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Trees; using Umbraco.Web.Routing; using Umbraco.Core.PropertyEditors; +using Umbraco.Web._Legacy.Actions; namespace Umbraco.Web.Models.Mapping { @@ -179,7 +180,7 @@ namespace Umbraco.Web.Models.Mapping Label = localizedText.Localize("content/releaseDate"), Value = display.ReleaseDate.HasValue ? display.ReleaseDate.Value.ToIsoString() : null, //Not editible for people without publish permission (U4-287) - View = display.AllowedActions.Contains('P') ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View + View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View //TODO: Fix up hard coded datepicker } , new ContentPropertyDisplay @@ -188,7 +189,7 @@ namespace Umbraco.Web.Models.Mapping Label = localizedText.Localize("content/unpublishDate"), Value = display.ExpireDate.HasValue ? display.ExpireDate.Value.ToIsoString() : null, //Not editible for people without publish permission (U4-287) - View = display.AllowedActions.Contains('P') ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View + View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View //TODO: Fix up hard coded datepicker }, new ContentPropertyDisplay diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index d1e3eae9f1..aa8cd16d53 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -159,7 +159,13 @@ namespace Umbraco.Web.Models.Mapping //FROM IMemberGroup TO MemberGroupDisplay config.CreateMap() - .ForMember(x => x.Path, expression => expression.MapFrom(group => "-1," + group.Id)); + .ForMember(x => x.Path, expression => expression.MapFrom(group => "-1," + group.Id)) + .ForMember(x => x.Notifications, expression => expression.Ignore()) + .ForMember(x => x.Icon, expression => expression.Ignore()) + .ForMember(x => x.Trashed, expression => expression.Ignore()) + .ForMember(x => x.ParentId, expression => expression.Ignore()) + .ForMember(x => x.Alias, expression => expression.Ignore()) + .ForMember(x => x.Path, expression => expression.Ignore()); } /// diff --git a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs index 774dabb6b3..2a8f16433a 100644 --- a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs @@ -5,7 +5,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.ContentPickerAlias, "Content Picker", "INT", "contentpicker", IsParameterEditor = true, Group = "Pickers")] + [PropertyEditor(Constants.PropertyEditors.ContentPickerAlias, "Content Picker", PropertyEditorValueTypes.Integer, "contentpicker", IsParameterEditor = true, Group = "Pickers")] public class ContentPickerPropertyEditor : PropertyEditor { diff --git a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs index f226fe1ee5..331495d119 100644 --- a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.DateAlias, "Date", "DATE", "datepicker", Icon="icon-calendar")] + [PropertyEditor(Constants.PropertyEditors.DateAlias, "Date", PropertyEditorValueTypes.Date, "datepicker", Icon="icon-calendar")] public class DatePropertyEditor : PropertyEditor { public DatePropertyEditor(ILogger logger): base(logger) diff --git a/src/Umbraco.Web/PropertyEditors/DateTimePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DateTimePropertyEditor.cs index 9dca5fb435..3925df1d23 100644 --- a/src/Umbraco.Web/PropertyEditors/DateTimePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateTimePropertyEditor.cs @@ -6,7 +6,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.DateTimeAlias, "Date/Time", "datepicker", ValueType = "DATETIME", Icon="icon-time")] + [PropertyEditor(Constants.PropertyEditors.DateTimeAlias, "Date/Time", "datepicker", ValueType = PropertyEditorValueTypes.DateTime, Icon="icon-time")] public class DateTimePropertyEditor : PropertyEditor { public DateTimePropertyEditor(ILogger logger): base(logger) diff --git a/src/Umbraco.Web/PropertyEditors/DecimalPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DecimalPropertyEditor.cs index 1d5ac82ae4..e66ec96673 100644 --- a/src/Umbraco.Web/PropertyEditors/DecimalPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DecimalPropertyEditor.cs @@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.DecimalAlias, "Decimal", "decimal", "decimal", IsParameterEditor = true)] + [PropertyEditor(Constants.PropertyEditors.DecimalAlias, "Decimal", PropertyEditorValueTypes.Decimal, "decimal", IsParameterEditor = true)] public class DecimalPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs index 4981e88412..51a4913b97 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published /// in cache and not the int ID. /// - [PropertyEditor(Constants.PropertyEditors.DropDownListAlias, "Dropdown list", "dropdown", ValueType = "STRING", Group = "lists", Icon = "icon-indent")] + [PropertyEditor(Constants.PropertyEditors.DropDownListAlias, "Dropdown list", "dropdown", ValueType = PropertyEditorValueTypes.String, Group = "lists", Icon = "icon-indent")] public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs index 2192af8d4f..a6106836b7 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs @@ -13,7 +13,7 @@ namespace Umbraco.Web.PropertyEditors /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published /// in cache and not the string value. /// - [PropertyEditor(Constants.PropertyEditors.DropdownlistPublishingKeysAlias, "Dropdown list, publishing keys", "dropdown", ValueType = "INT", Group = "lists", Icon = "icon-indent")] + [PropertyEditor(Constants.PropertyEditors.DropdownlistPublishingKeysAlias, "Dropdown list, publishing keys", "dropdown", ValueType = PropertyEditorValueTypes.Integer, Group = "lists", Icon = "icon-indent")] public class DropDownWithKeysPropertyEditor : PropertyEditor { private readonly ILocalizedTextService _textService; diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index 809716af62..0f49b50070 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -32,11 +32,11 @@ namespace Umbraco.Web.PropertyEditors if (mediaFileSystem == null) throw new ArgumentNullException("mediaFileSystem"); if (contentSettings == null) throw new ArgumentNullException("contentSettings"); if (textService == null) throw new ArgumentNullException("textService"); + _applicationStartup = new FileUploadPropertyEditorApplicationStartup(this); _mediaFileSystem = mediaFileSystem; _contentSettings = contentSettings; _textService = textService; - MemberService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); + } /// @@ -59,7 +59,7 @@ namespace Umbraco.Web.PropertyEditors /// Ensures any files associated are removed /// /// - static IEnumerable ServiceEmptiedRecycleBin(Dictionary> allPropertyData) + IEnumerable ServiceEmptiedRecycleBin(Dictionary> allPropertyData) { var list = new List(); //Get all values for any image croppers found @@ -81,7 +81,7 @@ namespace Umbraco.Web.PropertyEditors /// Ensures any files associated are removed /// /// - static IEnumerable ServiceDeleted(IEnumerable deletedEntities) + IEnumerable ServiceDeleted(IEnumerable deletedEntities) { var list = new List(); foreach (var property in deletedEntities.SelectMany(deletedEntity => deletedEntity @@ -267,36 +267,60 @@ namespace Umbraco.Web.PropertyEditors } #region Application event handler, used to bind to events on startup - public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - } - public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - } + private readonly FileUploadPropertyEditorApplicationStartup _applicationStartup; /// - /// We're going to bind to the MediaService Saving event so that we can populate the umbracoFile size, type, etc... label fields - /// if we find any attached to the current media item. + /// we're using a sub -class because this has the logic to prevent it from executing if the application is not configured /// - /// - /// I think this kind of logic belongs on this property editor, I guess it could exist elsewhere but it all has to do with the upload field. - /// + private class FileUploadPropertyEditorApplicationStartup : ApplicationEventHandler + { + private FileUploadPropertyEditor _fileUploadPropertyEditor; + + public FileUploadPropertyEditorApplicationStartup(FileUploadPropertyEditor fileUploadPropertyEditor) + { + this._fileUploadPropertyEditor = fileUploadPropertyEditor; + } + + /// + /// We're going to bind to the MediaService Saving event so that we can populate the umbracoFile size, type, etc... label fields + /// if we find any attached to the current media item. + /// + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + MediaService.Saving += _fileUploadPropertyEditor.MediaServiceSaving; + MediaService.Created += _fileUploadPropertyEditor.MediaServiceCreating; + ContentService.Copied += _fileUploadPropertyEditor.ContentServiceCopied; + + MediaService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_fileUploadPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + MediaService.EmptiedRecycleBin += (sender, args) => + args.Files.AddRange(_fileUploadPropertyEditor.ServiceEmptiedRecycleBin(args.AllPropertyData)); + ContentService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_fileUploadPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + ContentService.EmptiedRecycleBin += (sender, args) => + args.Files.AddRange(_fileUploadPropertyEditor.ServiceEmptiedRecycleBin(args.AllPropertyData)); + MemberService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_fileUploadPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + } + } + + public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationInitialized(umbracoApplication, applicationContext); + } + public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationStarting(umbracoApplication, applicationContext); + } public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { - MediaService.Saving += MediaServiceSaving; - MediaService.Created += MediaServiceCreating; - ContentService.Copied += ContentServiceCopied; - - MediaService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); - MediaService.EmptiedRecycleBin += (sender, args) => - args.Files.AddRange(ServiceEmptiedRecycleBin(args.AllPropertyData)); - ContentService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); - ContentService.EmptiedRecycleBin += (sender, args) => - args.Files.AddRange(ServiceEmptiedRecycleBin(args.AllPropertyData)); - } + //wrap + _applicationStartup.OnApplicationStarted(umbracoApplication, applicationContext); + } #endregion + } } diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index b6d65ec36a..522978fef1 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -1,23 +1,99 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Text; -using System.Threading.Tasks; using Umbraco.Core.Logging; -using Umbraco.Core.Models; +using Examine; +using Lucene.Net.Documents; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Umbraco.Core; using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; +using Umbraco.Core.Xml; +using UmbracoExamine; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Core.Constants.PropertyEditors.GridAlias, "Grid layout", "grid", HideLabel = true, IsParameterEditor = false, ValueType = "JSON", Group="rich content", Icon="icon-layout")] - public class GridPropertyEditor : PropertyEditor - { + [PropertyEditor(Core.Constants.PropertyEditors.GridAlias, "Grid layout", "grid", HideLabel = true, IsParameterEditor = false, ValueType = PropertyEditorValueTypes.Json, Group="rich content", Icon="icon-layout")] + public class GridPropertyEditor : PropertyEditor, IApplicationEventHandler + { /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public GridPropertyEditor(ILogger logger) : base(logger) + /// Constructor + /// + public GridPropertyEditor(ILogger logger, IExamineIndexCollectionAccessor indexCollection) : base(logger) + { + _applicationStartup = new GridPropertyEditorApplicationStartup(indexCollection); + } + + private static void DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e) { + var indexer = (BaseUmbracoIndexer)sender; + foreach (var field in indexer.IndexerData.UserFields) + { + if (e.Fields.ContainsKey(field.Name)) + { + if (e.Fields[field.Name].DetectIsJson()) + { + try + { + var json = JsonConvert.DeserializeObject(e.Fields[field.Name]); + + //check if this is formatted for grid json + JToken name; + JToken sections; + if (json.HasValues && json.TryGetValue("name", out name) && json.TryGetValue("sections", out sections)) + { + //get all values and put them into a single field (using JsonPath) + var sb = new StringBuilder(); + foreach (var row in json.SelectTokens("$.sections[*].rows[*]")) + { + var rowName = row["name"].Value(); + var areaVals = row.SelectTokens("$.areas[*].controls[*].value"); + + foreach (var areaVal in areaVals) + { + //TODO: If it's not a string, then it's a json formatted value - + // we cannot really index this in a smart way since it could be 'anything' + if (areaVal.Type == JTokenType.String) + { + var str = areaVal.Value(); + str = XmlHelper.CouldItBeXml(str) ? str.StripHtml() : str; + sb.Append(str); + sb.Append(" "); + + //add the row name as an individual field + e.Document.Add( + new Field( + string.Format("{0}.{1}", field.Name, rowName), str, Field.Store.YES, Field.Index.ANALYZED)); + } + + } + } + + if (sb.Length > 0) + { + //First save the raw value to a raw field + e.Document.Add( + new Field( + string.Format("{0}{1}", UmbracoContentIndexer.RawFieldPrefix, field.Name), + e.Fields[field.Name], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO)); + + //now replace the original value with the combined/cleaned value + e.Document.RemoveField(field.Name); + e.Document.Add( + new Field( + field.Name, + sb.ToString(), Field.Store.YES, Field.Index.ANALYZED)); + } + } + } + catch (JsonException) + { + //swallow...on purpose, there's a chance that this isn't json and we don't want that to affect + // the website. + } + + } + } + } } /// @@ -52,6 +128,51 @@ namespace Umbraco.Web.PropertyEditors [PreValueField("rte", "Rich text editor", "views/propertyeditors/rte/rte.prevalues.html", Description = "Rich text editor configuration")] public string Rte { get; set; } } + + #region Application event handler, used to bind to events on startup + + private readonly GridPropertyEditorApplicationStartup _applicationStartup; + + /// + /// we're using a sub -class because this has the logic to prevent it from executing if the application is not configured + /// + private class GridPropertyEditorApplicationStartup : ApplicationEventHandler + { + private readonly IExamineIndexCollectionAccessor _indexCollection; + + public GridPropertyEditorApplicationStartup(IExamineIndexCollectionAccessor indexCollection) + { + this._indexCollection = indexCollection; + } + + /// + /// We're going to bind to the Examine events so we can ensure grid data is index nicely. + /// + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + foreach (var i in _indexCollection.Indexes.Values.OfType()) + { + i.DocumentWriting += DocumentWriting; + } + } + } + + public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationInitialized(umbracoApplication, applicationContext); + } + public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationStarting(umbracoApplication, applicationContext); + } + public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationStarted(umbracoApplication, applicationContext); + } + #endregion } diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 87bb38fa1d..a9c040b022 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -16,7 +16,7 @@ using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.ImageCropperAlias, "Image Cropper", "imagecropper", ValueType = "JSON", HideLabel = false, Group="media", Icon="icon-crop")] + [PropertyEditor(Constants.PropertyEditors.ImageCropperAlias, "Image Cropper", "imagecropper", ValueType = PropertyEditorValueTypes.Json, HideLabel = false, Group="media", Icon="icon-crop")] public class ImageCropperPropertyEditor : PropertyEditor, IApplicationEventHandler { private readonly MediaFileSystem _mediaFileSystem; @@ -27,6 +27,9 @@ namespace Umbraco.Web.PropertyEditors { if (mediaFileSystem == null) throw new ArgumentNullException("mediaFileSystem"); if (contentSettings == null) throw new ArgumentNullException("contentSettings"); + + _applicationStartup = new FileUploadPropertyEditorApplicationStartup(this); + _mediaFileSystem = mediaFileSystem; _contentSettings = contentSettings; @@ -34,9 +37,7 @@ namespace Umbraco.Web.PropertyEditors { {"focalPoint", "{left: 0.5, top: 0.5}"}, {"src", ""} - }; - MemberService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); + }; } /// @@ -253,35 +254,58 @@ namespace Umbraco.Web.PropertyEditors } #region Application event handler, used to bind to events on startup - public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - } - public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - } + private readonly FileUploadPropertyEditorApplicationStartup _applicationStartup; /// - /// We're going to bind to the MediaService Saving event so that we can populate the umbracoFile size, type, etc... label fields - /// if we find any attached to the current media item. + /// we're using a sub -class because this has the logic to prevent it from executing if the application is not configured /// - /// - /// I think this kind of logic belongs on this property editor, I guess it could exist elsewhere but it all has to do with the cropper. - /// + private class FileUploadPropertyEditorApplicationStartup : ApplicationEventHandler + { + private readonly ImageCropperPropertyEditor _imageCropperPropertyEditor; + + public FileUploadPropertyEditorApplicationStartup(ImageCropperPropertyEditor imageCropperPropertyEditor) + { + _imageCropperPropertyEditor = imageCropperPropertyEditor; + } + + /// + /// We're going to bind to the MediaService Saving event so that we can populate the umbracoFile size, type, etc... label fields + /// if we find any attached to the current media item. + /// + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + MediaService.Saving += _imageCropperPropertyEditor.MediaServiceSaving; + MediaService.Created += _imageCropperPropertyEditor.MediaServiceCreated; + ContentService.Copied += _imageCropperPropertyEditor.ContentServiceCopied; + + MediaService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_imageCropperPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + MediaService.EmptiedRecycleBin += (sender, args) => + args.Files.AddRange(_imageCropperPropertyEditor.ServiceEmptiedRecycleBin(args.AllPropertyData)); + ContentService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_imageCropperPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + ContentService.EmptiedRecycleBin += (sender, args) => + args.Files.AddRange(_imageCropperPropertyEditor.ServiceEmptiedRecycleBin(args.AllPropertyData)); + MemberService.Deleted += (sender, args) => + args.MediaFilesToDelete.AddRange(_imageCropperPropertyEditor.ServiceDeleted(args.DeletedEntities.Cast())); + } + } + + public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationInitialized(umbracoApplication, applicationContext); + } + public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //wrap + _applicationStartup.OnApplicationStarting(umbracoApplication, applicationContext); + } public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { - MediaService.Saving += MediaServiceSaving; - MediaService.Created += MediaServiceCreated; - ContentService.Copied += ContentServiceCopied; - - MediaService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); - MediaService.EmptiedRecycleBin += (sender, args) => - args.Files.AddRange(ServiceEmptiedRecycleBin(args.AllPropertyData)); - ContentService.Deleted += (sender, args) => - args.MediaFilesToDelete.AddRange(ServiceDeleted(args.DeletedEntities.Cast())); - ContentService.EmptiedRecycleBin += (sender, args) => - args.Files.AddRange(ServiceEmptiedRecycleBin(args.AllPropertyData)); + //wrap + _applicationStartup.OnApplicationStarted(umbracoApplication, applicationContext); } #endregion } diff --git a/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs index dc134bc87f..ec3125181d 100644 --- a/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs @@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.IntegerAlias, "Numeric", "integer", IsParameterEditor = true, ValueType = "integer")] + [PropertyEditor(Constants.PropertyEditors.IntegerAlias, "Numeric", "integer", IsParameterEditor = true, ValueType = PropertyEditorValueTypes.IntegerAlternative)] public class IntegerPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs index 7c9b95f098..84d868aa7f 100644 --- a/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; -using System.ComponentModel; using System.Linq; -using System.Web.Mvc; +using Newtonsoft.Json.Linq; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -9,7 +8,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.NoEditAlias, "Label", "readonlyvalue", Icon="icon-readonly")] + [PropertyEditor(Constants.PropertyEditors.NoEditAlias, "Label", "readonlyvalue", Icon = "icon-readonly")] public class LabelPropertyEditor : PropertyEditor { /// @@ -18,7 +17,6 @@ namespace Umbraco.Web.PropertyEditors public LabelPropertyEditor(ILogger logger) : base(logger) { } - protected override PropertyValueEditor CreateValueEditor() { return new LabelPropertyValueEditor(base.CreateValueEditor()); @@ -28,7 +26,7 @@ namespace Umbraco.Web.PropertyEditors { return new LabelPreValueEditor(); } - + /// /// Custom value editor to mark it as readonly /// @@ -50,19 +48,26 @@ namespace Umbraco.Web.PropertyEditors internal class LabelPreValueEditor : PreValueEditor { + private const string LegacyPropertyEditorValuesKey = "values"; + public LabelPreValueEditor() { Fields.Add(new PreValueField() { HideLabel = true, View = "readonlykeyvalues", - Key = "values" + Key = LegacyPropertyEditorValuesKey }); + + ValueType = PropertyEditorValueTypes.String; } + [PreValueField(Constants.PropertyEditors.PreValueKeys.DataValueType, "Value type", "valuetype")] + public string ValueType { get; set; } + /// - /// Chuck all the values into one field so devs can see what is stored there - we want this in case we've converted a legacy proeprty editor over to a label - /// we should still show the pre-values stored for the data type. + /// Other than for the pre-value fields defined on this property editor, chuck all the values into one field so devs can see what is stored there. + /// We want this in case we've converted a legacy property editor over to a label as we should still show the pre-values stored for the data type. /// /// /// @@ -70,12 +75,81 @@ namespace Umbraco.Web.PropertyEditors public override IDictionary ConvertDbToEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals) { var existing = base.ConvertDbToEditor(defaultPreVals, persistedPreVals); - //convert to a list, easier to enumerate on the editor - var asList = existing.Select(e => new KeyValuePair(e.Key, e.Value)).ToList(); - var result = new Dictionary { { "values", asList } }; + + // Check for a saved value type. If not found set to default string type. + var valueType = PropertyEditorValueTypes.String; + if (existing.ContainsKey(Constants.PropertyEditors.PreValueKeys.DataValueType)) + { + valueType = (string)existing[Constants.PropertyEditors.PreValueKeys.DataValueType]; + } + + // Convert any other values from a legacy property editor to a list, easier to enumerate on the editor. + // Make sure to exclude values defined on the label property editor itself. + var asList = existing + .Select(e => new KeyValuePair(e.Key, e.Value)) + .Where(e => e.Key != Constants.PropertyEditors.PreValueKeys.DataValueType) + .ToList(); + + var result = new Dictionary { { Constants.PropertyEditors.PreValueKeys.DataValueType, valueType } }; + if (asList.Any()) + { + result.Add(LegacyPropertyEditorValuesKey, asList); + } + return result; } - } + /// + /// When saving we want to avoid saving an empty "legacy property editor values" field if there are none. + /// + /// + /// + /// + public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue) + { + // notes (from the PR): + // + // "All stemmed from the fact that even though the label property editor could have pre-values (from a legacy type), + // they couldn't up to now be edited and saved through the UI. Now that a "true" pre-value has been added, it can, + // which led to some odd behaviour. + // + // Firstly there would be a pre-value record saved for legacy values even if there aren't any (the key would exist + // but with no value). In that case I remove that pre-value so it's not saved(likely does no harm, but it's not + // necessary - we only need this legacy values pre-value record if there are any). + // + // Secondly if there are legacy values, I found on each save the JSON structure containing them would get repeatedly + // nested (an outer JSON wrapper would be added each time). So what I'm doing is if there are legacy pre-values, + // I'm converting what comes in "wrapped" like (below) into the legacy property editor values." + + if (editorValue.ContainsKey(LegacyPropertyEditorValuesKey)) + { + // If provided value contains an empty legacy property editor values, don't save it + if (editorValue[LegacyPropertyEditorValuesKey] == null) + { + editorValue.Remove(LegacyPropertyEditorValuesKey); + } + else + { + // If provided value contains legacy property editor values, unwrap the value to save so it doesn't get repeatedly nested on saves. + // This is a bit funky - but basically needing to parse out the original value from a JSON structure that is passed in + // looking like: + // Value = {[ + // { + // "Key": "values", + // "Value": { + // + // }} + // ]} + var values = editorValue[LegacyPropertyEditorValuesKey] as JArray; + if (values != null && values.Count == 1 && values.First.Values().Count() == 2) + { + editorValue[LegacyPropertyEditorValuesKey] = values.First.Values().Last(); + } + } + } + + return base.ConvertEditorToDb(editorValue, currentValue); + } + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/MacroContainerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MacroContainerPropertyEditor.cs index 3fbf46a840..79cc725f65 100644 --- a/src/Umbraco.Web/PropertyEditors/MacroContainerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MacroContainerPropertyEditor.cs @@ -10,7 +10,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.MacroContainerAlias, "Macro container", "macrocontainer", ValueType = "TEXT", Group="rich content", Icon="icon-settings-alt")] + [PropertyEditor(Constants.PropertyEditors.MacroContainerAlias, "Macro container", "macrocontainer", ValueType = PropertyEditorValueTypes.Text, Group="rich content", Icon="icon-settings-alt")] public class MacroContainerPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs index 9abf0933df..4ea62b5edd 100644 --- a/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MarkdownPropertyEditor.cs @@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.MarkdownEditorAlias, "Markdown editor", "markdowneditor", ValueType = "TEXT", Icon="icon-code", Group="rich content")] + [PropertyEditor(Constants.PropertyEditors.MarkdownEditorAlias, "Markdown editor", "markdowneditor", ValueType = PropertyEditorValueTypes.Text, Icon="icon-code", Group="rich content")] public class MarkdownPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs index 23b2621ce5..ab6af9d32e 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs @@ -10,7 +10,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.MediaPickerAlias, "Legacy Media Picker", "INT", "mediapicker", Group="media", Icon="icon-picture")] + [PropertyEditor(Constants.PropertyEditors.MediaPickerAlias, "Legacy Media Picker", PropertyEditorValueTypes.Integer, "mediapicker", Group="media", Icon="icon-picture")] public class MediaPickerPropertyEditor : PropertyEditor { public MediaPickerPropertyEditor(ILogger logger) : base(logger) diff --git a/src/Umbraco.Web/PropertyEditors/MemberPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MemberPickerPropertyEditor.cs index cfc8d933ba..6175fd9157 100644 --- a/src/Umbraco.Web/PropertyEditors/MemberPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MemberPickerPropertyEditor.cs @@ -9,7 +9,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.MemberPickerAlias, "Member Picker", "INT", "memberpicker", Group = "People", Icon = "icon-user")] + [PropertyEditor(Constants.PropertyEditors.MemberPickerAlias, "Member Picker", PropertyEditorValueTypes.Integer, "memberpicker", Group = "People", Icon = "icon-user")] public class MemberPickerPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/MultipleMediaPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleMediaPickerPropertyEditor.cs index f3185b72a4..c5b5a0f9f3 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleMediaPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleMediaPickerPropertyEditor.cs @@ -26,6 +26,9 @@ namespace Umbraco.Web.PropertyEditors [PreValueField("onlyImages", "Pick only images", "boolean", Description = "Only let the editor choose images from media.")] public bool OnlyImages { get; set; } + [PreValueField("disableFolderSelect", "Disable folder select", "boolean", Description = "Do not allow folders to be picked.")] + public bool DisableFolderSelect { get; set; } + [PreValueField("startNodeId", "Start node", "mediapicker")] public int StartNodeId { get; set; } } diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index d668535feb..6125d9fde6 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -14,7 +14,7 @@ using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.MultipleTextstringAlias, "Repeatable textstrings", "multipletextbox", ValueType = "TEXT", Icon="icon-ordered-list", Group="lists")] + [PropertyEditor(Constants.PropertyEditors.MultipleTextstringAlias, "Repeatable textstrings", "multipletextbox", ValueType = PropertyEditorValueTypes.Text, Icon="icon-ordered-list", Group="lists")] public class MultipleTextStringPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs index 8ac6bff69e..63f4ef5e9b 100644 --- a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs @@ -13,7 +13,7 @@ namespace Umbraco.Web.PropertyEditors /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published /// in cache and not the string value. /// - [PropertyEditor(Constants.PropertyEditors.RadioButtonListAlias, "Radio button list", "radiobuttons", ValueType = "INT", Group="lists", Icon="icon-target")] + [PropertyEditor(Constants.PropertyEditors.RadioButtonListAlias, "Radio button list", "radiobuttons", ValueType = PropertyEditorValueTypes.Integer, Group="lists", Icon="icon-target")] public class RadioButtonsPropertyEditor : DropDownWithKeysPropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/RelatedLinksPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RelatedLinksPropertyEditor.cs index 4dd31f558b..7b3bcc6f92 100644 --- a/src/Umbraco.Web/PropertyEditors/RelatedLinksPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RelatedLinksPropertyEditor.cs @@ -9,7 +9,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.RelatedLinksAlias, "Related links", "relatedlinks", ValueType ="JSON", Icon="icon-thumbnail-list", Group="pickers")] + [PropertyEditor(Constants.PropertyEditors.RelatedLinksAlias, "Related links", "relatedlinks", ValueType = PropertyEditorValueTypes.Json, Icon="icon-thumbnail-list", Group="pickers")] public class RelatedLinksPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index de460d0196..0b01cbabef 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.TinyMCEAlias, "Rich Text Editor", "rte", ValueType = "TEXT", HideLabel = false, Group="Rich Content", Icon="icon-browser-window")] + [PropertyEditor(Constants.PropertyEditors.TinyMCEAlias, "Rich Text Editor", "rte", ValueType = PropertyEditorValueTypes.Text, HideLabel = false, Group="Rich Content", Icon="icon-browser-window")] public class RichTextPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs index 09b85dee1f..ae2e6ffdc0 100644 --- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs @@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.TextboxMultipleAlias, "Textarea", "textarea", IsParameterEditor = true, ValueType = "TEXT", Icon="icon-application-window-alt")] + [PropertyEditor(Constants.PropertyEditors.TextboxMultipleAlias, "Textarea", "textarea", IsParameterEditor = true, ValueType = PropertyEditorValueTypes.Text, Icon="icon-application-window-alt")] public class TextAreaPropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs index 1145d125c2..720efbc19b 100644 --- a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs @@ -4,7 +4,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "True/False", "INT", "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] + [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "True/False", PropertyEditorValueTypes.Integer, "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] public class TrueFalsePropertyEditor : PropertyEditor { /// diff --git a/src/Umbraco.Web/PropertyEditors/UserPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/UserPickerPropertyEditor.cs index 6b6de5a1b3..6384397ebb 100644 --- a/src/Umbraco.Web/PropertyEditors/UserPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/UserPickerPropertyEditor.cs @@ -7,7 +7,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.UserPickerAlias, "User picker", "INT", "entitypicker", Group="People", Icon="icon-user")] + [PropertyEditor(Constants.PropertyEditors.UserPickerAlias, "User picker", PropertyEditorValueTypes.Integer, "entitypicker", Group="People", Icon="icon-user")] public class UserPickerPropertyEditor : PropertyEditor { private IDictionary _defaultPreValues; diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs index 8b3fd79252..04b2cf0a7b 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs @@ -1,22 +1,16 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Runtime.CompilerServices; using System.Text; using System.Xml; using System.Xml.XPath; using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Xml; using Umbraco.Web.Routing; -using Umbraco.Web; -using umbraco; using System.Linq; -using System.Web; -using umbraco.BusinessLogic; using Umbraco.Core.Cache; namespace Umbraco.Web.PublishedCache.XmlPublishedCache @@ -92,17 +86,27 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache // cache if we have a content and not previewing if (content != null && preview == false && _routesCache != null) - { - var domainRootNodeId = route.StartsWith("/") ? -1 : int.Parse(route.Substring(0, route.IndexOf('/'))); - var iscanon = DomainHelper.ExistsDomainInPath(_domainCache.GetAll(false), content.Path, domainRootNodeId) == false; - // and only if this is the canonical url (the one GetUrl would return) - if (iscanon) - _routesCache.Store(content.Id, route); - } + AddToCacheIfDeepestRoute(content, route); return content; } + private void AddToCacheIfDeepestRoute(IPublishedContent content, string route) + { + var domainRootNodeId = route.StartsWith("/") ? -1 : int.Parse(route.Substring(0, route.IndexOf('/'))); + + // so we have a route that maps to a content... say "1234/path/to/content" - however, there could be a + // domain set on "to" and route "4567/content" would also map to the same content - and due to how + // urls computing work (by walking the tree up to the first domain we find) it is that second route + // that would be returned - the "deepest" route - and that is the route we want to cache, *not* the + // longer one - so make sure we don't cache the wrong route + + var deepest = DomainHelper.ExistsDomainInPath(_domainCache.GetAll(false), content.Path, domainRootNodeId) == false; + + if (deepest) + _routesCache.Store(content.Id, route); + } + public IPublishedContent GetByRoute(string route, bool? hideTopLevelNode = null) { return GetByRoute(PreviewDefault, route, hideTopLevelNode); @@ -120,11 +124,35 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache // else actually determine the route route = DetermineRouteById(preview, contentId); - // cache if we have a route and not previewing - if (route != null && preview == false) + // node not found + if (route == null) + return null; + + // find the content back, detect routes collisions: we should find ourselves back, + // else it means that another content with "higher priority" is sharing the same route. + // perf impact: + // - non-colliding, adds one complete "by route" lookup, only on the first time a url is computed (then it's cached anyways) + // - colliding, adds one "by route" lookup, the first time the url is computed, then one dictionary looked each time it is computed again + // assuming no collisions, the impact is one complete "by route" lookup the first time each url is computed + var loopId = preview ? 0 : (_routesCache?.GetNodeId(route) ?? 0); // might be cached already in case of collision + if (loopId == 0) + { + var content = DetermineIdByRoute(preview, route, GlobalSettings.HideTopLevelNodeFromPath); + + // add the other route to cache so next time we have it already + if (content != null && preview == false) + AddToCacheIfDeepestRoute(content, route); + + loopId = content?.Id ?? 0; // though... 0 here would be quite weird? + } + + // cache if we have a route and not previewing and it's not a colliding route + // (the result of DetermineRouteById is always the deepest route) + if (/*route != null &&*/ preview == false && loopId == contentId) _routesCache?.Store(contentId, route); - return route; + // return route if no collision, else report collision + return loopId == contentId ? route : ("err/" + loopId); } public string GetRouteById(int contentId) diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs index a9c1c1bd20..ec20cb3264 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs @@ -152,32 +152,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache } } - public override async Task RunAsync(CancellationToken token) + public override Task RunAsync(CancellationToken token) { - lock (_locko) - { - _logger.Debug("Run now (async)."); - // just make sure - in case the runner is running the task on shutdown - _released = true; - } - - // http://stackoverflow.com/questions/13489065/best-practice-to-call-configureawait-for-all-server-side-code - // http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html - // do we really need that ConfigureAwait here? - - // - In theory, no, because we are already executing on a background thread because we know it is there and - // there won't be any SynchronizationContext to resume to, however this is 'library' code and - // who are we to say that this will never be executed in a sync context... this is best practice to be sure - // it won't cause problems. - // .... so yes we want it. - - using (await _runLock.LockAsync()) - { - await _store.SaveXmlToFileAsync().ConfigureAwait(false); - } + throw new NotImplementedException(); } - public override bool IsAsync => true; + public override bool IsAsync => false; public override void Run() { diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs index 506b0c64e9..25d77d48f3 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Reflection; using System.Web; using System.Xml; +using Umbraco.Core; using umbraco.cms.businesslogic.web; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; @@ -35,13 +37,37 @@ namespace Umbraco.Web.Routing { _logger.Debug("Looking for a page to handle 404."); + // try to find a culture as best as we can + var errorCulture = CultureInfo.CurrentUICulture; + if (pcr.HasDomain) + { + errorCulture = pcr.Domain.Culture; + } + else + { + var route = pcr.Uri.GetAbsolutePathDecoded(); + var pos = route.LastIndexOf('/'); + IPublishedContent node = null; + while (pos > 1) + { + route = route.Substring(0, pos); + node = pcr.RoutingContext.UmbracoContext.ContentCache.GetByRoute(route); + if (node != null) break; + pos = route.LastIndexOf('/'); + } + if (node != null) + { + var d = DomainHelper.FindWildcardDomainInPath(pcr.RoutingContext.UmbracoContext.Facade.DomainCache.GetAll(true), node.Path, null); + if (d != null) + errorCulture = d.Culture; + } + } + var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId( _contentConfigSection.Error404Collection.ToArray(), - //TODO: Is there a better way to extract this value? at least we're not relying on singletons here though - pcr.RoutingContext.UmbracoContext.HttpContext.Request.ServerVariables["SERVER_NAME"], pcr.RoutingContext.UmbracoContext.Application.Services.EntityService, new PublishedContentQuery(pcr.RoutingContext.UmbracoContext.ContentCache, pcr.RoutingContext.UmbracoContext.MediaCache), - pcr.RoutingContext.UmbracoContext.Application.Services.DomainService); + errorCulture); IPublishedContent content = null; diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index ea1b96c091..8df1e83718 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -54,6 +54,14 @@ namespace Umbraco.Web.Routing return null; } + if (route.StartsWith("err/")) + { + LogHelper.Debug( + "Page with nodeId={0} has a colliding url with page with nodeId={1}.", + () => id, () => route.Substring(4)); + return "#err-" + route.Substring(4); + } + var domainHelper = new DomainHelper(umbracoContext.Facade.DomainCache); // extract domainUri and path @@ -96,6 +104,9 @@ namespace Umbraco.Web.Routing return null; } + if (route.StartsWith("err/")) + return null; + var domainHelper = new DomainHelper(umbracoContext.Facade.DomainCache); // extract domainUri and path diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs index 143e16354e..dd8ba0f008 100644 --- a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; @@ -31,42 +32,24 @@ namespace Umbraco.Web.Routing IEntityService entityService, ITypedPublishedContentQuery publishedContentQuery, IDomainService domainService) + { + throw new NotImplementedException(); + } + + internal static int? GetCurrentNotFoundPageId( + IContentErrorPage[] error404Collection, + IEntityService entityService, + ITypedPublishedContentQuery publishedContentQuery, + CultureInfo errorCulture) { if (error404Collection.Length > 1) { - // try to get the 404 based on current culture (via domain) - IContentErrorPage cultureErr; - - var d = domainService.GetByName(requestServerName); - - if (d != null && d.LanguageId.HasValue) - { - // test if a 404 page exists with current culture - cultureErr = error404Collection - .FirstOrDefault(x => x.Culture == d.LanguageIsoCode); - - if (cultureErr != null) - { - return GetContentIdFromErrorPageConfig(cultureErr, entityService, publishedContentQuery); - } - } - // test if a 404 page exists with current culture thread - cultureErr = error404Collection - .FirstOrDefault(x => x.Culture == System.Threading.Thread.CurrentThread.CurrentUICulture.Name); - if (cultureErr != null) - { - return GetContentIdFromErrorPageConfig(cultureErr, entityService, publishedContentQuery); - } - - // there should be a default one! - cultureErr = error404Collection - .FirstOrDefault(x => x.Culture == "default"); + var cultureErr = error404Collection.FirstOrDefault(x => x.Culture == errorCulture.Name) + ?? error404Collection.FirstOrDefault(x => x.Culture == "default"); // there should be a default one! if (cultureErr != null) - { return GetContentIdFromErrorPageConfig(cultureErr, entityService, publishedContentQuery); - } } else { diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index e00cc21809..09201776b0 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -50,6 +50,30 @@ namespace Umbraco.Web.Routing else urls.Add(umbracoContext.Application.Services.TextService.Localize("content/parentNotPublished", new[] { parent.Name })); } + else if (url.StartsWith("#err-")) + { + // route error, report + var id = int.Parse(url.Substring(5)); + var o = umbracoContext.ContentCache.GetById(id); + string s; + if (o == null) + { + s = "(unknown)"; + } + else + { + var l = new List(); + while (o != null) + { + l.Add(o.Name); + o = o.Parent; + } + l.Reverse(); + s = "/" + string.Join("/", l) + " (id=" + id + ")"; + + } + urls.Add(umbracoContext.Application.Services.TextService.Localize("content/routeError", s)); + } else { urls.Add(url); diff --git a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs index adb9c6c0dd..d63fbb4606 100644 --- a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs +++ b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs @@ -305,7 +305,9 @@ namespace Umbraco.Web.Scheduling // tasks in the queue will be executed... if (wait == false) return; - _runningTask.Wait(); // wait for whatever is running to end... + + if (_runningTask != null) + _runningTask.Wait(); // wait for whatever is running to end... } /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f533cf8e57..32f8e3751d 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1,5 +1,5 @@  - + 9.0.30729 @@ -40,6 +40,7 @@ ..\ true + AnyCPU bin\Debug\ @@ -97,161 +98,7 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine - - ..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll - True - - - ..\packages\ClientDependency.1.8.4\lib\net45\ClientDependency.Core.dll - False - True - - - False - ..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll - - - ..\packages\dotless.1.4.1.0\lib\dotless.Core.dll - - - ..\packages\Examine.2.0.0-Beta2\lib\net45\Examine.dll - True - - - False - ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll - - - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - True - - - ..\packages\LightInject.4.0.9\lib\net46\LightInject.dll - True - - - ..\packages\LightInject.Annotation.1.0.0.4\lib\net45\LightInject.Annotation.dll - True - - - ..\packages\LightInject.Mvc.1.0.0.4\lib\net45\LightInject.Mvc.dll - True - - - ..\packages\LightInject.Web.1.0.0.7\lib\net45\LightInject.Web.dll - True - - - ..\packages\LightInject.WebApi.1.0.0.4\lib\net45\LightInject.WebApi.dll - True - - - ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll - True - - - ..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Analyzers.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Core.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.FastVectorHighlighter.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Highlighter.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Memory.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Queries.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Regex.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SimpleFacetedSearch.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Snowball.dll - True - - - ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SpellChecker.dll - True - - - ..\packages\Markdown.1.14.4\lib\net45\MarkdownSharp.dll - False - True - - - False - ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - False - ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll - - - False - ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - False - ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll - - - False - ..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll - - - False - ..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - False - ..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - False - True - - - ..\packages\MiniProfiler.3.2.0.157\lib\net40\MiniProfiler.dll - True - - - ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll - True - - - ..\packages\NPoco.3.3.0-beta3\lib\net45\NPoco.dll - True - - - False - ..\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\packages\semver.1.1.2\lib\net451\Semver.dll - True - System @@ -268,10 +115,6 @@ - - False - ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - @@ -284,55 +127,14 @@ - - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll - False - True - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - True - - - False - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - True - - - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll - False - True - System.Web.Services - - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll - False - True - - - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll - False - True - - - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll - False - True - System.XML - - {5BA5425F-27A7-4677-865E-82246498AA2E} - SqlCE4Umbraco - {31785BC3-256C-4613-B2F5-A1B0BDDED8C1} Umbraco.Core @@ -349,11 +151,6 @@ {C7CB79F0-1C97-4B33-BFA7-00731B579AE2} umbraco.datalayer - - ..\packages\UrlRewritingNet.UrlRewriter.2.0.7\lib\UrlRewritingNet.UrlRewriter.dll - False - False - @@ -372,6 +169,7 @@ + @@ -1753,9 +1551,6 @@ ASPXCodeBehind - - Designer - Reference.map @@ -1836,6 +1631,7 @@ Resources.Designer.cs Designer + @@ -1883,5 +1679,4 @@ - \ No newline at end of file diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 773933b374..b10fadcdd8 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -43,6 +43,7 @@ using Umbraco.Core.Strings; using Umbraco.Web.Cache; using Umbraco.Web.DependencyInjection; using Umbraco.Web._Legacy.Actions; +using UmbracoExamine; using Action = System.Action; using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine; @@ -347,6 +348,8 @@ namespace Umbraco.Web container.Register(); container.RegisterSingleton(); container.RegisterSingleton(); + + container.RegisterSingleton(); } /// diff --git a/src/Umbraco.Web/WebServices/SaveFileController.cs b/src/Umbraco.Web/WebServices/SaveFileController.cs index 8a6210af41..010e1be2cb 100644 --- a/src/Umbraco.Web/WebServices/SaveFileController.cs +++ b/src/Umbraco.Web/WebServices/SaveFileController.cs @@ -192,7 +192,8 @@ namespace Umbraco.Web.WebServices new { path = syncPath, - contents = t.Design + contents = t.Design, + alias = t.Alias // might have been updated! }); } catch (Exception ex) diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config deleted file mode 100644 index a41fb82bc3..0000000000 --- a/src/Umbraco.Web/packages.config +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Web/project.json b/src/Umbraco.Web/project.json new file mode 100644 index 0000000000..8912a26d41 --- /dev/null +++ b/src/Umbraco.Web/project.json @@ -0,0 +1,47 @@ +{ + "dependencies": { + "AutoMapper": "4.2.*", + "ClientDependency": "1.8.*", + "dotless": "1.4.1.0", + "Examine": "2.0.0-beta2", + "HtmlAgilityPack": "1.4.*", + "LightInject": "4.0.*", + "LightInject.Annotation": "1.0.*", + "LightInject.Mvc": "1.0.*", + "LightInject.Web": "1.0.*", + "LightInject.WebApi": "1.0.*", + "log4net": "2.0.*", + "Lucene.Net": "3.0.3", + "Markdown": "1.*", + "Microsoft.AspNet.Identity.Core": "2.2.1", + "Microsoft.AspNet.Identity.Owin": "2.2.1", + "Microsoft.AspNet.Mvc": "5.2.3", + "Microsoft.AspNet.Razor": "3.2.3", + "Microsoft.AspNet.WebApi": "5.2.3", + "Microsoft.AspNet.WebApi.Client": "5.2.3", + "Microsoft.AspNet.WebApi.Core": "5.2.3", + "Microsoft.AspNet.WebApi.WebHost": "5.2.3", + "Microsoft.AspNet.WebPages": "3.2.3", + "Microsoft.Owin": "3.0.*", + "Microsoft.Owin.Host.SystemWeb": "3.0.*", + "Microsoft.Owin.Security": "3.0.*", + "Microsoft.Owin.Security.Cookies": "3.0.*", + "Microsoft.Owin.Security.OAuth": "3.0.*", + "Microsoft.Web.Infrastructure": "1.0.0.0", + "MiniProfiler": "3.2.*", + "Newtonsoft.Json": "8.0.*", + "NPoco": "3.3.3", + "Owin": "1.0.*", + "semver": "1.*", + "SharpZipLib": "0.86.0", + "UrlRewritingNet.UrlRewriter": "2.0.7", + "xmlrpcnet": "2.5.0" + }, + "frameworks": { + "net461": { } + }, + "runtimes": { + "win-anycpu": { }, + "win": { } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index 53ddb50c65..39ca2524c4 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -1427,30 +1427,26 @@ namespace umbraco /// /// Sends an e-mail using the System.Net.Mail.MailMessage object /// - /// The sender of the e-mail - /// The recipient of the e-mail - /// E-mail subject - /// The complete content of the e-mail - /// Set to true when using Html formatted mails - public static void SendMail(string FromMail, string ToMail, string Subject, string Body, bool IsHtml) + /// The sender of the e-mail + /// The recipient(s) of the e-mail, add multiple email addresses by using a semicolon between them + /// E-mail subject + /// The complete content of the e-mail + /// Set to true when using Html formatted mails + public static void SendMail(string fromMail, string toMail, string subject, string body, bool isHtml) { try { - // create the mail message - MailMessage mail = new MailMessage(FromMail.Trim(), ToMail.Trim()); - - // populate the message - mail.Subject = Subject; - if (IsHtml) - mail.IsBodyHtml = true; - else - mail.IsBodyHtml = false; - - mail.Body = Body; - - // send it - SmtpClient smtpClient = new SmtpClient(); - smtpClient.Send(mail); + using (var mail = new MailMessage()) + { + mail.From = new MailAddress(fromMail.Trim()); + foreach (var mailAddress in toMail.Split(';')) + mail.To.Add(new MailAddress(mailAddress.Trim())); + mail.Subject = subject; + mail.IsBodyHtml = isHtml; + mail.Body = body; + using (var smtpClient = new SmtpClient()) + smtpClient.Send(mail); + } } catch (Exception ee) { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/language.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/language.ascx.cs index ffd7bf52a0..6fd456731b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/language.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/create/language.ascx.cs @@ -47,7 +47,7 @@ namespace umbraco.cms.presentation.create.controls Cultures.SelectedValue); ClientTools - .ChildNodeCreated() + .ReloadActionNode(false, true) .CloseModalWindow(); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs index dcc8bc9301..85a1bcac3f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs @@ -95,22 +95,33 @@ namespace umbraco.presentation.dialogs protected void doTranslation_Click(object sender, EventArgs e) { - // testing translate - MakeNew( - _currentPage, - Security.CurrentUser, - Services.UserService.GetUserById(int.Parse(translator.SelectedValue)), - new Language(int.Parse(language.SelectedValue)), - comment.Text, includeSubpages.Checked, - true); + int languageId; + if (int.TryParse(language.SelectedValue, out languageId)) + { + // testing translate + MakeNew( + _currentPage, + Security.CurrentUser, + Services.UserService.GetUserById(int.Parse(translator.SelectedValue)), + new Language(int.Parse(language.SelectedValue)), + comment.Text, includeSubpages.Checked, + true); - pane_form.Visible = false; - pl_buttons.Visible = false; + pane_form.Visible = false; + pl_buttons.Visible = false; - feedback.Text = Services.TextService.Localize("translation/pageHasBeenSendToTranslation", new[] { _currentPage.Text}) + "

    " + Services.TextService.Localize("defaultdialogs/closeThisWindow") + "

    "; - feedback.type = Feedback.feedbacktype.success; + feedback.Text = Services.TextService.Localize("translation/pageHasBeenSendToTranslation", _currentPage.Text) + + "

    " + + Services.TextService.Localize("defaultdialogs/closeThisWindow") + "

    "; + feedback.type = Feedback.feedbacktype.success; + } + else + { + feedback.Text = Services.TextService.Localize("translation/noLanguageSelected"); + feedback.type = Feedback.feedbacktype.error; + } } - + public void MakeNew(CMSNode Node, IUser User, IUser Translator, Language Language, string Comment, bool IncludeSubpages, bool SendEmail) { @@ -152,21 +163,25 @@ namespace umbraco.presentation.dialogs Translator.Email.Contains("@")) { // create the mail message - MailMessage mail = new MailMessage(User.Email, Translator.Email); - - // populate the message - mail.Subject = Services.TextService.Localize("translation/mailSubject", Translator.GetUserCulture(Services.TextService), subjectVars); - mail.IsBodyHtml = false; - mail.Body = Services.TextService.Localize("translation/mailBody", Translator.GetUserCulture(Services.TextService), bodyVars); - try + using (MailMessage mail = new MailMessage(User.Email, Translator.Email)) { - SmtpClient sender = new SmtpClient(); - sender.Send(mail); - } - catch (Exception ex) - { - LogHelper.Error("Error sending translation e-mail", ex); + // populate the message + mail.Subject = Services.TextService.Localize("translation/mailSubject", Translator.GetUserCulture(Services.TextService), subjectVars); + mail.IsBodyHtml = false; + mail.Body = Services.TextService.Localize("translation/mailBody", Translator.GetUserCulture(Services.TextService), bodyVars); + try + { + using (SmtpClient sender = new SmtpClient()) + { + sender.Send(mail); + } + } + catch (Exception ex) + { + LogHelper.Error("Error sending translation e-mail", ex); + } } + } else { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs index 7b3c076848..d86b14eaed 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs @@ -184,7 +184,10 @@ namespace umbraco.presentation.webservices //content.Instance.SortNodes(parentId); //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here - ApplicationContext.Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, ApplicationContext); + if (parentId > 0) + { + ApplicationContext.Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, ApplicationContext); + } } catch (Exception ex) diff --git a/src/UmbracoExamine/BaseUmbracoIndexer.cs b/src/UmbracoExamine/BaseUmbracoIndexer.cs index 1fe1e8b7af..0ac59c79e2 100644 --- a/src/UmbracoExamine/BaseUmbracoIndexer.cs +++ b/src/UmbracoExamine/BaseUmbracoIndexer.cs @@ -25,7 +25,6 @@ using Directory = Lucene.Net.Store.Directory; namespace UmbracoExamine { - /// /// An abstract provider containing the basic functionality to be able to query against /// Umbraco data. diff --git a/src/UmbracoExamine/ExamineIndexCollectionAccessor.cs b/src/UmbracoExamine/ExamineIndexCollectionAccessor.cs new file mode 100644 index 0000000000..f2e30fe5d0 --- /dev/null +++ b/src/UmbracoExamine/ExamineIndexCollectionAccessor.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Examine; + +namespace UmbracoExamine +{ + /// + /// Default implementation of IExamineIndexCollectionAccessor to return indexes from Examinemanager + /// + public class ExamineIndexCollectionAccessor : IExamineIndexCollectionAccessor + { + public IReadOnlyDictionary Indexes => ExamineManager.Instance.IndexProviders; + } +} \ No newline at end of file diff --git a/src/UmbracoExamine/IExamineIndexCollectionAccessor.cs b/src/UmbracoExamine/IExamineIndexCollectionAccessor.cs new file mode 100644 index 0000000000..7edb93719c --- /dev/null +++ b/src/UmbracoExamine/IExamineIndexCollectionAccessor.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Examine; + +namespace UmbracoExamine +{ + /// + /// Returns a collection of IExamineIndexer + /// + public interface IExamineIndexCollectionAccessor + { + IReadOnlyDictionary Indexes { get; } + } +} \ No newline at end of file diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj index 3fd07cecc9..749faaf27c 100644 --- a/src/UmbracoExamine/UmbracoExamine.csproj +++ b/src/UmbracoExamine/UmbracoExamine.csproj @@ -135,12 +135,12 @@ True - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll True - - ..\packages\NPoco.3.3.0-beta3\lib\net45\NPoco.dll + + ..\packages\NPoco.3.3.3\lib\net45\NPoco.dll True @@ -163,6 +163,8 @@ + + @@ -223,7 +225,6 @@ -