NuspecFileDepencyIds(string nuspecfileName)
67 | {
68 | var pathHelper = new TestPathHelper("NuspecTests/NuspecFiles");
69 | string nuspecAbsolutePath = pathHelper.rootToAbsolutePath("~/" + nuspecfileName);
70 |
71 | var nuspecFile = new NuspecFile(nuspecAbsolutePath);
72 | return nuspecFile.DependencyIds;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DynamicBundles.Test")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DynamicBundles.Test")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("6b32a272-a076-468e-8571-5ee6c5ec0764")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Tests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using DynamicBundles.Models;
4 | using DynamicBundles;
5 | using System.Collections.Generic;
6 | using System.Web.Optimization;
7 | using System.Linq;
8 |
9 | namespace DynamicBundles.Test.RelativeFileDependencies
10 | {
11 | [TestClass]
12 | public class UnitTest1
13 | {
14 | [TestMethod]
15 | public void RelativeFileDependencies()
16 | {
17 | string[] assetDirs =
18 | new [] {
19 | "~/Views/Account/Details",
20 | "~/Views/Shared/_Layout",
21 | "~/Views/Shared/_LayoutContainer"
22 | };
23 |
24 | string[][] expectedScriptFiles =
25 | {
26 | new string[] {
27 | "~/Views/Shared/_LayoutContainer/jquery-1.8.2.js"
28 | },
29 | new string[] {
30 | "~/Views/Account/AccountDetailsAssets/AccountDetailsAssets.js"
31 | }
32 | };
33 |
34 | string[][] expectedStyleFiles =
35 | {
36 | new [] {
37 | "~/Views/Shared/_LayoutContainer/Site.css",
38 | "~/Views/Shared/_Layout/_Layout.css"
39 | },
40 | new string[] {
41 | "~/Views/Account/AccountDetailsAssets/AccountDetailsAssets.css"
42 | }
43 | };
44 |
45 | Tester.Test("RelativeFileDependencies",
46 | assetDirs,
47 | expectedScriptFiles,
48 | expectedStyleFiles);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/AccountDetailsAssets/AccountDetailsAssets.css:
--------------------------------------------------------------------------------
1 | .account-dependencies {
2 | border: 2px pink solid;
3 | }
4 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/AccountDetailsAssets/AccountDetailsAssets.js:
--------------------------------------------------------------------------------
1 | alert("AccountDetailsAssets");
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/Details/Details.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Details";
3 | }
4 |
5 | Details
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/Details/Details.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/EditDetails/EditDetails.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "EditDetails";
3 | }
4 |
5 | EditDetails
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/EditDetails/EditDetails.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Account/Login.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Login";
3 | }
4 |
5 | Login
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Index";
3 | }
4 |
5 | Index
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Product/Details.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Details";
3 | }
4 |
5 | Details
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Shared/_Layout/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewBag.Title
7 | @Styles.Render("~/Content/css")
8 | @Scripts.Render("~/bundles/modernizr")
9 |
10 |
11 | @RenderBody()
12 |
13 | @Scripts.Render("~/bundles/jquery")
14 | @RenderSection("scripts", required: false)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Shared/_Layout/_Layout.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: .85em;
3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
4 | color: #232323;
5 | background-color: #fff;
6 | }
7 |
8 | header, footer, nav, section {
9 | display: block;
10 | }
11 |
12 |
13 | /* Styles for basic forms
14 | -----------------------------------------------------------*/
15 | fieldset {
16 | border: 1px solid #ddd;
17 | padding: 0 1.4em 1.4em 1.4em;
18 | margin: 0 0 1.5em 0;
19 | }
20 |
21 | legend {
22 | font-size: 1.2em;
23 | font-weight: bold;
24 | }
25 |
26 | textarea {
27 | min-height: 75px;
28 | }
29 |
30 | .editor-label {
31 | margin: 1em 0 0 0;
32 | }
33 |
34 | .editor-field {
35 | margin: 0.5em 0 0 0;
36 | }
37 |
38 |
39 | /* Styles for validation helpers
40 | -----------------------------------------------------------*/
41 | .field-validation-error {
42 | color: #f00;
43 | }
44 |
45 | .field-validation-valid {
46 | display: none;
47 | }
48 |
49 | .input-validation-error {
50 | border: 1px solid #f00;
51 | background-color: #fee;
52 | }
53 |
54 | .validation-summary-errors {
55 | font-weight: bold;
56 | color: #f00;
57 | }
58 |
59 | .validation-summary-valid {
60 | display: none;
61 | }
62 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Shared/_LayoutContainer/Site.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: .85em;
3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
4 | color: #232323;
5 | background-color: #fff;
6 | }
7 |
8 | header, footer, nav, section {
9 | display: block;
10 | }
11 |
12 |
13 | /* Styles for basic forms
14 | -----------------------------------------------------------*/
15 | fieldset {
16 | border: 1px solid #ddd;
17 | padding: 0 1.4em 1.4em 1.4em;
18 | margin: 0 0 1.5em 0;
19 | }
20 |
21 | legend {
22 | font-size: 1.2em;
23 | font-weight: bold;
24 | }
25 |
26 | textarea {
27 | min-height: 75px;
28 | }
29 |
30 | .editor-label {
31 | margin: 1em 0 0 0;
32 | }
33 |
34 | .editor-field {
35 | margin: 0.5em 0 0 0;
36 | }
37 |
38 |
39 | /* Styles for validation helpers
40 | -----------------------------------------------------------*/
41 | .field-validation-error {
42 | color: #f00;
43 | }
44 |
45 | .field-validation-valid {
46 | display: none;
47 | }
48 |
49 | .input-validation-error {
50 | border: 1px solid #f00;
51 | background-color: #fee;
52 | }
53 |
54 | .validation-summary-errors {
55 | font-weight: bold;
56 | color: #f00;
57 | }
58 |
59 | .validation-summary-valid {
60 | display: none;
61 | }
62 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Shared/_LayoutContainer/_LayoutContainer.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewBag.Title
7 | @Styles.Render("~/Content/css")
8 | @Scripts.Render("~/bundles/modernizr")
9 |
10 |
11 | @RenderBody()
12 |
13 | @Scripts.Render("~/bundles/jquery")
14 | @RenderSection("scripts", required: false)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RelativeFileDependencies/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout.cshtml";
3 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Tests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using DynamicBundles.Models;
4 | using DynamicBundles;
5 | using System.Collections.Generic;
6 | using System.Web.Optimization;
7 | using System.Linq;
8 |
9 | namespace DynamicBundles.Test.RootRelativeFileDependencies
10 | {
11 | [TestClass]
12 | public class UnitTest1
13 | {
14 | [TestMethod]
15 | public void RootRelativeFileDependencies()
16 | {
17 | string[] assetDirs =
18 | new [] {
19 | "~/Views/Account/Details",
20 | "~/Views/Shared/_Layout",
21 | "~/Views/Shared/_LayoutContainer"
22 | };
23 |
24 | string[][] expectedScriptFiles =
25 | {
26 | new string[] {
27 | "~/Views/Shared/_LayoutContainer/jquery-1.8.2.js"
28 | },
29 | new string[] {
30 | "~/Views/Account/AccountDetailsAssets/AccountDetailsAssets.js"
31 | }
32 | };
33 |
34 | string[][] expectedStyleFiles =
35 | {
36 | new [] {
37 | "~/Views/Shared/_LayoutContainer/Site.css",
38 | "~/Views/Shared/_Layout/_Layout.css"
39 | },
40 | new string[] {
41 | "~/Views/Account/AccountDetailsAssets/AccountDetailsAssets.css"
42 | }
43 | };
44 |
45 | Tester.Test("RootRelativeFileDependencies",
46 | assetDirs,
47 | expectedScriptFiles,
48 | expectedStyleFiles);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/AccountDetailsAssets/AccountDetailsAssets.css:
--------------------------------------------------------------------------------
1 | .account-dependencies {
2 | border: 2px pink solid;
3 | }
4 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/AccountDetailsAssets/AccountDetailsAssets.js:
--------------------------------------------------------------------------------
1 | alert("AccountDetailsAssets");
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/Details/Details.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Details";
3 | }
4 |
5 | Details
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/Details/Details.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/EditDetails/EditDetails.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "EditDetails";
3 | }
4 |
5 | EditDetails
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/EditDetails/EditDetails.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Account/Login.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Login";
3 | }
4 |
5 | Login
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Index";
3 | }
4 |
5 | Index
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Product/Details.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Details";
3 | }
4 |
5 | Details
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Shared/_Layout/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewBag.Title
7 | @Styles.Render("~/Content/css")
8 | @Scripts.Render("~/bundles/modernizr")
9 |
10 |
11 | @RenderBody()
12 |
13 | @Scripts.Render("~/bundles/jquery")
14 | @RenderSection("scripts", required: false)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Shared/_Layout/_Layout.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: .85em;
3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
4 | color: #232323;
5 | background-color: #fff;
6 | }
7 |
8 | header, footer, nav, section {
9 | display: block;
10 | }
11 |
12 |
13 | /* Styles for basic forms
14 | -----------------------------------------------------------*/
15 | fieldset {
16 | border: 1px solid #ddd;
17 | padding: 0 1.4em 1.4em 1.4em;
18 | margin: 0 0 1.5em 0;
19 | }
20 |
21 | legend {
22 | font-size: 1.2em;
23 | font-weight: bold;
24 | }
25 |
26 | textarea {
27 | min-height: 75px;
28 | }
29 |
30 | .editor-label {
31 | margin: 1em 0 0 0;
32 | }
33 |
34 | .editor-field {
35 | margin: 0.5em 0 0 0;
36 | }
37 |
38 |
39 | /* Styles for validation helpers
40 | -----------------------------------------------------------*/
41 | .field-validation-error {
42 | color: #f00;
43 | }
44 |
45 | .field-validation-valid {
46 | display: none;
47 | }
48 |
49 | .input-validation-error {
50 | border: 1px solid #f00;
51 | background-color: #fee;
52 | }
53 |
54 | .validation-summary-errors {
55 | font-weight: bold;
56 | color: #f00;
57 | }
58 |
59 | .validation-summary-valid {
60 | display: none;
61 | }
62 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Shared/_LayoutContainer/Site.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: .85em;
3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
4 | color: #232323;
5 | background-color: #fff;
6 | }
7 |
8 | header, footer, nav, section {
9 | display: block;
10 | }
11 |
12 |
13 | /* Styles for basic forms
14 | -----------------------------------------------------------*/
15 | fieldset {
16 | border: 1px solid #ddd;
17 | padding: 0 1.4em 1.4em 1.4em;
18 | margin: 0 0 1.5em 0;
19 | }
20 |
21 | legend {
22 | font-size: 1.2em;
23 | font-weight: bold;
24 | }
25 |
26 | textarea {
27 | min-height: 75px;
28 | }
29 |
30 | .editor-label {
31 | margin: 1em 0 0 0;
32 | }
33 |
34 | .editor-field {
35 | margin: 0.5em 0 0 0;
36 | }
37 |
38 |
39 | /* Styles for validation helpers
40 | -----------------------------------------------------------*/
41 | .field-validation-error {
42 | color: #f00;
43 | }
44 |
45 | .field-validation-valid {
46 | display: none;
47 | }
48 |
49 | .input-validation-error {
50 | border: 1px solid #f00;
51 | background-color: #fee;
52 | }
53 |
54 | .validation-summary-errors {
55 | font-weight: bold;
56 | color: #f00;
57 | }
58 |
59 | .validation-summary-valid {
60 | display: none;
61 | }
62 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Shared/_LayoutContainer/_LayoutContainer.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewBag.Title
7 | @Styles.Render("~/Content/css")
8 | @Scripts.Render("~/bundles/modernizr")
9 |
10 |
11 | @RenderBody()
12 |
13 | @Scripts.Render("~/bundles/jquery")
14 | @RenderSection("scripts", required: false)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/RootRelativeFileDependencies/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout.cshtml";
3 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.Test/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/App_Start/BundleConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using System.Web.Optimization;
3 |
4 | namespace DynamicBundles.TestWeb
5 | {
6 | public class BundleConfig
7 | {
8 | // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
9 | public static void RegisterBundles(BundleCollection bundles)
10 | {
11 | //bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
12 | // "~/Scripts/jquery-{version}.js"));
13 |
14 | //bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
15 | // "~/Scripts/jquery-ui-{version}.js"));
16 |
17 | //bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
18 | // "~/Scripts/jquery.unobtrusive*",
19 | // "~/Scripts/jquery.validate*"));
20 |
21 | //// Use the development version of Modernizr to develop with and learn from. Then, when you're
22 | //// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
23 | //bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
24 | // "~/Scripts/modernizr-*"));
25 |
26 | // bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
27 |
28 | //bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
29 | // "~/Content/themes/base/jquery.ui.core.css",
30 | // "~/Content/themes/base/jquery.ui.resizable.css",
31 | // "~/Content/themes/base/jquery.ui.selectable.css",
32 | // "~/Content/themes/base/jquery.ui.accordion.css",
33 | // "~/Content/themes/base/jquery.ui.autocomplete.css",
34 | // "~/Content/themes/base/jquery.ui.button.css",
35 | // "~/Content/themes/base/jquery.ui.dialog.css",
36 | // "~/Content/themes/base/jquery.ui.slider.css",
37 | // "~/Content/themes/base/jquery.ui.tabs.css",
38 | // "~/Content/themes/base/jquery.ui.datepicker.css",
39 | // "~/Content/themes/base/jquery.ui.progressbar.css",
40 | // "~/Content/themes/base/jquery.ui.theme.css"));
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/App_Start/FilterConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using System.Web.Mvc;
3 |
4 | namespace DynamicBundles.TestWeb
5 | {
6 | public class FilterConfig
7 | {
8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters)
9 | {
10 | filters.Add(new HandleErrorAttribute());
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/App_Start/RouteConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Mvc;
6 | using System.Web.Routing;
7 |
8 | namespace DynamicBundles.TestWeb
9 | {
10 | public class RouteConfig
11 | {
12 | public static void RegisterRoutes(RouteCollection routes)
13 | {
14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
15 |
16 | routes.MapRoute(
17 | name: "Default",
18 | url: "{controller}/{action}/{id}",
19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
20 | namespaces: new string[] { "DynamicBundles.TestWeb.Controllers" }
21 | );
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web.Http;
5 |
6 | namespace DynamicBundles.TestWeb
7 | {
8 | public static class WebApiConfig
9 | {
10 | public static void Register(HttpConfiguration config)
11 | {
12 | config.Routes.MapHttpRoute(
13 | name: "DefaultApi",
14 | routeTemplate: "api/{controller}/{id}",
15 | defaults: new { id = RouteParameter.Optional }
16 | );
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Mvc;
6 |
7 | namespace DynamicBundles.TestWeb.Areas.TestArea.Controllers
8 | {
9 | public class HomeController : Controller
10 | {
11 |
12 | [ChildActionOnly]
13 | public ActionResult MyPerson()
14 | {
15 | Person s = new Person
16 | {
17 | FirstName = "Joe Area",
18 | LastName = "Smith",
19 | HomeAddress = new HomeAddress
20 | {
21 | Street = "Area Country Lane",
22 | HouseNumber = 1145,
23 | City = "Rochester"
24 | }
25 | };
26 |
27 | return PartialView(s);
28 | }
29 |
30 | //
31 | // GET: /TestArea/Home/
32 |
33 | public ActionResult Index()
34 | {
35 | return View();
36 | }
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/TestAreaAreaRegistration.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Mvc;
2 |
3 | namespace DynamicBundles.TestWeb.Areas.TestArea
4 | {
5 | public class TestAreaAreaRegistration : AreaRegistration
6 | {
7 | public override string AreaName
8 | {
9 | get
10 | {
11 | return "TestArea";
12 | }
13 | }
14 |
15 | public override void RegisterArea(AreaRegistrationContext context)
16 | {
17 | context.MapRoute(
18 | "TestArea_default",
19 | "TestArea/{controller}/{action}/{id}",
20 | new { action = "Index", id = UrlParameter.Optional },
21 | new string[] { "DynamicBundles.TestWeb.Areas.TestArea.Controllers" }
22 | );
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Index";
3 | Layout = "~/Areas/TestArea/Views/Shared/_Layout.cshtml";
4 | }
5 | TestArea - Index
6 |
7 | @Html.Action("MyPerson")
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Home/Index.css:
--------------------------------------------------------------------------------
1 | .Index { color: blue; border: 1px red solid; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Home/Index.js:
--------------------------------------------------------------------------------
1 | // comment Area index
2 | alert("Area index");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Home/MyPerson.cshtml:
--------------------------------------------------------------------------------
1 | @model DynamicBundles.TestWeb.Person
2 |
3 |
4 | Area My person
5 |
6 |
7 | First Name:
8 | @Html.EditorFor(m=>m.FirstName)
9 |
10 |
11 | Last Name:
12 | @Html.EditorFor(m=>m.LastName)
13 |
14 |
15 | Address:
16 | @Html.EditorFor(m=>m.HomeAddress)
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout/_Layout.cshtml";
3 | }
4 |
5 | TestArea _Layout
6 |
7 |
8 | @Html.Partial("_SharedBox3")
9 |
10 | @Html.Partial("_SharedBox2")
11 |
12 |
13 | @RenderBody()
14 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_Layout.css:
--------------------------------------------------------------------------------
1 | .L_ayout { color: orange; border: 1px red solid; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_Layout.js:
--------------------------------------------------------------------------------
1 | // comment _Layout
2 | alert("_Layout");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_SharedBox3/_SharedBox3.cshtml:
--------------------------------------------------------------------------------
1 |
2 | Shared box3
3 |
4 |
5 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_SharedBox3/_SharedBox3.css:
--------------------------------------------------------------------------------
1 | .SharedBox3 { color: green; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Shared/_SharedBox3/_SharedBox3.js:
--------------------------------------------------------------------------------
1 | // comment _SharedBox3
2 | alert("_SharedBox3");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Areas/TestArea/Views/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Content/Site.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: .85em;
3 | font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
4 | color: #232323;
5 | background-color: #fff;
6 | }
7 |
8 | header, footer, nav, section {
9 | display: block;
10 | }
11 |
12 |
13 | /* Styles for basic forms
14 | -----------------------------------------------------------*/
15 | fieldset {
16 | border: 1px solid #ddd;
17 | padding: 0 1.4em 1.4em 1.4em;
18 | margin: 0 0 1.5em 0;
19 | }
20 |
21 | legend {
22 | font-size: 1.2em;
23 | font-weight: bold;
24 | }
25 |
26 | textarea {
27 | min-height: 75px;
28 | }
29 |
30 | .editor-label {
31 | margin: 1em 0 0 0;
32 | }
33 |
34 | .editor-field {
35 | margin: 0.5em 0 0 0;
36 | }
37 |
38 |
39 | /* Styles for validation helpers
40 | -----------------------------------------------------------*/
41 | .field-validation-error {
42 | color: #f00;
43 | }
44 |
45 | .field-validation-valid {
46 | display: none;
47 | }
48 |
49 | .input-validation-error {
50 | border: 1px solid #f00;
51 | background-color: #fee;
52 | }
53 |
54 | .validation-summary-errors {
55 | font-weight: bold;
56 | color: #f00;
57 | }
58 |
59 | .validation-summary-valid {
60 | display: none;
61 | }
62 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Controllers/DefaultController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Mvc;
6 |
7 | namespace DynamicBundles.TestWeb.Controllers
8 | {
9 | public class DefaultController : Controller
10 | {
11 | //
12 | // GET: /Default/
13 |
14 | public ActionResult Index()
15 | {
16 | return View();
17 | }
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Mvc;
6 |
7 | namespace DynamicBundles.TestWeb.Controllers
8 | {
9 | public class HomeController : Controller
10 | {
11 | //
12 | // GET: /Home/
13 |
14 | public ActionResult Index()
15 | {
16 | return View("Index/Index");
17 | }
18 |
19 | public ActionResult Product()
20 | {
21 | return View("Product");
22 | }
23 |
24 | public ActionResult About()
25 | {
26 | return View();
27 | }
28 |
29 | [ChildActionOnly]
30 | public ActionResult MyChild()
31 | {
32 | string s = "xyz";
33 | return PartialView("MyChild", s);
34 | }
35 |
36 | [ChildActionOnly]
37 | public ActionResult MyPerson()
38 | {
39 | Person s = new Person {
40 | FirstName = "Joe",
41 | LastName = "Smith",
42 | HomeAddress = new HomeAddress {
43 | Street = "Country Lane",
44 | HouseNumber = 45,
45 | City = "Rochester"
46 | }
47 | };
48 |
49 | return PartialView(s);
50 | }
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="DynamicBundles.TestWeb.MvcApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Global.asax.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Http;
6 | using System.Web.Mvc;
7 | using System.Web.Optimization;
8 | using System.Web.Routing;
9 |
10 | namespace DynamicBundles.TestWeb
11 | {
12 | // Note: For instructions on enabling IIS6 or IIS7 classic mode,
13 | // visit http://go.microsoft.com/?LinkId=9394801
14 |
15 | public class MvcApplication : System.Web.HttpApplication
16 | {
17 | protected void Application_Start()
18 | {
19 | AreaRegistration.RegisterAllAreas();
20 |
21 | //@@@@@@@@@@@@@@@@@@@@@
22 | //leave the normal razor engine ViewEngines.Engines.Clear();
23 |
24 |
25 |
26 | // Add DynamicBundles view engine. This functions the same as the Razor view engine,
27 | // but can find views sitting in their own directories, such as ~/Views/Home/Index/Index.cshtml
28 | // Note: this leaves the other view engines in place, so they can still be used.
29 | ViewEngines.Engines.Add(new DynamicBundles.DynamicBundlesViewEngine());
30 | //@@@@@@@@@@@@@@@@@@@@@
31 |
32 | WebApiConfig.Register(GlobalConfiguration.Configuration);
33 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
34 | RouteConfig.RegisterRoutes(RouteTable.Routes);
35 |
36 |
37 | // BundleConfig.RegisterBundles(BundleTable.Bundles);
38 | }
39 |
40 |
41 |
42 |
43 |
44 |
45 | protected void Application_EndRequest()
46 | {
47 | }
48 |
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.Mvc;
6 |
7 | namespace DynamicBundles.TestWeb.Helpers
8 | {
9 | public static class Helpers
10 | {
11 | public static MvcHtmlString MyHelper(this HtmlHelper html, string x)
12 | {
13 | return new MvcHtmlString(x + "x");
14 | }
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Models/HomeAddress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 |
6 | namespace DynamicBundles.TestWeb
7 | {
8 | public class HomeAddress
9 | {
10 | public string Street { get; set; }
11 | public int HouseNumber { get; set; }
12 | public string City { get; set; }
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Models/Person.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 |
6 | namespace DynamicBundles.TestWeb
7 | {
8 | public class Person
9 | {
10 | public string FirstName { get; set; }
11 | public string LastName { get; set; }
12 | public HomeAddress HomeAddress { get; set; }
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DynamicBundles.TestWeb")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DynamicBundles.TestWeb")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("3a12d5cc-ffb8-43ec-b61b-9376e654e294")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Default/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewBag.Title = "Index";
3 | }
4 |
5 | Default Index
6 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/About.cshtml:
--------------------------------------------------------------------------------
1 | @using DynamicBundles.TestWeb.Helpers
2 |
3 | @{
4 | ViewBag.Title = "About";
5 | }
6 |
7 | Home About
8 |
9 | @Html.Partial("_SharedBox")
10 | @Html.Partial("_SharedBox2")
11 |
12 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Home.css:
--------------------------------------------------------------------------------
1 | .HomeAddress { color: yellow; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Home.js:
--------------------------------------------------------------------------------
1 | // comment Home
2 | alert("Home");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Index/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using DynamicBundles.TestWeb.Helpers
2 |
3 | @{
4 | ViewBag.Title = "Index";
5 | }
6 |
7 | Home Index
8 |
9 | @Html.Partial("_SharedBox")
10 |
11 |
12 | abcde
13 |
14 |
15 | @Html.Action("MyChild")
16 |
17 |
18 | After child
19 |
20 |
21 | @Html.MyHelper("hello helper")
22 |
23 |
24 | @Html.Action("MyPerson")
25 |
26 |
27 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Index/Index.css:
--------------------------------------------------------------------------------
1 | .Index { color: orange; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Index/Index.js:
--------------------------------------------------------------------------------
1 | // comment Index
2 | alert("Index");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/MyChild.cshtml:
--------------------------------------------------------------------------------
1 | @model string
2 |
3 |
4 | child:
5 | @Model
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/MyPerson.cshtml:
--------------------------------------------------------------------------------
1 | @model DynamicBundles.TestWeb.Person
2 |
3 |
4 | First Name:
5 | @Html.EditorFor(m=>m.FirstName)
6 |
7 |
8 | Last Name:
9 | @Html.EditorFor(m=>m.LastName)
10 |
11 |
12 | Address:
13 | @Html.EditorFor(m=>m.HomeAddress)
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Product/Product.cshtml:
--------------------------------------------------------------------------------
1 | @using DynamicBundles.TestWeb.Helpers
2 |
3 | @{
4 | ViewBag.Title = "Product";
5 | }
6 |
7 | Home Product
8 |
9 |
10 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Product/Product.css:
--------------------------------------------------------------------------------
1 | .Product { color: orange; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Home/Product/Product.js:
--------------------------------------------------------------------------------
1 | // comment Index
2 | alert("Product");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/EditorTemplates/HomeAddress.cshtml:
--------------------------------------------------------------------------------
1 | @model DynamicBundles.TestWeb.HomeAddress
2 |
3 |
4 | @Html.TextAreaFor(m => m.Street, new { @class = "street"}) - @Html.TextBoxFor(m=>m.HouseNumber)
5 |
6 |
7 | @Html.TextBoxFor(m=>m.City)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/EditorTemplates/HomeAddress.css:
--------------------------------------------------------------------------------
1 | .HomeAddress {
2 | color: yellow;
3 | }
4 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/EditorTemplates/HomeAddress.js:
--------------------------------------------------------------------------------
1 | // comment HomeAddress
2 | alert("HomeAddress");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_Layout/_Layout.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | //@@@@@@@@@@@@@@@@@@@@@@@@@
3 | // Add _LayoutContainer as the container for the _Layout.cshtml file itself.
4 | Layout = "../_LayoutContainer/_LayoutContainer.cshtml";
5 | }
6 |
7 |
8 |
9 |
10 | @ViewBag.Title
11 | @* @Styles.Render("~/Content/css")*@
12 | @* @Styles.Render(bundlePath)*@
13 |
14 | @*@@@@@@@@@@@@@@@@@*@
15 | @* @DynamicBundlesTopRender()*@
16 |
17 |
18 | @* @Scripts.Render("~/bundles/modernizr")*@
19 |
20 |
21 | Main _Layout
22 |
23 |
24 |
25 | @Html.Partial("_SharedBox2")
26 |
27 |
28 |
29 | @RenderBody()
30 |
31 | @* @Scripts.Render("~/bundles/jquery")*@
32 | @RenderSection("scripts", required: false)
33 | @* @Styles.Render("~/Content/css")*@
34 | @* @Styles.Render(bundlePath)*@
35 |
36 |
37 |
38 | @* @DynamicBundlesBottomRender()*@
39 |
40 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_Layout/_Layout.css:
--------------------------------------------------------------------------------
1 | .L_ayout { color: pink; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_Layout/jquery.validate.unobtrusive.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | ** Unobtrusive validation support library for jQuery and jQuery Validate
3 | ** Copyright (C) Microsoft Corporation. All rights reserved.
4 | */
5 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(c){var b=a(c),d=b.data(e),f=a.proxy(n,c);if(!d){d={options:{errorClass:"input-validation-error",errorElement:"span",errorPlacement:a.proxy(m,c),invalidHandler:a.proxy(l,c),messages:{},rules:{},success:a.proxy(k,c)},attachValidation:function(){b.unbind("reset."+e,f).bind("reset."+e,f).validate(this.options)},validate:function(){b.validate();return b.valid()}};b.data(e,d)}return d}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(b){var c=a(b).parents("form").andSelf().add(a(b).find("form")).filter("form");a(b).find(":input[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});c.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});b.addSingleVal("accept","exts").addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery);
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_LayoutContainer/_LayoutContainer.cshtml:
--------------------------------------------------------------------------------
1 |
2 | @*@@@@@@@@@@@@@@@@@@@@@@@@*@
3 | @*Nominate where to load the bundles. The bundles themselves are automatically generated.*@
4 | @DynamicBundlesTopRender()
5 |
6 | @RenderBody()
7 |
8 | @DynamicBundlesBottomRender()
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox/_SharedBox.cshtml:
--------------------------------------------------------------------------------
1 |
2 | Shared box
3 |
4 |
5 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox/_SharedBox.css:
--------------------------------------------------------------------------------
1 | .SharedBox { color: red; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox/_SharedBox.js:
--------------------------------------------------------------------------------
1 | // comment _SharedBox
2 | alert("_SharedBox");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox2/_SharedBox2.cshtml:
--------------------------------------------------------------------------------
1 |
2 | Shared box2
3 |
4 |
5 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox2/_SharedBox2.css:
--------------------------------------------------------------------------------
1 | .SharedBox2 { color: green; }
2 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Shared/_SharedBox2/_SharedBox2.js:
--------------------------------------------------------------------------------
1 | // comment _SharedBox2
2 | alert("_SharedBox2");
3 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/_Layout/_Layout.cshtml";
3 | }
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.TestWeb/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 2012 for Web
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicBundles", "DynamicBundles\DynamicBundles.csproj", "{37C5ED5D-3951-4325-9191-BCD55DDDD3FE}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicBundles.TestWeb", "DynamicBundles.TestWeb\DynamicBundles.TestWeb.csproj", "{4A836FF7-DAB1-498B-A698-C4B99BCC6B20}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicBundles.Test", "DynamicBundles.Test\DynamicBundles.Test.csproj", "{DECBC746-AEF8-4425-B7DF-92ACD738F7D0}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {37C5ED5D-3951-4325-9191-BCD55DDDD3FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {37C5ED5D-3951-4325-9191-BCD55DDDD3FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {37C5ED5D-3951-4325-9191-BCD55DDDD3FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {37C5ED5D-3951-4325-9191-BCD55DDDD3FE}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {4A836FF7-DAB1-498B-A698-C4B99BCC6B20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {4A836FF7-DAB1-498B-A698-C4B99BCC6B20}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {4A836FF7-DAB1-498B-A698-C4B99BCC6B20}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {4A836FF7-DAB1-498B-A698-C4B99BCC6B20}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {DECBC746-AEF8-4425-B7DF-92ACD738F7D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {DECBC746-AEF8-4425-B7DF-92ACD738F7D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {DECBC746-AEF8-4425-B7DF-92ACD738F7D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {DECBC746-AEF8-4425-B7DF-92ACD738F7D0}.Release|Any CPU.Build.0 = Release|Any CPU
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | EndGlobal
33 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/AssetPath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.IO;
8 |
9 | namespace DynamicBundles
10 | {
11 | ///
12 | /// Represents a path to a file or directory.
13 | /// That file or directory must live within the current project.
14 | ///
15 | /// This is called "AssetPath" rather than "Path" to not clash with the .Net Path class.
16 | ///
17 | public class AssetPath
18 | {
19 | public string RootRelativePath { get; private set; }
20 |
21 | private Func _rootToAbsolutePathFunc = null;
22 |
23 | ///
24 | /// Constructor.
25 | ///
26 | ///
27 | /// Path to the file or directory. Must be relative to the root of the project (start with a ~).
28 | ///
29 | ///
30 | /// Lambda that takes a root relative path and returns an absolute path.
31 | /// Does the same as HttpContext.Current.Server.MapPath
32 | ///
33 | public AssetPath(string rootRelativePath, Func rootToAbsolutePathFunc)
34 | {
35 | RootRelativePath = rootRelativePath;
36 | _rootToAbsolutePathFunc = rootToAbsolutePathFunc;
37 | }
38 |
39 | private string _absolutePath = null;
40 | public string AbsolutePath
41 | {
42 | get
43 | {
44 | if (_absolutePath == null)
45 | {
46 | _absolutePath = _rootToAbsolutePathFunc(RootRelativePath);
47 | }
48 |
49 | return _absolutePath;
50 | }
51 | }
52 |
53 | ///
54 | /// The absolute counterpart of say "~/Views/Home" might be something like
55 | /// "d:\dev\Views\Home". In that case, the "absolute prefix" (the stuff that replaces the ~) is "d:\dev",
56 | /// which is 6 chars long. ///
57 | ///
58 | private int? _absolutePathPrefixLength = null;
59 | private int AbsolutePathPrefixLength
60 | {
61 | get
62 | {
63 | if (_absolutePathPrefixLength == null)
64 | {
65 | const int lengthTilde = 1;
66 |
67 | _absolutePathPrefixLength =
68 | AbsolutePath.Length - RootRelativePath.Length + lengthTilde;
69 | }
70 |
71 | return _absolutePathPrefixLength.Value;
72 | }
73 | }
74 |
75 | ///
76 | /// Converts a absolute file name or directory name (c:\...) to an AssetPath containing an application relative url (~/....).
77 | /// The file or directory must sit in the same project as the file or directory represented by this AssetPath object.
78 | /// Returns a new AssetPath representing the file or directory.
79 | ///
80 | ///
81 | ///
82 | ///
83 | public AssetPath AbsolutePathToAssetPath(string absolutePath)
84 | {
85 | string rootRelativePath = "~" + absolutePath.Substring(AbsolutePathPrefixLength).Replace('\\', '/');
86 | return new AssetPath(rootRelativePath, _rootToAbsolutePathFunc);
87 | }
88 |
89 | ///
90 | /// Create a new AssetPath with the same rootToAbsolutePathFunc as this AssetPath.
91 | ///
92 | /// If the given path is not root relative, it is assumed to be relative to this AssetPath.
93 | ///
94 | public AssetPath Create(string path)
95 | {
96 | if (!path.StartsWith("~"))
97 | {
98 | return RootRelativeCombine(RootRelativePath, path);
99 | }
100 |
101 | return new AssetPath(path, _rootToAbsolutePathFunc);
102 | }
103 |
104 | private AssetPath RootRelativeCombine(string rootRelativePath, string relativePath)
105 | {
106 | // If relativePath contains .. (such as ..\dir), then rootRelativePathWithDots also has ..
107 | // This somehow leads to an endless loop.
108 | string rootRelativePathWithDots = Path.Combine(RootRelativePath, relativePath);
109 |
110 | string absolutePath = Path.GetFullPath(_rootToAbsolutePathFunc(rootRelativePathWithDots));
111 | AssetPath assetPath = AbsolutePathToAssetPath(absolutePath);
112 | return assetPath;
113 | }
114 |
115 | ///
116 | /// Returns a list with parent dirs of this file or directory, and the file or directory itself.
117 | /// If stopDirectory is given, it will stop when it hits that directory. Otherwise, it stops at ~
118 | ///
119 | /// For example, suppose this object represents
120 | /// ~/Views/Shared/EditorTemplates/HomeAddress
121 | /// and the stopDirectory is
122 | /// Views
123 | ///
124 | /// Then this method returns
125 | /// ~/Views/Shared/EditorTemplates/HomeAddress
126 | /// ~/Views/Shared/EditorTemplates
127 | /// ~/Views/Shared
128 | ///
129 | ///
130 | public IEnumerable ParentDirs(string stopDirectory = "~")
131 | {
132 | List parentDirs = new List();
133 | string currentRootRelativePath = RootRelativePath;
134 |
135 | while (!currentRootRelativePath.EndsWith(stopDirectory))
136 | {
137 | parentDirs.Add(new AssetPath(currentRootRelativePath, _rootToAbsolutePathFunc));
138 | currentRootRelativePath = Path.GetDirectoryName(currentRootRelativePath);
139 | }
140 |
141 | return parentDirs;
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/BundleFactories.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Optimization;
7 |
8 | namespace DynamicBundles
9 | {
10 | public class BundleFactories
11 | {
12 | private Dictionary _log = null;
13 |
14 | public BundleFactories()
15 | {
16 | }
17 |
18 | ///
19 | /// Constructor
20 | ///
21 | ///
22 | /// A record of all bundle paths and the files in each bundle will be kept here.
23 | ///
24 | public BundleFactories(Dictionary log)
25 | {
26 | _log = log;
27 | }
28 |
29 | ///
30 | /// Creates a script bundle with the given path (= name) and files
31 | ///
32 | public ScriptBundle ScriptBundleFactory(string bundleVirtualPath, string[] fileRootRelativePaths)
33 | {
34 | return BundleWithPaths(new ScriptBundle(bundleVirtualPath), fileRootRelativePaths);
35 | }
36 |
37 | ///
38 | /// Creates a style bundle with the given path (= name) and files
39 | ///
40 | public StyleBundle StyleBundleFactory(string bundleVirtualPath, string[] fileRootRelativePaths)
41 | {
42 | return BundleWithPaths(new StyleBundle(bundleVirtualPath), fileRootRelativePaths);
43 | }
44 |
45 | private T BundleWithPaths(T bundle, string[] fileRootRelativePaths) where T: Bundle
46 | {
47 | bundle.Include(fileRootRelativePaths);
48 |
49 | if (_log != null)
50 | {
51 | _log[bundle.Path] = fileRootRelativePaths;
52 | }
53 |
54 | return bundle;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/BundleHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Optimization;
7 | using BundleTransformer.Core.Transformers;
8 |
9 | namespace DynamicBundles
10 | {
11 | internal class BundleHelper
12 | {
13 | ///
14 | /// Takes a list of lists of file paths. Each file path is root relative (starts with ~).
15 | /// Turns these lists of paths into bundles. Ensures each file path is added only once.
16 | ///
17 | /// Adds the bundles to the given bundle collection, but only if there is no bundle yet with the same files,
18 | /// regardless of the order of the files or casing. That is, (a.css, b.css) is regarded as the same as (B.css, a.css).
19 | /// Returns a list with the bundle paths, in the same order as the originating lists
20 | /// in the input list of lists.
21 | ///
22 | ///
23 | ///
24 | ///
25 | /// Used to create a new bundle object.
26 | ///
27 | ///
28 | public static List AddFileListsAsBundles(IDynamicBundleCollection bundles,
29 | List> fileLists,
30 | Func bundleFactory)
31 | {
32 | var bundleNames = new List();
33 | foreach (List fileList in fileLists)
34 | {
35 | if (fileList.Count > 0)
36 | {
37 |
38 | // You can optimise things by doing the deduping inside HashCodeForList, because that
39 | // represents the strings as integers (hash codes), which are faster to dedupe.
40 |
41 | IEnumerable filePathsList = fileList.Select(f => f.RootRelativePath);
42 |
43 | // Reverse the order of the files. Files that have been added later tend to be more generic
44 | // (such as files in _Layout are added before those in _LayoutContainer). This way, files that depend on the
45 | // more generic files are loaded later.
46 | string[] dedupedFileRootRelativePaths = filePathsList.Distinct().Reverse().ToArray();
47 |
48 | string listHashCode = StringListHelper.HashCodeForList(dedupedFileRootRelativePaths);
49 | string bundleName = "~/" + listHashCode;
50 |
51 | if (!bundles.Exists(bundleName))
52 | {
53 | Bundle newBundle = bundleFactory(bundleName, dedupedFileRootRelativePaths);
54 | bundles.Add(newBundle);
55 | }
56 |
57 | bundleNames.Add(bundleName);
58 | }
59 | }
60 |
61 | return bundleNames;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/CacheHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web;
7 | using System.Web.Caching;
8 |
9 | namespace DynamicBundles
10 | {
11 | public interface ICacheHelper
12 | {
13 | T Get(string cacheKey, Func createItem, IEnumerable directories);
14 | }
15 |
16 | public class CacheHelper : ICacheHelper
17 | {
18 | private static object lockThis = new Object();
19 |
20 | ///
21 | /// Gets an item from cache.
22 | /// If the item is not in cache, creates it and stores it, with a dependency on a collection of directories -
23 | /// so if a file is added/deleted or changed, the cache item is removed from cache.
24 | ///
25 | ///
26 | /// Type of the item.
27 | ///
28 | ///
29 | /// Cache key.
30 | ///
31 | ///
32 | /// Lambda that creates the item.
33 | ///
34 | ///
35 | /// New cache item is dependend on these directories.
36 | ///
37 | ///
38 | public T Get(string cacheKey, Func createItem, IEnumerable directories)
39 | {
40 | T item = (T)HttpContext.Current.Cache[cacheKey];
41 |
42 | if (item == null)
43 | {
44 | lock(lockThis)
45 | {
46 | item = (T)HttpContext.Current.Cache[cacheKey];
47 | if (item == null)
48 | {
49 | item = createItem();
50 | HttpContext.Current.Cache.Insert(cacheKey, item, new CacheDependency(directories.ToArray()));
51 | }
52 | }
53 | }
54 |
55 | return item;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DependencyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using DynamicBundles.Models;
7 | using System.IO;
8 | using System.Web;
9 |
10 | namespace DynamicBundles
11 | {
12 | public interface IDependencyResolver
13 | {
14 | FileListsByAssetType GetRequiredFilesForDirectory(AssetPath dirPath);
15 | }
16 |
17 | public class DependencyResolver : IDependencyResolver
18 | {
19 | ICacheHelper _cacheHelper = null;
20 |
21 | public DependencyResolver(ICacheHelper cacheHelper)
22 | {
23 | _cacheHelper = cacheHelper;
24 | }
25 |
26 | ///
27 | /// Takes the path to a directory and returns the files in that directory, the files in the parent directories (down to the Views or ~ dir),
28 | /// and all the files
29 | /// that that directory depends on (via .nuspec files).
30 | ///
31 | /// It does not go into sub directories.
32 | ///
33 | /// Uses caching to reduce trips to the file system.
34 | ///
35 | ///
36 | /// Path to the directory.
37 | ///
38 | ///
39 | /// The required files, split by asset type.
40 | ///
41 | public FileListsByAssetType GetRequiredFilesForDirectory(AssetPath dirPath)
42 | {
43 | string absolutePath = dirPath.AbsolutePath;
44 | var fileListsByAssetType = _cacheHelper.Get(absolutePath, () => GetRequiredFilesForDirectoryUnchached(dirPath), new[] { absolutePath });
45 | return fileListsByAssetType;
46 | }
47 |
48 | ///
49 | /// Same as GetRequiredFilesForDirectory, but uncached.
50 | ///
51 | ///
52 | /// Path to the directory.
53 | ///
54 | ///
55 | private FileListsByAssetType GetRequiredFilesForDirectoryUnchached(AssetPath dirPath)
56 | {
57 | FileListsByAssetType fileListsByAssetType = new FileListsByAssetType();
58 |
59 | // Note: parentDirs will contain dirPath itself.
60 | //
61 | // dirPath.ParentDirs will give you something like
62 | /// ~/Views/Shared/EditorTemplates/HomeAddress
63 | /// ~/Views/Shared/EditorTemplates
64 | /// ~/Views/Shared
65 | // However, the longer directory tends to have the more specific files. If there is a dependency between files in these
66 | // directories, it would be from more specific to less specific, not the other way around. So process the directories in
67 | // reverse order, so CSS and JS files in more common directories are loaded first.
68 |
69 | IEnumerable parentDirs = dirPath.ParentDirs("Views").Reverse();
70 | foreach (AssetPath parentDir in parentDirs)
71 | {
72 | AddRequiredFilesSingleDirectory(fileListsByAssetType, parentDir);
73 | }
74 |
75 | return fileListsByAssetType;
76 | }
77 |
78 | ///
79 | /// Adds all files in a single directory to a fileListsByAssetType
80 | ///
81 | ///
82 | ///
83 | private void AddRequiredFilesSingleDirectory(FileListsByAssetType fileListsByAssetType, AssetPath dirPath)
84 | {
85 | string absolutePath = dirPath.AbsolutePath;
86 | IEnumerable filePaths = Directory.EnumerateFiles(absolutePath);
87 |
88 | // Need to first process the nuspec files, and then the asset files.
89 | // This because the asset files may depend on the files pointed at by the nuspec files.
90 | for (int i = 0; i < 2; i++)
91 | {
92 | foreach (string filePath in filePaths)
93 | {
94 | if (i == 0)
95 | {
96 | if (NuspecFile.IsNuspecFile(filePath))
97 | {
98 | fileListsByAssetType.Append(GetDependencies(filePath, dirPath));
99 | }
100 | }
101 | else
102 | {
103 | AssetType? assetType = AssetTypeOfFile(filePath);
104 | if (assetType != null)
105 | {
106 | fileListsByAssetType.Add(dirPath.AbsolutePathToAssetPath(filePath), assetType.Value);
107 | }
108 | }
109 | }
110 | }
111 | }
112 |
113 | ///
114 | /// Reads the dependencies in a Nuspec file. These are directories.
115 | /// Accumulates the assets in those directories to in a FileListsByAssetType.
116 | /// This is then returned.
117 | ///
118 | /// This method calls the dependency resolver concurrently.
119 | ///
120 | ///
121 | /// Path of the nuspec file
122 | ///
123 | ///
124 | /// The directory where the nuspec file is located.
125 | ///
126 | ///
127 | private FileListsByAssetType GetDependencies(string absoluteNuspecPath, AssetPath nuspecFileDirPath)
128 | {
129 | FileListsByAssetType fileListsByAssetType = new FileListsByAssetType();
130 |
131 | var nuspecFile = new NuspecFile(absoluteNuspecPath);
132 | List dependencyAssetPaths = nuspecFile.DependencyIds.Select(d => nuspecFileDirPath.Create(d)).ToList();
133 |
134 | // Call the dependency resolver concurrently for each dependency
135 | foreach (AssetPath dependencyAssetPath in dependencyAssetPaths)
136 | {
137 | fileListsByAssetType.Append(GetRequiredFilesForDirectory(dependencyAssetPath));
138 | }
139 |
140 | return fileListsByAssetType;
141 | }
142 |
143 | ///
144 | /// Takes a file path, and returns the asset type of that file.
145 | /// If there is no known asset type for the file, returns null.
146 | ///
147 | ///
148 | ///
149 | private AssetType? AssetTypeOfFile(string filePath)
150 | {
151 | string extension = Path.GetExtension(filePath).ToLower();
152 |
153 | switch (extension)
154 | {
155 | case ".js":
156 | return AssetType.Script;
157 |
158 | case ".css":
159 | return AssetType.StyleSheet;
160 |
161 | default:
162 | return null;
163 | }
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DynamicBundleCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Optimization;
7 |
8 | namespace DynamicBundles
9 | {
10 | public interface IDynamicBundleCollection
11 | {
12 | bool Exists(string bundleName);
13 | void Add(Bundle bundleName);
14 | }
15 |
16 | ///
17 | /// Encapsulates the MVC BundleCollection. The difference is that this class
18 | /// implements IBundleCollection, so it can be replaced by a mock
19 | /// during unit testing.
20 | ///
21 | internal class DynamicBundleCollection : IDynamicBundleCollection
22 | {
23 | private BundleCollection _bundles = null;
24 |
25 | public DynamicBundleCollection(BundleCollection bundles)
26 | {
27 | _bundles = bundles;
28 | }
29 |
30 | ///
31 | /// Returns true if a bundle with the passed in name exists.
32 | ///
33 | public bool Exists(string bundleName)
34 | {
35 | return (_bundles.GetBundleFor(bundleName) != null);
36 | }
37 |
38 | ///
39 | /// Adds the given Bundle to the bundle collection
40 | ///
41 | public void Add(Bundle bundle)
42 | {
43 | _bundles.Add(bundle);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DynamicBundles.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {37C5ED5D-3951-4325-9191-BCD55DDDD3FE}
8 | Library
9 | Properties
10 | DynamicBundles
11 | DynamicBundles
12 | v4.5
13 | 512
14 | ..\packages\WebGrease.1.5.2\lib
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | false
35 |
36 |
37 |
38 | ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll
39 |
40 |
41 | ..\packages\BundleTransformer.Core.1.9.25\lib\net40\BundleTransformer.Core.dll
42 |
43 |
44 | ..\packages\JavaScriptEngineSwitcher.Core.1.2.0\lib\net40\JavaScriptEngineSwitcher.Core.dll
45 |
46 |
47 | True
48 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
49 |
50 |
51 | False
52 | ..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll
53 |
54 |
55 |
56 |
57 |
58 | False
59 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.Helpers.dll
60 |
61 |
62 | False
63 | ..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll
64 |
65 |
66 | False
67 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll
68 |
69 |
70 | False
71 | ..\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll
72 |
73 |
74 | False
75 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.dll
76 |
77 |
78 | False
79 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Deployment.dll
80 |
81 |
82 | False
83 | ..\packages\Microsoft.AspNet.WebPages.3.2.2\lib\net45\System.Web.WebPages.Razor.dll
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | ..\packages\WebGrease.1.5.2\lib\WebGrease.dll
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
127 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DynamicBundles.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $version$
6 | $title$
7 | $author$
8 | $author$
9 | http://getdynamicbundles.com/
10 | false
11 | $description$
12 | Copyright 2014
13 | MVC Bundles CSS JavaScript images HTML
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DynamicBundlesBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using DynamicBundles.Models;
7 | using System.Web.Optimization;
8 |
9 | namespace DynamicBundles
10 | {
11 | public class DynamicBundlesBuilder
12 | {
13 | IDynamicBundleCollection _bundles;
14 | ICacheHelper _cacheHelper;
15 | BundleFactories _bundleFactories;
16 |
17 | ///
18 | /// The bundle collection that the bundles will be added to.
19 | ///
20 | /// Outside tests, this would always be BundleTable.Bundles
21 | ///
22 | ///
23 | /// Cachehelper to use.
24 | ///
25 | public DynamicBundlesBuilder(IDynamicBundleCollection bundles, ICacheHelper cacheHelper, BundleFactories bundleFactories)
26 | {
27 | _bundles = bundles;
28 | _cacheHelper = cacheHelper;
29 | _bundleFactories = bundleFactories;
30 | }
31 |
32 | ///
33 | /// Builds the bundles that need to be loaded on the page.
34 | ///
35 | ///
36 | /// The directories with assets that need to be included. These directories may have dependencies
37 | /// on other directories, such as via .nuspec dependencies files and parent directories.
38 | ///
39 | /// When a view is processed, its directory is normally added to this list.
40 | ///
41 | ///
42 | /// The virtual paths of the generated script bundles.
43 | ///
44 | ///
45 | /// The virtual paths of the generated style bundles.
46 | ///
47 | public void Builder(List assetDirectoryList,
48 | out List scriptBundleVirtualPaths,
49 | out List styleBundleVirtualPaths)
50 | {
51 | var fileListsByAssetType = new FileListsByAssetType();
52 | var dependencyResolver = new DependencyResolver(_cacheHelper);
53 |
54 | foreach (AssetPath assetDirectory in assetDirectoryList)
55 | {
56 | FileListsByAssetType requiredFilesByAssetType = dependencyResolver.GetRequiredFilesForDirectory(assetDirectory);
57 | fileListsByAssetType.Append(requiredFilesByAssetType);
58 | }
59 |
60 | // fileListsByAssetType now contains all required files by asset type
61 |
62 | scriptBundleVirtualPaths = CreateBundles(fileListsByAssetType, AssetType.Script, _bundleFactories.ScriptBundleFactory);
63 | styleBundleVirtualPaths = CreateBundles(fileListsByAssetType, AssetType.StyleSheet, _bundleFactories.StyleBundleFactory);
64 | }
65 |
66 | private List CreateBundles(FileListsByAssetType fileListsByAssetType, AssetType assetType, Func bundleFactory)
67 | {
68 | List files = fileListsByAssetType.GetList(assetType);
69 | List> filesByAreaController = RouteHelper.FilePathsSortedByRoute(files);
70 | List bundleVirtualPaths = BundleHelper.AddFileListsAsBundles(_bundles, filesByAreaController, bundleFactory);
71 | return bundleVirtualPaths;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/DynamicBundlesViewEngine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Mvc;
7 |
8 | namespace DynamicBundles
9 | {
10 | public class DynamicBundlesViewEngine : RazorViewEngine
11 | {
12 | public DynamicBundlesViewEngine(): base()
13 | {
14 | // Finds views sitting in own directories, such as ~/Views/Home/Index/Index.cshtml.
15 | // Note that this only works if you specify only the name of the view ("Index"), because only then
16 | // does the view engine do a search. If you specify the path, then you need to specify the view's directory as well
17 | // (such as: "~/Views/Shared/_Layout/_Layout.cshtml")
18 | //
19 | // See book "Pro ASP.NET MVC 4, page 495
20 | ViewLocationFormats = new string[]
21 | {
22 | "~/Views/{1}/{0}/{0}.cshtml",
23 | "~/Views/{1}/{0}/{0}.vbhtml",
24 | "~/Views/Shared/{0}/{0}.cshtml",
25 | "~/Views/Shared/{0}/{0}.vbhtml"
26 | };
27 |
28 | MasterLocationFormats = ViewLocationFormats;
29 | PartialViewLocationFormats = ViewLocationFormats;
30 |
31 | AreaViewLocationFormats = new string[]
32 | {
33 | "~/Areas/{2}/Views/{1}/{0}/{0}.cshtml",
34 | "~/Areas/{2}/Views/{1}/{0}/{0}.vbhtml",
35 | "~/Areas/{2}/Views/Shared/{0}/{0}.cshtml",
36 | "~/Areas/{2}/Views/Shared/{0}/{0}.vbhtml"
37 | };
38 |
39 | AreaMasterLocationFormats = AreaViewLocationFormats;
40 | AreaPartialViewLocationFormats = AreaViewLocationFormats;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/HttpContextStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web;
7 |
8 | namespace DynamicBundles
9 | {
10 | ///
11 | /// Strongly typed access to the HttpContext.Items store, which holds
12 | /// per-request info.
13 | ///
14 | public static class HttpContextStore
15 | {
16 | private static readonly string AssetDirectoryItemKey = "__DynamicBundles_AssetDirectory";
17 | private static readonly string FirstTimeItemKey = "__DynamicBundles_FirstTime";
18 | private static readonly string TopBundleNamesItemKey = "__DynamicBundles_TopBundleNames";
19 | private static readonly string BottomBundleNamesItemKey = "__DynamicBundles_BottomBundleNames";
20 |
21 | ///
22 | /// Adds a directory with assets (script files, etc.) to the stored list of asset directories.
23 | ///
24 | ///
25 | public static void AddAssetDirectory(AssetPath dirPath)
26 | {
27 | List assetDirectoryList = (List)HttpContext.Current.Items[AssetDirectoryItemKey];
28 | if (assetDirectoryList == null)
29 | {
30 | assetDirectoryList = new List();
31 | HttpContext.Current.Items[AssetDirectoryItemKey] = assetDirectoryList;
32 | }
33 |
34 | assetDirectoryList.Add(dirPath);
35 | }
36 |
37 | ///
38 | /// Gets the list of asset directories
39 | ///
40 | ///
41 | public static List GetAssetDirectories()
42 | {
43 | List assetDirectoryList = (List)HttpContext.Current.Items[AssetDirectoryItemKey];
44 |
45 | // There should be at least one asset directory - that of the main view.
46 | if (assetDirectoryList == null)
47 | {
48 | throw new Exception("GetAssetDirectories - assetDirectoryList is null");
49 | }
50 |
51 | return assetDirectoryList;
52 | }
53 |
54 | ///
55 | /// Returns true if this is the first time this method is called
56 | /// for this request. Returns false otherwise.
57 | ///
58 | ///
59 | public static bool FirstTime()
60 | {
61 | object firstTimeSet = HttpContext.Current.Items[FirstTimeItemKey];
62 |
63 | if (firstTimeSet != null) { return false; }
64 |
65 | HttpContext.Current.Items[FirstTimeItemKey] = true;
66 |
67 | return true;
68 | }
69 |
70 | ///
71 | /// Stores the list with names of bundles that need to be rendered
72 | /// near the top of the _Layout file.
73 | ///
74 | public static void StoreTopBundleNames(List bundleNames)
75 | {
76 | HttpContext.Current.Items[TopBundleNamesItemKey] = bundleNames;
77 | }
78 |
79 | ///
80 | /// Gets the list with names of bundles that need to be rendered
81 | /// near the top of the _Layout file.
82 | ///
83 | public static List GetTopBundleNames()
84 | {
85 | List bundleNames = (List)HttpContext.Current.Items[TopBundleNamesItemKey];
86 |
87 | if (bundleNames == null)
88 | {
89 | throw new Exception("GetTopBundleNames - bundleNames is null");
90 | }
91 |
92 | return bundleNames;
93 | }
94 |
95 | ///
96 | /// Stores the list with names of bundles that need to be rendered
97 | /// near the bottom of the _Layout file.
98 | ///
99 | public static void StoreBottomBundleNames(List bundleNames)
100 | {
101 | HttpContext.Current.Items[BottomBundleNamesItemKey] = bundleNames;
102 | }
103 |
104 | ///
105 | /// Gets the list with names of bundles that need to be rendered
106 | /// near the bottom of the _Layout file.
107 | ///
108 | public static List GetBottomBundleNames()
109 | {
110 | List bundleNames = (List)HttpContext.Current.Items[BottomBundleNamesItemKey];
111 |
112 | if (bundleNames == null)
113 | {
114 | throw new Exception("GetBottomBundleNames - bundleNames is null");
115 | }
116 |
117 | return bundleNames;
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/Models/AssetType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DynamicBundles.Models
8 | {
9 | public enum AssetType
10 | {
11 | Script,
12 | StyleSheet
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/Models/FileListsByAssetType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DynamicBundles.Models
8 | {
9 | ///
10 | /// Stores lists of file paths by asset type.
11 | ///
12 | public class FileListsByAssetType: ListsByKey
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/Models/ListsByKey.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DynamicBundles.Models
8 | {
9 | ///
10 | /// Stores lists of T by keys of type K.
11 | ///
12 | public class ListsByKey
13 | {
14 | Dictionary> store = new Dictionary>();
15 |
16 | private Dictionary> Store
17 | {
18 | get { return store; }
19 | }
20 |
21 | public ListsByKey()
22 | {
23 | }
24 |
25 | ///
26 | /// Appends another ListsByKey to this ListsByKey.
27 | /// This means that the lists of T of the other ListsByKey are appended
28 | /// to the lists in this ListsByKey, by key.
29 | ///
30 | /// The order of the items in listsByKey is preserved.
31 | ///
32 | ///
33 | public void Append(ListsByKey listsByKey)
34 | {
35 | foreach (KeyValuePair> kvp in listsByKey.Store)
36 | {
37 | AddRange(kvp.Value, kvp.Key);
38 | }
39 | }
40 |
41 | ///
42 | /// Adds an item to the list with the given key.
43 | ///
44 | public void Add(T item, K key)
45 | {
46 | if (!store.ContainsKey(key))
47 | {
48 | store[key] = new List();
49 | }
50 |
51 | store[key].Add(item);
52 | }
53 |
54 | ///
55 | /// Adds a list of items to the list with the given key.
56 | ///
57 | public void AddRange(List items, K key)
58 | {
59 | if (!store.ContainsKey(key))
60 | {
61 | store[key] = new List();
62 | }
63 |
64 | store[key].AddRange(items);
65 | }
66 |
67 | ///
68 | /// Returns the list for the given key.
69 | ///
70 | ///
71 | ///
72 | public List GetList(K key)
73 | {
74 | if (!store.ContainsKey(key))
75 | {
76 | return new List();
77 | }
78 |
79 | return store[key];
80 | }
81 |
82 | ///
83 | /// Returns all lists, by key.
84 | ///
85 | ///
86 | public List>> GetListOfLists()
87 | {
88 | return store.ToList();
89 | }
90 |
91 |
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/NuGet/readme.txt:
--------------------------------------------------------------------------------
1 | ==================================
2 | DynamicBundles is not yet fully installed
3 | ==================================
4 |
5 | To finish the installation, a few more steps need to be done. See
6 |
7 | http://getdynamicbundles.com/#installation
8 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/NuspecFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using System.Xml.Serialization;
8 |
9 | namespace DynamicBundles
10 | {
11 | public class NuspecFile
12 | {
13 | #region classes
14 |
15 | ///
16 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
17 | [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
18 | public partial class package
19 | {
20 |
21 | private packageMetadata metadataField;
22 |
23 | private packageFile[] filesField;
24 |
25 | ///
26 | public packageMetadata metadata
27 | {
28 | get
29 | {
30 | return this.metadataField;
31 | }
32 | set
33 | {
34 | this.metadataField = value;
35 | }
36 | }
37 |
38 | ///
39 | [System.Xml.Serialization.XmlArrayItemAttribute("file", IsNullable = false)]
40 | public packageFile[] files
41 | {
42 | get
43 | {
44 | return this.filesField;
45 | }
46 | set
47 | {
48 | this.filesField = value;
49 | }
50 | }
51 | }
52 |
53 | ///
54 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
55 | public partial class packageMetadata
56 | {
57 |
58 | private string idField;
59 |
60 | private string versionField;
61 |
62 | private string titleField;
63 |
64 | private string authorsField;
65 |
66 | private string ownersField;
67 |
68 | private string projectUrlField;
69 |
70 | private string iconUrlField;
71 |
72 | private bool requireLicenseAcceptanceField;
73 |
74 | private string descriptionField;
75 |
76 | private string copyrightField;
77 |
78 | private string tagsField;
79 |
80 | private packageMetadataDependency[] dependenciesField;
81 |
82 | ///
83 | public string id
84 | {
85 | get
86 | {
87 | return this.idField;
88 | }
89 | set
90 | {
91 | this.idField = value;
92 | }
93 | }
94 |
95 | ///
96 | public string version
97 | {
98 | get
99 | {
100 | return this.versionField;
101 | }
102 | set
103 | {
104 | this.versionField = value;
105 | }
106 | }
107 |
108 | ///
109 | public string title
110 | {
111 | get
112 | {
113 | return this.titleField;
114 | }
115 | set
116 | {
117 | this.titleField = value;
118 | }
119 | }
120 |
121 | ///
122 | public string authors
123 | {
124 | get
125 | {
126 | return this.authorsField;
127 | }
128 | set
129 | {
130 | this.authorsField = value;
131 | }
132 | }
133 |
134 | ///
135 | public string owners
136 | {
137 | get
138 | {
139 | return this.ownersField;
140 | }
141 | set
142 | {
143 | this.ownersField = value;
144 | }
145 | }
146 |
147 | ///
148 | public string projectUrl
149 | {
150 | get
151 | {
152 | return this.projectUrlField;
153 | }
154 | set
155 | {
156 | this.projectUrlField = value;
157 | }
158 | }
159 |
160 | ///
161 | public string iconUrl
162 | {
163 | get
164 | {
165 | return this.iconUrlField;
166 | }
167 | set
168 | {
169 | this.iconUrlField = value;
170 | }
171 | }
172 |
173 | ///
174 | public bool requireLicenseAcceptance
175 | {
176 | get
177 | {
178 | return this.requireLicenseAcceptanceField;
179 | }
180 | set
181 | {
182 | this.requireLicenseAcceptanceField = value;
183 | }
184 | }
185 |
186 | ///
187 | public string description
188 | {
189 | get
190 | {
191 | return this.descriptionField;
192 | }
193 | set
194 | {
195 | this.descriptionField = value;
196 | }
197 | }
198 |
199 | ///
200 | public string copyright
201 | {
202 | get
203 | {
204 | return this.copyrightField;
205 | }
206 | set
207 | {
208 | this.copyrightField = value;
209 | }
210 | }
211 |
212 | ///
213 | public string tags
214 | {
215 | get
216 | {
217 | return this.tagsField;
218 | }
219 | set
220 | {
221 | this.tagsField = value;
222 | }
223 | }
224 |
225 | ///
226 | [System.Xml.Serialization.XmlArrayItemAttribute("dependency", IsNullable = false)]
227 | public packageMetadataDependency[] dependencies
228 | {
229 | get
230 | {
231 | return this.dependenciesField;
232 | }
233 | set
234 | {
235 | this.dependenciesField = value;
236 | }
237 | }
238 | }
239 |
240 | ///
241 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
242 | public partial class packageMetadataDependency
243 | {
244 |
245 | private string idField;
246 |
247 | private string versionField;
248 |
249 | ///
250 | [System.Xml.Serialization.XmlAttributeAttribute()]
251 | public string id
252 | {
253 | get
254 | {
255 | return this.idField;
256 | }
257 | set
258 | {
259 | this.idField = value;
260 | }
261 | }
262 |
263 | ///
264 | [System.Xml.Serialization.XmlAttributeAttribute()]
265 | public string version
266 | {
267 | get
268 | {
269 | return this.versionField;
270 | }
271 | set
272 | {
273 | this.versionField = value;
274 | }
275 | }
276 | }
277 |
278 | ///
279 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
280 | public partial class packageFile
281 | {
282 |
283 | private string srcField;
284 |
285 | private string targetField;
286 |
287 | ///
288 | [System.Xml.Serialization.XmlAttributeAttribute()]
289 | public string src
290 | {
291 | get
292 | {
293 | return this.srcField;
294 | }
295 | set
296 | {
297 | this.srcField = value;
298 | }
299 | }
300 |
301 | ///
302 | [System.Xml.Serialization.XmlAttributeAttribute()]
303 | public string target
304 | {
305 | get
306 | {
307 | return this.targetField;
308 | }
309 | set
310 | {
311 | this.targetField = value;
312 | }
313 | }
314 | }
315 | #endregion
316 |
317 | private package _package;
318 |
319 | ///
320 | /// Constructor.
321 | ///
322 | ///
323 | /// Absolute path of the Nuspec file.
324 | ///
325 | public NuspecFile(string absolutePath)
326 | {
327 | using (TextReader reader = new StreamReader(absolutePath))
328 | {
329 | XmlSerializer serializer = new XmlSerializer(typeof(package));
330 | _package = (package)serializer.Deserialize(reader);
331 | }
332 | }
333 |
334 | public static bool IsNuspecFile(string absolutePath)
335 | {
336 | string extension = Path.GetExtension(absolutePath);
337 | return (String.CompareOrdinal(extension, ".nuspec") == 0);
338 | }
339 |
340 | ///
341 | /// Returns the ids of the dependencies in the nuspec file.
342 | ///
343 | ///
344 | public IEnumerable DependencyIds
345 | {
346 | get
347 | {
348 | if ((_package.metadata == null) || (_package.metadata.dependencies == null)) { return new List(); }
349 |
350 | return _package.metadata.dependencies.Select(d => d.id);
351 | }
352 | }
353 | }
354 | }
355 |
356 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------
2 | // Generated.cs gets copied from Generated.cs.template
3 | // During the copy, 0.9.1 is replaced by the actual version.
4 | // ---------------------------------------------------------------------------
5 |
6 | using System.Reflection;
7 | using System.Runtime.CompilerServices;
8 | using System.Runtime.InteropServices;
9 |
10 | // General Information about an assembly is controlled through the following
11 | // set of attributes. Change these attribute values to modify the information
12 | // associated with an assembly.
13 | [assembly: AssemblyTitle("DynamicBundles - Dynamic MVC Bundles")]
14 | [assembly: AssemblyDescription("Co-locate HTML, CSS, JavaScript and image files that make up a page or component for easier reuse and maintainability. Auto generate your MVC bundles to ensure the right files are loaded in the right order.")]
15 | [assembly: AssemblyConfiguration("")]
16 | [assembly: AssemblyCompany("Matt Perdeck")]
17 | [assembly: AssemblyProduct("DynamicBundles")]
18 | [assembly: AssemblyCopyright("Copyright ? 2014")]
19 | [assembly: AssemblyTrademark("")]
20 | [assembly: AssemblyCulture("")]
21 |
22 | // Setting ComVisible to false makes the types in this assembly not visible
23 | // to COM components. If you need to access a type in this assembly from
24 | // COM, set the ComVisible attribute to true on that type.
25 | [assembly: ComVisible(false)]
26 |
27 | // The following GUID is for the ID of the typelib if this project is exposed to COM
28 | [assembly: Guid("12074b3f-e31f-4f70-ab10-4d6fde8d7209")]
29 |
30 | // Version information for an assembly consists of the following four values:
31 | //
32 | // Major Version
33 | // Minor Version
34 | // Build Number
35 | // Revision
36 | //
37 | // You can specify all the values or you can default the Build and Revision Numbers
38 | // by using the '*' as shown below:
39 | // [assembly: AssemblyVersion("1.0.*")]
40 | [assembly: AssemblyVersion("0.9.1")]
41 | [assembly: AssemblyFileVersion("0.9.1")]
42 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/Properties/AssemblyInfo.cs.template:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------
2 | // Generated.cs gets copied from Generated.cs.template
3 | // During the copy, __Version__ is replaced by the actual version.
4 | // ---------------------------------------------------------------------------
5 |
6 | using System.Reflection;
7 | using System.Runtime.CompilerServices;
8 | using System.Runtime.InteropServices;
9 |
10 | // General Information about an assembly is controlled through the following
11 | // set of attributes. Change these attribute values to modify the information
12 | // associated with an assembly.
13 | [assembly: AssemblyTitle("DynamicBundles - Dynamic MVC Bundles")]
14 | [assembly: AssemblyDescription("Co-locate HTML, CSS, JavaScript and image files that make up a page or component for easier reuse and maintainability. Auto generate your MVC bundles to ensure the right files are loaded in the right order.")]
15 | [assembly: AssemblyConfiguration("")]
16 | [assembly: AssemblyCompany("Matt Perdeck")]
17 | [assembly: AssemblyProduct("DynamicBundles")]
18 | [assembly: AssemblyCopyright("Copyright © 2014")]
19 | [assembly: AssemblyTrademark("")]
20 | [assembly: AssemblyCulture("")]
21 |
22 | // Setting ComVisible to false makes the types in this assembly not visible
23 | // to COM components. If you need to access a type in this assembly from
24 | // COM, set the ComVisible attribute to true on that type.
25 | [assembly: ComVisible(false)]
26 |
27 | // The following GUID is for the ID of the typelib if this project is exposed to COM
28 | [assembly: Guid("12074b3f-e31f-4f70-ab10-4d6fde8d7209")]
29 |
30 | // Version information for an assembly consists of the following four values:
31 | //
32 | // Major Version
33 | // Minor Version
34 | // Build Number
35 | // Revision
36 | //
37 | // You can specify all the values or you can default the Build and Revision Numbers
38 | // by using the '*' as shown below:
39 | // [assembly: AssemblyVersion("1.0.*")]
40 | [assembly: AssemblyVersion("__Version__")]
41 | [assembly: AssemblyFileVersion("__Version__")]
42 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/RouteHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using DynamicBundles.Models;
8 |
9 | namespace DynamicBundles
10 | {
11 | public class RouteHelper
12 | {
13 |
14 | ///
15 | /// Takes a list of paths and puts them in separate lists, by area and controller.
16 | /// So all files in Area "Admin" and Controller "Home" go into one list, whilst
17 | /// all files without Area and Controller "About" go into another list.
18 | ///
19 | /// Within the lists, the original order of the files is preserved. So if
20 | /// the input list contains two files in Area "Admin" and Controller "Home", they are
21 | /// added to the result list in the same order as in the input list.
22 | ///
23 | /// The list of lists is sorted as follows, to ensure that the caller can
24 | /// place library files (such as jQuery) ahead of other files in the bundles:
25 | ///
26 | /// * files with no Area, with controller Shared, and that live in a directory with a name starting with _Layout
27 | /// * files with no Area, with controller Shared
28 | /// * files with an Area, with controller Shared, and that live in a directory with a name starting with _Layout
29 | /// * files with an Area, with controller Shared
30 | /// * all other files.
31 | ///
32 | ///
33 | ///
34 | public static List> FilePathsSortedByRoute(List filePaths)
35 | {
36 | var filePathsBySortKey = new ListsByKey();
37 |
38 | foreach (AssetPath filePath in filePaths)
39 | {
40 | filePathsBySortKey.Add(filePath, FilePathSortKey(filePath));
41 | }
42 |
43 | var sortedListOfLists = filePathsBySortKey.GetListOfLists();
44 | sortedListOfLists.Sort((firstPair, nextPair) => firstPair.Key.CompareTo(nextPair.Key));
45 |
46 | List> result = sortedListOfLists.Select(p => p.Value).ToList();
47 | return result;
48 | }
49 |
50 | ///
51 | /// Takes a file path and returns a string formatted like this:
52 | ///
53 | /// * files with no Area, with controller Shared, and that live in a directory with a name starting with _Layout:
54 | /// @___@
55 | ///
56 | /// * files with no Area, with controller Shared, but don't live in a directory with a name starting with _Layout:
57 | /// @___@@
58 | ///
59 | /// * files with an Area, with controller Shared, and that live in a directory with a name starting with _Layout:
60 | /// [Area]___@
61 | ///
62 | /// * files with an Area, with controller Shared, but don't live in a directory with a name starting with _Layout:
63 | /// [Area]___@@
64 | ///
65 | /// * all other files, with no area
66 | /// @___[Controller]
67 | ///
68 | /// * all other files, with an area
69 | /// [Area]___[Controller]
70 | ///
71 | /// Note that alphabetically, @ sorts before any letter or digit.
72 | /// Also, @___@@ sorts after @___@.
73 | ///
74 | /// The method assumes that the file path is root relative, and follows MVC conventions:
75 | ///
76 | /// * path with an Area:
77 | /// ~/Areas/TestArea/Views/home/index/indexspecific.css
78 | ///
79 | /// * path without an Area:
80 | /// ~/Views/home/index/indexspecific.css
81 | ///
82 | /// If the file path doesn't adhere to this, the method returns
83 | /// @
84 | ///
85 | ///
86 | ///
87 | public static string FilePathSortKey(AssetPath assetPath)
88 | {
89 | string filePath = assetPath.RootRelativePath;
90 |
91 | if (!filePath.StartsWith("~/"))
92 | {
93 | throw new Exception(string.Format("FilePathSortKey - filePath {0} does not start with ~/", filePath));
94 | }
95 |
96 | string[] filePathComponents = filePath.Split(new char[] { '/' });
97 |
98 | // Note that the first element in filePathComponents will be the ~
99 | // The last element is the file name itself.
100 |
101 | string area = "@";
102 | int nbrComponents = filePathComponents.Length;
103 | int controllerIdx = 2;
104 |
105 | if (string.CompareOrdinal(filePathComponents[1], "Areas") == 0)
106 | {
107 | if ((nbrComponents < 6) || (string.CompareOrdinal(filePathComponents[3], "Views") != 0))
108 | {
109 | return "@";
110 | }
111 |
112 | area = filePathComponents[2];
113 | controllerIdx = 4;
114 | }
115 | else if (string.CompareOrdinal(filePathComponents[1], "Views") == 0)
116 | {
117 | if (nbrComponents < 4)
118 | {
119 | return "@";
120 | }
121 | }
122 | else
123 | {
124 | return "@";
125 | }
126 |
127 | string controller = filePathComponents[controllerIdx];
128 | if (string.CompareOrdinal(controller, "Shared") == 0)
129 | {
130 | controller = "@";
131 | }
132 |
133 | string postfix = "@";
134 | int postControllerDirectoryIdx = (controllerIdx + 1);
135 | if (nbrComponents > postControllerDirectoryIdx)
136 | {
137 | string postControllerDirectory = filePathComponents[postControllerDirectoryIdx].ToLower();
138 | if (postControllerDirectory.StartsWith("_layout"))
139 | {
140 | postfix = "";
141 | }
142 | }
143 |
144 | string sortKey = area + "___" + controller + postfix;
145 |
146 | return sortKey;
147 | }
148 | }
149 | }
150 |
151 |
152 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/StringListHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DynamicBundles
8 | {
9 | public static class StringListHelper
10 | {
11 | ///
12 | /// Returns a string that is unique to the given list of strings.
13 | /// Order and casing are not relevant here, so (a.css, b.css) and (B.css, a.css)
14 | /// give the same code.
15 | ///
16 | ///
17 | ///
18 | ///
19 | /// See http://stackoverflow.com/questions/670063/getting-hash-of-a-list-of-strings-regardless-of-order
20 | ///
21 | public static string HashCodeForList(IEnumerable list)
22 | {
23 | List codes = new List();
24 | foreach (string item in list)
25 | {
26 | codes.Add(item.ToLower().GetHashCode());
27 | }
28 |
29 | codes.Sort();
30 | long hash = 0;
31 |
32 | foreach (int code in codes)
33 | {
34 | unchecked {
35 | hash *= 251; // multiply by a prime number
36 | hash += code; // add next hash code
37 | }
38 | }
39 |
40 | return hash.ToString("X");
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/WebViewPage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Optimization;
7 | using System.Web;
8 | using System.IO;
9 | using DynamicBundles.Models;
10 |
11 | namespace DynamicBundles
12 | {
13 | ///
14 | /// All view classes inherit either this class, or WebViewPage
15 | ///
16 | public abstract class WebViewPage: System.Web.Mvc.WebViewPage
17 | {
18 | protected override void InitializePage()
19 | {
20 | WebViewPageStatic.InitializePage(this.VirtualPath);
21 | base.InitializePage();
22 | }
23 |
24 | public override void ExecutePageHierarchy()
25 | {
26 | WebViewPageStatic.ExecutePageHierarchy();
27 | base.ExecutePageHierarchy();
28 | }
29 |
30 | public static IHtmlString DynamicBundlesTopRender()
31 | {
32 | return WebViewPageStatic.DynamicBundlesTopRender();
33 | }
34 |
35 | public static IHtmlString DynamicBundlesBottomRender()
36 | {
37 | return WebViewPageStatic.DynamicBundlesBottomRender();
38 | }
39 | }
40 |
41 | public abstract class WebViewPage: System.Web.Mvc.WebViewPage
42 | {
43 | protected override void InitializePage()
44 | {
45 | WebViewPageStatic.InitializePage(this.VirtualPath);
46 | base.InitializePage();
47 | }
48 |
49 | public override void ExecutePageHierarchy()
50 | {
51 | WebViewPageStatic.ExecutePageHierarchy();
52 | base.ExecutePageHierarchy();
53 | }
54 |
55 | public static IHtmlString DynamicBundlesTopRender()
56 | {
57 | return WebViewPageStatic.DynamicBundlesTopRender();
58 | }
59 |
60 | public static IHtmlString DynamicBundlesBottomRender()
61 | {
62 | return WebViewPageStatic.DynamicBundlesBottomRender();
63 | }
64 | }
65 |
66 | internal static class WebViewPageStatic
67 | {
68 | private static DynamicBundlesBuilder _dynamicBundlesBuilder =
69 | new DynamicBundlesBuilder(new DynamicBundleCollection(BundleTable.Bundles),
70 | new CacheHelper(),
71 | new BundleFactories());
72 |
73 | ///
74 | /// Called when a view file is being processed, such as the main view file, partial views and layout views.
75 | ///
76 | ///
77 | /// Root relative path to the view.
78 | ///
79 | public static void InitializePage(string viewVirtualPath)
80 | {
81 | // Store the directory that the view file lives in
82 | HttpContextStore.AddAssetDirectory(new AssetPath(Path.GetDirectoryName(viewVirtualPath), HttpContext.Current.Server.MapPath));
83 | }
84 |
85 | ///
86 | /// ExecutePageHierarchy is executed after all InitializePage calls,
87 | /// but before the bundles are created.
88 | ///
89 | public static void ExecutePageHierarchy()
90 | {
91 | }
92 |
93 | ///
94 | /// Call this method from the top level _Layout view, in the head section.
95 | /// It replaces the normal
96 | /// @Styles.Render("....") and
97 | /// @Scripts.Render("....")
98 | /// lines that sit near the top of the page.
99 | ///
100 | /// It renders all the bundles that the page needs (these can be different per page) and need to go
101 | /// near the top (mainly style bundles).
102 | ///
103 | ///
104 | ///
105 | /// When this method is called, you have to add any bundles that need to be added,
106 | /// so the ones that need to be rendered at the top of the page can be rendered here.
107 | /// That is, when this runs, the time for gathering file dependencies is over and you need to
108 | /// process them into bundles.
109 | ///
110 | public static IHtmlString DynamicBundlesTopRender()
111 | {
112 | if (!HttpContextStore.FirstTime()) { return new HtmlString(""); }
113 |
114 | List assetDirectoryList = HttpContextStore.GetAssetDirectories();
115 | List scriptBundleVirtualPaths;
116 | List styleBundleVirtualPaths;
117 |
118 | _dynamicBundlesBuilder.Builder(assetDirectoryList, out scriptBundleVirtualPaths, out styleBundleVirtualPaths);
119 |
120 | HttpContextStore.StoreBottomBundleNames(scriptBundleVirtualPaths);
121 |
122 | // Note that Styles.Render assumes that all the bundles are StyleBundles
123 | return Styles.Render(styleBundleVirtualPaths.ToArray());
124 | }
125 |
126 | ///
127 | /// Same as DynamicBundlesTopRender, but to be used near the bottom of the page
128 | /// (would render script bundles).
129 | ///
130 | ///
131 | public static IHtmlString DynamicBundlesBottomRender()
132 | {
133 | // Note that this assumes that all the bundles are ScriptBundles
134 | return Scripts.Render(HttpContextStore.GetBottomBundleNames().ToArray());
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/DynamicBundles/DynamicBundles/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | dynamicbundles
2 | ==============
3 |
4 | Dependency resolver for MVC web sites, using MVC bundles
5 |
--------------------------------------------------------------------------------