Feature: Plugin UI Extensions
Initially available for 'Job Show' action
This commit is contained in:
@@ -101,6 +101,10 @@
|
||||
<Compile Include="Logging\Targets\LogPersistContext.cs" />
|
||||
<Compile Include="Logging\Utilities.cs" />
|
||||
<Compile Include="Plugins\CommunityInterop\PluginLibraryUpdateTask.cs" />
|
||||
<Compile Include="Plugins\Features\UIExtension\Results\LiteralResult.cs" />
|
||||
<Compile Include="Plugins\Features\UIExtension\Results\PluginResourceScriptResult.cs" />
|
||||
<Compile Include="Plugins\Features\UIExtension\UIExtensionResult.cs" />
|
||||
<Compile Include="Plugins\Features\UIExtension\UIExtensionFeature.cs" />
|
||||
<Compile Include="Plugins\UpdatePluginsAfterDiscoUpdateTask.cs" />
|
||||
<Compile Include="Plugins\UpdatePluginTask.cs" />
|
||||
<Compile Include="Plugins\InstallPluginTask.cs" />
|
||||
@@ -133,6 +137,7 @@
|
||||
<Compile Include="Tasks\ScheduledTaskStatus.cs" />
|
||||
<Compile Include="Tasks\ScheduledTasksLiveStatusService.cs" />
|
||||
<Compile Include="Tasks\ScheduledTaskStatusLive.cs" />
|
||||
<Compile Include="UIExtensions\UIExtensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Disco.Data\Disco.Data.csproj">
|
||||
@@ -152,7 +157,7 @@
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="True" />
|
||||
<UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" BuildVersion_BuildAction="ReBuild" BuildVersion_StartDate="2001/1/1" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
public class LiteralResult : UIExtensionResult
|
||||
{
|
||||
private string _content;
|
||||
|
||||
public LiteralResult(PluginFeatureManifest Source, string Content) : base(Source)
|
||||
{
|
||||
this._content = Content;
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(WebViewPage<T> page)
|
||||
{
|
||||
page.Write(new HtmlString(_content));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
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 PluginResourceScriptResult : UIExtensionResult
|
||||
{
|
||||
private string _resource;
|
||||
|
||||
public PluginResourceScriptResult(PluginFeatureManifest Source, string Resource) : base(Source)
|
||||
{
|
||||
this._resource = Resource;
|
||||
}
|
||||
|
||||
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>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
using Disco.Models.UI;
|
||||
using Disco.Services.Plugins.Features.UIExtension.Results;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension
|
||||
{
|
||||
[PluginFeatureCategory(DisplayName = "User Interface Extensions")]
|
||||
public abstract class UIExtensionFeature<UIModel> : PluginFeature where UIModel : BaseUIModel
|
||||
{
|
||||
public abstract UIExtensionResult ExecuteAction(ControllerContext context, UIModel model);
|
||||
|
||||
#region ActionResults
|
||||
|
||||
protected LiteralResult Literal(string Content)
|
||||
{
|
||||
return new LiteralResult(this.Manifest, Content);
|
||||
}
|
||||
protected PluginResourceScriptResult ScriptResource(string Resource)
|
||||
{
|
||||
return new PluginResourceScriptResult(this.Manifest, Resource);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Registration
|
||||
public bool Register()
|
||||
{
|
||||
return UIExtensions.UIExtensions.RegisterExtension(this);
|
||||
}
|
||||
public bool Unregister()
|
||||
{
|
||||
return UIExtensions.UIExtensions.UnregisterExtension(this);
|
||||
}
|
||||
public bool IsRegistered
|
||||
{
|
||||
get
|
||||
{
|
||||
return UIExtensions.UIExtensions.ExtensionRegistered(this);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension
|
||||
{
|
||||
public abstract class UIExtensionResult
|
||||
{
|
||||
public PluginFeatureManifest Source { get; private set; }
|
||||
|
||||
public UIExtensionResult(PluginFeatureManifest Source)
|
||||
{
|
||||
this.Source = Source;
|
||||
}
|
||||
|
||||
public abstract void ExecuteResult<T>(WebViewPage<T> page);
|
||||
}
|
||||
}
|
||||
@@ -1,190 +1,202 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Data.Repository;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web;
|
||||
using System.Web.Mvc.Html;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
public static class PluginExtensions
|
||||
{
|
||||
#region Model Binding from Controller
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, null, controller.ValueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, IValueProvider valueProvider) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, null, valueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, string prefix) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, prefix, controller.ValueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, string prefix, IValueProvider valueProvider) where TModel : class
|
||||
{
|
||||
if (model == null)
|
||||
throw new ArgumentNullException("model");
|
||||
if (valueProvider == null)
|
||||
throw new ArgumentNullException("valueProvider");
|
||||
|
||||
Predicate<string> predicate = propertyName => true;
|
||||
IModelBinder binder = ModelBinders.Binders.GetBinder(typeof(TModel));
|
||||
|
||||
ModelBindingContext context2 = new ModelBindingContext
|
||||
{
|
||||
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
|
||||
ModelName = prefix,
|
||||
ModelState = controller.ModelState,
|
||||
PropertyFilter = predicate,
|
||||
ValueProvider = valueProvider
|
||||
};
|
||||
|
||||
ModelBindingContext bindingContext = context2;
|
||||
|
||||
binder.BindModel(controller.ControllerContext, bindingContext);
|
||||
|
||||
return controller.ModelState.IsValid;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Virtual Directories
|
||||
//public static string WebHandlerResource(this PluginManifest pluginManifest, string resourcePath, RequestContext requestContext)
|
||||
//{
|
||||
// var rootPath = WebHandlerRootUrl(pluginManifest, requestContext);
|
||||
// return string.Concat(rootPath, resourcePath);
|
||||
//}
|
||||
//public static string WebHandlerRootUrl(this PluginManifest pluginManifest, RequestContext requestContext)
|
||||
//{
|
||||
// var tempPath = pluginManifest.WebHandlerActionUrl(requestContext, "_");
|
||||
// return tempPath.Substring(0, tempPath.LastIndexOf(@"/") + 1);
|
||||
//}
|
||||
//public static string WebHandlerActionUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
//public static string WebHandlerResourceUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
|
||||
|
||||
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource)
|
||||
{
|
||||
return ViewPage.DiscoPluginResourceUrl(Resource, false);
|
||||
}
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource, bool Download)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Resource))
|
||||
throw new ArgumentNullException("Resource");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
var resourcePath = manifest.WebResourcePath(Resource);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, res = Resource });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin_Resources", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
|
||||
pluginActionUrl += string.Format("?v={0}", resourcePath.Item2);
|
||||
|
||||
if (Download)
|
||||
pluginActionUrl += "&Download=true";
|
||||
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static HtmlString DiscoPluginActionUrl<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
throw new ArgumentNullException("PluginAction");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, PluginAction = PluginAction });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static HtmlString DiscoPluginConfigureUrl<T>(this WebViewPage<T> ViewPage)
|
||||
{
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Config_Plugins_Configure", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
throw new ArgumentNullException("PluginAction");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, PluginAction = PluginAction });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
|
||||
return ViewPage.FormHelper(pluginActionUrl, method, htmlAttributes);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, method, null);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, htmlAttributes);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, null);
|
||||
}
|
||||
|
||||
private static MvcForm FormHelper<T>(this WebViewPage<T> ViewPage, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
TagBuilder builder = new TagBuilder("form");
|
||||
builder.MergeAttributes<string, object>(htmlAttributes);
|
||||
builder.MergeAttribute("action", formAction);
|
||||
builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
|
||||
bool flag = ViewPage.ViewContext.ClientValidationEnabled && !ViewPage.ViewContext.UnobtrusiveJavaScriptEnabled;
|
||||
if (flag)
|
||||
{
|
||||
object obj2 = ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"];
|
||||
int num = (obj2 != null) ? (((int)obj2) + 1) : 1000;
|
||||
ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"] = num;
|
||||
|
||||
builder.GenerateId(string.Format(CultureInfo.InvariantCulture, "form{0}", new object[] { num }));
|
||||
}
|
||||
ViewPage.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
|
||||
MvcForm form = new MvcForm(ViewPage.ViewContext);
|
||||
if (flag)
|
||||
{
|
||||
ViewPage.ViewContext.FormContext.FormId = builder.Attributes["id"];
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Disco.Data.Repository;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web;
|
||||
using System.Web.Mvc.Html;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
public static class PluginExtensions
|
||||
{
|
||||
#region Model Binding from Controller
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, null, controller.ValueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, IValueProvider valueProvider) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, null, valueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, string prefix) where TModel : class
|
||||
{
|
||||
return controller.TryUpdateModel<TModel>(model, prefix, controller.ValueProvider);
|
||||
}
|
||||
public static bool TryUpdateModel<TModel>(this Controller controller, TModel model, string prefix, IValueProvider valueProvider) where TModel : class
|
||||
{
|
||||
if (model == null)
|
||||
throw new ArgumentNullException("model");
|
||||
if (valueProvider == null)
|
||||
throw new ArgumentNullException("valueProvider");
|
||||
|
||||
Predicate<string> predicate = propertyName => true;
|
||||
IModelBinder binder = ModelBinders.Binders.GetBinder(typeof(TModel));
|
||||
|
||||
ModelBindingContext context2 = new ModelBindingContext
|
||||
{
|
||||
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
|
||||
ModelName = prefix,
|
||||
ModelState = controller.ModelState,
|
||||
PropertyFilter = predicate,
|
||||
ValueProvider = valueProvider
|
||||
};
|
||||
|
||||
ModelBindingContext bindingContext = context2;
|
||||
|
||||
binder.BindModel(controller.ControllerContext, bindingContext);
|
||||
|
||||
return controller.ModelState.IsValid;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Virtual Directories
|
||||
//public static string WebHandlerResource(this PluginManifest pluginManifest, string resourcePath, RequestContext requestContext)
|
||||
//{
|
||||
// var rootPath = WebHandlerRootUrl(pluginManifest, requestContext);
|
||||
// return string.Concat(rootPath, resourcePath);
|
||||
//}
|
||||
//public static string WebHandlerRootUrl(this PluginManifest pluginManifest, RequestContext requestContext)
|
||||
//{
|
||||
// var tempPath = pluginManifest.WebHandlerActionUrl(requestContext, "_");
|
||||
// return tempPath.Substring(0, tempPath.LastIndexOf(@"/") + 1);
|
||||
//}
|
||||
//public static string WebHandlerActionUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
//public static string WebHandlerResourceUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
|
||||
|
||||
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource)
|
||||
{
|
||||
return ViewPage.DiscoPluginResourceUrl(Resource, false);
|
||||
}
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource, bool Download)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Resource))
|
||||
throw new ArgumentNullException("Resource");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
return ViewPage.DiscoPluginResourceUrl(Resource, false, manifest);
|
||||
}
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource, bool Download, PluginManifest manifest)
|
||||
{
|
||||
var resourcePath = manifest.WebResourcePath(Resource);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, res = Resource });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin_Resources", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
|
||||
pluginActionUrl += string.Format("?v={0}", resourcePath.Item2);
|
||||
|
||||
if (Download)
|
||||
pluginActionUrl += "&Download=true";
|
||||
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static HtmlString DiscoPluginActionUrl<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
throw new ArgumentNullException("PluginAction");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
return ViewPage.DiscoPluginActionUrl(PluginAction, manifest);
|
||||
}
|
||||
public static HtmlString DiscoPluginActionUrl<T>(this WebViewPage<T> ViewPage, string PluginAction, PluginManifest manifest)
|
||||
{
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, PluginAction = PluginAction });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static HtmlString DiscoPluginConfigureUrl<T>(this WebViewPage<T> ViewPage)
|
||||
{
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
return ViewPage.DiscoPluginConfigureUrl(manifest);
|
||||
}
|
||||
public static HtmlString DiscoPluginConfigureUrl<T>(this WebViewPage<T> ViewPage, PluginManifest manifest)
|
||||
{
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Config_Plugins_Configure", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
throw new ArgumentNullException("PluginAction");
|
||||
|
||||
// Find Plugin
|
||||
var pageType = ViewPage.GetType();
|
||||
var pageAssembly = pageType.Assembly;
|
||||
var manifest = Plugins.GetPlugin(pageAssembly);
|
||||
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, PluginAction = PluginAction });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, ViewPage.ViewContext.RequestContext, false);
|
||||
|
||||
return ViewPage.FormHelper(pluginActionUrl, method, htmlAttributes);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, method, null);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, htmlAttributes);
|
||||
}
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, null);
|
||||
}
|
||||
|
||||
private static MvcForm FormHelper<T>(this WebViewPage<T> ViewPage, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
TagBuilder builder = new TagBuilder("form");
|
||||
builder.MergeAttributes<string, object>(htmlAttributes);
|
||||
builder.MergeAttribute("action", formAction);
|
||||
builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
|
||||
bool flag = ViewPage.ViewContext.ClientValidationEnabled && !ViewPage.ViewContext.UnobtrusiveJavaScriptEnabled;
|
||||
if (flag)
|
||||
{
|
||||
object obj2 = ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"];
|
||||
int num = (obj2 != null) ? (((int)obj2) + 1) : 1000;
|
||||
ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"] = num;
|
||||
|
||||
builder.GenerateId(string.Format(CultureInfo.InvariantCulture, "form{0}", new object[] { num }));
|
||||
}
|
||||
ViewPage.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
|
||||
MvcForm form = new MvcForm(ViewPage.ViewContext);
|
||||
if (flag)
|
||||
{
|
||||
ViewPage.ViewContext.FormContext.FormId = builder.Attributes["id"];
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.2.0219.1854")]
|
||||
[assembly: AssemblyFileVersion("1.2.0219.1854")]
|
||||
[assembly: AssemblyVersion("1.2.0221.1820")]
|
||||
[assembly: AssemblyFileVersion("1.2.0221.1820")]
|
||||
|
||||
@@ -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.UIExtensions
|
||||
{
|
||||
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