diff --git a/src/Orchard.Web/Core/Localization/Views/Admin/Translate.cshtml b/src/Orchard.Web/Core/Localization/Views/Admin/Translate.cshtml index 4ea7d6076..4435e8f97 100644 --- a/src/Orchard.Web/Core/Localization/Views/Admin/Translate.cshtml +++ b/src/Orchard.Web/Core/Localization/Views/Admin/Translate.cshtml @@ -7,8 +7,9 @@ Model.Content.Zones.AddRenderPartial("primary:before", "CultureSelection", Model @Html.EditorForItem(m=>m.Content) } -@using(Html.Capture(script => WorkContext.Page.Tail.Add(script) ){ +@using(Script.Foot()){ } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Routable/Views/EditorTemplates/Parts/Routable.RoutePart.cshtml b/src/Orchard.Web/Core/Routable/Views/EditorTemplates/Parts/Routable.RoutePart.cshtml index 528cb1e22..44ea24b54 100644 --- a/src/Orchard.Web/Core/Routable/Views/EditorTemplates/Parts/Routable.RoutePart.cshtml +++ b/src/Orchard.Web/Core/Routable/Views/EditorTemplates/Parts/Routable.RoutePart.cshtml @@ -12,22 +12,24 @@ @Html.EditorFor(m => m.PromoteToHomePage) -@using(Capture(script => WorkContext.Page.Tail.Add(script))){ - + }) +//]]> + } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Shapes/CoreShapes.cs b/src/Orchard.Web/Core/Shapes/CoreShapes.cs index 71629ff1a..e0a3117de 100644 --- a/src/Orchard.Web/Core/Shapes/CoreShapes.cs +++ b/src/Orchard.Web/Core/Shapes/CoreShapes.cs @@ -89,15 +89,13 @@ namespace Orchard.Core.Shapes { [Shape] public void HeadScripts(HtmlHelper Html, IResourceManager ResourceManager) { WriteResources(Html, ResourceManager, "script", ResourceLocation.Head, null); + WriteLiteralScripts(Html, ResourceManager.GetRegisteredHeadScripts()); } [Shape] public void FootScripts(HtmlHelper Html, IResourceManager ResourceManager) { WriteResources(Html, ResourceManager, "script", null, ResourceLocation.Head); - TextWriter captured; - if (LayoutViewContext.From(Html.ViewContext).Contents.TryGetValue("end-of-page-scripts", out captured)) { - Html.ViewContext.Writer.Write(captured); - } + WriteLiteralScripts(Html, ResourceManager.GetRegisteredFootScripts()); } [Shape] @@ -119,6 +117,16 @@ namespace Orchard.Core.Shapes { WriteResources(Html, ResourceManager, "stylesheet", null, null); } + private static void WriteLiteralScripts(HtmlHelper html, IEnumerable scripts) { + if (scripts == null) { + return; + } + var writer = html.ViewContext.Writer; + foreach (string script in scripts) { + writer.WriteLine(script); + } + } + private static void WriteResources(HtmlHelper html, IResourceManager rm, string resourceType, ResourceLocation? includeLocation, ResourceLocation? excludeLocation) { var defaultSettings = new RequireSettings { DebugMode = html.ViewContext.HttpContext.IsDebuggingEnabled, diff --git a/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.cshtml b/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.cshtml index 766b2af9e..109c0aea0 100644 --- a/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.cshtml +++ b/src/Orchard.Web/Modules/TinyMce/Views/EditorTemplates/TinyMceTextEditor.cshtml @@ -1,25 +1,26 @@ @model Orchard.Core.Common.ViewModels.BodyEditorViewModel @{ Script.Require("TinyMce"); - using(Capture(script => WorkContext.Page.Tail.Add(script))) { - - } } - +@using(Script.Foot()) { + +} @Html.TextArea("Text", Model.Text, 25, 80, new { @class = "html" }) diff --git a/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs b/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs index efbb725c2..3f6f147ae 100644 --- a/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs +++ b/src/Orchard/Mvc/ViewEngines/Razor/WebViewPage.cs @@ -1,5 +1,6 @@ using System; using System.Web; +using System.Web.Mvc; using Autofac; using Microsoft.WebPages; using Orchard.DisplayManagement; @@ -33,7 +34,7 @@ namespace Orchard.Mvc.ViewEngines.Razor { public ScriptRegister Script { get { return _scriptRegister ?? - (_scriptRegister = new ScriptRegister(Html.ViewDataContainer, Html.Resolve())); + (_scriptRegister = new WebViewScriptRegister(this, Html.ViewDataContainer, Html.Resolve())); } } @@ -106,9 +107,25 @@ namespace Orchard.Mvc.ViewEngines.Razor { _callback(writer); } } + + class WebViewScriptRegister : ScriptRegister { + private readonly WebPageBase _viewPage; + + public WebViewScriptRegister(WebPageBase viewPage, IViewDataContainer container, IResourceManager resourceManager) + : base(container, resourceManager) { + _viewPage = viewPage; + } + + public override IDisposable Head() { + return new CaptureScope(_viewPage, s => ResourceManager.RegisterHeadScript(s.ToString())); + } + + public override IDisposable Foot() { + return new CaptureScope(_viewPage, s => ResourceManager.RegisterFootScript(s.ToString())); + } + } } public abstract class WebViewPage : WebViewPage { } - } diff --git a/src/Orchard/Mvc/ViewPage.cs b/src/Orchard/Mvc/ViewPage.cs index 1e78a727b..032b2fdb6 100644 --- a/src/Orchard/Mvc/ViewPage.cs +++ b/src/Orchard/Mvc/ViewPage.cs @@ -26,7 +26,7 @@ namespace Orchard.Mvc { public ScriptRegister Script { get { return _scriptRegister ?? - (_scriptRegister = new ScriptRegister(Html.ViewDataContainer, Html.Resolve())); + (_scriptRegister = new ViewPageScriptRegister(Writer, Html.ViewDataContainer, Html.Resolve())); } } @@ -44,7 +44,7 @@ namespace Orchard.Mvc { } } - public override void InitHelpers() { + public override void InitHelpers() { base.InitHelpers(); _workContext = ViewContext.GetWorkContext(); @@ -113,6 +113,22 @@ namespace Orchard.Mvc { } } + internal class ViewPageScriptRegister : ScriptRegister { + private readonly HtmlTextWriter _context; + + public ViewPageScriptRegister(HtmlTextWriter context, IViewDataContainer container, IResourceManager resourceManager) + : base(container, resourceManager) { + _context = context; + } + + public override IDisposable Head() { + return new CaptureScope(_context, s => ResourceManager.RegisterHeadScript(s.ToString())); + } + + public override IDisposable Foot() { + return new CaptureScope(_context, s => ResourceManager.RegisterFootScript(s.ToString())); + } + } } public class ViewPage : ViewPage { diff --git a/src/Orchard/Mvc/ViewUserControl.cs b/src/Orchard/Mvc/ViewUserControl.cs index de6b6cd20..0513db46c 100644 --- a/src/Orchard/Mvc/ViewUserControl.cs +++ b/src/Orchard/Mvc/ViewUserControl.cs @@ -33,7 +33,7 @@ namespace Orchard.Mvc { public ScriptRegister Script { get { return _scriptRegister ?? - (_scriptRegister = new ScriptRegister(Html.ViewDataContainer, Html.Resolve())); + (_scriptRegister = new ViewPage.ViewPageScriptRegister(Writer, Html.ViewDataContainer, Html.Resolve())); } } diff --git a/src/Orchard/UI/Resources/IResourceManager.cs b/src/Orchard/UI/Resources/IResourceManager.cs index f7ff3d5d0..342960596 100644 --- a/src/Orchard/UI/Resources/IResourceManager.cs +++ b/src/Orchard/UI/Resources/IResourceManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Orchard.UI.Resources { public interface IResourceManager : IDependency { @@ -6,11 +7,15 @@ namespace Orchard.UI.Resources { IList BuildRequiredResources(string resourceType); IList GetRegisteredLinks(); IList GetRegisteredMetas(); + IList GetRegisteredHeadScripts(); + IList GetRegisteredFootScripts(); IEnumerable ResourceProviders { get; } ResourceManifest DynamicResources { get; } ResourceDefinition FindResource(RequireSettings settings); void NotRequired(string resourceType, string resourceName); RequireSettings Require(string resourceType, string resourceName); + void RegisterHeadScript(string script); + void RegisterFootScript(string script); void RegisterLink(LinkEntry link); void SetMeta(MetaEntry meta); void AppendMeta(MetaEntry meta, string contentSeparator); diff --git a/src/Orchard/UI/Resources/ResourceManager.cs b/src/Orchard/UI/Resources/ResourceManager.cs index 433837155..a7523ce89 100644 --- a/src/Orchard/UI/Resources/ResourceManager.cs +++ b/src/Orchard/UI/Resources/ResourceManager.cs @@ -13,6 +13,8 @@ namespace Orchard.UI.Resources { private readonly List _links = new List(); private readonly Dictionary _metas = new Dictionary(); private readonly Dictionary> _builtResources = new Dictionary>(); + private List _headScripts; + private List _footScripts; public ResourceManager(IEnumerable resourceProviders) { ResourceProviders = resourceProviders; @@ -44,6 +46,20 @@ namespace Orchard.UI.Resources { return settings; } + public virtual void RegisterHeadScript(string script) { + if (_headScripts == null) { + _headScripts = new List(); + } + _headScripts.Add(script); + } + + public virtual void RegisterFootScript(string script) { + if (_footScripts == null) { + _footScripts = new List(); + } + _footScripts.Add(script); + } + public virtual void NotRequired(string resourceType, string resourceName) { if (resourceType == null) { throw new ArgumentNullException("resourceType"); @@ -100,6 +116,14 @@ namespace Orchard.UI.Resources { return _metas.Values.ToList().AsReadOnly(); } + public virtual IList GetRegisteredHeadScripts() { + return _headScripts == null ? null : _headScripts.AsReadOnly(); + } + + public virtual IList GetRegisteredFootScripts() { + return _footScripts == null ? null : _footScripts.AsReadOnly(); + } + public virtual IList BuildRequiredResources(string resourceType) { IList requiredResources; if (_builtResources.TryGetValue(resourceType, out requiredResources) && requiredResources != null) { diff --git a/src/Orchard/UI/Resources/ResourceRegister.cs b/src/Orchard/UI/Resources/ResourceRegister.cs index 8d2072662..d6a5940e5 100644 --- a/src/Orchard/UI/Resources/ResourceRegister.cs +++ b/src/Orchard/UI/Resources/ResourceRegister.cs @@ -9,32 +9,35 @@ using JetBrains.Annotations; namespace Orchard.UI.Resources { public class ResourceRegister { private readonly TemplateControl _templateContainer; - private readonly string _resourceType; - private readonly IResourceManager _resourceManager; public ResourceRegister(IViewDataContainer container, IResourceManager resourceManager, string resourceType) { _templateContainer = container as TemplateControl; - _resourceManager = resourceManager; - _resourceType = resourceType; + ResourceManager = resourceManager; + ResourceType = resourceType; } + protected IResourceManager ResourceManager { get; private set; } + protected string ResourceType { get; private set; } + public RequireSettings Require(string resourceName) { return Require(resourceName, (string)null); } public virtual RequireSettings Require(string resourceName, string minimumVersion) { - var settings = _resourceManager.Require(_resourceType, resourceName) + var settings = ResourceManager.Require(ResourceType, resourceName) .WithMinimumVersion(minimumVersion); if (_templateContainer != null) { - settings.WithBasePath(ResourceDefinition.GetBasePathFromViewPath(_resourceType, _templateContainer.AppRelativeVirtualPath)); + settings.WithBasePath(ResourceDefinition.GetBasePathFromViewPath(ResourceType, _templateContainer.AppRelativeVirtualPath)); } return settings; } } - public class ScriptRegister : ResourceRegister { - public ScriptRegister(IViewDataContainer container, IResourceManager resourceManager) : base(container, resourceManager, "script") { + public abstract class ScriptRegister : ResourceRegister { + protected ScriptRegister(IViewDataContainer container, IResourceManager resourceManager) : base(container, resourceManager, "script") { } - // todo: Head/Tail registration + + public abstract IDisposable Head(); + public abstract IDisposable Foot(); } } diff --git a/src/ResourceManager.txt b/src/ResourceManager.txt index 025fd1f69..4abd83649 100644 --- a/src/ResourceManager.txt +++ b/src/ResourceManager.txt @@ -4,12 +4,12 @@ ResourceManager Notes from Bertrand x No default parameters x Refactor to take over resource manager name Better interface pattern for defining resources -Script.Load API that is a view engine specific helper and that directs rendering within the using (using Idisposable pattern) to a buffer that can be rendered later. +x Script.Load API that is a view engine specific helper and that directs rendering within the using (using Idisposable pattern) to a buffer that can be rendered later. x Script.Require returns RequireSettings and has fluent api to add stuff later. When using the shortcut registration+require Script.Require("../script/foo.js") we resolve the url to an app-relative path and use that as the id. If you want ot define a debug version in that case, just do a proper registration. To decide if the app is in debug mode, we look at a setting on the require, then at site setting mode and as a last resort on the compilation mode of the app. -Merge asap, then debug, then refactor. +x Merge asap, then debug, then refactor. Raw notes from Dave during meeting: ==================================== @@ -25,13 +25,13 @@ Raw notes from Dave during meeting: // x no defualt params // better interface/pattern for defining resources -// Script.Load (view-engine specific helper required) +// x Script.Load (view-engine specific helper required) // x Script.Require returns RequireSettings and has fluent api? // x (no) Add Script.RequireHead <-- or no due to fluent api // x Rename Localization resource manager // Require w/ app relative url means inline definitin of url only, resolved url is resource name // Site setting for debug mode true false or from web.config setting -// Moved all copies of jquery and jquery related scripts to a single location +// x Moved all copies of jquery and jquery related scripts to a single location // Get minified versions of any external scripts that we don't currently have. // Integrate MS ajax min to build to minify our own js and css files?