Merge branch '7.1.0' of https://github.com/umbraco/Umbraco-CMS into 7.1.0

This commit is contained in:
Shannon
2014-02-19 16:36:28 +11:00
44 changed files with 313 additions and 461 deletions

View File

@@ -280,11 +280,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
}
}
IImagingCrops IContentSection.ImageCrops
{
get { return Imaging.Crops; }
}
string IContentSection.NotificationEmailAddress
{
get { return Notifications.NotificationEmailAddress; }

View File

@@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingCropCollection : ConfigurationElementCollection, IEnumerable<IImagingCrop>
{
internal void Add(ContentImagingCropElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new ContentImagingCropElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ContentImagingCropElement)element).MediaTypeAlias;
}
IEnumerator<IImagingCrop> IEnumerable<IImagingCrop>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IImagingCrop;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -1,33 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingCropElement : ConfigurationElement, IImagingCrop
{
[ConfigurationProperty("mediaTypeAlias", IsRequired = true)]
public string MediaTypeAlias
{
get { return (string)base["mediaTypeAlias"]; }
}
[ConfigurationProperty("focalPointProperty", IsRequired = false)]
public string FocalPointProperty
{
get { return (string)base["focalPointProperty"]; }
}
[ConfigurationCollection(typeof(ContentImagingCropSizeCollection))]
[ConfigurationProperty("", IsDefaultCollection = true)]
public ContentImagingCropSizeCollection CropSizeCollection
{
get { return (ContentImagingCropSizeCollection)base[""]; }
//set { base[""] = value; }
}
IEnumerable<IImagingCropSize> IImagingCrop.CropSizes
{
get { return CropSizeCollection; }
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingCropSizeCollection : ConfigurationElementCollection, IEnumerable<IImagingCropSize>
{
internal void Add(ContentImagingCropSizeElement c)
{
BaseAdd(c);
}
protected override ConfigurationElement CreateNewElement()
{
return new ContentImagingCropSizeElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ContentImagingCropSizeElement)element).Alias;
}
IEnumerator<IImagingCropSize> IEnumerable<IImagingCropSize>.GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
yield return BaseGet(i) as IImagingCropSize;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -1,25 +0,0 @@
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingCropSizeElement : ConfigurationElement, IImagingCropSize
{
[ConfigurationProperty("alias", IsRequired = true)]
public string Alias
{
get { return (string)base["alias"]; }
}
[ConfigurationProperty("width", IsRequired = true)]
public int Width
{
get { return (int)base["width"]; }
}
[ConfigurationProperty("height", IsRequired = true)]
public int Height
{
get { return (int)base["height"]; }
}
}
}

View File

@@ -1,27 +0,0 @@
using System.Collections.Generic;
using System.Configuration;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingCropsElement : ConfigurationElement, IImagingCrops
{
[ConfigurationProperty("saveFiles", DefaultValue = false)]
public bool SaveFiles
{
get { return (bool)base["saveFiles"]; }
}
[ConfigurationCollection(typeof(ContentImagingCropCollection), AddItemName = "crop")]
[ConfigurationProperty("", IsDefaultCollection = true)]
public ContentImagingCropCollection CropCollection
{
get { return (ContentImagingCropCollection)base[""]; }
//set { base[""] = value; }
}
IEnumerable<IImagingCrop> IImagingCrops.Crops
{
get { return CropCollection; }
}
}
}

View File

@@ -4,12 +4,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
internal class ContentImagingElement : ConfigurationElement
{
[ConfigurationProperty("crops")]
internal ContentImagingCropsElement Crops
{
get { return (ContentImagingCropsElement)base["crops"]; }
}
[ConfigurationProperty("imageFileTypes")]
internal CommaDelimitedConfigurationElement ImageFileTypes
{

View File

@@ -4,8 +4,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IContentSection : IUmbracoConfigurationSection
{
IImagingCrops ImageCrops { get; }
string NotificationEmailAddress { get; }
bool DisableHtmlEmail { get; }

View File

@@ -1,13 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IImagingCrop
{
string MediaTypeAlias { get; }
string FocalPointProperty { get; }
IEnumerable<IImagingCropSize> CropSizes { get; }
}
}

View File

@@ -1,11 +0,0 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IImagingCropSize
{
string Alias { get; }
int Width { get; }
int Height { get; }
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IImagingCrops
{
bool SaveFiles { get; }
IEnumerable<IImagingCrop> Crops { get; }
}
}

View File

@@ -203,14 +203,6 @@
<Compile Include="Configuration\UmbracoSettings\ContentError404Collection.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentErrorPageElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentErrorsElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingCropCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingCropElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingCropsElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingCropSizeCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingCropSizeElement.cs" />
<Compile Include="Configuration\UmbracoSettings\IImagingCrop.cs" />
<Compile Include="Configuration\UmbracoSettings\IImagingCrops.cs" />
<Compile Include="Configuration\UmbracoSettings\IImagingCropSize.cs" />
<Compile Include="Configuration\UmbracoSettings\ImagingAutoFillPropertiesCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\ImagingAutoFillUploadFieldElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ContentImagingElement.cs" />

View File

@@ -11,24 +11,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
get { return true; }
}
[Test]
public override void ImageCrops()
{
Assert.IsFalse(SettingsSection.Content.ImageCrops.SaveFiles);
}
[Test]
public override void ImageCropItem()
{
Assert.AreEqual(0, SettingsSection.Content.ImageCrops.Crops.Count());
}
[Test]
public override void ImageCropSizes()
{
Assert.AreEqual(0, SettingsSection.Content.ImageCrops.Crops.Count());
}
[Test]
public override void DisableHtmlEmail()
{

View File

@@ -11,59 +11,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
[TestFixture]
public class ContentElementTests : UmbracoSettingsTests
{
[Test]
public virtual void ImageCrops()
{
Assert.AreEqual(true, SettingsSection.Content.ImageCrops.SaveFiles);
Assert.AreEqual(2, SettingsSection.Content.ImageCrops.Crops.Count());
}
[Test]
public virtual void ImageCropItem()
{
Assert.AreEqual("image", SettingsSection.Content.ImageCrops.Crops.First().MediaTypeAlias);
Assert.AreEqual("umbracoFocalPoint", SettingsSection.Content.ImageCrops.Crops.First().FocalPointProperty);
Assert.AreEqual(3, SettingsSection.Content.ImageCrops.Crops.First().CropSizes.Count());
Assert.AreEqual("custom", SettingsSection.Content.ImageCrops.Crops.Last().MediaTypeAlias);
Assert.AreEqual("customPoint", SettingsSection.Content.ImageCrops.Crops.Last().FocalPointProperty);
Assert.AreEqual(2, SettingsSection.Content.ImageCrops.Crops.Last().CropSizes.Count());
}
[Test]
public virtual void ImageCropSizes()
{
var toVerify1 = new List<Tuple<string, int, int>>
{
new Tuple<string, int, int>("thumb", 100, 100),
new Tuple<string, int, int>("portrait", 320, 400),
new Tuple<string, int, int>("banner", 620, 140),
};
var toVerify2 = new List<Tuple<string, int, int>>
{
new Tuple<string, int, int>("thumb", 100, 100),
new Tuple<string, int, int>("banner", 600, 100),
};
for (var i = 0; i < SettingsSection.Content.ImageCrops.Crops.First().CropSizes.Count(); i++)
{
var size = SettingsSection.Content.ImageCrops.Crops.First().CropSizes.ElementAt(i);
var verify = toVerify1[i];
Assert.AreEqual(verify.Item1, size.Alias);
Assert.AreEqual(verify.Item2, size.Width);
Assert.AreEqual(verify.Item3, size.Height);
}
for (var i = 0; i < SettingsSection.Content.ImageCrops.Crops.Last().CropSizes.Count(); i++)
{
var size = SettingsSection.Content.ImageCrops.Crops.Last().CropSizes.ElementAt(i);
var verify = toVerify2[i];
Assert.AreEqual(verify.Item1, size.Alias);
Assert.AreEqual(verify.Item2, size.Width);
Assert.AreEqual(verify.Item3, size.Height);
}
}
[Test]
public void EmailAddress()
{

View File

@@ -1,2 +1,2 @@
/*yepnope1.5.x|WTFPL*/
(function (a, b, c) { function d(a) { return "[object Function]" == o.call(a) } function e(a) { return "string" == typeof a } function f() { } function g(a) { return !a || "loaded" == a || "complete" == a || "uninitialized" == a } function h() { var a = p.shift(); q = 1, a ? a.t ? m(function () { ("c" == a.t ? B.injectCss : B.injectJs)(a.s, 0, a.a, a.x, a.e, 1) }, 0) : (a(), h()) : q = 0 } function i(a, c, d, e, f, i, j) { function k(b) { if (!o && g(l.readyState) && (u.r = o = 1, !q && h(), l.onload = l.onreadystatechange = null, b)) { "img" != a && m(function () { t.removeChild(l) }, 50); for (var d in y[c]) y[c].hasOwnProperty(d) && y[c][d].onload() } } var j = j || B.errorTimeout, l = b.createElement(a), o = 0, r = 0, u = { t: d, s: c, e: f, a: i, x: j }; 1 === y[c] && (r = 1, y[c] = []), "object" == a ? l.data = c : (l.src = c, l.type = a), l.width = l.height = "0", l.onerror = l.onload = l.onreadystatechange = function () { k.call(this, r) }, p.splice(e, 0, u), "img" != a && (r || 2 === y[c] ? (t.insertBefore(l, s ? null : n), m(k, j)) : y[c].push(l)) } function j(a, b, c, d, f) { return q = 0, b = b || "j", e(a) ? i("c" == b ? v : u, a, b, this.i++, c, d, f) : (p.splice(this.i++, 0, a), 1 == p.length && h()), this } function k() { var a = B; return a.loader = { load: j, i: 0 }, a } var l = b.documentElement, m = a.setTimeout, n = b.getElementsByTagName("script")[0], o = {}.toString, p = [], q = 0, r = "MozAppearance" in l.style, s = r && !!b.createRange().compareNode, t = s ? l : n.parentNode, l = a.opera && "[object Opera]" == o.call(a.opera), l = !!b.attachEvent && !l, u = r ? "object" : l ? "script" : "img", v = l ? "script" : u, w = Array.isArray || function (a) { return "[object Array]" == o.call(a) }, x = [], y = {}, z = { timeout: function (a, b) { return b.length && (a.timeout = b[0]), a } }, A, B; B = function (a) { function b(a) { var a = a.split("!"), b = x.length, c = a.pop(), d = a.length, c = { url: c, origUrl: c, prefixes: a }, e, f, g; for (f = 0; f < d; f++) g = a[f].split("="), (e = z[g.shift()]) && (c = e(c, g)); for (f = 0; f < b; f++) c = x[f](c); return c } function g(a, e, f, g, h) { var i = b(a), j = i.autoCallback; i.url.split(".").pop().split("?").shift(), i.bypass || (e && (e = d(e) ? e : e[a] || e[g] || e[a.split("/").pop().split("?")[0]]), i.instead ? i.instead(a, e, f, g, h) : (y[i.url] ? i.noexec = !0 : y[i.url] = 1, f.load(i.url, i.forceCSS || !i.forceJS && "css" == i.url.split(".").pop().split("?").shift() ? "c" : c, i.noexec, i.attrs, i.timeout), (d(e) || d(j)) && f.load(function () { k(), e && e(i.origUrl, h, g), j && j(i.origUrl, h, g), y[i.url] = 2 }))) } function h(a, b) { function c(a, c) { if (a) { if (e(a)) c || (j = function () { var a = [].slice.call(arguments); k.apply(this, a), l() }), g(a, j, b, 0, h); else if (Object(a) === a) for (n in m = function () { var b = 0, c; for (c in a) a.hasOwnProperty(c) && b++; return b }(), a) a.hasOwnProperty(n) && (!c && !--m && (d(j) ? j = function () { var a = [].slice.call(arguments); k.apply(this, a), l() } : j[n] = function (a) { return function () { var b = [].slice.call(arguments); a && a.apply(this, b), l() } }(k[n])), g(a[n], j, b, n, h)) } else !c && l() } var h = !!a.test, i = a.load || a.both, j = a.callback || f, k = j, l = a.complete || f, m, n; c(h ? a.yep : a.nope, !!i), i && c(i) } var i, j, l = this.yepnope.loader; if (e(a)) g(a, 0, l, 0); else if (w(a)) for (i = 0; i < a.length; i++) j = a[i], e(j) ? g(j, 0, l, 0) : w(j) ? B(j) : Object(j) === j && h(j, l); else Object(a) === a && h(a, l) }, B.addPrefix = function (a, b) { z[a] = b }, B.addFilter = function (a) { x.push(a) }, B.errorTimeout = 1e4, null == b.readyState && b.addEventListener && (b.readyState = "loading", b.addEventListener("DOMContentLoaded", A = function () { b.removeEventListener("DOMContentLoaded", A, 0), b.readyState = "complete" }, 0)), a.yepnope = k(), a.yepnope.executeStack = h, a.yepnope.injectJs = function (a, c, d, e, i, j) { var k = b.createElement("script"), l, o, e = e || B.errorTimeout; k.src = a; for (o in d) k.setAttribute(o, d[o]); c = j ? h : c || f, k.onreadystatechange = k.onload = function () { !l && g(k.readyState) && (l = 1, c(), k.onload = k.onreadystatechange = null) }, m(function () { l || (l = 1, c(1)) }, e), i ? k.onload() : n.parentNode.insertBefore(k, n) }, a.yepnope.injectCss = function (a, c, d, e, g, i) { var e = b.createElement("link"), j, c = i ? h : c || f; e.href = a, e.rel = "stylesheet", e.type = "text/css"; for (j in d) e.setAttribute(j, d[j]); g || (n.parentNode.insertBefore(e, n), m(c, 0)) } })(this, document);
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);

View File

@@ -177,7 +177,10 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
function doLoad(tree) {
var childrenAndSelf = [tree].concat(tree.children);
scope.activeTree = _.find(childrenAndSelf, function (node) {
return node.metaData.treeAlias === treeAlias;
if(node && node.metaData){
return node.metaData.treeAlias === treeAlias;
}
return false;
});
if (!scope.activeTree) {

View File

@@ -44,6 +44,17 @@ angular.module('umbraco.services')
.factory('assetsService', function ($q, $log, angularHelper, umbRequestHelper, $rootScope, $http) {
var initAssetsLoaded = false;
var appendRnd = function(url){
//if we don't have a global umbraco obj yet, the app is bootstrapping
if(!Umbraco.Sys.ServerVariables.application){
return url;
}
var rnd = Umbraco.Sys.ServerVariables.isDebuggingEnabled ? (new Date()).getTime() : Umbraco.Sys.ServerVariables.application.version +"."+Umbraco.Sys.ServerVariables.application.cdf;
var _op = (url.indexOf("?")>0) ? "&" : "?";
url = url + _op + "umb__rnd=" + rnd;
return url;
};
return {
@@ -85,29 +96,23 @@ angular.module('umbraco.services')
* @param {Number} timeout in milliseconds
* @returns {Promise} Promise object which resolves when the file has loaded
*/
loadCss : function(path, scope, attributes, timeout){
var deferred = $q.defer();
var t = timeout || 5000;
var a = attributes || undefined;
loadCss : function(path, scope, attributes, timeout){
var deferred = $q.defer();
var t = timeout || 5000;
var a = attributes || undefined;
yepnope({
forceCSS: true,
load: path,
timeout: t,
attrs: a,
callback: function (url, result, key) {
if (!scope) {
deferred.resolve(true);
}else{
angularHelper.safeApply(scope, function () {
deferred.resolve(true);
});
}
}
});
yepnope.injectCss(appendRnd(path), function () {
if (!scope) {
deferred.resolve(true);
}else{
angularHelper.safeApply(scope, function () {
deferred.resolve(true);
});
}
},a,t);
return deferred.promise;
},
return deferred.promise;
},
/**
* @ngdoc method
@@ -127,30 +132,8 @@ angular.module('umbraco.services')
var deferred = $q.defer();
var t = timeout || 5000;
var a = attributes || undefined;
/*
yepnope({
forceJS: true,
load: path,
timeout: t,
attrs: a,
callback: function (url, result, key) {
if (!scope) {
deferred.resolve(true);
}else{
angularHelper.safeApply(scope, function () {
deferred.resolve(true);
});
}
}
});
*/
yepnope.injectJs(path, function () {
yepnope.injectJs(appendRnd(path), function () {
if (!scope) {
deferred.resolve(true);
}else{
@@ -158,7 +141,6 @@ angular.module('umbraco.services')
deferred.resolve(true);
});
}
},a,t);
@@ -181,14 +163,14 @@ angular.module('umbraco.services')
*/
load: function (pathArray, scope) {
var deferred = $q.defer();
var nonEmpty = _.reject(pathArray, function(item) {
return item === undefined || item === "";
});
//don't load anything if there's nothing to load
if (nonEmpty.length > 0) {
yepnope({
load: pathArray,
complete: function() {

View File

@@ -4,6 +4,10 @@
* @description A helper object used for dealing with media items
**/
function mediaHelper(umbRequestHelper) {
//container of fileresolvers
var _mediaFileResolvers = {};
return {
/**
* @ngdoc function
@@ -204,6 +208,40 @@ function mediaHelper(umbRequestHelper) {
var lowered = imagePath.toLowerCase();
var ext = lowered.substr(lowered.lastIndexOf(".") + 1);
return ("," + Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes + ",").indexOf("," + ext + ",") !== -1;
},
registerFileResolver: function(propertyEditorAlias, func){
_mediaFileResolvers[propertyEditorAlias] = func;
},
resolveFile : function(mediaItem){
var _props = [];
//we either have properties raw on the object, or spread out on tabs
if(mediaItem.properties){
_props = mediaItem.properties;
}else if(mediaItem.tabs){
_.each(mediaItem.tabs, function(tab){
if(tab.properties){
_props.concat(tab.propeties);
}
});
}
//we go through our file resolvers to see if any of them matches the editors
var result = "";
_.each(_mediaFileResolvers, function(resolver, key){
var property = _.find(_props, function(property){ return property.editor === key; });
if(property){
var file = resolver(property);
if(file){
result = file;
}
}
});
return result;
}
};
}

View File

@@ -21,15 +21,18 @@ function packageHelper(assetsService, treeService, eventsService, $templateCache
}
angular.module('umbraco.services').factory('packageHelper', packageHelper);
function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, umbRequestHelper) {
function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, mediaHelper, umbRequestHelper) {
return {
/** sets the image's url - will check if it is a folder or a real image */
setImageUrl: function(img) {
//get the image property (if one exists)
var imageProp = imageHelper.getImagePropertyValue({ imageModel: img });
if (!imageProp) {
//var imageProp = imageHelper.getImagePropertyValue({ imageModel: img });
img.thumbnail = mediaHelper.resolveFile(img);
if (!img.thumbnail){
img.thumbnail = "none";
}
/*
else {
//get the proxy url for big thumbnails (this ensures one is always generated)
@@ -38,7 +41,7 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, um
"GetBigThumbnail",
[{ mediaId: img.id }]);
img.thumbnail = thumbnailUrl;
}
}*/
},
/** sets the images original size properties - will check if it is a folder and if so will just make it square */

View File

@@ -1,7 +1,7 @@
<div class="umb-cropper umb-editor" ng-show="src">
<div class="crop-container">
<div class="viewport" ng-style="style()">
<img src="{{src}}" ng-style="dimensions.image"/>
<img ng-src="{{src}}" ng-style="dimensions.image"/>
<div class="overlay" ng-style="dimensions.image"></div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<div class="umb-cropper-gravity">
<div class="gravity-container">
<div class="viewport">
<img src="{{src}}" style="max-width: 100%; max-height: 100%" />
<img ng-src="{{src}}" style="max-width: 100%; max-height: 100%" />
<div class="overlay" ng-style="style()">

View File

@@ -1,4 +1,4 @@
<div class="umb-crop-thumbnail-container"
ng-style="{height: height, width: width, overflow: 'hidden', position: 'relative'}">
<img src="{{src}}" ng-style="preview" class="noScale" />
<img ng-src="{{src}}" ng-style="preview" class="noScale" />
</div>

View File

@@ -0,0 +1,34 @@
angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesController",
function ($scope, $timeout) {
$scope.newItem = {};
if(!$scope.model.value){
$scope.model.value = [];
}
$scope.remove = function(item, evt) {
evt.preventDefault();
$scope.model.value = _.reject($scope.model.value, function (x) {
return x.alias === item.alias;
});
};
$scope.add = function (evt) {
evt.preventDefault();
if ($scope.newItem) {
var exists = _.find($scope.model.value, function(item){return $scope.newItem.alias === item.alias;});
if (!exists){
$scope.model.value.push($scope.newItem);
$scope.newItem = {};
$scope.hasError = false;
return;
}
}
//there was an error, do the highlight (will be set back by the directive)
$scope.hasError = true;
};
});

View File

@@ -0,0 +1,58 @@
<div ng-controller="Umbraco.PrevalueEditors.CropSizesController" class="umb-editor umb-cropsizes">
<div class="control-group">
<div class="row">
<div class="span3">
<label>Alias</label>
<input name="newItem.alias" type="text"
ng-model="newItem.alias" val-highlight="hasError" />
</div>
<div class="span3">
<label>Height</label>
<input name="newItem.height" type="number"
ng-model="newItem.height" val-highlight="hasError" />
</div>
<div class="span3">
<label>Width</label>
<input name="newItem.width" type="number"
ng-model="newItem.width" val-highlight="hasError" />
</div>
<div class="span3">
<button class="btn btn-small" ng-click="add($event)">Add</button>
</div>
</div>
</div>
<div class="control-group">
<div class="row" ng-repeat="item in model.value">
<div class="span3">
<label>Alias</label>
<input name="newItem.alias" type="text"
ng-model="item.alias"
required val-highlight="hasError" />
</div>
<div class="span3">
<label>Height</label>
<input name="newItem.height" type="number"
ng-model="item.height"
required val-highlight="hasError" />
</div>
<div class="span3">
<label>Width</label>
<input name="newItem.width" type="number"
ng-model="item.width"
required val-highlight="hasError" />
</div>
<div class="span3">
<button class="btn btn-small btn-danger" ng-click="remove(item, $event)">Remove</button>
</div>
</div>
</div>
</div>

View File

@@ -122,7 +122,12 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
//}
}
});
};
angular.module("umbraco").controller('Umbraco.PropertyEditors.FileUploadController', fileUploadController);
angular.module("umbraco")
.controller('Umbraco.PropertyEditors.FileUploadController', fileUploadController)
.run(function(mediaHelper){
mediaHelper.registerFileResolver("Umbraco.FileUpload", function(property){
return property.value;
});
});

View File

@@ -1,9 +1,19 @@
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco').controller("Umbraco.PropertyEditors.ImageCropperController",
function($rootScope, $routeParams, $scope, mediaHelper, cropperHelper, $timeout, editorState, umbRequestHelper, fileManager) {
angular.module('umbraco')
.run(function(mediaHelper){
mediaHelper.registerFileResolver("Umbraco.ImageCropper", function(property){
if(property.value.src){
return property.value.src;
}else if(angular.isString(property.value)){
return property.value;
}
});
})
.controller("Umbraco.PropertyEditors.ImageCropperController",
function($rootScope, $routeParams, $scope, $log, mediaHelper, cropperHelper, $timeout, editorState, umbRequestHelper, fileManager) {
cropperHelper.configuration("Image").then(function(config){
var config = $scope.model.config;
//move previously saved value to the editor
if($scope.model.value){
@@ -11,10 +21,27 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.ImageCropperContro
if(angular.isString($scope.model.value)){
config.src = $scope.model.value;
$scope.model.value = config;
}else if($scope.model.value.crops){
//sync any config changes with the editor and drop outdated crops
_.each($scope.model.value.crops, function(saved){
var configured = _.find(config.crops, function(item){return item.alias === saved.alias});
if(configured && configured.height === saved.height && configured.width === saved.width){
configured.coordinates = saved.coordinates;
}
});
$scope.model.value.crops = config.crops;
//restore focalpoint if missing
if(!$scope.model.value.focalPoint){
$scope.model.value.focalPoint = {left: 0.5, top: 0.5};
}
}
$scope.imageSrc = $scope.model.value.src;
}
//crop a specific crop
$scope.crop = function(crop){
$scope.currentCrop = crop;
@@ -76,6 +103,4 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.ImageCropperContro
reader.readAsDataURL(args.files[0]);
}
});
});
});

View File

@@ -1,6 +1,7 @@
<div class="umb-editor umb-mediapicker"
ng-controller="Umbraco.PropertyEditors.ImageCropperController">
<span class="fileinput-button umb-upload-button-big"
style="margin-bottom: 5px;"
ng-hide="imageSrc">

View File

@@ -90,7 +90,7 @@
//tell the assetsService to load the bootstrap slider
//libs from the plugin folder
assetsService
.loadJs("lib/slider/bootstrap-slider.js")
.loadJs("lib/slider/js/bootstrap-slider.js")
.then(function () {
createSlider();

View File

@@ -15,14 +15,6 @@
<extensionFieldAlias>umbracoExtension</extensionFieldAlias>
</uploadField>
</autoFillImageProperties>
<crops saveFiles="false">
<crop mediaTypeAlias="Image">
<add alias="thumbnail" height="100" width="100" />
<add alias="landscape" height="200" width="600" />
<add alias="Portrait" height="400" width="300" />
</crop>
</crops>
</imaging>
<scripteditor>

View File

@@ -182,11 +182,6 @@ namespace Umbraco.Web.Editors
"rteApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<RichTextPreValueController>(
controller => controller.GetConfiguration())
},
{
"imageCropperApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<ImageCropperPreValueController>(
controller => controller.GetConfiguration(string.Empty))
},
{
"stylesheetApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<StylesheetController>(
controller => controller.GetAll())
@@ -261,7 +256,7 @@ namespace Umbraco.Web.Editors
: string.Format("{0}-{1}", UmbracoVersion.Current.ToString(3), UmbracoVersion.CurrentComment);
app.Add("version", version);
app.Add("cdf", ClientDependency.Core.Config.ClientDependencySettings.Instance.Version);
return app;
}

View File

@@ -34,7 +34,6 @@ namespace Umbraco.Web
return ic;
}
internal static ImageCropDataSet SerializeToCropDataSet(this string json)
{
var imageCrops = new ImageCropDataSet();
@@ -44,9 +43,9 @@ namespace Umbraco.Web
{
imageCrops = JsonConvert.DeserializeObject<ImageCropDataSet>(json);
}
catch
catch(Exception ex)
{
var e = ex;
}
}
@@ -105,8 +104,8 @@ namespace Umbraco.Web
if (allTheCrops != null && allTheCrops.Crops.Any())
{
var crop = cropAlias != null
? allTheCrops.Crops[cropAlias]
: allTheCrops.Crops.First().Value;
? allTheCrops.Crops.First(x => x.Alias ==cropAlias)
: allTheCrops.Crops.First();
if (crop != null)
{
return true;
@@ -131,8 +130,8 @@ namespace Umbraco.Web
if (allTheCrops != null && allTheCrops.Crops.Any())
{
var crop = cropAlias != null
? allTheCrops.Crops[cropAlias]
: allTheCrops.Crops.First().Value;
? allTheCrops.Crops.First(x => x.Alias ==cropAlias)
: allTheCrops.Crops.First();
if (crop != null)
{
return true;

View File

@@ -10,11 +10,7 @@ namespace Umbraco.Web
{
public static class ImageCropperTemplateExtensions
{
public static bool HasCrop(this IPublishedContent publishedContent, string propertyAlias, string cropAlias)
{
return ImageCropperPropertyEditorHelper.GetCrop(publishedContent.ContentType.Alias, cropAlias) != null;
}
//this only takes the crop json into account
public static string Crop(this IPublishedContent mediaItem, string propertyAlias, string cropAlias)
{
@@ -26,7 +22,7 @@ namespace Umbraco.Web
if (property.IsJson())
{
var cropDataSet = property.SerializeToCropDataSet();
var currentCrop = cropDataSet.Crops[cropAlias];
var currentCrop = cropDataSet.Crops.First(x => x.Alias ==cropAlias);
return cropDataSet.Src + currentCrop.ToUrl();
}
else
@@ -38,10 +34,7 @@ namespace Umbraco.Web
}
public static string Crop(
public static string Crop(
this IPublishedContent mediaItem,
int? width = null,
int? height = null,
@@ -72,7 +65,7 @@ namespace Umbraco.Web
Mode? mode = null,
Anchor? anchor = null,
string imageCropperValue = null,
string imageCropperCropId = null,
string cropAlias = null,
string furtherOptions = null,
bool slimmage = false)
{
@@ -86,9 +79,9 @@ namespace Umbraco.Web
var allTheCrops = imageCropperValue.SerializeToCropDataSet();
if (allTheCrops != null && allTheCrops.Crops.Any())
{
var crop = imageCropperCropId != null
? allTheCrops.Crops[imageCropperCropId]
: allTheCrops.Crops.First().Value;
var crop = cropAlias != null
? allTheCrops.Crops.First(x => x.Alias ==cropAlias)
: allTheCrops.Crops.First();
if (crop != null)
{
imageResizerUrl.Append(crop.ToUrl());

View File

@@ -21,6 +21,10 @@ namespace Umbraco.Web.Models.ContentEditing
[Required(AllowEmptyStrings = false)]
public string Alias { get; set; }
[DataMember(Name = "editor", IsRequired = false)]
public string Editor { get; set; }
/// <summary>
/// Used internally during model mapping
/// </summary>

View File

@@ -13,17 +13,11 @@ namespace Umbraco.Web.Models
[DataMember(Name="src")]
public string Src { get; set;}
[DataMember(Name = "imagePropertyAlias")]
public string ImagePropertyAlias { get; set; }
[DataMember(Name = "focalPointPropertyAlias")]
public string FocalPointPropertyAlias { get; set; }
[DataMember(Name = "focalPoint")]
public ImageCropFocalPoint FocalPoint { get; set; }
[DataMember(Name = "crops")]
public IDictionary<string, ImageCropData> Crops { get; set; }
public IEnumerable<ImageCropData> Crops { get; set; }
}
[DataContract(Name = "imageCropFocalPoint")]
@@ -59,8 +53,8 @@ namespace Umbraco.Web.Models
[DataMember(Name = "alias")]
public string Alias { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
//[DataMember(Name = "name")]
//public string Name { get; set; }
[DataMember(Name = "width")]
public int Width { get; set; }

View File

@@ -44,7 +44,8 @@ namespace Umbraco.Web.Models.Mapping
Id = property.Id,
Value = editor.ValueEditor.ConvertDbToEditor(property, property.PropertyType, DataTypeService.Value),
Alias = property.Alias,
PropertyEditor = editor
PropertyEditor = editor,
Editor = editor.Alias
};
return result;

View File

@@ -74,16 +74,25 @@ namespace Umbraco.Web.PropertyEditors
if (uploadFieldConfigNode != null)
{
//now we need to check if there is a value
if (p.Value is string && ((string) p.Value).IsNullOrWhiteSpace() == false)
{
//there might be multiple, we can only process the first one!
var split = ((string) p.Value).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
if (split.Any())
if (!p.Value.ToString().IsJson())
{
var fullPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(split[0]));
var umbracoFile = new UmbracoMediaFile(fullPath);
FillProperties(uploadFieldConfigNode, model, umbracoFile);
//there might be multiple, we can only process the first one!
var split = ((string)p.Value).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (split.Any())
{
var fullPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(split[0]));
var umbracoFile = new UmbracoMediaFile(fullPath);
FillProperties(uploadFieldConfigNode, model, umbracoFile);
}
}
else
{
//for now I'm just resetting this
ResetProperties(uploadFieldConfigNode, model);
}
}
else

View File

@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core.Configuration;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
namespace Umbraco.Web.PropertyEditors
{
public class ImageCropperPreValueController : UmbracoAuthorizedJsonController
{
//Returns the collection of allowed crops on a given media alias type
public Models.ImageCropDataSet GetConfiguration(string mediaTypeAlias)
{
return ImageCropperPropertyEditorHelper.GetConfigurationForType(mediaTypeAlias);
}
//Returns a specific crop on a media type
public Models.ImageCropData GetCrop(string mediaTypeAlias, string cropAlias)
{
return ImageCropperPropertyEditorHelper.GetCrop(mediaTypeAlias, cropAlias);
}
}
}

View File

@@ -21,5 +21,34 @@ namespace Umbraco.Web.PropertyEditors
var baseEditor = base.CreateValueEditor();
return new ImageCropperPropertyValueEditor(baseEditor);
}
protected override PreValueEditor CreatePreValueEditor()
{
return new ImageCropperPreValueEditor();
}
public ImageCropperPropertyEditor()
{
_internalPreValues = new Dictionary<string, object>
{
{"crops", "[]"},
{"focalPoint", "{left: 0.5, top: 0.5}"},
{"src", ""}
};
}
private IDictionary<string, object> _internalPreValues;
public override IDictionary<string, object> DefaultPreValues
{
get { return _internalPreValues; }
set { _internalPreValues = value; }
}
internal class ImageCropperPreValueEditor : PreValueEditor
{
[PreValueField("crops", "Crop sizes", "cropsizes")]
public string Crops { get; set; }
}
}
}

View File

@@ -9,44 +9,29 @@ namespace Umbraco.Web.PropertyEditors
{
internal class ImageCropperPropertyEditorHelper
{
//Returns the collection of allowed crops on a given media alias type
internal static Models.ImageCropDataSet GetConfigurationForType(string mediaTypeAlias)
{
var defaultModel = new Models.ImageCropDataSet();
defaultModel.FocalPoint = new Models.ImageCropFocalPoint() { Left = 0.5M, Top = 0.5M };
var configuredCrops = UmbracoConfig.For.UmbracoSettings().Content.ImageCrops.Crops.FirstOrDefault(x => x.MediaTypeAlias == mediaTypeAlias);
if (configuredCrops == null || !configuredCrops.CropSizes.Any())
return defaultModel;
var crops = new Dictionary<string, Umbraco.Web.Models.ImageCropData>();
foreach (var cropSize in configuredCrops.CropSizes)
crops.Add(cropSize.Alias, new Models.ImageCropData() { Alias = cropSize.Alias, Height = cropSize.Height, Width = cropSize.Width });
defaultModel.Crops = crops;
return defaultModel;
}
internal static Umbraco.Web.Models.ImageCropData GetCrop(string mediaTypeAlias, string cropAlias){
var _crops = GetConfigurationForType(mediaTypeAlias);
return null;
/*var _crops = GetConfigurationForType(mediaTypeAlias);
if (_crops == null || _crops.Crops == null)
return null;
return _crops.Crops[cropAlias];
return _crops.Crops[cropAlias];*/
}
//this queries all crops configured
internal static Umbraco.Web.Models.ImageCropData GetCrop(string cropAlias)
{
/*
foreach (var typeCrops in UmbracoConfig.For.UmbracoSettings().Content.ImageCrops.Crops)
{
var cropSize = typeCrops.CropSizes.FirstOrDefault(x => x.Alias == cropAlias);
if(cropSize != null)
return new Models.ImageCropData() { Alias = cropSize.Alias, Height = cropSize.Height, Width = cropSize.Width };
}
}*/
return null;
}

View File

@@ -23,6 +23,7 @@ namespace Umbraco.Web.PropertyEditors
}
/// <summary>
/// Overrides the deserialize value so that we can save the file accordingly
/// </summary>
@@ -62,7 +63,7 @@ namespace Umbraco.Web.PropertyEditors
//compare old and new src path
//if not alike, that means we have a new file, or delete the current one...
if (oldFile != newFile)
if (string.IsNullOrEmpty(newFile) || editorValue.AdditionalData.ContainsKey("files"))
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
@@ -118,4 +119,6 @@ namespace Umbraco.Web.PropertyEditors
return editorValue.Value.ToString();
}
}
}

View File

@@ -41,13 +41,21 @@ namespace Umbraco.Web.UI.JavaScript
public string GetJavascriptInitialization(HttpContextBase httpContext, JArray umbracoInit, JArray additionalJsFiles = null)
{
var result = GetJavascriptInitializationArray(httpContext, umbracoInit, additionalJsFiles);
var noCache = string.Empty;
//if debugging, add timestamp, if in production CDF will append CDF version (and should also append umb version)
var noCache = Resources.JsNoCache;
//if debugging, add timestamp, if in production we tell yepNope to append umb+cdf version
//this is needed even tho cdf does this on its serverside merged js
//as assetsService.load() also need to append these versions to ensure cache bursting on updates + pack installs
if (httpContext.IsDebuggingEnabled)
noCache = Resources.JsNoCache;
noCache = noCache.Replace("##rnd##", "(new Date).getTime()");
else
{
var version = "'" + Umbraco.Core.Configuration.UmbracoVersion.Current.ToString() + "." + ClientDependency.Core.Config.ClientDependencySettings.Instance.Version + "'";
noCache = noCache.Replace("##rnd##", version);
}
return ParseMain(
noCache,
result.ToString(),

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18408
// Runtime Version:4.0.30319.18444
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -89,6 +89,7 @@ namespace Umbraco.Web.UI.JavaScript {
/// <summary>
/// Looks up a localized string similar to yepnope.addFilter(function (resourceObj) {
/// var url = resourceObj.url;
/// var rnd = ##rnd##;
/// var _op = &quot;?&quot;;
/// if(url.indexOf(&quot;lib/&quot;) === 0 || url.indexOf(&quot;js/umbraco.&quot;) === 0){
/// return resourceObj;
@@ -97,7 +98,7 @@ namespace Umbraco.Web.UI.JavaScript {
/// _op = &quot;&amp;&quot;;
/// }
///
/// resourceObj.url = resourceObj.url + _op + &quot;umb__rnd=&quot; + (new Date).getTime();
/// resourceObj.url = resourceObj.url + _op + &quot;umb__rnd=&quot; + rnd;
/// return resourceObj;
///});.
/// </summary>

View File

@@ -124,6 +124,7 @@
<data name="JsNoCache" xml:space="preserve">
<value>yepnope.addFilter(function (resourceObj) {
var url = resourceObj.url;
var rnd = ##rnd##;
var _op = "?";
if(url.indexOf("lib/") === 0 || url.indexOf("js/umbraco.") === 0){
return resourceObj;
@@ -132,7 +133,7 @@
_op = "&amp;";
}
resourceObj.url = resourceObj.url + _op + "umb__rnd=" + (new Date).getTime();
resourceObj.url = resourceObj.url + _op + "umb__rnd=" + rnd;
return resourceObj;
});</value>
</data>

View File

@@ -346,7 +346,6 @@
<Compile Include="PropertyEditors\ColorListPreValueEditor.cs" />
<Compile Include="PropertyEditors\EmailAddressPropertyEditor.cs" />
<Compile Include="ImageCropperBaseExtensions.cs" />
<Compile Include="PropertyEditors\ImageCropperPrevalueController.cs" />
<Compile Include="PropertyEditors\ImageCropperPropertyEditor.cs" />
<Compile Include="PropertyEditors\ImageCropperPropertyEditorHelper.cs" />
<Compile Include="PropertyEditors\ImageCropperPropertyValueEditor.cs" />