Update: Plugin UI Extensions
Add additional Results; Implemented UI Extensions on Device, Job and User Controllers
This commit is contained in:
@@ -12,14 +12,16 @@ namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
private string _content;
|
||||
|
||||
public LiteralResult(PluginFeatureManifest Source, string Content) : base(Source)
|
||||
public LiteralResult(PluginFeatureManifest Source, string Content)
|
||||
: base(Source)
|
||||
{
|
||||
this._content = Content;
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(WebViewPage<T> page)
|
||||
{
|
||||
page.Write(new HtmlString(_content));
|
||||
if (!string.IsNullOrEmpty(_content))
|
||||
page.Write(new HtmlString(_content));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
public class MultipleResult : UIExtensionResult
|
||||
{
|
||||
private IEnumerable<UIExtensionResult> results;
|
||||
|
||||
public MultipleResult(PluginFeatureManifest Source, params UIExtensionResult[] Results) : base(Source)
|
||||
{
|
||||
if (Results == null || Results.Length == 0)
|
||||
throw new ArgumentException("At least one result is required", "Results");
|
||||
|
||||
this.results = Results;
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(System.Web.Mvc.WebViewPage<T> page)
|
||||
{
|
||||
foreach (var result in this.results)
|
||||
{
|
||||
result.ExecuteResult(page);
|
||||
page.WriteLiteral("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
public class PluginResourceCssResult : UIExtensionResult
|
||||
{
|
||||
private string _resource;
|
||||
private HtmlString _resourceUrl;
|
||||
|
||||
public PluginResourceCssResult(PluginFeatureManifest Source, string Resource)
|
||||
: base(Source)
|
||||
{
|
||||
this._resource = Resource;
|
||||
this._resourceUrl = HttpContext.Current.Request.RequestContext.DiscoPluginResourceUrl(Resource, false, Source.PluginManifest);
|
||||
|
||||
var deferredBundles = HttpContext.Current.Items["Bundles.UIExtensionCss"] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
HttpContext.Current.Items["Bundles.UIExtensionCss"] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(this._resourceUrl))
|
||||
deferredBundles.Add(this._resourceUrl);
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(System.Web.Mvc.WebViewPage<T> page)
|
||||
{
|
||||
// Nothing Done
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,44 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
public class PluginResourceScriptResult : UIExtensionResult
|
||||
{
|
||||
private string _resource;
|
||||
private HtmlString _resourceUrl;
|
||||
private bool _placeInPageHead;
|
||||
|
||||
public PluginResourceScriptResult(PluginFeatureManifest Source, string Resource) : base(Source)
|
||||
public PluginResourceScriptResult(PluginFeatureManifest Source, string Resource, bool PlaceInPageHead)
|
||||
: base(Source)
|
||||
{
|
||||
this._resource = Resource;
|
||||
this._resourceUrl = HttpContext.Current.Request.RequestContext.DiscoPluginResourceUrl(Resource, false, Source.PluginManifest);
|
||||
this._placeInPageHead = PlaceInPageHead;
|
||||
|
||||
if (this._placeInPageHead)
|
||||
{
|
||||
var deferredBundles = HttpContext.Current.Items["Bundles.UIExtensionScripts"] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
HttpContext.Current.Items["Bundles.UIExtensionScripts"] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(this._resourceUrl))
|
||||
deferredBundles.Add(this._resourceUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(System.Web.Mvc.WebViewPage<T> page)
|
||||
{
|
||||
page.WriteLiteral("<script src=\"");
|
||||
page.WriteLiteral(page.DiscoPluginResourceUrl(_resource, false, this.Source.PluginManifest));
|
||||
page.WriteLiteral("\" type=\"text/javascript\"></script>");
|
||||
if (!this._placeInPageHead)
|
||||
{
|
||||
page.WriteLiteral("<script src=\"");
|
||||
page.WriteLiteral(_resourceUrl);
|
||||
page.WriteLiteral("\" type=\"text/javascript\"></script>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.WebPages;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
public class PrecompiledPartialViewResult : UIExtensionResult
|
||||
{
|
||||
private Type viewType;
|
||||
private object model;
|
||||
|
||||
public PrecompiledPartialViewResult(PluginFeatureManifest Source, Type ViewType, object Model = null)
|
||||
: base(Source)
|
||||
{
|
||||
if (!typeof(WebViewPage).IsAssignableFrom(ViewType))
|
||||
throw new ArgumentException("The View Type must inherit from WebViewPage", "ViewType");
|
||||
|
||||
this.viewType = ViewType;
|
||||
this.model = Model;
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(System.Web.Mvc.WebViewPage<T> page)
|
||||
{
|
||||
WebViewPage partialView = Activator.CreateInstance(viewType) as WebViewPage;
|
||||
if (partialView == null)
|
||||
throw new InvalidOperationException("Invalid View Type");
|
||||
partialView.ViewContext = page.ViewContext;
|
||||
partialView.ViewData = new ViewDataDictionary(this.model);
|
||||
partialView.InitHelpers();
|
||||
partialView.ExecutePageHierarchy(new WebPageContext(page.ViewContext.HttpContext, null, model), page.ViewContext.Writer, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,25 @@ namespace Disco.Services.Plugins.Features.UIExtension
|
||||
{
|
||||
return new LiteralResult(this.Manifest, Content);
|
||||
}
|
||||
protected PluginResourceScriptResult ScriptResource(string Resource)
|
||||
protected LiteralResult Nothing()
|
||||
{
|
||||
return new PluginResourceScriptResult(this.Manifest, Resource);
|
||||
return new LiteralResult(this.Manifest, null);
|
||||
}
|
||||
protected PluginResourceScriptResult ScriptResource(string Resource, bool PlaceInPageHead)
|
||||
{
|
||||
return new PluginResourceScriptResult(this.Manifest, Resource, PlaceInPageHead);
|
||||
}
|
||||
protected PluginResourceCssResult CssResource(string Resource)
|
||||
{
|
||||
return new PluginResourceCssResult(this.Manifest, Resource);
|
||||
}
|
||||
protected MultipleResult Multiple(params UIExtensionResult[] Results)
|
||||
{
|
||||
return new MultipleResult(this.Manifest, Results);
|
||||
}
|
||||
protected PrecompiledPartialViewResult Partial(Type PartialViewType, object Model = null)
|
||||
{
|
||||
return new PrecompiledPartialViewResult(this.Manifest, PartialViewType, Model);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -30,17 +46,17 @@ namespace Disco.Services.Plugins.Features.UIExtension
|
||||
#region Registration
|
||||
public bool Register()
|
||||
{
|
||||
return UIExtensions.UIExtensions.RegisterExtension(this);
|
||||
return UIExtensions.RegisterExtension(this);
|
||||
}
|
||||
public bool Unregister()
|
||||
{
|
||||
return UIExtensions.UIExtensions.UnregisterExtension(this);
|
||||
return UIExtensions.UnregisterExtension(this);
|
||||
}
|
||||
public bool IsRegistered
|
||||
{
|
||||
get
|
||||
{
|
||||
return UIExtensions.UIExtensions.ExtensionRegistered(this);
|
||||
return UIExtensions.ExtensionRegistered(this);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Disco.Models.UI;
|
||||
using Disco.Services.Plugins;
|
||||
using Disco.Services.Plugins.Features.UIExtension;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension
|
||||
{
|
||||
public static class UIExtensions
|
||||
{
|
||||
private const string ViewDataKey = "___DiscoUIExtensionResults";
|
||||
|
||||
// Warning: No type-safety, validate types before updating
|
||||
private static Dictionary<Type, List<PluginFeatureManifest>> _registrations = new Dictionary<Type, List<PluginFeatureManifest>>();
|
||||
|
||||
private static List<PluginFeatureManifest> GetUIModelRegistrations<UIModel>() where UIModel : BaseUIModel
|
||||
{
|
||||
Type uiModelType = typeof(UIModel);
|
||||
List<PluginFeatureManifest> modelRegistrations;
|
||||
if (!_registrations.TryGetValue(uiModelType, out modelRegistrations))
|
||||
{
|
||||
lock (_registrations)
|
||||
{
|
||||
if (!_registrations.TryGetValue(uiModelType, out modelRegistrations))
|
||||
{
|
||||
modelRegistrations = new List<PluginFeatureManifest>();
|
||||
_registrations.Add(uiModelType, modelRegistrations);
|
||||
}
|
||||
}
|
||||
}
|
||||
return modelRegistrations;
|
||||
}
|
||||
|
||||
public static void ExecuteExtensions<UIModel>(ControllerContext context, UIModel model) where UIModel : BaseUIModel
|
||||
{
|
||||
var uiExts = UIExtensions.GetRegisteredExtensions<UIModel>();
|
||||
Queue<UIExtensionResult> uiExtResults = new Queue<UIExtensionResult>();
|
||||
foreach (var uiExt in uiExts)
|
||||
{
|
||||
using (var uiExtInstance = uiExt.CreateInstance<UIExtensionFeature<UIModel>>())
|
||||
{
|
||||
uiExtResults.Enqueue(uiExtInstance.ExecuteAction(context, model));
|
||||
}
|
||||
}
|
||||
context.Controller.ViewData[ViewDataKey] = uiExtResults;
|
||||
}
|
||||
public static void ExecuteExtensionResult<UIModel>(WebViewPage<UIModel> page)
|
||||
{
|
||||
Queue<UIExtensionResult> uiExtResults = page.ViewData[ViewDataKey] as Queue<UIExtensionResult>;
|
||||
|
||||
if (uiExtResults != null && uiExtResults.Count > 0)
|
||||
{
|
||||
page.WriteLiteral("<!-- BEGIN: Disco UI Extensions -->");
|
||||
page.WriteLiteral("\n<div id=\"layout_uiExtensions\">");
|
||||
foreach (var uiExtResult in uiExtResults)
|
||||
{
|
||||
string extensionDescription = HttpUtility.HtmlEncode(string.Format("{0} @ {1} v{2}", uiExtResult.Source.Id, uiExtResult.Source.PluginManifest.Id, uiExtResult.Source.PluginManifest.Version.ToString(4)));
|
||||
page.WriteLiteral(string.Format("\n<!-- BEGIN UI EXTENSION: {0} -->\n", extensionDescription));
|
||||
uiExtResult.ExecuteResult(page);
|
||||
page.WriteLiteral(string.Format("\n<!-- END UI EXTENSION: {0} -->", extensionDescription));
|
||||
}
|
||||
page.WriteLiteral("\n</div>");
|
||||
page.WriteLiteral("\n<!-- END: Disco UI Extensions -->");
|
||||
}
|
||||
}
|
||||
|
||||
public static ReadOnlyCollection<PluginFeatureManifest> GetRegisteredExtensions<UIModel>() where UIModel : BaseUIModel
|
||||
{
|
||||
List<PluginFeatureManifest> modelRegistrations = GetUIModelRegistrations<UIModel>();
|
||||
return new ReadOnlyCollection<PluginFeatureManifest>(modelRegistrations);
|
||||
}
|
||||
|
||||
internal static bool ExtensionRegistered<UIModel>(UIExtensionFeature<UIModel> Extension) where UIModel : BaseUIModel
|
||||
{
|
||||
List<PluginFeatureManifest> modelRegistrations = GetUIModelRegistrations<UIModel>();
|
||||
return modelRegistrations.Contains(Extension.Manifest);
|
||||
}
|
||||
|
||||
internal static bool RegisterExtension<UIModel>(UIExtensionFeature<UIModel> Extension) where UIModel : BaseUIModel
|
||||
{
|
||||
List<PluginFeatureManifest> modelRegistrations = GetUIModelRegistrations<UIModel>();
|
||||
|
||||
lock (modelRegistrations)
|
||||
{
|
||||
if (!modelRegistrations.Contains(Extension.Manifest))
|
||||
{
|
||||
modelRegistrations.Add(Extension.Manifest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
internal static bool UnregisterExtension<UIModel>(UIExtensionFeature<UIModel> Extension) where UIModel : BaseUIModel
|
||||
{
|
||||
List<PluginFeatureManifest> modelRegistrations = GetUIModelRegistrations<UIModel>();
|
||||
|
||||
lock (modelRegistrations)
|
||||
{
|
||||
if (modelRegistrations.Contains(Extension.Manifest))
|
||||
{
|
||||
modelRegistrations.Remove(Extension.Manifest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user