Feature: Plugin UI Extensions

Initially available for 'Job Show' action
This commit is contained in:
Gary Sharp
2013-02-21 18:28:24 +11:00
parent e8e141c9af
commit 69c61a9b7d
23 changed files with 1847 additions and 1537 deletions
@@ -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);
}
}
+202 -190
View File
@@ -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
}
}