Compare commits

...

21 Commits

Author SHA1 Message Date
Sebastiaan Janssen 4664266b8d Bumps version to 7.10.3 2018-04-12 16:40:10 +02:00
Sebastiaan Janssen 5003a55aca Cherry picked - Fix scope leaks caused by database messenger [U4-11207] #2580 2018-04-12 16:32:34 +02:00
Dave Woestenborghs 354505fde3 U4-11149 fixed error when creating new xslt file (#2540)
* U4-10659 added create task back for xslt files

* Add fix to UI.Release.xml as well
2018-04-09 14:47:09 +02:00
Sebastiaan Janssen 95d40049f5 Bumps version to 7.10.2 2018-04-09 08:30:39 +02:00
Sebastiaan Janssen f003c3602c Merge pull request #2545 from dawoe/temp-U4-11155
U4-11155 fixed error when creating member groups
2018-04-09 08:28:03 +02:00
Shannon Deminick e25d648f44 Merge pull request #2556 from dawoe/temp-U4-11167
U4-11167 Fixes rare syncTree error
2018-04-06 14:46:23 +10:00
Warren Buckley 43e32e66b6 Merge pull request #2550 from dawoe/temp-U4-11161
U4-11161 fix for adding multiple items in a single content picker
2018-04-05 10:15:39 +01:00
Dave Woestenborghs 859cb6ce1a U4-11167 removed the time out..only check if the syncTree method exists 2018-04-04 09:44:29 +02:00
Warren bdaa70592f Adds in missing $scope dependency for Dynamic Dashboard Controller 2018-04-04 08:28:41 +01:00
Dave Woestenborghs 27b19a0a33 U4-11167 only wrap in time out when syncTree method is undefined 2018-04-03 07:37:37 +02:00
Shannon 047a05cfb3 bumps version 2018-04-03 11:38:13 +10:00
Shannon e77ebc0c1c Fixes all references to assetsService.load* that do not pass in a required scope object and changes assets.service to always use the $rootScope of an explicit scope is not passed 2018-04-03 11:27:53 +10:00
Shannon a27ea994b7 updates the loadMomentLocaleForCurrentUser to always return a promise 2018-04-03 10:59:55 +10:00
Shannon e019c94207 changes back to correct version 2018-04-03 10:42:57 +10:00
Shannon 5b7193aa64 Merge branch 'temp-U4-11164' of https://github.com/dawoe/Umbraco-CMS into dawoe-temp-U4-11164 2018-04-03 10:41:01 +10:00
Dave Woestenborghs f6263aad5b U4-11167 wrap syncTree method to handle rare occasions where it is not defined yet 2018-03-31 15:09:30 +02:00
Dave Woestenborghs 28a0e30315 U4-11164 fixed blank screen for about 30 seconds after logging in. Because of q.all we don't need to wait until promise is resolved, because all promises are resolved when this is hit 2018-03-30 11:20:41 +02:00
Dave Woestenborghs d1eb6b1aa8 U4-11161 don't show help text when it's not a multipicker 2018-03-28 17:07:56 +02:00
Dave Woestenborghs 458d023ff4 U4-11161 set min and max number in default config 2018-03-28 17:03:35 +02:00
Claus 716020602d adding using statement to preview file to prevent missing htmlhelper error. 2018-03-23 11:55:23 +01:00
Sebastiaan Janssen 8c0ec489c2 Bump version to 7.11 2018-03-23 09:54:11 +01:00
33 changed files with 165 additions and 94 deletions
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.10.0")]
[assembly: AssemblyInformationalVersion("7.10.0")]
[assembly: AssemblyFileVersion("7.10.3")]
[assembly: AssemblyInformationalVersion("7.10.3")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.10.0");
private static readonly Version Version = new Version("7.10.3");
/// <summary>
/// Gets the current version of Umbraco.
+7 -8
View File
@@ -402,7 +402,7 @@ namespace Umbraco.Core.Persistence
}
// Helper to handle named parameters from object properties
static Regex rxParams = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
static readonly Regex rxParams = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
public static string ProcessParams(string _sql, object[] args_src, List<object> args_dest)
{
return rxParams.Replace(_sql, m =>
@@ -545,7 +545,7 @@ namespace Umbraco.Core.Persistence
}
// Create a command
static Regex rxParamsPrefix = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
static readonly Regex rxParamsPrefix = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
public IDbCommand CreateCommand(IDbConnection connection, string sql, params object[] args)
{
// Perform named argument replacements
@@ -666,8 +666,8 @@ namespace Umbraco.Core.Persistence
return ExecuteScalar<T>(sql.SQL, sql.Arguments);
}
Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
static readonly Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
static readonly Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
string AddSelectClause<T>(string sql)
{
if (sql.StartsWith(";"))
@@ -701,9 +701,9 @@ namespace Umbraco.Core.Persistence
return Fetch<T>(sql.SQL, sql.Arguments);
}
static Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static Regex rxOrderBy = new Regex(@"\bORDER\s+BY\s+(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static Regex rxDistinct = new Regex(@"\ADISTINCT\s", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static readonly Regex rxColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static readonly Regex rxOrderBy = new Regex(@"\bORDER\s+BY\s+(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
static readonly Regex rxDistinct = new Regex(@"\ADISTINCT\s", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
public static bool SplitSqlForPaging(string sql, out string sqlCount, out string sqlSelectRemoved, out string sqlOrderBy)
{
sqlSelectRemoved = null;
@@ -2546,5 +2546,4 @@ namespace Umbraco.Core.Persistence
}
}
}
}
+3
View File
@@ -20,6 +20,7 @@ namespace Umbraco.Core.Scoping
public NoScope(ScopeProvider scopeProvider)
{
_scopeProvider = scopeProvider;
Timestamp = DateTime.Now;
#if DEBUG_SCOPES
_scopeProvider.RegisterScope(this);
#endif
@@ -28,6 +29,8 @@ namespace Umbraco.Core.Scoping
private readonly Guid _instanceId = Guid.NewGuid();
public Guid InstanceId { get { return _instanceId; } }
public DateTime Timestamp { get; }
/// <inheritdoc />
public bool CallContext { get { return false; } }
+1 -1
View File
@@ -374,7 +374,7 @@ namespace Umbraco.Core.Scoping
}
var parent = ParentScope;
_scopeProvider.AmbientScope = parent;
_scopeProvider.AmbientScope = parent; // might be null = this is how scopes are removed from context objects
#if DEBUG_SCOPES
_scopeProvider.Disposed(this);
+51 -6
View File
@@ -2,10 +2,12 @@
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Web;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
#if DEBUG_SCOPES
using System.Linq;
@@ -66,22 +68,38 @@ namespace Umbraco.Core.Scoping
// tests, any other things (see https://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx),
// but we don't want to make all of our objects serializable since they are *not* meant to be
// used in cross-AppDomain scenario anyways.
//
// in addition, whatever goes into the logical call context is serialized back and forth any
// time cross-AppDomain code executes, so if we put an "object" there, we'll can *another*
// "object" instance - and so we cannot use a random object as a key.
// time cross-AppDomain code executes, so if we put an "object" there, we'll get *another*
// "object" instance back - and so we cannot use a random object as a key.
//
// so what we do is: we register a guid in the call context, and we keep a table mapping those
// guids to the actual objects. the guid serializes back and forth without causing any issue,
// and we can retrieve the actual objects from the table.
// only issue: how are we supposed to clear the table? we can't, really. objects should take
// care of de-registering themselves from context.
// everything we use does, except the NoScope scope, which just stays there
//
// during tests, NoScope can to into call context... nothing much we can do about it
// so far, the only objects that go into this table are scopes (using ScopeItemKey) and
// scope contexts (using ContextItemKey).
private static readonly object StaticCallContextObjectsLock = new object();
private static readonly Dictionary<Guid, object> StaticCallContextObjects
= new Dictionary<Guid, object>();
// normal scopes and scope contexts take greate care removing themselves when disposed, so it
// is all safe. OTOH the NoScope *CANNOT* remove itself, this is by design, it *WILL* leak and
// there is little (nothing) we can do about it - NoScope exists for backward compatibility
// reasons and relying on it is greatly discouraged.
//
// however... we can *try* at protecting the app against memory leaks, by collecting NoScope
// instances that are too old. if anything actually *need* to retain a NoScope instance for
// a long time, it will break. but that's probably ok. so: the constants below define how
// long a NoScope instance can stay in the table before being removed, and how often we should
// collect the table - and collecting happens anytime SetCallContextObject is invoked
private static readonly TimeSpan StaticCallContextNoScopeLifeSpan = TimeSpan.FromMinutes(30);
private static readonly TimeSpan StaticCallContextCollectPeriod = TimeSpan.FromMinutes(4);
private static DateTime _staticCallContextLastCollect = DateTime.MinValue;
#if DEBUG_SCOPES
public Dictionary<Guid, object> CallContextObjects
{
@@ -156,6 +174,7 @@ namespace Umbraco.Core.Scoping
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
StaticCallContextObjects.Remove(objectKey);
CollectStaticCallContextObjectsLocked();
}
}
else
@@ -171,11 +190,37 @@ namespace Umbraco.Core.Scoping
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
StaticCallContextObjects.Add(objectKey, value);
CollectStaticCallContextObjectsLocked();
}
CallContext.LogicalSetData(key, objectKey);
}
}
private static void CollectStaticCallContextObjectsLocked()
{
// is it time to collect?
var now = DateTime.Now;
if (now - _staticCallContextLastCollect <= StaticCallContextCollectPeriod)
return;
// disable warning: this method is invoked from within a lock
// ReSharper disable InconsistentlySynchronizedField
var threshold = now.Add(-StaticCallContextNoScopeLifeSpan);
var guids = StaticCallContextObjects
.Where(x => x.Value is NoScope noScope && noScope.Timestamp < threshold)
.Select(x => x.Key)
.ToList();
if (guids.Count > 0)
{
LogHelper.Warn<ScopeProvider>($"Collected {guids.Count} NoScope instances from StaticCallContextObjects.");
foreach (var guid in guids)
StaticCallContextObjects.Remove(guid);
}
// ReSharper restore InconsistentlySynchronizedField
_staticCallContextLastCollect = now;
}
// this is for tests exclusively until we have a proper accessor in v8
internal static Func<IDictionary> HttpContextItemsGetter { get; set; }
@@ -5,7 +5,6 @@ using Umbraco.Web.UI;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.interfaces;
using Umbraco.Web.umbraco.presentation.umbraco.create;
namespace Umbraco.Tests.UI
{
@@ -125,7 +125,7 @@
function link(scope, el, attr, ngModel) {
// Load in ace library
assetsService.load(['lib/ace-builds/src-min-noconflict/ace.js', 'lib/ace-builds/src-min-noconflict/ext-language_tools.js']).then(function () {
assetsService.load(['lib/ace-builds/src-min-noconflict/ace.js', 'lib/ace-builds/src-min-noconflict/ext-language_tools.js'], scope).then(function () {
if (angular.isUndefined(window.ace)) {
throw new Error('ui-ace need ace to work... (o rly?)');
} else {
@@ -101,7 +101,7 @@
var clipboard;
var target = element[0];
assetsService.loadJs("lib/clipboard/clipboard.min.js")
assetsService.loadJs("lib/clipboard/clipboard.min.js", scope)
.then(function () {
if(scope.umbClipboardTarget) {
@@ -92,10 +92,10 @@ Use this directive to render a date time picker
scope.hasTranscludedContent = element.find('.js-datePicker__transcluded-content')[0].children.length > 0;
// load css file for the date picker
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css');
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', scope);
// load the js file for the date picker
assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js').then(function () {
assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js', scope).then(function () {
// init date picker
initDatePicker();
});
@@ -129,14 +129,12 @@ angular.module('umbraco.services')
asset.state = "loading";
LazyLoad.css(appendRnd(path), function () {
if (!scope) {
asset.state = "loaded";
asset.deferred.resolve(true);
} else {
asset.state = "loaded";
angularHelper.safeApply(scope, function () {
asset.deferred.resolve(true);
});
scope = $rootScope;
}
asset.state = "loaded";
angularHelper.safeApply(scope, function () {
asset.deferred.resolve(true);
});
});
} else if (asset.state === "loaded") {
asset.deferred.resolve(true);
@@ -171,14 +169,12 @@ angular.module('umbraco.services')
LazyLoad.js(appendRnd(path), function () {
if (!scope) {
asset.state = "loaded";
asset.deferred.resolve(true);
} else {
asset.state = "loaded";
angularHelper.safeApply(scope, function () {
asset.deferred.resolve(true);
});
scope = $rootScope;
}
asset.state = "loaded";
angularHelper.safeApply(scope, function () {
asset.deferred.resolve(true);
});
});
} else if (asset.state === "loaded") {
@@ -234,8 +230,7 @@ angular.module('umbraco.services')
assets.push(asset);
}
//we need to always push to the promises collection to monitor correct
//execution
//we need to always push to the promises collection to monitor correct execution
promises.push(asset.deferred.promise);
}
});
@@ -256,8 +251,7 @@ angular.module('umbraco.services')
function assetLoaded(asset) {
asset.state = "loaded";
if (!scope) {
asset.deferred.resolve(true);
return;
scope = $rootScope;
}
angularHelper.safeApply(scope,
function () {
@@ -280,4 +274,4 @@ angular.module('umbraco.services')
};
return service;
});
});
@@ -288,9 +288,12 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
throw "args.tree cannot be null";
}
if (mainTreeEventHandler) {
//returns a promise
return mainTreeEventHandler.syncTree(args);
if (mainTreeEventHandler) {
if (mainTreeEventHandler.syncTree) {
//returns a promise,
return mainTreeEventHandler.syncTree(args);
}
}
//couldn't sync
@@ -278,8 +278,6 @@ angular.module('umbraco.services')
/** Loads the Moment.js Locale for the current user. */
loadMomentLocaleForCurrentUser: function () {
var deferred = $q.defer();
function loadLocales(currentUser, supportedLocales) {
var locale = currentUser.locale.toLowerCase();
@@ -294,11 +292,14 @@ angular.module('umbraco.services')
localeUrls.push('lib/moment/' + majorLocale);
}
}
assetsService.load(localeUrls).then(function () {
deferred.resolve(localeUrls);
});
} else {
deferred.resolve(['']);
return assetsService.load(localeUrls, $rootScope);
}
else {
//return a noop promise
var deferred = $q.defer();
var promise = deferred.promise;
deferred.resolve(true);
return promise;
}
}
@@ -307,11 +308,11 @@ angular.module('umbraco.services')
supportedLocales: javascriptLibraryService.getSupportedLocalesForMoment()
}
$q.all(promises).then(function (values) {
loadLocales(values.currentUser, values.supportedLocales);
return $q.all(promises).then(function (values) {
return loadLocales(values.currentUser, values.supportedLocales);
});
return deferred.promise;
},
@@ -1,6 +1,6 @@
angular.module("umbraco")
.controller("Umbraco.Dialogs.ApprovedColorPickerController", function ($scope, $http, umbPropEditorHelper, assetsService) {
assetsService.loadJs("lib/cssparser/cssparser.js")
assetsService.loadJs("lib/cssparser/cssparser.js", $scope)
.then(function () {
var cssPath = $scope.dialogData.cssPath;
@@ -19,7 +19,7 @@ angular.module("umbraco")
$scope.classes.splice(0, 0, "noclass");
})
assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/uSky.Grid.ApprovedColorPicker.css");
assetsService.loadCss(cssPath);
assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/uSky.Grid.ApprovedColorPicker.css", $scope);
assetsService.loadCss(cssPath, $scope);
});
});
});
@@ -18,7 +18,7 @@ function startUpVideosDashboardController($scope, xmlhelper, $log, $http) {
angular.module("umbraco").controller("Umbraco.Dashboard.StartupVideosController", startUpVideosDashboardController);
function startUpDynamicContentController($timeout, dashboardResource, assetsService, tourService, eventsService) {
function startUpDynamicContentController($timeout, $scope, dashboardResource, assetsService, tourService, eventsService) {
var vm = this;
var evts = [];
@@ -95,7 +95,7 @@ function startUpDynamicContentController($timeout, dashboardResource, assetsServ
}));
//proxy remote css through the local server
assetsService.loadCss( dashboardResource.getRemoteDashboardCssUrl("content") );
assetsService.loadCss(dashboardResource.getRemoteDashboardCssUrl("content"), $scope);
dashboardResource.getRemoteDashboardContent("content").then(
function (data) {
@@ -249,7 +249,7 @@
function init() {
//we need to load this somewhere, for now its here.
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
@@ -355,4 +355,4 @@
}
angular.module("umbraco").controller("Umbraco.Editors.PartialViewMacros.EditController", partialViewMacrosEditController);
})();
})();
@@ -242,7 +242,7 @@
function init() {
//we need to load this somewhere, for now its here.
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
@@ -105,5 +105,5 @@
};
//load the separate css for the editor to avoid it blocking our js loading
assetsService.loadCss("lib/spectrum/spectrum.css");
assetsService.loadCss("lib/spectrum/spectrum.css", $scope);
});
@@ -66,6 +66,8 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
showOpenButton: false,
showEditButton: false,
showPathOnHover: false,
maxNumber: 1,
minNumber : 0,
startNode: {
query: "",
type: "content",
@@ -28,7 +28,7 @@
<localize key="general_add">Add</localize>
</a>
<div class="umb-contentpicker__min-max-help">
<div class="umb-contentpicker__min-max-help" ng-if="model.config.multiPicker === true">
<!-- Both min and max items -->
<span ng-if="model.config.minNumber && model.config.maxNumber && model.config.minNumber !== model.config.maxNumber">
@@ -112,7 +112,7 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
//get the current user to see if we can localize this picker
userService.getCurrentUser().then(function (user) {
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css').then(function() {
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', $scope).then(function() {
var filesToLoad = ["lib/datetimepicker/bootstrap-datetimepicker.js"];
@@ -2,7 +2,7 @@ angular.module("umbraco")
.controller("Umbraco.PropertyEditors.GoogleMapsController",
function ($element, $rootScope, $scope, notificationsService, dialogService, assetsService, $log, $timeout) {
assetsService.loadJs('https://www.google.com/jsapi')
assetsService.loadJs('https://www.google.com/jsapi', $scope)
.then(function () {
google.load("maps", "3",
{
@@ -94,4 +94,4 @@ angular.module("umbraco")
//update the display val again if it has changed from the server
initMap();
};
});
});
@@ -74,7 +74,7 @@ function MarkdownEditorController($scope, $element, assetsService, dialogService
});
//load the seperat css for the editor to avoid it blocking our js loading TEMP HACK
assetsService.loadCss("lib/markdown/markdown.css");
assetsService.loadCss("lib/markdown/markdown.css", $scope);
})
}
@@ -117,5 +117,5 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
});
// load TinyMCE skin which contains css for font-icons
assetsService.loadCss("lib/tinymce/skins/umbraco/skin.min.css");
});
assetsService.loadCss("lib/tinymce/skins/umbraco/skin.min.css", $scope);
});
@@ -211,7 +211,7 @@
});
//load the separate css for the editor to avoid it blocking our js loading
assetsService.loadCss("lib/slider/bootstrap-slider.css");
assetsService.loadCss("lib/slider/bootstrap-slider-custom.css");
assetsService.loadCss("lib/slider/bootstrap-slider.css", $scope);
assetsService.loadCss("lib/slider/bootstrap-slider-custom.css", $scope);
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.SliderController", sliderController);
@@ -7,7 +7,7 @@ angular.module("umbraco")
$scope.isLoading = true;
$scope.tagToAdd = "";
assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js").then(function () {
assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js", $scope).then(function () {
$scope.isLoading = false;
@@ -92,7 +92,7 @@
function init() {
//we need to load this somewhere, for now its here.
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
codefileResource.getScaffold("scripts", $routeParams.id).then(function (script) {
@@ -199,4 +199,4 @@
}
angular.module("umbraco").controller("Umbraco.Editors.Scripts.EditController", ScriptsEditController);
})();
})();
@@ -105,7 +105,7 @@
vm.init = function () {
//we need to load this somewhere, for now its here.
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
//load templates - used in the master template picker
templateResource.getAll()
+2 -2
View File
@@ -1035,9 +1035,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7100</DevelopmentServerPort>
<DevelopmentServerPort>7103</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7100</IISUrl>
<IISUrl>http://localhost:7103</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -19,6 +19,7 @@
<header>Macro</header>
<usercontrol>/create/xslt.ascx</usercontrol>
<tasks>
<create assembly="umbraco" type="XsltTasks" />
<delete assembly="umbraco" type="XsltTasks" />
</tasks>
</nodeType>
@@ -19,6 +19,7 @@
<header>Macro</header>
<usercontrol>/create/xslt.ascx</usercontrol>
<tasks>
<create assembly="umbraco" type="XsltTasks" />
<delete assembly="umbraco" type="XsltTasks" />
</tasks>
</nodeType>
@@ -9,6 +9,7 @@ using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Sync;
using Umbraco.Web.Routing;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
using Umbraco.Web.Scheduling;
namespace Umbraco.Web
@@ -21,9 +22,12 @@ namespace Umbraco.Web
/// </remarks>
public class BatchedDatabaseServerMessenger : DatabaseServerMessenger
{
private readonly ApplicationContext _appContext;
public BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options)
: base(appContext, enableDistCalls, options)
{
_appContext = appContext;
Scheduler.Initializing += Scheduler_Initializing;
}
@@ -42,7 +46,7 @@ namespace Umbraco.Web
//start the background task runner for processing instructions
const int delayMilliseconds = 60000;
var instructionProcessingRunner = new BackgroundTaskRunner<IBackgroundTask>("InstructionProcessing", ApplicationContext.ProfilingLogger.Logger);
var instructionProcessingTask = new InstructionProcessing(instructionProcessingRunner, this, delayMilliseconds, Options.ThrottleSeconds * 1000);
var instructionProcessingTask = new InstructionProcessing(instructionProcessingRunner, this, _appContext.ScopeProvider, delayMilliseconds, Options.ThrottleSeconds * 1000);
instructionProcessingRunner.TryAdd(instructionProcessingTask);
e.Add(instructionProcessingTask);
}
@@ -73,18 +77,31 @@ namespace Umbraco.Web
private class InstructionProcessing : RecurringTaskBase
{
private readonly DatabaseServerMessenger _messenger;
private readonly IScopeProvider _scopeProvider;
public InstructionProcessing(IBackgroundTaskRunner<RecurringTaskBase> runner,
DatabaseServerMessenger messenger,
IScopeProvider scopeProvider,
int delayMilliseconds, int periodMilliseconds)
: base(runner, delayMilliseconds, periodMilliseconds)
{
_messenger = messenger;
_scopeProvider = scopeProvider;
}
public override bool PerformRun()
{
_messenger.Sync();
// beware!
// DatabaseServerMessenger uses _appContext.DatabaseContext.Database without creating
// scopes, and since we are running in a background task, there will be no ambient
// scope (as would be the case within a web request), and so we would end up creating
// (and leaking) a NoScope instance, which is bad - better make sure we have a true
// scope here! - see U4-11207
using (var scope = _scopeProvider.CreateScope())
{
_messenger.Sync();
scope.Complete();
}
//return true to repeat
return true;
}
@@ -121,14 +138,17 @@ namespace Umbraco.Web
batch.Clear();
//Write the instructions but only create JSON blobs with a max instruction count equal to MaxProcessingInstructionCount
foreach (var instructionsBatch in instructions.InGroupsOf(Options.MaxProcessingInstructionCount))
using (var scope = _appContext.ScopeProvider.CreateScope())
{
WriteInstructions(instructionsBatch);
foreach (var instructionsBatch in instructions.InGroupsOf(Options.MaxProcessingInstructionCount))
{
WriteInstructions(scope, instructionsBatch);
}
scope.Complete();
}
}
private void WriteInstructions(IEnumerable<RefreshInstruction> instructions)
private void WriteInstructions(IScope scope, IEnumerable<RefreshInstruction> instructions)
{
var dto = new CacheInstructionDto
{
@@ -137,8 +157,7 @@ namespace Umbraco.Web
OriginIdentity = LocalIdentity,
InstructionCount = instructions.Sum(x => x.JsonIdCount)
};
ApplicationContext.DatabaseContext.Database.Insert(dto);
scope.Database.Insert(dto);
}
protected ICollection<RefreshInstructionEnvelope> GetBatch(bool create)
@@ -179,16 +198,19 @@ namespace Umbraco.Web
if (batch == null)
{
//only write the json blob with a maximum count of the MaxProcessingInstructionCount
foreach (var maxBatch in instructions.InGroupsOf(Options.MaxProcessingInstructionCount))
using (var scope = _appContext.ScopeProvider.CreateScope())
{
WriteInstructions(maxBatch);
foreach (var maxBatch in instructions.InGroupsOf(Options.MaxProcessingInstructionCount))
{
WriteInstructions(scope, maxBatch);
}
scope.Complete();
}
}
else
{
batch.Add(new RefreshInstructionEnvelope(servers, refresher, instructions));
}
}
}
}
}
}
@@ -2,9 +2,10 @@ using System.Linq;
using System.Web.Security;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.member;
using Umbraco.Web;
using Umbraco.Web.UI;
namespace Umbraco.Web.umbraco.presentation.umbraco.create
namespace umbraco
{
public class MemberGroupTasks : LegacyDialogTask
{